Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/hip-starfishes-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"viem": patch
---

Made `getNonce` optional on `SmartAccountImplementation`.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Address, type TypedData, parseAbi } from 'abitype'
import type { Address, TypedData } from 'abitype'
import {
type WebAuthnData,
parseSignature as parseP256Signature,
Expand Down Expand Up @@ -132,19 +132,6 @@ export async function toCoinbaseSmartAccount(
return { factory: factory.address, factoryData }
},

async getNonce({ key = 0n } = {}) {
const address = await this.getAddress()
const nonce = await readContract(client, {
abi: parseAbi([
'function getNonce(address, uint192) pure returns (uint256)',
]),
address: entryPoint.address,
functionName: 'getNonce',
args: [address, key],
})
return nonce
},

async getStubSignature() {
if (owner.type === 'webAuthn')
return '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000001949fc7c88032b9fcb5f6efc7a7b8c63668eae9871b765e23123bb473ff57aa831a7c0d9276168ebcc29f2875a0239cffdf2a9cd1c2007c5c77c071db9264df1d000000000000000000000000000000000000000000000000000000000000002549960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2273496a396e6164474850596759334b7156384f7a4a666c726275504b474f716d59576f4d57516869467773222c226f726967696e223a2268747470733a2f2f7369676e2e636f696e626173652e636f6d222c2263726f73734f726967696e223a66616c73657d00000000000000000000000000000000000000000000'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Abi, type Address, type TypedData, parseAbi } from 'abitype'
import type { Abi, Address, TypedData } from 'abitype'

import { parseAccount } from '../../../accounts/utils/parseAccount.js'
import { readContract } from '../../../actions/public/readContract.js'
Expand Down Expand Up @@ -34,6 +34,7 @@ export type ToSoladySmartAccountParameters<
}
| undefined
factoryAddress?: Address | undefined
getNonce?: SmartAccountImplementation['getNonce'] | undefined
owner: Address | Account
salt?: Hex | undefined
}
Expand Down Expand Up @@ -86,6 +87,7 @@ export async function toSoladySmartAccount<
version: '0.7',
},
factoryAddress = '0x5d82735936c6Cd5DE57cC3c1A799f6B2E6F933Df',
getNonce,
salt = '0x0',
} = parameters

Expand All @@ -103,6 +105,7 @@ export async function toSoladySmartAccount<
return toSmartAccount({
client,
entryPoint,
getNonce,

extend: { abi, factory },

Expand Down Expand Up @@ -144,19 +147,6 @@ export async function toSoladySmartAccount<
return { factory: factory.address, factoryData }
},

async getNonce({ key = 0n } = {}) {
const address = await this.getAddress()
const nonce = await readContract(client, {
abi: parseAbi([
'function getNonce(address, uint192) pure returns (uint256)',
]),
address: entryPoint.address,
functionName: 'getNonce',
args: [address, key],
})
return nonce
},

async getStubSignature() {
return '0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c'
},
Expand Down
25 changes: 25 additions & 0 deletions src/account-abstraction/accounts/toSmartAccount.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -966,3 +966,28 @@ test('return value: `getFactoryArgs`', async () => {
}
`)
})

test('return value: `getNonce`', async () => {
const { factoryAddress } = await deploySoladyAccount_07()

const account = await toSoladySmartAccount({
client,
factoryAddress,
owner: accounts[1].address,
})
expect(await account.getNonce()).toBeDefined()
})

test('return value: `getNonce` (implementation override)', async () => {
const { factoryAddress } = await deploySoladyAccount_07()

const account = await toSoladySmartAccount({
client,
factoryAddress,
owner: accounts[1].address,
async getNonce() {
return 69n
},
})
expect(await account.getNonce()).toBe(69n)
})
17 changes: 15 additions & 2 deletions src/account-abstraction/accounts/toSmartAccount.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Abi } from 'abitype'
import { type Abi, parseAbi } from 'abitype'

import { getCode } from '../../actions/public/getCode.js'
import { readContract } from '../../actions/public/readContract.js'
import type { Prettify } from '../../types/utils.js'
import { getAction } from '../../utils/getAction.js'
import { createNonceManager } from '../../utils/nonceManager.js'
Expand Down Expand Up @@ -64,7 +65,19 @@ export async function toSmartAccount<
client: implementation.client,
}),
)
return await implementation.getNonce({ ...parameters, key })

if (implementation.getNonce)
return await implementation.getNonce({ ...parameters, key })

const nonce = await readContract(implementation.client, {
abi: parseAbi([
'function getNonce(address, uint192) pure returns (uint256)',
]),
address: implementation.entryPoint.address,
functionName: 'getNonce',
args: [address, key],
})
return nonce
},
async isDeployed() {
if (deployed) return true
Expand Down
18 changes: 15 additions & 3 deletions src/account-abstraction/accounts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,11 @@ export type SmartAccountImplementation<
* // 1n
* ```
*/
getNonce: (
parameters?: { key?: bigint | undefined } | undefined,
) => Promise<bigint>
getNonce?:
| ((
parameters?: { key?: bigint | undefined } | undefined,
) => Promise<bigint>)
| undefined
/**
* Retrieves the User Operation "stub" signature for gas estimation.
*
Expand Down Expand Up @@ -184,6 +186,16 @@ export type SmartAccount<
{
/** Address of the Smart Account. */
address: Address
/**
* Retrieves the nonce of the Account.
*
* @example
* ```ts
* const nonce = await account.getNonce()
* // 1n
* ```
*/
getNonce: NonNullable<SmartAccountImplementation['getNonce']>
/** Whether or not the Smart Account has been deployed. */
isDeployed: () => Promise<boolean>
/** Type of account. */
Expand Down