-
-
Notifications
You must be signed in to change notification settings - Fork 645
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: EIP-3074
signAuthMessage
+ utils (#2155)
* wip: signAuthMessage + utils * docs * chore: update snaps * chore: changeset
- Loading branch information
Showing
48 changed files
with
1,223 additions
and
127 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,9 @@ | ||
--- | ||
"viem": patch | ||
--- | ||
|
||
Added experimental 3074 utilties: | ||
|
||
- `signAuthMessage` | ||
- `recoverAuthMessageAddress` | ||
- `verifyAuthMessage` |
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
139 changes: 139 additions & 0 deletions
139
site/pages/experimental/eip3074/recoverAuthMessageAddress.mdx
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,139 @@ | ||
--- | ||
description: Recovers the original signing address from an auth message & signature. | ||
--- | ||
|
||
# recoverAuthMessageAddress | ||
|
||
Recovers the original signing address from an auth message & signature. | ||
|
||
## Usage | ||
|
||
:::code-group | ||
|
||
```ts twoslash [example.ts] | ||
import { recoverAuthMessageAddress } from 'viem/experimental' | ||
import { account, walletClient } from './config' | ||
|
||
const args = { | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
} | ||
|
||
const signature = await walletClient.signAuthMessage({ | ||
...args, | ||
account, | ||
}) | ||
|
||
const address = await recoverAuthMessageAddress({ // [!code focus:99] | ||
...args, | ||
signature, | ||
}) | ||
``` | ||
|
||
```ts twoslash [config.ts] filename="config.ts" | ||
import { createWalletClient, http } from 'viem' | ||
import { mainnet } from 'viem/chains' | ||
import { walletActionsEip3074 } from 'viem/experimental' | ||
|
||
export const walletClient = createWalletClient({ | ||
chain: mainnet, | ||
transport: http(), | ||
}).extend(walletActionsEip3074()) | ||
``` | ||
|
||
::: | ||
|
||
## Returns | ||
|
||
`Address` | ||
|
||
The recovered address. | ||
|
||
## Parameters | ||
|
||
### chainId | ||
|
||
- **Type:** `number` | ||
|
||
The chain ID. | ||
|
||
```ts | ||
const address = await recoverAuthMessageAddress({ | ||
chainId: 1, // [!code focus] | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
signature: | ||
'0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', | ||
}) | ||
``` | ||
|
||
### commit | ||
|
||
- **Type:** `Hash` | ||
|
||
The commit. | ||
|
||
```ts | ||
const address = await recoverAuthMessageAddress({ | ||
chainId: 1, | ||
commit: keccak256('0x1234'), // [!code focus] | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
signature: | ||
'0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', | ||
}) | ||
``` | ||
|
||
### invokerAddress | ||
|
||
- **Type:** `Hash` | ||
|
||
Address of the intended invoker. | ||
|
||
```ts | ||
const address = await recoverAuthMessageAddress({ | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] | ||
nonce: 69, | ||
signature: | ||
'0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', | ||
}) | ||
``` | ||
|
||
### nonce | ||
|
||
- **Type:** `Hash` | ||
|
||
Nonce of the sender account. | ||
|
||
```ts | ||
const address = await recoverAuthMessageAddress({ | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, // [!code focus] | ||
signature: | ||
'0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', | ||
}) | ||
``` | ||
|
||
### signature | ||
|
||
- **Type:** `Hex | ByteArray` | ||
|
||
The signature that was generated by signing the message with the address's private key. | ||
|
||
```ts | ||
const address = await recoverAuthMessageAddress({ | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
signature: // [!code focus:2] | ||
'0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', | ||
}) | ||
``` |
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,186 @@ | ||
# signAuthMessage | ||
|
||
Calculates an [EIP-3074](https://eips.ethereum.org/EIPS/eip-3074) auth signature. | ||
|
||
With the calculated signature, you can: | ||
|
||
- pass it to an EIP-3074 compatible invoker contract, | ||
- use [`verifyAuthMessage`](/experimental/eip3074/verifyAuthMessage) to verify the signature, | ||
- use [`recoverAuthMessageAddress`](/experimental/eip3074/recoverAuthMessageAddress) to recover the signing address from a signature. | ||
|
||
## Usage | ||
|
||
:::code-group | ||
|
||
```ts twoslash [example.ts] | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
import { account, walletClient } from './config' | ||
|
||
const account = privateKeyToAccount('0x...') | ||
|
||
const signature = await walletClient.signAuthMessage({ // [!code focus:99] | ||
account, | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
}) | ||
``` | ||
|
||
```ts twoslash [config.ts] filename="config.ts" | ||
import { createWalletClient, http } from 'viem' | ||
import { mainnet } from 'viem/chains' | ||
import { walletActionsEip3074 } from 'viem/experimental' | ||
|
||
export const walletClient = createWalletClient({ | ||
chain: mainnet, | ||
transport: http(), | ||
}).extend(walletActionsEip3074()) | ||
``` | ||
|
||
::: | ||
|
||
:::tip[Tip] | ||
|
||
Viem also exposes an `experimental_signAuthMessage` method on the `LocalAccount` interface. | ||
|
||
Helpful if you don't need the ceremony of setting up a Viem Client. | ||
|
||
```ts twoslash | ||
import { keccak256 } from 'viem' | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
|
||
// ---cut--- | ||
const account = privateKeyToAccount('0x...') | ||
|
||
const signature = await account.experimental_signAuthMessage({ | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
}) | ||
``` | ||
|
||
::: | ||
|
||
### Account Hoisting | ||
|
||
If you do not wish to pass an `account` to every `signAuthMessage`, you can also hoist the Account on the Wallet Client (see `config.ts`). | ||
|
||
[Learn more](/docs/clients/wallet#withaccount). | ||
|
||
:::code-group | ||
|
||
```ts twoslash [example.ts] | ||
import { walletClient } from './config' | ||
|
||
const signature = await walletClient.signAuthMessage({ // [!code focus:99] | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
}) | ||
``` | ||
|
||
```ts twoslash [config.ts] filename="config.ts" | ||
import { createWalletClient, http } from 'viem' | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
import { mainnet } from 'viem/chains' | ||
import { walletActionsEip3074 } from 'viem/experimental' | ||
|
||
export const walletClient = createWalletClient({ | ||
account: privateKeyToAccount('0x...'), // [!code ++] | ||
chain: mainnet, | ||
transport: http(), | ||
}).extend(walletActionsEip3074()) | ||
``` | ||
|
||
::: | ||
|
||
## Returns | ||
|
||
[`Hex`](/docs/glossary/types#hex) | ||
|
||
The signed auth message. | ||
|
||
## Parameters | ||
|
||
### chainId | ||
|
||
- **Type:** `number` | ||
|
||
The chain ID. | ||
|
||
```ts twoslash | ||
import { keccak256 } from 'viem' | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
|
||
const account = privateKeyToAccount('0x...') | ||
// ---cut--- | ||
const signature = await account.experimental_signAuthMessage({ | ||
chainId: 1, // [!code focus] | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
}) | ||
``` | ||
|
||
### commit | ||
|
||
- **Type:** `Hash` | ||
|
||
The commit. | ||
|
||
```ts twoslash | ||
import { keccak256 } from 'viem' | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
|
||
const account = privateKeyToAccount('0x...') | ||
// ---cut--- | ||
const signature = await account.experimental_signAuthMessage({ | ||
chainId: 1, | ||
commit: keccak256('0x1234'), // [!code focus] | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, | ||
}) | ||
``` | ||
|
||
### invokerAddress | ||
|
||
- **Type:** `Hash` | ||
|
||
Address of the intended invoker. | ||
|
||
```ts twoslash | ||
import { keccak256 } from 'viem' | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
|
||
const account = privateKeyToAccount('0x...') | ||
// ---cut--- | ||
const signature = await account.experimental_signAuthMessage({ | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] | ||
nonce: 69, | ||
}) | ||
``` | ||
|
||
### nonce | ||
|
||
- **Type:** `Hash` | ||
|
||
Nonce of the sender account. | ||
|
||
```ts twoslash | ||
import { keccak256 } from 'viem' | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
|
||
const account = privateKeyToAccount('0x...') | ||
// ---cut--- | ||
const signature = await account.experimental_signAuthMessage({ | ||
chainId: 1, | ||
commit: keccak256('0x1234'), | ||
invokerAddress: '0xd2135CfB216b74109775236E36d4b433F1DF507B', | ||
nonce: 69, // [!code focus] | ||
}) | ||
``` |
Oops, something went wrong.