-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* docs: Passkeys in the SDK references (#495) * add passkeys in the doc references * Update pages/sdk/protocol-kit/reference/safe-factory.md Co-authored-by: Germán Martínez <[email protected]> * Update pages/sdk/protocol-kit/reference/safe.md Co-authored-by: Germán Martínez <[email protected]> * Update pages/sdk/protocol-kit/reference/safe.md Co-authored-by: Germán Martínez <[email protected]> * Update pages/sdk/protocol-kit/reference/safe.md Co-authored-by: Germán Martínez <[email protected]> * Update pages/sdk/relay-kit/reference/safe-4337-pack.mdx Co-authored-by: Germán Martínez <[email protected]> --------- Co-authored-by: Germán Martínez <[email protected]> * docs: Add Passkeys section, overview and guide (#498) * Add Passkeys section * Add Passkeys overview * Add passkeys guide * Create missing pages * Update steps style in Passkeys guide * fix: copy edits * feat: add safe and passkeys section * fix: vale errors * fix: formatting error * fix: updates based on feedback * feat: add flow diagram * fix: minor update * Add passkeys tutorial * Minor fixes to passkeys tutorial * Fix vale errors * Fix screenshots * Fix screenshots * fix: minor edits * fix: minor edits * Minor fixes * fix: correct term * Add passkeys FAQs * Minor fixes * feat: add new chains * Fix typo * Fix styling * fix: correct based on feedback * feat: add api reference for passkeys remove and swap owners (#505) * Fix typo in tutorial layout * Get tutorial code examples from github * Update 7579 code examples * Move passkeys code examples outside of the /pages folder * Add developer preview notice in 7579 and passkeys tutorials --------- Co-authored-by: Dani Somoza <[email protected]> Co-authored-by: Germán Martínez <[email protected]> Co-authored-by: Germán Martínez <[email protected]> Co-authored-by: Tanay Pant <tanaypantprotonmail.com> Co-authored-by: leonardotc <[email protected]>
- Loading branch information
1 parent
510c32b
commit 2dd756a
Showing
31 changed files
with
1,387 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
const fs = require('fs') | ||
|
||
const repos = [ | ||
{ | ||
organization: '5afe', | ||
repo: 'safe-passkeys-tutorial', | ||
destination: './examples/passkeys', | ||
branch: 'main', | ||
files: [ | ||
'/lib/constants.ts', | ||
'/lib/utils.ts', | ||
'/lib/passkeys.ts', | ||
'/lib/usdc.ts', | ||
'/components/PasskeyList.tsx', | ||
'/app/page.tsx', | ||
'/app/layout.tsx' | ||
] | ||
}, | ||
{ | ||
organization: '5afe', | ||
repo: 'safe-7579-tutorial', | ||
destination: './examples/erc-7579', | ||
branch: 'main', | ||
files: [ | ||
'/lib/permissionless.ts', | ||
'/lib/scheduledTransfers.ts', | ||
'/components/ScheduledTransferForm.tsx', | ||
'/app/page.tsx', | ||
'/app/layout.tsx' | ||
] | ||
} | ||
] | ||
|
||
const generateCodeExamples = async ({ | ||
organization, | ||
repo, | ||
branch, | ||
destination, | ||
files | ||
}) => { | ||
const fetch = await import('node-fetch') | ||
files.forEach(async filePath => { | ||
const url = `https://raw.githubusercontent.com/${organization}/${repo}/${branch}${filePath}?token=$(date +%s)` | ||
await fetch | ||
.default(url) | ||
.then(async res => { | ||
if (!res.ok) throw new Error(res.statusText) | ||
const text = await res.text() | ||
const destinationDirectory = | ||
destination + filePath.substring(0, filePath.lastIndexOf('/')) | ||
if (!fs.existsSync(destinationDirectory)) { | ||
fs.mkdirSync(destinationDirectory, { recursive: true }) | ||
} | ||
fs.writeFileSync(destination + filePath, text) | ||
}) | ||
.catch((res) => { | ||
console.error('Error fetching file for', filePath, ':', res.statusText) | ||
}) | ||
}) | ||
} | ||
|
||
repos.forEach(generateCodeExamples) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import type { Metadata } from 'next' | ||
import { Inter } from 'next/font/google' | ||
import Img from 'next/image' | ||
import './globals.css' | ||
|
||
const inter = Inter({ subsets: ['latin'] }) | ||
|
||
export const metadata: Metadata = { | ||
title: 'Safe Tutorial: Passkeys', | ||
description: 'Generated by create next app' | ||
} | ||
|
||
export default function RootLayout ({ | ||
children | ||
}: Readonly<{ | ||
children: React.ReactNode | ||
}>) { | ||
return ( | ||
<html lang='en'> | ||
<body className={inter.className}> | ||
<nav | ||
style={{ | ||
display: 'flex', | ||
justifyContent: 'space-between', | ||
padding: '1rem' | ||
}} | ||
> | ||
<a href='https://safe.global'> | ||
<Img width={95} height={36} alt='safe-logo' src='/safe.svg' /> | ||
</a> | ||
<div style={{ display: 'flex' }}> | ||
<a | ||
href='https://docs.safe.global/home/passkeys-tutorials/safe-passkeys-tutorial' | ||
style={{ | ||
display: 'flex', | ||
alignItems: 'center', | ||
marginRight: '1rem' | ||
}} | ||
> | ||
Read tutorial{' '} | ||
<Img | ||
width={20} | ||
height={20} | ||
alt='link-icon' | ||
src='/external-link.svg' | ||
style={{ marginLeft: '0.5rem' }} | ||
/> | ||
</a> | ||
<a | ||
href='https://github.com/5afe/safe-passkeys-tutorial' | ||
style={{ display: 'flex', alignItems: 'center' }} | ||
> | ||
View on GitHub{' '} | ||
<Img | ||
width={24} | ||
height={24} | ||
alt='github-icon' | ||
src='/github.svg' | ||
style={{ marginLeft: '0.5rem' }} | ||
/> | ||
</a> | ||
</div> | ||
</nav> | ||
<div style={{ width: '100%', textAlign: 'center' }}> | ||
<h1>Passkeys tutorial</h1> | ||
|
||
<div>Create a new 4337 compatible Safe Account using passkeys</div> | ||
</div> | ||
<div | ||
style={{ | ||
display: 'flex', | ||
alignItems: 'flex-start', | ||
justifyContent: 'space-between', | ||
marginLeft: '40px', | ||
marginRight: '40px' | ||
}} | ||
> | ||
{children} | ||
</div> | ||
</body> | ||
</html> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
'use client' | ||
|
||
import { useState } from 'react' | ||
import { Safe4337Pack } from '@safe-global/relay-kit' | ||
import Img from 'next/image' | ||
|
||
import PasskeyList from '../components/PasskeyList' | ||
import { executeUSDCTransfer } from '../lib/usdc' | ||
import { getPasskeyFromRawId, type PasskeyArgType } from '../lib/passkeys' | ||
import { BUNDLER_URL, CHAIN_NAME, RPC_URL } from '../lib/constants' | ||
import { bufferToString } from '../lib/utils' | ||
|
||
function Create4337SafeAccount () { | ||
const [selectedPasskey, setSelectedPasskey] = useState<PasskeyArgType>() | ||
const [safeAddress, setSafeAddress] = useState<string>() | ||
const [isSafeDeployed, setIsSafeDeployed] = useState<boolean>() | ||
const [userOp, setUserOp] = useState<string>() | ||
|
||
const selectPasskeySigner = async (rawId: string) => { | ||
console.log('selected passkey signer: ', rawId) | ||
|
||
const passkey = await getPasskeyFromRawId(rawId) | ||
|
||
const safe4337Pack = await Safe4337Pack.init({ | ||
provider: RPC_URL, | ||
rpcUrl: RPC_URL, | ||
signer: passkey, | ||
bundlerUrl: BUNDLER_URL, | ||
options: { | ||
owners: [], | ||
threshold: 1 | ||
} | ||
}) | ||
|
||
const safeAddress = await safe4337Pack.protocolKit.getAddress() | ||
const isSafeDeployed = await safe4337Pack.protocolKit.isSafeDeployed() | ||
|
||
setSelectedPasskey(passkey) | ||
setSafeAddress(safeAddress) | ||
setIsSafeDeployed(isSafeDeployed) | ||
} | ||
|
||
return ( | ||
<> | ||
<div | ||
style={{ | ||
width: '50%' | ||
}} | ||
> | ||
{selectedPasskey && ( | ||
<> | ||
<h2>Passkey Selected</h2> | ||
|
||
<div style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}> | ||
{bufferToString(selectedPasskey.rawId)} | ||
</div> | ||
</> | ||
)} | ||
<PasskeyList selectPasskeySigner={selectPasskeySigner} /> | ||
</div> | ||
{safeAddress && ( | ||
<div | ||
style={{ | ||
width: '50%' | ||
}} | ||
> | ||
<h2>Safe Account</h2> | ||
|
||
<div style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}> | ||
Address: {safeAddress} | ||
</div> | ||
<div> | ||
Is deployed?:{' '} | ||
{isSafeDeployed ? ( | ||
<a | ||
href={`https://app.safe.global/transactions/history?safe=sep:${safeAddress}`} | ||
target='_blank' | ||
rel='noreferrer' | ||
> | ||
Yes{' '} | ||
<Img | ||
src='/external-link.svg' | ||
alt='External link' | ||
width={14} | ||
height={14} | ||
/> | ||
</a> | ||
) : ( | ||
'No' | ||
)} | ||
</div> | ||
<div> | ||
{' '} | ||
<a | ||
href='https://faucet.circle.com/' | ||
target='_blank' | ||
rel='noreferrer' | ||
> | ||
Get some test USDC for your Safe{' '} | ||
<Img | ||
src='/external-link.svg' | ||
alt='External link' | ||
width={14} | ||
height={14} | ||
/> | ||
</a> | ||
</div> | ||
{selectedPasskey && ( | ||
<button | ||
onClick={async () => | ||
await executeUSDCTransfer({ | ||
signer: selectedPasskey, | ||
safeAddress | ||
}).then(userOpHash => { | ||
setUserOp(userOpHash) | ||
setIsSafeDeployed(true) | ||
}) | ||
} | ||
> | ||
Sign transaction with passkey | ||
</button> | ||
)} | ||
{userOp && isSafeDeployed && ( | ||
<> | ||
<div> | ||
Done! Check the transaction status on{' '} | ||
<a | ||
href={`https://jiffyscan.xyz/userOpHash/${userOp}?network=${CHAIN_NAME}`} | ||
target='_blank' | ||
rel='noreferrer' | ||
> | ||
Jiffy Scan{' '} | ||
<Img | ||
src='/external-link.svg' | ||
alt='External link' | ||
width={14} | ||
height={14} | ||
/> | ||
</a> | ||
</div> | ||
</> | ||
)} | ||
</div> | ||
)} | ||
</> | ||
) | ||
} | ||
|
||
export default Create4337SafeAccount |
Oops, something went wrong.