Skip to content

Commit

Permalink
PRO-2196 - Added ARKA wrapper as sub package (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
vignesha22 authored Mar 20, 2024
1 parent 310dc80 commit 658f675
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Changelog
## [1.6.3] - 2024-03-19
### New
- Added ArkaPaymaster as a sub-module

## [1.6.2] - 2024-03-15
### Bug Fixes
- Fixed browser-side querystring issue
Expand Down
23 changes: 23 additions & 0 deletions examples/24-ArkaPaymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ArkaPaymaster } from "../src";
import * as dotenv from 'dotenv';

dotenv.config();

async function main() {
const arka_api_key = 'arka_public_key';
const arka_url = 'https://arka.etherspot.io'; // Only testnets are available, if you need further assistance in setting up a paymaster service for your dapp, please reach out to us on discord or https://etherspot.fyi/arka/intro

// initializating sdk...
const arkaPaymaster = new ArkaPaymaster(Number(process.env.CHAIN_ID), arka_api_key, arka_url);

console.log(await arkaPaymaster.metadata());
console.log(await arkaPaymaster.getTokenPaymasterAddress("eUSDC"))
console.log(await arkaPaymaster.addWhitelist(["0xB3aF6CFDDc444B948132753AD8214a20605692eF"]));
console.log(await arkaPaymaster.removeWhitelist(["0xB3aF6CFDDc444B948132753AD8214a20605692eF"]));
console.log(await arkaPaymaster.checkWhitelist("0xB3aF6CFDDc444B948132753AD8214a20605692eF"));
console.log(await arkaPaymaster.deposit(0.001));
}

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.6.2",
"version": "1.6.3",
"description": "Etherspot Prime (Account Abstraction) SDK",
"keywords": [
"ether",
Expand Down
3 changes: 2 additions & 1 deletion src/sdk/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DataUtils } from './dataUtils';
import { PrimeSdk } from './sdk';
import { ArkaPaymaster } from './paymaster';

export * from './api';
export * from './dto';
Expand All @@ -9,5 +10,5 @@ export * from './state';
export * from './wallet';
export * from './bundler';

export { PrimeSdk, DataUtils };
export { PrimeSdk, DataUtils, ArkaPaymaster };
export default PrimeSdk;
1 change: 0 additions & 1 deletion src/sdk/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export interface SdkOptions {
stateStorage?: StateStorage;
rpcProviderUrl?: string;
graphqlEndpoint?: string;
etherspotBundlerApiKey?: string;
factoryWallet?: Factory;
walletFactoryAddress?: string;
entryPointAddress?: string;
Expand Down
5 changes: 5 additions & 0 deletions src/sdk/paymaster/ErrorMsg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const ErrorMessage = {
INVALID_ADDRESSES: 'Address Invalid. Please make sure that all the addresses are valid',
INVALID_ADDRESS: 'The given address is invalid. Please try again with valid address',
MAX_ADDRESSES: 'Max of 10 addresses are only allowed in one request',
}
2 changes: 2 additions & 0 deletions src/sdk/paymaster/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './interface';
export * from './provider';
6 changes: 6 additions & 0 deletions src/sdk/paymaster/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

export interface PaymasterProvider {
readonly url: string;
}

export type PaymasterProviderLike = PaymasterProvider;
210 changes: 210 additions & 0 deletions src/sdk/paymaster/provider/arka.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import { ethers } from "ethers";
import { PaymasterProvider } from "../interface";
import { ErrorMessage } from "../ErrorMsg";

export class ArkaPaymaster implements PaymasterProvider {
readonly url: string;
readonly apiKey: string;
readonly chainId: number;
readonly queryParams: string;

constructor(chainId: number, apiKey: string, paymasterUrl: string) {
this.url = paymasterUrl;
this.queryParams = `?apiKey=${apiKey}&chainId=${chainId}`;
this.apiKey = apiKey;
this.chainId = chainId;
}

/* This method is to get the paymaster address for the given token symbol if available
* @param tokenSym, the token symbol used as string ex: "USDC"
*/
async getTokenPaymasterAddress(tokenSym: string) {
let response = null;
const entryPointAddressV06 = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789';
const context = { token: tokenSym }
try {
response = await fetch(`${this.url}/pimlicoAddress${this.queryParams}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ params: [entryPointAddressV06, context] }),
})
.then(async (res) => {
const responseJson = await res.json();
if (responseJson.error) {
throw new Error(responseJson.error);
}
return responseJson
})
.catch((err) => {
throw new Error(err.message);
})
} catch (err) {
throw new Error(err.message)
}
if (response.message) return response.message;
return response;
}

/* This method is to whitelist the addresses given
* @param addresses, the array of addresses that needs to be whitelisted
*/
async addWhitelist(addresses: string[]) {
let response = null;
if (addresses.length > 10) throw new Error(ErrorMessage.MAX_ADDRESSES);
const validAddresses = addresses.every(ethers.utils.isAddress);
if (!validAddresses) throw new Error(ErrorMessage.INVALID_ADDRESS);
try {
response = await fetch(`${this.url}/whitelist${this.queryParams}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ params: [addresses] }),
})
.then(async (res) => {
const responseJson = await res.json();
if (responseJson.error) {
throw new Error(responseJson.error);
}
return responseJson
})
.catch((err) => {
throw new Error(err.message);
})
} catch (err) {
throw new Error(err.message)
}
if (response.message) return response.message;
return response;
}

