Skip to content

Commit

Permalink
Merge pull request #630 from nevermined-io/feat/zerodev-session-key
Browse files Browse the repository at this point in the history
feat: added support for zerodev session key providers
  • Loading branch information
r-marques authored Feb 14, 2024
2 parents 8998aad + 5abeea0 commit c64b26c
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nevermined-io/sdk",
"version": "2.1.4",
"version": "2.2.0",
"description": "Javascript SDK for connecting with Nevermined Data Platform ",
"main": "./dist/node/sdk.js",
"typings": "./dist/node/sdk.d.ts",
Expand Down
77 changes: 76 additions & 1 deletion src/keeper/contracts/ContractBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ethers,
} from 'ethers'
import { jsonReplacer, parseUnits } from '../../sdk'
import { ZeroDevAccountSigner } from '@zerodev/sdk'
import { SessionKeyProvider, ZeroDevAccountSigner } from '@zerodev/sdk'
export interface TxParameters {
value?: string
gasLimit?: bigint
Expand All @@ -20,6 +20,7 @@ export interface TxParameters {
maxFeePerGas?: string
signer?: ethers.Signer
zeroDevSigner?: ZeroDevAccountSigner<'ECDSA'>
sessionKeyProvider?: SessionKeyProvider
nonce?: number
progress?: (data: any) => void
}
Expand Down Expand Up @@ -232,6 +233,71 @@ export abstract class ContractBase extends Instantiable {
return transactionReceipt as ContractTransactionReceipt
}

private async internalSendSessionKeyProvider(
name: string,
from: string,
args: any[],
txparams: any,
progress: (data: any) => void,
): Promise<ContractTransactionReceipt> {
const { gasLimit, value } = txparams
const methodSignature = this.getSignatureOfMethod(name, args)

// make the call
if (progress) {
progress({
stage: 'sending',
args: this.searchMethodInputs(name, args),
method: name,
from,
value,
contractName: this.contractName,
contractAddress: this.address,
gasLimit,
})
}

// Send the transaction
const { hash } = await txparams.sessionKeyProvider.sendUserOperation({
target: this.address,
data: this.contract.interface.encodeFunctionData(methodSignature, args),
})

if (progress) {
progress({
stage: 'sent',
args: this.searchMethodInputs(name, args),
hash,
method: name,
from,
value,
contractName: this.contractName,
contractAddress: this.address,
gasLimit,
})
}

await txparams.sessionKeyProvider.waitForUserOperationTransaction(hash as `0x${string}`)
const userOperationReceipt = await txparams.sessionKeyProvider.getUserOperationReceipt(hash)
const receipt = userOperationReceipt.receipt

if (progress) {
progress({
stage: 'receipt',
args: this.searchMethodInputs(name, args),
receipt,
method: name,
from,
value,
contractName: this.contractName,
contractAddress: this.address,
gasLimit,
})
}

return receipt
}

public async send(
name: string,
from: string,
Expand All @@ -249,6 +315,15 @@ export abstract class ContractBase extends Instantiable {
contract,
params.progress,
)
} else if (params.sessionKeyProvider) {
const paramsFixed = { ...params, signer: undefined }
return await this.internalSendSessionKeyProvider(
name,
from,
args,
paramsFixed,
params.progress,
)
}

if (params.signer) {
Expand Down
8 changes: 5 additions & 3 deletions src/nevermined/Account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
import { TxParameters } from '../keeper'
import { KeeperError } from '../errors'
import { BigNumberish } from '../sdk'
import { ZeroDevAccountSigner } from '@zerodev/sdk'
import { SessionKeyProvider, ZeroDevAccountSigner } from '@zerodev/sdk'

/**
* Account information.
Expand All @@ -14,7 +14,7 @@ export class Account extends Instantiable {
public babyX?: string
public babyY?: string
public babySecret?: string
public zeroDevSigner: ZeroDevAccountSigner<'ECDSA'>
public zeroDevSigner: ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider

constructor(private id: string = '0x0', config?: InstantiableConfig) {
super()
Expand All @@ -29,7 +29,9 @@ export class Account extends Instantiable {
* @param signer - A zerodev account signer
* @returns The nevermined account
*/
static async fromZeroDevSigner(signer: ZeroDevAccountSigner<'ECDSA'>): Promise<Account> {
static async fromZeroDevSigner(
signer: ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider,
): Promise<Account> {
const address = await signer.getAddress()
const account = new Account(address)
account.zeroDevSigner = signer
Expand Down
12 changes: 7 additions & 5 deletions src/nevermined/utils/JwtUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract'
import { Account } from '../Account'
import { ethers } from 'ethers'
import { Babysig } from '../../models'
import { ZeroDevAccountSigner } from '@zerodev/sdk'
import { SessionKeyProvider, ZeroDevAccountSigner } from '@zerodev/sdk'

export interface Eip712Data {
message: string
Expand Down Expand Up @@ -32,7 +32,7 @@ export class EthSignJWT extends SignJWT {
}

public async ethSign(
signer: ethers.Signer | ZeroDevAccountSigner<'ECDSA'>,
signer: ethers.Signer | ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider,
eip712Data?: Eip712Data,
): Promise<string> {
const encoder = new TextEncoder()
Expand Down Expand Up @@ -99,7 +99,7 @@ export class EthSignJWT extends SignJWT {

private static async signMessage(
message: string | Uint8Array,
signer: ethers.Signer | ZeroDevAccountSigner<'ECDSA'>,
signer: ethers.Signer | ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider,
): Promise<string> {
if ((signer as ZeroDevAccountSigner<'ECDSA'>).signMessageWith6492) {
return (signer as ZeroDevAccountSigner<'ECDSA'>).signMessageWith6492(message)
Expand All @@ -112,7 +112,7 @@ export class EthSignJWT extends SignJWT {
domain: TypedDataDomain,
types: TypedDataTypes,
value: Record<string, any>,
signer: ethers.Signer | ZeroDevAccountSigner<'ECDSA'>,
signer: ethers.Signer | ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider,
): Promise<string> {
if ((signer as ZeroDevAccountSigner<'ECDSA'>).signTypedDataWith6492) {
return (signer as ZeroDevAccountSigner<'ECDSA'>).signTypedDataWith6492({
Expand Down Expand Up @@ -157,7 +157,9 @@ export class JwtUtils extends Instantiable {
this.tokenCache = new Map()
}

public async getSigner(account: Account): Promise<ethers.Signer | ZeroDevAccountSigner<'ECDSA'>> {
public async getSigner(
account: Account,
): Promise<ethers.Signer | ZeroDevAccountSigner<'ECDSA'> | SessionKeyProvider> {
const address = ethers.getAddress(account.getId())
return account.isZeroDev()
? account.zeroDevSigner
Expand Down

0 comments on commit c64b26c

Please sign in to comment.