Skip to content

Commit

Permalink
PRO-1849 - Paymaster Updates (#37)
Browse files Browse the repository at this point in the history
* added paymaster api to estimate
  • Loading branch information
vignesha22 authored Sep 28, 2023
1 parent bcaddb6 commit b11c30b
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Changelog
## [1.2.11] - 2023-09-20
### Breaking Changes
- Removed paymaster initialisation from sdk init place and added to estimate step to specify how each userOp is submitted rather than global paymaster initialisation

## [1.2.10] - 2023-09-27
### Fixes
Expand Down
57 changes: 57 additions & 0 deletions examples/12-paymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ethers } from 'ethers';
import { PrimeSdk } from '../src';
import { printOp } from '../src/sdk/common/OperationUtils';
import * as dotenv from 'dotenv';
import { sleep } from '../src/sdk/common';

dotenv.config();

const recipient = '0x80a1874E1046B1cc5deFdf4D3153838B72fF94Ac'; // recipient wallet address
const value = '0.01'; // transfer value

async function main() {
// initializating sdk...
const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, {
chainId: Number(process.env.CHAIN_ID), projectKey: '',
})

console.log('address: ', primeSdk.state.walletAddress)

// get address of EtherspotWallet...
const address: string = await primeSdk.getCounterFactualAddress();
console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${address}`);

// clear the transaction batch
await primeSdk.clearUserOpsFromBatch();

// add transactions to the batch
const transactionBatch = await primeSdk.addUserOpsToBatch({ to: recipient, value: ethers.utils.parseEther(value) });
console.log('transactions: ', transactionBatch);

// get balance of the account address
const balance = await primeSdk.getNativeBalance();

console.log('balances: ', balance);

// estimate transactions added to the batch and get the fee data for the UserOp
const op = await primeSdk.estimate({ url: 'https://arka.etherspot.io/', api_key: '', context: { mode: 'sponsor' } });
console.log(`Estimate UserOp: ${await printOp(op)}`);

// sign the UserOp and sending to the bundler...
const uoHash = await primeSdk.send(op);
console.log(`UserOpHash: ${uoHash}`);

// get transaction hash...
console.log('Waiting for transaction...');
let userOpsReceipt = null;
const timeout = Date.now() + 60000; // 1 minute timeout
while ((userOpsReceipt == null) && (Date.now() < timeout)) {
await sleep(2);
userOpsReceipt = await primeSdk.getUserOpReceipt(uoHash);
}
console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt);
}

main()
.catch(console.error)
.finally(() => process.exit());
47 changes: 38 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@etherspot/prime-sdk",
"version": "1.2.10",
"version": "1.2.11",
"description": "Etherspot Prime (Account Abstraction) SDK",
"keywords": [
"ether",
Expand Down Expand Up @@ -62,8 +62,8 @@
"commander": "10.0.1",
"cross-fetch": "3.1.5",
"ethers": "5.7.0",
"prettier": "2.8.8",
"reflect-metadata": "0.1.13"
"graphql-ws": "5.14.0",
"prettier": "2.8.8"
},
"devDependencies": {
"@types/node": "18.11.9",
Expand All @@ -75,6 +75,8 @@
"eslint-config-prettier": "6.11.0",
"eslint-plugin-import": "2.20.2",
"npm": "9.6.4",
"reflect-metadata": "0.1.13",
"rxjs": "6.6.7",
"ts-node": "8.10.2",
"typescript": "4.5.2"
}
Expand Down
6 changes: 4 additions & 2 deletions src/sdk/base/BaseAccountAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export interface BaseApiParams {
entryPointAddress: string;
accountAddress?: string;
overheads?: Partial<GasOverheads>;
paymasterAPI?: PaymasterAPI;
walletProvider: WalletProviderLike,
optionsLike?: SdkOptions
}
Expand Down Expand Up @@ -112,7 +111,6 @@ export abstract class BaseAccountAPI {
this.overheads = params.overheads;
this.entryPointAddress = params.entryPointAddress;
this.accountAddress = params.accountAddress;
this.paymasterAPI = params.paymasterAPI;

// factory "connect" define the contract address. the contract "connect" defines the "from" address.
this.entryPointView = EntryPoint__factory.connect(params.entryPointAddress, params.provider).connect(
Expand Down Expand Up @@ -178,6 +176,10 @@ export abstract class BaseAccountAPI {
return this.services.sessionService.createSession(ttl, fcmToken);
}

async setPaymasterApi(paymaster: PaymasterAPI | null) {
this.paymasterAPI = paymaster;
}


// private

Expand Down
1 change: 0 additions & 1 deletion src/sdk/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ export interface SdkOptions {
rpcProviderUrl?: string;
graphqlEndpoint?: string;
projectKey: string;
paymasterApi?: PaymasterApi;
}
15 changes: 7 additions & 8 deletions src/sdk/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
WalletConnect2WalletProvider,
WalletProviderLike
} from './wallet';
import { SdkOptions } from './interfaces';
import { PaymasterApi, SdkOptions } from './interfaces';
import { Network } from "./network";
import { BatchUserOpsRequest, Exception, getGasFee, onRampApiKey, openUrl, UserOpsRequest } from "./common";
import { BigNumber, ethers, providers } from 'ethers';
Expand Down Expand Up @@ -61,18 +61,12 @@ 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 ?? {}, optionsLike.paymasterApi.api_key, chainId)
}

this.etherspotWallet = new EtherspotWalletAPI({
provider,
walletProvider: walletConnectProvider ?? walletProvider,
optionsLike,
entryPointAddress: Networks[chainId].contracts.entryPoint,
factoryAddress: Networks[chainId].contracts.walletFactory,
paymasterAPI,
})

this.bundler = new HttpRpcClient(optionsLike.bundlerRpcUrl, Networks[chainId].contracts.entryPoint, Networks[chainId].chainId);
Expand Down Expand Up @@ -136,11 +130,16 @@ export class PrimeSdk {
return this.etherspotWallet.getCounterFactualAddress();
}

async estimate(gasDetails?: TransactionGasInfoForUserOp) {
async estimate(paymasterDetails?: PaymasterApi, gasDetails?: TransactionGasInfoForUserOp) {
if (this.userOpsBatch.to.length < 1) {
throw new Error("cannot sign empty transaction batch");
}

if (paymasterDetails?.url) {
const paymasterAPI = new VerifyingPaymasterAPI(paymasterDetails.url, Networks[this.chainId].contracts.entryPoint, paymasterDetails.context ?? {}, paymasterDetails.api_key, this.chainId)
this.etherspotWallet.setPaymasterApi(paymasterAPI)
} else this.etherspotWallet.setPaymasterApi(null);

const tx: TransactionDetailsForUserOp = {
target: this.userOpsBatch.to,
values: this.userOpsBatch.value,
Expand Down

0 comments on commit b11c30b

Please sign in to comment.