-
-
Notifications
You must be signed in to change notification settings - Fork 958
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: experimental solady erc1271 sign actions (#2413)
* wip: solady * Delete test/contracts/src/CounterfactualContractCall.sol * wip: add factory + factoryData to verifyHash * tweak * tweak * snaps * wip: checkpoint * docs * docs * size * rebase * size
- Loading branch information
Showing
24 changed files
with
2,430 additions
and
117 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,5 @@ | ||
--- | ||
"viem": patch | ||
--- | ||
|
||
**Experimental:** Added [Solady flavoured ERC-1271](https://github.com/Vectorized/solady/blob/678c9163550810b08f0ffb09624c9f7532392303/src/accounts/ERC1271.sol) `signMessage` & `signTypedData` for Smart Accounts that implement (or conform to) [Solady's `ERC1271.sol`](https://github.com/Vectorized/solady/blob/678c9163550810b08f0ffb09624c9f7532392303/src/accounts/ERC1271.sol#L110-L180). |
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,196 @@ | ||
--- | ||
description: Signs a personal sign message via Solady's ERC-1271 format. | ||
--- | ||
|
||
# signMessage | ||
|
||
Signs an [EIP-191](https://eips.ethereum.org/EIPS/eip-191) personal sign message via Solady's [ERC-1271 `PersonalSign` format](https://github.com/Vectorized/solady/blob/678c9163550810b08f0ffb09624c9f7532392303/src/accounts/ERC1271.sol#L154-L166). | ||
|
||
This Action is suitable to sign messages for contracts (e.g. ERC-4337 Smart Accounts) that implement (or conform to) Solady's [ERC1271.sol](https://github.com/Vectorized/solady/blob/main/src/accounts/ERC1271.sol). | ||
|
||
With the calculated signature, you can use [`verifyMessage`](/docs/actions/public/verifyMessage) to verify the signature | ||
|
||
## Usage | ||
|
||
:::code-group | ||
|
||
```ts twoslash [example.ts] | ||
import { account, walletClient } from './config' | ||
|
||
const signature_1 = await walletClient.signMessage({ // [!code focus:99] | ||
// Account used for signing. | ||
account, | ||
message: 'hello world', | ||
// Verifying contract address (e.g. ERC-4337 Smart Account). | ||
verifier: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2' | ||
}) | ||
|
||
const signature_2 = await walletClient.signMessage({ | ||
// Account used for signing. | ||
account, | ||
// Hex data representation of message. | ||
message: { raw: '0x68656c6c6f20776f726c64' }, | ||
// Verifying contract address (e.g. ERC-4337 Smart Account) | ||
verifier: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2' | ||
}) | ||
``` | ||
|
||
```ts twoslash [config.ts] filename="config.ts" | ||
import { createWalletClient, http } from 'viem' | ||
import { mainnet } from 'viem/chains' | ||
import { soladyActions } from 'viem/experimental' | ||
|
||
export const walletClient = createWalletClient({ | ||
chain: mainnet, | ||
transport: http(), | ||
}).extend(soladyActions()) | ||
|
||
export const [account] = await walletClient.getAddresses() | ||
// @log: ↑ JSON-RPC Account | ||
|
||
// export const account = privateKeyToAccount(...) | ||
// @log: ↑ Local Account | ||
``` | ||
|
||
::: | ||
|
||
## Account and/or Verifier Hoisting | ||
|
||
If you do not wish to pass an `account` and/or `verifier` to every `signMessage`, you can also hoist the Account and/or Verifier 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.signMessage({ // [!code focus:99] | ||
message: 'hello world', | ||
}) | ||
``` | ||
|
||
```ts [config.ts (JSON-RPC Account)] | ||
import { createWalletClient, custom } from 'viem' | ||
import { soladyActions } from 'viem/experimental' | ||
|
||
// Retrieve Account from an EIP-1193 Provider. | ||
const [account] = await window.ethereum.request({ | ||
method: 'eth_requestAccounts' | ||
}) | ||
|
||
export const walletClient = createWalletClient({ | ||
account, | ||
transport: custom(window.ethereum!) | ||
}).extend(soladyActions({ | ||
verifier: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2' | ||
})) | ||
``` | ||
|
||
```ts twoslash [config.ts (Local Account)] filename="config.ts" | ||
import { createWalletClient, http } from 'viem' | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
import { soladyActions } from 'viem/experimental' | ||
|
||
export const walletClient = createWalletClient({ | ||
account: privateKeyToAccount('0x...'), | ||
transport: http() | ||
}).extend(soladyActions({ | ||
verifier: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2' | ||
})) | ||
``` | ||
|
||
::: | ||
|
||
## Returns | ||
|
||
[`Hex`](/docs/glossary/types#hex) | ||
|
||
The signed message. | ||
|
||
## Parameters | ||
|
||
### account | ||
|
||
- **Type:** `Account | Address` | ||
|
||
Account to used to sign the message. | ||
|
||
Accepts a [JSON-RPC Account](/docs/clients/wallet#json-rpc-accounts) or [Local Account (Private Key, etc)](/docs/clients/wallet#local-accounts-private-key-mnemonic-etc). | ||
|
||
```ts twoslash | ||
import { walletClient } from './config' | ||
|
||
const signature = await walletClient.signMessage({ | ||
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus:1] | ||
message: 'hello world', | ||
verifier: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2' | ||
}) | ||
``` | ||
|
||
### message | ||
|
||
- **Type:** `string | { raw: Hex | ByteArray }` | ||
|
||
Message to sign. | ||
|
||
By default, viem signs the UTF-8 representation of the message. | ||
|
||
```ts twoslash | ||
import { walletClient } from './config' | ||
|
||
const signature = await walletClient.signMessage({ | ||
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', | ||
message: 'hello world', // [!code focus:1] | ||
verifier: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2', | ||
}) | ||
``` | ||
|
||
To sign the data representation of the message, you can use the `raw` attribute. | ||
|
||
```ts twoslash | ||
import { walletClient } from './config' | ||
|
||
const signature = await walletClient.signMessage({ | ||
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', | ||
message: { raw: '0x68656c6c6f20776f726c64' }, // [!code focus:1] | ||
verifier: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2', | ||
}) | ||
``` | ||
|
||
### verifier | ||
|
||
- **Type:** `Address` | ||
|
||
The address of the verifying contract (e.g. a ERC-4337 Smart Account). Required if `verifierDomain` is not passed. | ||
|
||
```ts twoslash | ||
import { walletClient } from './config' | ||
|
||
const signature = await walletClient.signMessage({ | ||
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', | ||
message: 'hello world', | ||
verifier: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2', // [!code focus:1] | ||
}) | ||
``` | ||
|
||
### verifierDomain | ||
|
||
- **Type:** `TypedDataDomain` | ||
|
||
Account domain separator. Required if `verifier` is not passed. | ||
|
||
```ts twoslash | ||
import { walletClient } from './config' | ||
|
||
const signature = await walletClient.signMessage({ | ||
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', | ||
message: 'hello world', | ||
verifierDomain: { // [!code focus] | ||
name: 'Mock4337Account', // [!code focus] | ||
version: '1', // [!code focus] | ||
chainId: 1, // [!code focus] | ||
verifyingContract: '0xCB9fA1eA9b8A3bf422a8639f23Df77ea66020eC2' // [!code focus] | ||
}, // [!code focus] | ||
}) | ||
``` |
Oops, something went wrong.