Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

W3i register recaps #1559

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/components/PlatformTabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ const PLATFORM_MAP = [
{
value: 'web3js',
label: 'Web3.js'
},
{
value: '1clickauth',
label: '1 Click Auth'
}
]

Expand Down
153 changes: 150 additions & 3 deletions docs/web3inbox/frontend-integration/api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,8 @@ client.watchAccount(account => {
### Registering an account

<PlatformTabs
groupId="w3iw"
activeOptions={["react", "javascript"]}
>
groupId="w3iw-register"
activeOptions={["react", "javascript", "1clickauth"]}>

**Note**: [EIP-1271 signatures](https://eips.ethereum.org/EIPS/eip-1271) coming from smart wallets are supported in version `1.1.0` and above.

Expand Down Expand Up @@ -151,6 +150,154 @@ Some suggested methods of signing the message:

</PlatformTabItem>

<PlatformTabItem value="1clickauth">
With [1 Click Auth](https://docs.walletconnect.com/web3wallet/authenticatedSessions), you can avoid the secondary signature request needed for typical `register` call. Instead, you can use a SIWE config like the one below for [Web3Modal SIWE](TODO LINK HERE WHEN ITS OUT OF ALPHA)

```ts
let registerParams: Awaited<ReturnType<Web3InboxClient['prepareRegistrationViaRecaps']>> | null =
null

export const getMessageParams = async (client: Web3InboxClient | null) => {
if (!client) {
throw new Error('Client not ready yet')
}

registerParams = await client.prepareRegistrationViaRecaps({
domain: window.location.hostname,
allApps: true
})

const { cacaoPayload } = registerParams

return {
chains: wagmiConfig.chains.map(chain => chain.id),
domain: cacaoPayload.domain,
statement: cacaoPayload.statement ?? undefined,
uri: cacaoPayload.uri,
resources: cacaoPayload.resources
}
}

export const createMessage = ({ address, ...args }: SIWECreateMessageArgs) => {
if (!registerParams) {
throw new Error("Can't create message if registerParams is undefined")
}

registerParams = {
...registerParams,
cacaoPayload: {
...registerParams?.cacaoPayload,
...args
}
}

const message = formatMessage(registerParams.cacaoPayload, address)

// statement is generated in format message and not part of original payload.
const statement = message.split('\n')[3]
registerParams.cacaoPayload.statement = statement

return message
}

export const getNonce = async () => {
return registerParams?.cacaoPayload.nonce ?? 'FAILED_NONCE'
}

export const getSession = async (client: Web3InboxClient | null) => {
const { address, chainId } = getAccount({ ...wagmiConfig })

await waitFor(async () => !!client)

const account = `eip155:${chainId}:${address}`

const identityKey = await client?.getAccountIsRegistered(account)

const invalidSession = !(address && chainId && identityKey)

if (invalidSession) throw new Error('Failed to get account')

return {
address,
chainId
}
}

const verifySiweMessage = async (params: SIWEVerifyMessageArgs, client: Web3InboxClient | null) => {
if (!client) {
throw new Error('Failed to verify message - no client')
}

if (!registerParams) {
throw new Error('Failed to verify message - no registerParams saved')
}

// Start signing the signature modal so it does not show up
// in sign 2.5
const account = composeDidPkh(
`${getChainIdFromMessage(params.message)}:${getAddressFromMessage(params.message)}`
)

if (await client.getAccountIsRegistered(account)) {
return true
}

// Unregister account if registered with a faulty registration.
try {
await client.unregister({ account })
} catch (e) {}

await client.register({
registerParams: {
allApps: true,
cacaoPayload: {
...registerParams.cacaoPayload,
...params.cacao?.p,
iss: account
},
privateIdentityKey: registerParams.privateIdentityKey
},
signature: params.signature
})

return true
}

export const verifyMessage = async (
params: SIWEVerifyMessageArgs,
client: Web3InboxClient | null
) => {
try {
const messageIsValid = await verifySiweMessage(params, client)

const account = `${getChainIdFromMessage(params.message)}:${getAddressFromMessage(params.message)}`

if (messageIsValid) {
await waitFor(() => client!.getAccountIsRegistered(account))
}

return messageIsValid
} catch (e) {
return false
}
}
```

#### References

- **isRegistered:** A boolean of whether or not the account currently set is registered
- **prepareRegistration:** Prepare registration params
- **register:** Register using a signature and register params
- **isLoading:** A boolean, representing if an account is being registered

Some suggested methods of signing the message:

- `@wagmi/core` [`signMessage` method](https://wagmi.sh/core/api/actions/signMessage)
- The [`useSignMessage` hook](https://wagmi.sh/react/hooks/useSignMessage) in `@wagmi`
- Ethers.js [`Wallet.signMessage` method](https://docs.ethers.org/v5/api/signer/#Signer-signMessage)

</PlatformTabItem>

<PlatformTabItem value="javascript">

```ts
Expand Down