Skip to content

Commit

Permalink
Merge pull request #15 from pimlicolabs/feature/getAccountNonce
Browse files Browse the repository at this point in the history
Add getAccountNonce
  • Loading branch information
kristofgazso authored Oct 5, 2023
2 parents 4f3e43e + 4b625b5 commit ec3df0c
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/two-boats-begin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"permissionless": patch
---

Added getAccountNonce
5 changes: 3 additions & 2 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {

import type { GetSenderAddressParams } from "./public"

import { getSenderAddress } from "./public"
import { getAccountNonce, getSenderAddress } from "./public"

export type {
SendUserOperationParameters,
Expand All @@ -41,5 +41,6 @@ export {
chainId,
getUserOperationByHash,
getUserOperationReceipt,
getSenderAddress
getSenderAddress,
getAccountNonce
}
65 changes: 63 additions & 2 deletions src/actions/public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
import { BaseError } from "viem"

export type GetSenderAddressParams = { initCode: Hex; entryPoint: Address }
export type GetAccountNonceParams = { address: Address; entryPoint: Address; key?: bigint }

export class InvalidEntryPointError extends BaseError {
override name = "InvalidEntryPointError"
Expand All @@ -31,8 +32,8 @@ export class InvalidEntryPointError extends BaseError {
*
*
* @param publicClient {@link PublicClient} that you created using viem's createPublicClient.
* @param args {@link GetSenderAddressParams}
* @returns Address
* @param args {@link GetSenderAddressParams} initCode & entryPoint
* @returns Sender's Address
*
* @example
* import { createPublicClient } from "viem"
Expand Down Expand Up @@ -102,3 +103,63 @@ export const getSenderAddress = async (

throw new InvalidEntryPointError({ entryPoint })
}

/**
* Returns the nonce of the account with the entry point.
*
* - Docs: https://docs.pimlico.io/permissionless/reference/public-actions/getAccountNonce
*
* @param publicClient {@link PublicClient} that you created using viem's createPublicClient.
* @param args {@link GetAccountNonceParams} address, entryPoint & key
* @returns bigint nonce
*
* @example
* import { createPublicClient } from "viem"
* import { getAccountNonce } from "permissionless/actions"
*
* const publicClient = createPublicClient({
* chain: goerli,
* transport: http("https://goerli.infura.io/v3/your-infura-key")
* })
*
* const nonce = await getAccountNonce(publicClient, {
* address,
* entryPoint,
* key
* })
*
* // Return 0n
*/
export const getAccountNonce = async (
publicClient: PublicClient,
{ address, entryPoint, key = 0n }: GetAccountNonceParams
): Promise<bigint> => {
return await publicClient.readContract({
address: entryPoint,
abi: [
{
inputs: [
{
name: "sender",
type: "address"
},
{
name: "key",
type: "uint192"
}
],
name: "getNonce",
outputs: [
{
name: "nonce",
type: "uint256"
}
],
stateMutability: "view",
type: "function"
}
],
functionName: "getNonce",
args: [address, key]
})
}
25 changes: 17 additions & 8 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getSenderAddress,
getUserOperationHash
} from "permissionless"
import { getAccountNonce } from "permissionless/actions"
import {
PimlicoBundlerClient,
PimlicoPaymasterClient,
Expand Down Expand Up @@ -116,13 +117,6 @@ const getDummySignature = (): Hex => {
return "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"
}

const getNonce = async (accountAddress: Address): Promise<bigint> => {
if (!(await isAccountDeployed(accountAddress))) {
return 0n
}
return entryPointContract.read.getNonce([accountAddress, BigInt(0)])
}

const testSupportedEntryPoints = async (bundlerClient: BundlerClient) => {
const supportedEntryPoints = await bundlerClient.supportedEntryPoints()

Expand All @@ -141,12 +135,27 @@ const buildUserOp = async (eoaWalletClient: WalletClient) => {
if (!accountAddress) throw new Error("Account address not found")

console.log("accountAddress", accountAddress)

const nonce = await getAccountNonce(publicClient, {
address: accountAddress,
entryPoint: entryPoint
})

console.log("nonce", nonce)

const oldNonce = await getAccountNonce(publicClient, {
address: "0xc1020c634b737e177249ff4b2236e58c661e037f",
entryPoint: entryPoint
})

console.log("old account nonce", oldNonce)

const userOperation: PartialBy<
UserOperation,
"maxFeePerGas" | "maxPriorityFeePerGas" | "callGasLimit" | "verificationGasLimit" | "preVerificationGas"
> = {
sender: accountAddress,
nonce: await getNonce(accountAddress),
nonce: nonce,
initCode: await getInitCode(factoryAddress, eoaWalletClient),
callData: await encodeExecute(zeroAddress as Hex, 0n, "0x" as Hex),
paymasterAndData: "0x" as Hex,
Expand Down

0 comments on commit ec3df0c

Please sign in to comment.