From 33aca843ad51fecf07078b37947b849d3b51d05d Mon Sep 17 00:00:00 2001 From: Vignesh Date: Thu, 27 Jul 2023 13:27:24 +0530 Subject: [PATCH 1/2] enabled the use of paymaster --- src/sdk/base/BaseAccountAPI.ts | 13 ++++++++++--- src/sdk/base/PaymasterAPI.ts | 5 +++-- src/sdk/base/VerifyingPaymasterAPI.ts | 27 ++++++++++++++++----------- src/sdk/interfaces.ts | 7 ++++++- src/sdk/sdk.ts | 9 +++++++-- 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/sdk/base/BaseAccountAPI.ts b/src/sdk/base/BaseAccountAPI.ts index 4c113916..a8f44da3 100644 --- a/src/sdk/base/BaseAccountAPI.ts +++ b/src/sdk/base/BaseAccountAPI.ts @@ -10,6 +10,7 @@ import { ErrorSubject, Exception, getUserOpHash, NotPromise, packUserOp, Service import { calcPreVerificationGas, GasOverheads } from './calcPreVerificationGas'; import { AccountService, AccountTypes, CreateSessionDto, isWalletProvider, Network, NetworkNames, NetworkService, SdkOptions, Session, SessionService, SignMessageDto, State, StateService, validateDto, WalletProviderLike, WalletService } from '..'; import { Context } from '../context'; +import { paymasterResponse } from './VerifyingPaymasterAPI'; export interface BaseApiParams { provider: Provider; @@ -474,16 +475,17 @@ export abstract class BaseAccountAPI { }; - let paymasterAndData: string | undefined; + let paymasterAndData: paymasterResponse | undefined = null; if (this.paymasterAPI != null) { // fill (partial) preVerificationGas (all except the cost of the generated paymasterAndData) const userOpForPm = { ...partialUserOp, preVerificationGas: this.getPreVerificationGas(partialUserOp), }; - paymasterAndData = await this.paymasterAPI.getPaymasterAndData(userOpForPm); + paymasterAndData = (await this.paymasterAPI.getPaymasterAndData(userOpForPm)); + partialUserOp.verificationGasLimit = BigNumber.from(paymasterAndData.verificationGasLimit); } - partialUserOp.paymasterAndData = paymasterAndData ?? '0x'; + partialUserOp.paymasterAndData = paymasterAndData ? paymasterAndData.paymasterAndData : '0x'; return { ...partialUserOp, preVerificationGas: this.getPreVerificationGas(partialUserOp), @@ -497,6 +499,11 @@ export abstract class BaseAccountAPI { */ async signUserOp(userOp: UserOperationStruct): Promise { const userOpHash = await this.getUserOpHash(userOp); + if (this.paymasterAPI != null) { + const paymasterAndData = await this.paymasterAPI.getPaymasterAndData(userOp); + userOp.paymasterAndData = paymasterAndData.paymasterAndData; + userOp.verificationGasLimit = BigNumber.from(paymasterAndData.verificationGasLimit); + } const signature = await this.signUserOpHash(userOpHash); return { ...userOp, diff --git a/src/sdk/base/PaymasterAPI.ts b/src/sdk/base/PaymasterAPI.ts index 118464b1..8efffe69 100644 --- a/src/sdk/base/PaymasterAPI.ts +++ b/src/sdk/base/PaymasterAPI.ts @@ -1,4 +1,5 @@ import { UserOperationStruct } from '../contracts/src/aa-4337/core/BaseAccount'; +import { paymasterResponse } from './VerifyingPaymasterAPI'; /** * an API to external a UserOperation with paymaster info @@ -10,7 +11,7 @@ export class PaymasterAPI { * paymasterAndData value, which will only be returned by this method.. * @returns the value to put into the PaymasterAndData, undefined to leave it empty */ - async getPaymasterAndData(userOp: Partial): Promise { - return '0x'; + async getPaymasterAndData(userOp: Partial): Promise { + return { paymasterAndData: '0x', verificationGasLimit: '0x' }; } } diff --git a/src/sdk/base/VerifyingPaymasterAPI.ts b/src/sdk/base/VerifyingPaymasterAPI.ts index 7c84e071..0b54a556 100644 --- a/src/sdk/base/VerifyingPaymasterAPI.ts +++ b/src/sdk/base/VerifyingPaymasterAPI.ts @@ -9,22 +9,23 @@ const SIG_SIZE = 65; const DUMMY_PAYMASTER_AND_DATA = '0x0101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000001010101010100000000000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101'; -interface paymasterResponse { - jsonrpc: string; - id: number; - result: BytesLike; +export interface paymasterResponse { + paymasterAndData: string; + verificationGasLimit: string; } export class VerifyingPaymasterAPI extends PaymasterAPI { private paymasterUrl: string; private entryPoint: string; - constructor(paymasterUrl: string, entryPoint: string) { + private context: any; + constructor(paymasterUrl: string, entryPoint: string, context: any) { super(); this.paymasterUrl = paymasterUrl; this.entryPoint = entryPoint; + this.context = context; } - async getPaymasterAndData(userOp: Partial): Promise { + async getPaymasterAndData(userOp: Partial): Promise { // Hack: userOp includes empty paymasterAndData which calcPreVerificationGas requires. try { // userOp.preVerificationGas contains a promise that will resolve to an error. @@ -48,16 +49,20 @@ export class VerifyingPaymasterAPI extends PaymasterAPI { op.preVerificationGas = calcPreVerificationGas(op); // Ask the paymaster to sign the transaction and return a valid paymasterAndData value. - return axios + const paymasterAndData = axios .post(this.paymasterUrl, { jsonrpc: '2.0', id: 1, method: 'pm_sponsorUserOperation', - params: [await toJSON(op), this.entryPoint], + params: [await toJSON(op), this.entryPoint, this.context], }) - .then((res) => res.data.result.toString()); + .then((res) => { + return res.data + }); + + return paymasterAndData; } } -export const getVerifyingPaymaster = (paymasterUrl: string, entryPoint: string) => - new VerifyingPaymasterAPI(paymasterUrl, entryPoint); +export const getVerifyingPaymaster = (paymasterUrl: string, entryPoint: string, context: any) => + new VerifyingPaymasterAPI(paymasterUrl, entryPoint, context); diff --git a/src/sdk/interfaces.ts b/src/sdk/interfaces.ts index dbeda006..c60d5b6a 100644 --- a/src/sdk/interfaces.ts +++ b/src/sdk/interfaces.ts @@ -2,6 +2,11 @@ import { StateStorage } from './state'; import { SessionStorage } from './session'; import { VerifyingPaymasterAPI } from './base'; +export interface PaymasterApi { + url: string; + context: any; +} + export interface SdkOptions { chainId: number; stateStorage?: StateStorage; @@ -9,5 +14,5 @@ export interface SdkOptions { omitWalletProviderNetworkCheck?: boolean; bundlerRpcUrl?: string; rpcProviderUrl?: string; - paymasterApi?: VerifyingPaymasterAPI; + paymasterApi?: PaymasterApi; } diff --git a/src/sdk/sdk.ts b/src/sdk/sdk.ts index 3515268a..8d516b69 100644 --- a/src/sdk/sdk.ts +++ b/src/sdk/sdk.ts @@ -7,7 +7,7 @@ import { BatchUserOpsRequest, Exception, getGasFee, UserOpsRequest } from "./com import { BigNumber, ethers, providers } from 'ethers'; import { getNetworkConfig, Networks } from './network/constants'; import { UserOperationStruct } from './contracts/src/aa-4337/core/BaseAccount'; -import { EtherspotWalletAPI, HttpRpcClient } from './base'; +import { EtherspotWalletAPI, HttpRpcClient, VerifyingPaymasterAPI } from './base'; import { TransactionDetailsForUserOp, TransactionGasInfoForUserOp } from './base/TransactionDetailsForUserOp'; import { CreateSessionDto, SignMessageDto, validateDto } from './dto'; import { Session } from '.'; @@ -49,13 +49,18 @@ export class PrimeSdk { provider = new providers.JsonRpcProvider(rpcProviderUrl); } else provider = new providers.JsonRpcProvider(optionsLike.bundlerRpcUrl); + let paymasterAPI = null; + if (optionsLike.paymasterApi && optionsLike.paymasterApi.url) { + paymasterAPI = new VerifyingPaymasterAPI(optionsLike.paymasterApi.url, Networks[chainId].contracts.entryPoint, optionsLike.paymasterApi.context ?? {}) + } + this.etherspotWallet = new EtherspotWalletAPI({ provider, walletProvider, optionsLike, entryPointAddress: Networks[chainId].contracts.entryPoint, factoryAddress: Networks[chainId].contracts.walletFactory, - paymasterAPI: optionsLike.paymasterApi, + paymasterAPI, }) this.bundler = new HttpRpcClient(optionsLike.bundlerRpcUrl, Networks[chainId].contracts.entryPoint, Networks[chainId].chainId); From 684e6f39041fafc4b245c20ef160c3f1b9e6570e Mon Sep 17 00:00:00 2001 From: Vignesh Date: Mon, 21 Aug 2023 16:09:14 +0530 Subject: [PATCH 2/2] updated package version --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 292749c1..4fb88893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # Changelog +## [1.1.4] - 2023-08-21 +### Breaking Changes +- Changed the way of initialising the Paymaster url to string as before it was unreachable code to get VerifyingPaymasterApi class to pass on to the Prime-Sdk +- Changed the response object got from the paymaster to be compatible with our Arka service + ## [1.1.2] - 2023-07-31 ### New - Added onRamper to get the url diff --git a/package.json b/package.json index f2e063b6..3d519e15 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@etherspot/prime-sdk", - "version": "1.1.3", + "version": "1.1.4", "description": "Etherspot Prime (Account Abstraction) SDK", "keywords": [ "ether",