Skip to content

Commit

Permalink
feat: initial upgrade of zerodev
Browse files Browse the repository at this point in the history
  • Loading branch information
eruizgar91 committed Jan 15, 2025
1 parent 6d19581 commit f301047
Show file tree
Hide file tree
Showing 13 changed files with 235 additions and 195 deletions.
20 changes: 8 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@
},
"homepage": "https://github.com/nevermined-io/sdk-js#readme",
"dependencies": {
"@alchemy/aa-core": "3.12.1",
"@apollo/client": "^3.7.16",
"@turnkey/viem": "0.4.16",
"@zerodev/ecdsa-validator": "5.2.3",
"@zerodev/sdk": "5.2.11",
"@zerodev/session-key": "5.3.0",
"@zerodev/ecdsa-validator": "^5.4.1",
"@zerodev/sdk": "^5.4.9",
"@zerodev/session-key": "^5.5.0",
"assert": "^2.0.0",
"cross-fetch": "^4.0.0",
"crypto-browserify": "^3.12.0",
Expand All @@ -71,24 +70,21 @@
"node-fetch": "^2.6.1",
"os-browserify": "^0.3.0",
"path-browserify": "^1.0.1",
"permissionless": "^0.1.22",
"pluralize": "^8.0.0",
"save-file": "^2.3.1",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"url": "^0.11.0",
"uuid": "^9.0.1",
"viem": "2.9.31",
"viem": "2.22.8",
"vm-browserify": "^1.1.2",
"whatwg-url": "^14.0.0"
},
"peerDependencies": {
"@alchemy/aa-core": "3.12.1",
"@zerodev/ecdsa-validator": "^5.2.3",
"@zerodev/sdk": "^5.2.11",
"@zerodev/session-key": "^5.3.0",
"permissionless": "^0.1.26",
"viem": "2.9.31"
"@zerodev/ecdsa-validator": "^5.4.1",
"@zerodev/sdk": "^5.4.9",
"@zerodev/session-key": "^5.5.0",
"viem": "2.22.8"
},
"devDependencies": {
"@ambire/signature-validator": "^1.3.1",
Expand Down
5 changes: 5 additions & 0 deletions src/interfaces.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="node" />

interface Window {
ethereum?: any
}
20 changes: 9 additions & 11 deletions src/keeper/contracts/ContractBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
getInputsOfFunctionFormatted,
getSignatureOfFunction,
} from '../../nevermined/utils/BlockchainViemUtils'
import { ENTRYPOINT_ADDRESS_V06, bundlerActions } from 'permissionless'

