Skip to content

Commit

Permalink
PRO-1923 - Flare Network Support (#43)
Browse files Browse the repository at this point in the history
* added flare network, example for token paymaster

* updated package version
  • Loading branch information
vignesha22 authored Oct 18, 2023
1 parent e0fc1bc commit c287343
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Changelog
## [1.3.2] - 2023-10-18
### New
- Added Flare testnet and Mainnet network support
- Added an example to execute token paymasters using ARKA

## [1.3.1] - 2023-10-13
### Fixes
- Updated all chains to the latest zeroDev factory contract as previously only goerli chain has the latest factory(0x5de4839a76cf55d0c90e2061ef4386d962E15ae3) and others was on previous factory contract which doesn't work on the latest changes made by zeroDev
Expand Down
112 changes: 112 additions & 0 deletions examples/16-paymaster-arka.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { ethers, utils } from 'ethers';
import { PrimeSdk } from '../src';
import { printOp } from '../src/sdk/common/OperationUtils';
import * as dotenv from 'dotenv';
import { sleep } from '../src/sdk/common';
import { ERC20_ABI } from '../src/sdk/helpers/abi/ERC20_ABI';

dotenv.config();

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

const arka_api_key = '';
const arka_url = '';

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

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

const entryPointAddress = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789';

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

// get balance of the account address
let balance = await primeSdk.getNativeBalance();
console.log('balances: ', balance);

const tokenAddress = "0x0FA8781a83E46826621b3BC094Ea2A0212e71B23"; // USDC Token address on Mumbai

/**
* The fetching of pimlico erc20 paymaster address is only required for the first time for each specified gas token since we need to approve the tokens to spend
* from the paymaster address on behalf of you.
*/
const returnedValue = await fetch(`${arka_url}/pimlicoAddress`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ "params": [entryPointAddress, { token: "USDC" }, Number(process.env.CHAIN_ID), arka_api_key] })
})
.then((res) => {
return res.json()
}).catch((err) => {
console.log(err);
});
const paymasterAddress = returnedValue.message;

if (utils.isAddress(paymasterAddress)) {
console.log('Value returned: ', paymasterAddress); // getting paymaster address for the selected gas token

const erc20Contract = new ethers.Contract(tokenAddress, ERC20_ABI)
const encodedData = erc20Contract.interface.encodeFunctionData('approve', [paymasterAddress, ethers.constants.MaxUint256]) // Infinite Approval
await primeSdk.addUserOpsToBatch({ to: tokenAddress, data: encodedData });
const approveOp = await primeSdk.estimate();
console.log(`UserOpHash: ${await printOp(approveOp)}`);
const uoHash1 = await primeSdk.send(approveOp);
console.log(`UserOpHash: ${uoHash1}`);

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

// 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
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: arka_url, api_key: arka_api_key, context: { token: "USDC", mode: 'erc20' } });
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);
} else {
console.log('Unable to fetch the paymaster address. Error returned: ', returnedValue)
}
}

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

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@etherspot/prime-sdk",
"version": "1.3.1",
"version": "1.3.2",
"description": "Etherspot Prime (Account Abstraction) SDK",
"keywords": [
"ether",
Expand Down
32 changes: 31 additions & 1 deletion src/sdk/network/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ export enum NetworkNames {
Fuji = 'fuji',
Linea = 'linea',
LineaTestnet = 'lineaTestnet',
FlareTestnet = 'flareTestnet',
Flare = 'flare'
}

export const SupportedNetworks =
[1, 5, 10, 31, 56, 97, 100, 122, 123, 137, 420, 2357, 5000, 5001, 8453, 10200, 20197, 42161, 43113, 43114, 59140, 59144, 80001, 84531, 421613, 11155111]
[1, 5, 10, 14, 31, 56, 97, 100, 114, 122, 123, 137, 420, 2357, 5000, 5001, 8453, 10200, 20197, 42161, 43113, 43114, 59140, 59144, 80001, 84531, 421613, 11155111]

export const NETWORK_NAME_TO_CHAIN_ID: {
[key: string]: number;
Expand Down Expand Up @@ -61,6 +63,8 @@ export const NETWORK_NAME_TO_CHAIN_ID: {
[NetworkNames.Fuji]: 43113,
[NetworkNames.Linea]: 59144,
[NetworkNames.LineaTestnet]: 59140,
[NetworkNames.FlareTestnet]: 114,
[NetworkNames.Flare]: 14,
};

export const onRamperAllNetworks = ['OPTIMISM', 'POLYGON', 'ARBITRUM', 'FUSE', 'GNOSIS', 'ETHEREUM']
Expand Down Expand Up @@ -406,6 +410,32 @@ export const Networks: {
},
graphqlEndpoint: ''
},
[114]: {
chainId: 114,
bundler: 'https://flaretestnet-bundler.etherspot.io/',
contracts: {
entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
walletFactory: {
etherspot: '0x7f6d8F107fE8551160BD5351d5F1514A6aD5d40E',
zeroDev: '',
simpleAccount: '',
}
},
graphqlEndpoint: ''
},
[14]: {
chainId: 14,
bundler: 'https://flare-bundler.etherspot.io/',
contracts: {
entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
walletFactory: {
etherspot: '0x7f6d8F107fE8551160BD5351d5F1514A6aD5d40E',
zeroDev: '',
simpleAccount: '0x9406Cc6185a346906296840746125a0E44976454',
}
},
graphqlEndpoint: ''
},
};

interface ISafeConstant {
Expand Down

0 comments on commit c287343

Please sign in to comment.