/* This method is to remove whitelisted addresses given
* @param addresses, the array of addresses that needs to be removed from whitelist
*/
async removeWhitelist(addresses: string[]) {
let response = null;
if (addresses.length > 10) throw new Error(ErrorMessage.MAX_ADDRESSES);
const validAddresses = addresses.every(ethers.utils.isAddress);
if (!validAddresses) throw new Error(ErrorMessage.INVALID_ADDRESS);
try {
response = await fetch(`${this.url}/removeWhitelist${this.queryParams}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ params: [addresses] }),
})
.then(async (res) => {
const responseJson = await res.json();
if (responseJson.error) {
throw new Error(responseJson.error);
}
return responseJson
})
.catch((err) => {
throw new Error(err.message);
})
} catch (err) {
throw new Error(err.message)
}
if (response.message) return response.message;
return response;
}

/* This method is to check a given address is whitelisted or not
* @param address, address that needs to be checked if its whitelisted or not
*/
async checkWhitelist(address: string) {
let response = null;
if (!ethers.utils.isAddress(address)) throw new Error(ErrorMessage.INVALID_ADDRESS)
try {
response = await fetch(`${this.url}/checkWhitelist${this.queryParams}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ params: [address] }),
})
.then(async (res) => {
const responseJson = await res.json();
if (responseJson.error) {
throw new Error(responseJson.error);
}
return responseJson
})
.catch((err) => {
throw new Error(err.message);
})
} catch (err) {
throw new Error(err.message)
}
if (response.message) return response.message;
return response;
}

/* This method is to deposit the amount for the paymaster to the entryPoint contract
* @param amountInEth, amount that needs to be deposited in ETH terms
*/
async deposit(amountInEth: number) {
let response = null;
try {
response = await fetch(`${this.url}/deposit${this.queryParams}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ params: [amountInEth] }),
})
.then(async (res) => {
const responseJson = await res.json();
if (responseJson.error) {
throw new Error(responseJson.error);
}
return responseJson
})
.catch((err) => {
throw new Error(err.message);
})
} catch (err) {
throw new Error(err.message)
}
if (response.message) return response.message;
return response;
}

// This method is to get the details of the paymaster associated to your apiKey
async metadata() {
let response = null;
try {
response = await fetch(`${this.url}/metadata${this.queryParams}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
.then(async (res) => {
const responseJson = await res.json();
if (responseJson.error) {
throw new Error(responseJson.error);
}
return responseJson
})
.catch((err) => {
throw new Error(err.message);
})
} catch (err) {
throw new Error(err.message)
}
if (response.message) return response.message;
return response;
}

}
1 change: 1 addition & 0 deletions src/sdk/paymaster/provider/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './arka';

0 comments on commit 658f675

Please sign in to comment.