export abstract class ContractBase extends Instantiable {
public readonly contractName: string
Expand Down Expand Up @@ -188,23 +187,22 @@ export abstract class ContractBase extends Instantiable {

const kernelClient = from.getKernelClient()
const data = encodeFunctionData({ abi: this.contract.abi, functionName: name, args })
// @ts-ignore
const txHash = await kernelClient.sendUserOperation({
userOperation: {
// @ts-ignore
callData: await kernelClient.account.encodeCallData({

const userOpHash = await kernelClient!.sendUserOperation({
callData: await kernelClient!.account.encodeCalls([
{
to: this.address,
value: txparams.value || 0n,
data,
}),
},
},
]),
})

if (progress) {
progress({
stage: 'sent',
args: functionInputs,
txHash,
userOpHash,
method: name,
from: from.getAccountSigner(),
value,
Expand All @@ -215,8 +213,8 @@ export abstract class ContractBase extends Instantiable {
}

// @ts-ignore
const bundlerClient = kernelClient.extend(bundlerActions(ENTRYPOINT_ADDRESS_V06))
const txReceipt = await bundlerClient.waitForUserOperationReceipt({ hash: txHash })
// const bundlerClient = kernelClient.extend(bundlerActions(ENTRYPOINT_ADDRESS_V06))
const txReceipt = await kernelClient!.waitForUserOperationReceipt({ hash: userOpHash })

if (progress) {
progress({
Expand Down
32 changes: 8 additions & 24 deletions src/models/NvmAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Account, Chain, LocalAccount, PrivateKeyAccount, Transport, toHex } fro
import { NvmAccountError } from '../errors/NeverminedErrors'
import { NvmAccountType } from '../types/AccountTypes'
import { parseAccount } from 'viem/utils'
import { KernelAccountClient, KernelSmartAccount } from '@zerodev/sdk'
import { KernelAccountClient } from '@zerodev/sdk'
import { SmartAccount } from 'viem/_types/account-abstraction'

/**
* Account information.
Expand All @@ -13,13 +14,8 @@ export class NvmAccount {
public babyY?: string
public babySecret?: string
private accountSigner?: Account | PrivateKeyAccount
private kernelClient?: KernelAccountClient<
'0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
Transport,
Chain,
any
>
private zeroDevSigner?: KernelSmartAccount<any> // ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider
private kernelClient?: KernelAccountClient<Transport, Chain, any>
private zeroDevSigner?: SmartAccount<any> // ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider
public accountType: NvmAccountType = { signerType: 'local', isZeroDev: false }

/**
Expand Down Expand Up @@ -54,12 +50,7 @@ export class NvmAccount {
* @returns The nevermined account
*/
static async fromZeroDevSigner(
kernelClient: KernelAccountClient<
'0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
Transport,
Chain,
any
>, // | ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider,
kernelClient: KernelAccountClient<Transport, Chain, any>, // | ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider,
): Promise<NvmAccount> {
const address = kernelClient.account.address
const account = new NvmAccount(address, { signerType: 'zerodev', isZeroDev: true })
Expand All @@ -68,14 +59,7 @@ export class NvmAccount {
return account
}

static fromZeroDevSessionKey(
kernelClient: KernelAccountClient<
'0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
Transport,
Chain,
any
>,
) {
static fromZeroDevSessionKey(kernelClient: KernelAccountClient<Transport, Chain, any>) {
const address = kernelClient.account.address
const account = new NvmAccount(address, { signerType: 'sessionKey', isZeroDev: true })
account.kernelClient = kernelClient
Expand All @@ -102,8 +86,8 @@ export class NvmAccount {
public getType() {
return this.accountType.signerType
}
public getZeroDevSigner(): KernelSmartAccount<any> {
return this.zeroDevSigner
public getZeroDevSigner(): SmartAccount<any> {
return this.zeroDevSigner!
}

public isZeroDev(): boolean {
Expand Down
6 changes: 3 additions & 3 deletions src/nevermined/NvmApp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SmartAccountSigner } from 'permissionless/accounts'
import { SmartAccount } from 'viem/account-abstraction'
import { NETWORK_FEE_DENOMINATOR } from '../constants/AssetConstants'
import { DDO } from '../ddo/DDO'
import { Web3Error } from '../errors/NeverminedErrors'
Expand Down Expand Up @@ -75,7 +75,7 @@ export class NvmApp {
private userAccount: NvmAccount | undefined
private searchSDK: Nevermined
private fullSDK: Nevermined | undefined
private zeroDevSignerAccount: SmartAccountSigner<'custom', `0x${string}`> | undefined
private zeroDevSignerAccount: SmartAccount | undefined
public assetProviders: NeverminedNodeInfo[] = []
private loginCredentials: string | undefined
private networkFeeReceiver: string | undefined
Expand Down Expand Up @@ -149,7 +149,7 @@ export class NvmApp {
* @returns An object containing the marketplace authentication token, user account, and zeroDev signer account (if applicable).
*/
public async connect(
account: string | NvmAccount | SmartAccountSigner<'custom', `0x${string}`>,
account: string | NvmAccount | SmartAccount,
message?: string,
config?: NeverminedOptions,
initOptions?: NeverminedInitializationOptions,
Expand Down
70 changes: 46 additions & 24 deletions src/nevermined/utils/BlockchainViemUtils.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator'
import {
SponsorUserOperationParameters,
createKernelAccount,
createKernelAccountClient,
createZeroDevPaymasterClient,
getUserOperationGasPrice,
} from '@zerodev/sdk'
import { KERNEL_V2_4, getEntryPoint } from '@zerodev/sdk/constants'
import {
deserializeSessionKeyAccount,
oneAddress,
serializeSessionKeyAccount,
signerToSessionKeyValidator,
} from '@zerodev/session-key'
import { ENTRYPOINT_ADDRESS_V06 } from 'permissionless'
import { EntryPoint } from 'permissionless/types'
import {
Abi,
AbiEvent,
AbiFunction,
Account,
PublicClient,
TransactionReceiptNotFoundError,
createPublicClient,
Expand Down Expand Up @@ -153,9 +153,12 @@ export async function deployContractInstance(
args: string[] = [],
client: Web3Clients,
) {
if (from.getAccountSigner()?.type === 'smart') {
throw new KeeperError(`Account not initialized`)
}
const txHash = await client.wallet.deployContract({
abi: artifact.abi,
account: from.getAccountSigner(),
account: from.getAccountSigner() as Account,
bytecode: artifact.bytecode,
chain: client.chain,
})
Expand Down Expand Up @@ -538,36 +541,50 @@ export async function createKernelClient(signer: any, chainId: number, zeroDevPr

const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
signer,
entryPoint: ENTRYPOINT_ADDRESS_V06,
entryPoint: getEntryPoint('0.6'),
kernelVersion: KERNEL_V2_4,
})

const account = await createKernelAccount(publicClient, {
plugins: {
sudo: ecdsaValidator,
},
entryPoint: ENTRYPOINT_ADDRESS_V06,
entryPoint: getEntryPoint('0.6'),
kernelVersion: KERNEL_V2_4,
})

return createKernelAccountClient({
account,
entryPoint: ENTRYPOINT_ADDRESS_V06,
chain: getChain(chainId),
bundlerTransport: http(`https://rpc.zerodev.app/api/v2/bundler/${zeroDevProjectId}`),
middleware: {
sponsorUserOperation: async ({ userOperation }) => {
const paymasterClient = createZeroDevPaymasterClient({
client: publicClient,
paymaster: {
getPaymasterData: (userOperation) => {
const zerodevPaymaster = createZeroDevPaymasterClient({
chain: getChain(chainId),
transport: http(`https://rpc.zerodev.app/api/v2/paymaster/${zeroDevProjectId}`),
entryPoint: ENTRYPOINT_ADDRESS_V06,
})
const _userOperation =
userOperation as SponsorUserOperationParameters<EntryPoint>['userOperation']
return paymasterClient.sponsorUserOperation({
userOperation: _userOperation,
entryPoint: ENTRYPOINT_ADDRESS_V06,
return zerodevPaymaster.sponsorUserOperation({
userOperation,
})
},
},
userOperation: {
estimateFeesPerGas: async ({ bundlerClient }) => {
return getUserOperationGasPrice(bundlerClient)
},
},

// middleware: {
// sponsorUserOperation: async ({ userOperation }) => {
// const _userOperation =
// userOperation as SponsorUserOperationParameters['userOperation']
// return paymasterClient.sponsorUserOperation({
// userOperation: _userOperation,
// entryPoint: getEntryPoint("0.6")
// })
// },
// },
})
}

Expand All @@ -580,15 +597,17 @@ export async function createKernelClient(signer: any, chainId: number, zeroDevPr
*/
export async function createSessionKey(signer: any, publicClient: any, permissions: any[]) {
const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
entryPoint: ENTRYPOINT_ADDRESS_V06,
entryPoint: getEntryPoint('0.6'),
signer,
kernelVersion: KERNEL_V2_4,
})
const sessionPrivateKey = generatePrivateKey()
const sessionKeySigner = privateKeyToAccount(sessionPrivateKey)

const sessionKeyValidator = await signerToSessionKeyValidator(publicClient, {
entryPoint: ENTRYPOINT_ADDRESS_V06,
entryPoint: getEntryPoint('0.6'),
signer: sessionKeySigner,
kernelVersion: KERNEL_V2_4,
validatorData: {
paymaster: oneAddress,
validAfter: 0,
Expand All @@ -597,7 +616,8 @@ export async function createSessionKey(signer: any, publicClient: any, permissio
},
})
const sessionKeyAccount = await createKernelAccount(publicClient, {
entryPoint: ENTRYPOINT_ADDRESS_V06,
entryPoint: getEntryPoint('0.6'),
kernelVersion: KERNEL_V2_4,
plugins: {
sudo: ecdsaValidator,
regular: sessionKeyValidator,
Expand All @@ -621,21 +641,23 @@ export async function getSessionKey(
const chainId = await publicClient.getChainId()
const sessionKeyAccount = await deserializeSessionKeyAccount(
publicClient,
ENTRYPOINT_ADDRESS_V06,
getEntryPoint('0.6'),
KERNEL_V2_4,
serializedSessionKey,
)
const kernelPaymaster = createZeroDevPaymasterClient({
entryPoint: ENTRYPOINT_ADDRESS_V06,
chain: getChain(chainId),
transport: http(`https://rpc.zerodev.app/api/v2/paymaster/${zeroDevProjectId}`),
})

const kernelClient = createKernelAccountClient({
entryPoint: ENTRYPOINT_ADDRESS_V06,
account: sessionKeyAccount,
chain: getChain(chainId),
bundlerTransport: http(`https://rpc.zerodev.app/api/v2/bundler/${zeroDevProjectId}`),
middleware: {
sponsorUserOperation: kernelPaymaster.sponsorUserOperation,
paymaster: {
getPaymasterData(userOperation) {
return kernelPaymaster.sponsorUserOperation({ userOperation })
},
},
})
return NvmAccount.fromZeroDevSessionKey(kernelClient)
Expand Down
4 changes: 2 additions & 2 deletions src/nevermined/utils/SignatureUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class SignatureUtils extends Instantiable {
typeof account === 'string' ? this.nevermined.accounts.getAccount(account) : account

if (nvmAccount.isZeroDev()) {
const result = await nvmAccount.getAccountSigner().signMessage({ message })
const result = await nvmAccount.getAccountSigner()?.signMessage({ message })
return result
} else if (nvmAccount.accountType.signerType === 'local') {
return (nvmAccount.getAccountSigner() as LocalAccount).signMessage({
Expand Down Expand Up @@ -75,7 +75,7 @@ export class SignatureUtils extends Instantiable {
typeof account === 'string' ? this.nevermined.accounts.getAccount(account) : account

if (nvmAccount.isZeroDev()) {
return await nvmAccount.getAccountSigner().signTransaction({ data: tx })
return await nvmAccount.getAccountSigner()!.signTransaction({ data: tx })
} else if (nvmAccount.accountType.signerType === 'local') {
return (nvmAccount.getAccountSigner() as LocalAccount).signTransaction({
data: tx,
Expand Down
18 changes: 0 additions & 18 deletions src/permissionless.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/types/AccountTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface NvmAccountType {
signerType: 'local' | 'json-rpc' | 'zerodev' | 'sessionKey'
signerType: 'local' | 'json-rpc' | 'smart' | 'zerodev' | 'sessionKey'
isZeroDev: boolean
}
Loading

0 comments on commit f301047

Please sign in to comment.