From 10e81f0548aba86bbe156b00c161f1395510d582 Mon Sep 17 00:00:00 2001 From: vignesha22 <82584664+vignesha22@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:05:31 +0530 Subject: [PATCH] PRO-2029 - PrimeSDK Code Refactor (#90) --- CHANGELOG.md | 8 + examples/02-transfer-funds.ts | 2 +- examples/03-transfer-erc20.ts | 2 +- examples/04-transfer-nft.ts | 2 +- examples/05-get-account-balances.ts | 20 +- examples/06-transaction.ts | 14 +- examples/08-nft-list.ts | 11 +- examples/09-exchange.ts | 14 +- examples/10-advance-routes-lifi.ts | 14 +- examples/11-cross-chain-quotes.ts | 13 +- examples/12-add-guardians.ts | 2 +- examples/13-paymaster.ts | 2 +- examples/16-paymaster-arka.ts | 2 +- examples/17-token-list.ts | 31 +- examples/18-exchange-rates.ts | 35 +-- .../19-paymaster-validUntil-validAfter.ts | 2 +- examples/20-callDataLimit.ts | 2 +- package-lock.json | 4 +- package.json | 2 +- src/sdk/account/__mocks__/account.service.ts | 35 --- src/sdk/account/account.service.ts | 72 ----- src/sdk/account/classes/account.ts | 22 -- src/sdk/account/classes/index.ts | 1 - src/sdk/account/constants.ts | 9 - src/sdk/account/index.ts | 3 - src/sdk/api/api.service.ts | 48 +-- src/sdk/api/interfaces.ts | 2 +- src/sdk/base/BaseAccountAPI.ts | 56 +--- src/sdk/base/EtherspotWalletAPI.ts | 6 +- src/sdk/base/SimpleAccountWalletAPI.ts | 26 +- src/sdk/base/ZeroDevWalletAPI.ts | 42 +-- src/sdk/context.ts | 8 - .../data/{data.service.ts => data.module.ts} | 62 ++-- src/sdk/data/index.ts | 2 +- src/sdk/dataUtils.ts | 232 ++++++++++++++ src/sdk/dto/advance-routes-lifi.dto.ts | 5 +- src/sdk/dto/create-session.dto.ts | 12 - src/sdk/dto/get-account-balances.dto.ts | 14 +- .../dto/get-exchange-cross-chain-quote.dto.ts | 7 +- src/sdk/dto/get-exchange-offers.dto.ts | 8 +- .../dto/get-exchange-supported-assets.dto.ts | 9 +- src/sdk/dto/get-nft-list.dto.ts | 5 +- src/sdk/dto/get-step-transactions-lifi.dto.ts | 4 + src/sdk/dto/get-transaction.dto.ts | 4 + src/sdk/dto/index.ts | 2 - src/sdk/dto/join-contract-account.dto.ts | 11 - src/sdk/index.ts | 5 +- src/sdk/interfaces.ts | 8 +- src/sdk/network/network.service.ts | 2 +- src/sdk/sdk.ts | 282 +----------------- src/sdk/session/__mocks__/session.service.ts | 6 - src/sdk/session/classes/index.ts | 1 - src/sdk/session/classes/session.ts | 54 ---- src/sdk/session/index.ts | 4 - src/sdk/session/interfaces.ts | 15 - src/sdk/session/session.service.ts | 193 ------------ src/sdk/session/session.storage.ts | 13 - .../session/utils/create-session-message.ts | 12 - src/sdk/session/utils/index.ts | 1 - src/sdk/state/classes/state.ts | 5 - src/sdk/state/interfaces.ts | 4 +- src/sdk/state/state.service.ts | 48 +-- src/sdk/wallet/interfaces.ts | 1 - src/sdk/wallet/wallet.service.ts | 9 +- 64 files changed, 452 insertions(+), 1100 deletions(-) delete mode 100644 src/sdk/account/__mocks__/account.service.ts delete mode 100644 src/sdk/account/account.service.ts delete mode 100644 src/sdk/account/classes/account.ts delete mode 100644 src/sdk/account/classes/index.ts delete mode 100644 src/sdk/account/constants.ts delete mode 100644 src/sdk/account/index.ts rename src/sdk/data/{data.service.ts => data.module.ts} (90%) create mode 100644 src/sdk/dataUtils.ts delete mode 100644 src/sdk/dto/create-session.dto.ts delete mode 100644 src/sdk/dto/join-contract-account.dto.ts delete mode 100644 src/sdk/session/__mocks__/session.service.ts delete mode 100644 src/sdk/session/classes/index.ts delete mode 100644 src/sdk/session/classes/session.ts delete mode 100644 src/sdk/session/index.ts delete mode 100644 src/sdk/session/interfaces.ts delete mode 100644 src/sdk/session/session.service.ts delete mode 100644 src/sdk/session/session.storage.ts delete mode 100644 src/sdk/session/utils/create-session-message.ts delete mode 100644 src/sdk/session/utils/index.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7200e9a..b983c06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,12 @@ # Changelog +## [1.4.0] +### Breaking Changes +- Changed the data service to initialise as a seperate entity independent of the primeSdk object +- Removed unnecessary state variables and changed the walletAddress variable name to EOAAddress for better understanding +- Optimised the fetching of accountAddress since before it was fetching from on chain for every request to getCounterFactualAddress from the rpc, now it stores the account address locally in the initialised PrimeSDK object +- Fixed network state variable to output the network which it is connected to + +## [1.3.14] ### New - Added ability to override callDataLimit on estimate step by the user diff --git a/examples/02-transfer-funds.ts b/examples/02-transfer-funds.ts index 8e6b9ab..297dfed 100644 --- a/examples/02-transfer-funds.ts +++ b/examples/02-transfer-funds.ts @@ -13,7 +13,7 @@ async function main() { // initializating sdk... const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { chainId: Number(process.env.CHAIN_ID), projectKey: 'public-prime-testnet-key' }) - console.log('address: ', primeSdk.state.walletAddress) + console.log('address: ', primeSdk.state.EOAAddress) // get address of EtherspotWallet... const address: string = await primeSdk.getCounterFactualAddress(); diff --git a/examples/03-transfer-erc20.ts b/examples/03-transfer-erc20.ts index c3aa0d8..d550279 100644 --- a/examples/03-transfer-erc20.ts +++ b/examples/03-transfer-erc20.ts @@ -16,7 +16,7 @@ async function main() { // initializating sdk... const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { chainId: Number(process.env.CHAIN_ID), projectKey: 'public-prime-testnet-key' }) - console.log('address: ', primeSdk.state.walletAddress) + console.log('address: ', primeSdk.state.EOAAddress) // get address of EtherspotWallet... const address: string = await primeSdk.getCounterFactualAddress(); diff --git a/examples/04-transfer-nft.ts b/examples/04-transfer-nft.ts index 68448ca..2a2efb2 100644 --- a/examples/04-transfer-nft.ts +++ b/examples/04-transfer-nft.ts @@ -15,7 +15,7 @@ async function main() { // initializating sdk... const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { chainId: Number(process.env.CHAIN_ID), projectKey: 'public-prime-testnet-key' }) - console.log('address: ', primeSdk.state.walletAddress) + console.log('address: ', primeSdk.state.EOAAddress) // get address of EtherspotWallet... const address: string = await primeSdk.getCounterFactualAddress(); diff --git a/examples/05-get-account-balances.ts b/examples/05-get-account-balances.ts index f52fa80..7aed782 100644 --- a/examples/05-get-account-balances.ts +++ b/examples/05-get-account-balances.ts @@ -1,23 +1,19 @@ -import { PrimeSdk } from '../src'; +import { DataUtils, graphqlEndpoints } from '../src'; import * as dotenv from 'dotenv'; dotenv.config(); async function main() { - // initializating sdk... - const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { - chainId: Number(process.env.CHAIN_ID), - projectKey: 'public-prime-testnet-key', // project key - }); + // initializating Data service... + const dataService = new DataUtils('public-prime-testnet-key', graphqlEndpoints.QA) - const balances = await primeSdk.getAccountBalances({ - account: '', // account address - chainId: 1, - }); - console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet balances:`, balances); + const balances = await dataService.getAccountBalances({ + account: '', // address + chainId: 1, + }); + console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet balances:`, balances); } main() .catch(console.error) .finally(() => process.exit()); - diff --git a/examples/06-transaction.ts b/examples/06-transaction.ts index 168e649..94c15c4 100644 --- a/examples/06-transaction.ts +++ b/examples/06-transaction.ts @@ -1,16 +1,13 @@ -import { PrimeSdk } from '../src'; +import { DataUtils, graphqlEndpoints } from '../src'; import * as dotenv from 'dotenv'; dotenv.config(); async function main(): Promise { - // initializating sdk... - const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { - chainId: Number(process.env.CHAIN_ID), - projectKey: 'public-prime-testnet-key', // project key - }); - const hash = '0xe6667a1185a6fd93cf082b96f78763514759041940e305da80224609bd1c6781'; - const transaction = await primeSdk.getTransaction({ hash }); + // initializating Data service... + const dataService = new DataUtils('public-prime-testnet-key', graphqlEndpoints.QA) + const hash = '0x7f8633f21d0c0c71d248333a0a2b976495015109a270a6f8a51befe3baf6fb6e'; + const transaction = await dataService.getTransaction({ hash, chainId: 80001 }); console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet transaction:`, transaction); } @@ -18,4 +15,3 @@ async function main(): Promise { main() .catch(console.error) .finally(() => process.exit()); - diff --git a/examples/08-nft-list.ts b/examples/08-nft-list.ts index 1083439..d3e530c 100644 --- a/examples/08-nft-list.ts +++ b/examples/08-nft-list.ts @@ -1,17 +1,14 @@ -import { PrimeSdk } from '../src'; +import { DataUtils, graphqlEndpoints } from '../src'; import * as dotenv from 'dotenv'; dotenv.config(); async function main(): Promise { - // initializating sdk... - const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { - chainId: Number(process.env.CHAIN_ID), - projectKey: 'public-prime-testnet-key', // project key - }); + // initializating Data service... + const dataService = new DataUtils('public-prime-testnet-key', graphqlEndpoints.QA) const chainId = 137; const account = ''; // account address - const nfts = await primeSdk.getNftList({ chainId, account }); + const nfts = await dataService.getNftList({ chainId, account }); console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet nfts:`, nfts); } diff --git a/examples/09-exchange.ts b/examples/09-exchange.ts index 765e258..486dec9 100644 --- a/examples/09-exchange.ts +++ b/examples/09-exchange.ts @@ -1,16 +1,13 @@ -import { PrimeSdk } from '../src'; +import { DataUtils, graphqlEndpoints } from '../src'; import * as dotenv from 'dotenv'; import { BigNumber, constants } from 'ethers'; dotenv.config(); async function main(): Promise { - const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { - chainId: Number(process.env.CHAIN_ID), - projectKey: 'public-prime-testnet-key', // project key - }); - - const exchangeSupportedAssets = await primeSdk.getExchangeSupportedAssets({ page: 1, limit: 100 }); + // initializating Data service... + const dataService = new DataUtils('public-prime-testnet-key', graphqlEndpoints.QA) + const exchangeSupportedAssets = await dataService.getExchangeSupportedAssets({ page: 1, limit: 100, account: '', chainId: Number(process.env.CHAIN_ID) }); console.log('\x1b[33m%s\x1b[0m', `Found exchange supported assets:`, exchangeSupportedAssets.items.length); const fromTokenAddress = '0xe3818504c1b32bf1557b16c238b2e01fd3149c17'; @@ -18,7 +15,8 @@ async function main(): Promise { const fromAmount = '1000000000000000000'; const fromChainId = 1; - const offers = await primeSdk.getExchangeOffers({ + const offers = await dataService.getExchangeOffers({ + fromAddress: '', fromChainId, fromTokenAddress, toTokenAddress, diff --git a/examples/10-advance-routes-lifi.ts b/examples/10-advance-routes-lifi.ts index 1651a71..1ec772a 100644 --- a/examples/10-advance-routes-lifi.ts +++ b/examples/10-advance-routes-lifi.ts @@ -1,14 +1,11 @@ import { ethers, utils } from 'ethers'; -import { PrimeSdk } from '../src'; +import { DataUtils, graphqlEndpoints } from '../src'; import * as dotenv from 'dotenv'; dotenv.config(); async function main(): Promise { - // initializating sdk... - const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { - chainId: Number(process.env.CHAIN_ID), - projectKey: 'public-prime-testnet-key', // project key - }); + // initializating Data service... + const dataService = new DataUtils('public-prime-testnet-key', graphqlEndpoints.QA) const fromChainId = 56; const toChainId = 137; @@ -16,6 +13,7 @@ async function main(): Promise { const fromAmount = utils.parseUnits('1', 18); const quoteRequestPayload = { + fromAddress: '', fromChainId: fromChainId, toChainId: toChainId, fromTokenAddress: ethers.constants.AddressZero, @@ -23,13 +21,13 @@ async function main(): Promise { fromAmount: fromAmount, }; - const quotes = await primeSdk.getAdvanceRoutesLiFi(quoteRequestPayload); + const quotes = await dataService.getAdvanceRoutesLiFi(quoteRequestPayload); console.log('\x1b[33m%s\x1b[0m', `Quotes:`, quotes.items); if (quotes.items.length > 0) { const quote = quotes.items[0]; // Selected the first route - const transactions = await primeSdk.getStepTransaction({ route: quote }); + const transactions = await dataService.getStepTransaction({ route: quote, account: '' }); console.log('\x1b[33m%s\x1b[0m', `transactions:`, transactions); } diff --git a/examples/11-cross-chain-quotes.ts b/examples/11-cross-chain-quotes.ts index 0ab4a3c..9245ad2 100644 --- a/examples/11-cross-chain-quotes.ts +++ b/examples/11-cross-chain-quotes.ts @@ -1,15 +1,12 @@ import { utils } from 'ethers'; -import { PrimeSdk } from '../src'; +import { DataUtils, graphqlEndpoints } from '../src'; import * as dotenv from 'dotenv'; import { BridgingQuotes, CrossChainServiceProvider } from '../src/sdk/data'; dotenv.config(); async function main(): Promise { - // initializating sdk... - const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { - chainId: Number(process.env.CHAIN_ID), - projectKey: 'public-prime-testnet-key', // project key - }); + // initializating Data service... + const dataService = new DataUtils('public-prime-testnet-key', graphqlEndpoints.QA) const XdaiUSDC = '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83'; // Xdai - USDC const MaticUSDC = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174'; // Matic - USDC @@ -27,12 +24,12 @@ async function main(): Promise { toChainId: toChainId, fromTokenAddress: fromTokenAddress, toTokenAddress: toTokenAddress, - fromAddress: '', // account address + fromAddress: '', // from address fromAmount: fromAmount, serviceProvider: CrossChainServiceProvider.LiFi, // Optional parameter }; - const quotes: BridgingQuotes = await primeSdk.getCrossChainQuotes(quoteRequestPayload); + const quotes: BridgingQuotes = await dataService.getCrossChainQuotes(quoteRequestPayload); console.log('\x1b[33m%s\x1b[0m', `Quotes:`, quotes); } diff --git a/examples/12-add-guardians.ts b/examples/12-add-guardians.ts index 1e1b8ee..590e284 100644 --- a/examples/12-add-guardians.ts +++ b/examples/12-add-guardians.ts @@ -13,7 +13,7 @@ async function main() { { chainId: Number(process.env.CHAIN_ID), projectKey: 'public-prime-testnet-key' }, ); - console.log('address: ', primeSdk.state.walletAddress); + console.log('address: ', primeSdk.state.EOAAddress); // get address of EtherspotWallet const address: string = await primeSdk.getCounterFactualAddress(); diff --git a/examples/13-paymaster.ts b/examples/13-paymaster.ts index 2052c91..52a7306 100644 --- a/examples/13-paymaster.ts +++ b/examples/13-paymaster.ts @@ -16,7 +16,7 @@ async function main() { chainId: Number(process.env.CHAIN_ID), projectKey: 'public-prime-testnet-key', }) - console.log('address: ', primeSdk.state.walletAddress) + console.log('address: ', primeSdk.state.EOAAddress) // get address of EtherspotWallet... const address: string = await primeSdk.getCounterFactualAddress(); diff --git a/examples/16-paymaster-arka.ts b/examples/16-paymaster-arka.ts index 5768735..8f0c35c 100644 --- a/examples/16-paymaster-arka.ts +++ b/examples/16-paymaster-arka.ts @@ -20,7 +20,7 @@ async function main() { chainId: Number(process.env.CHAIN_ID), projectKey: 'public-prime-testnet-key', }) - console.log('address: ', primeSdk.state.walletAddress) + console.log('address: ', primeSdk.state.EOAAddress) const entryPointAddress = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789'; diff --git a/examples/17-token-list.ts b/examples/17-token-list.ts index f160d74..4ce48c9 100644 --- a/examples/17-token-list.ts +++ b/examples/17-token-list.ts @@ -1,32 +1,29 @@ -import { PrimeSdk } from '../src'; +import { DataUtils, graphqlEndpoints } from '../src'; import * as dotenv from 'dotenv'; dotenv.config(); async function main(): Promise { - // initializating sdk... - const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { - chainId: Number(process.env.CHAIN_ID), - projectKey: 'public-prime-testnet-key', // project key - }); + // initializating Data service... + const dataService = new DataUtils('public-prime-testnet-key', graphqlEndpoints.QA) - const tokenLists = await primeSdk.getTokenLists(); + const tokenLists = await dataService.getTokenLists(); - console.log('\x1b[33m%s\x1b[0m', `TokenLists:`, tokenLists); + console.log('\x1b[33m%s\x1b[0m', `TokenLists:`, tokenLists); - const { name } = tokenLists[0]; + const { name } = tokenLists[0]; - let tokenListTokens = await primeSdk.getTokenListTokens(); + let tokenListTokens = await dataService.getTokenListTokens(); - console.log('\x1b[33m%s\x1b[0m', `Default token list tokens length:`, tokenListTokens.length); + console.log('\x1b[33m%s\x1b[0m', `Default token list tokens length:`, tokenListTokens.length); - tokenListTokens = await primeSdk.getTokenListTokens({ - name, - }); + tokenListTokens = await dataService.getTokenListTokens({ + name, + }); - console.log('\x1b[33m%s\x1b[0m', `${name} token list tokens length:`, tokenListTokens.length); + console.log('\x1b[33m%s\x1b[0m', `${name} token list tokens length:`, tokenListTokens.length); } main() - .catch(console.error) - .finally(() => process.exit()); + .catch(console.error) + .finally(() => process.exit()); diff --git a/examples/18-exchange-rates.ts b/examples/18-exchange-rates.ts index bf25a93..b5d1e5a 100644 --- a/examples/18-exchange-rates.ts +++ b/examples/18-exchange-rates.ts @@ -1,31 +1,28 @@ -import { PrimeSdk, RateData } from '../src'; +import { DataUtils, RateData, graphqlEndpoints } from '../src'; import * as dotenv from 'dotenv'; dotenv.config(); async function main(): Promise { - // initializating sdk... - const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { - chainId: Number(process.env.CHAIN_ID), - projectKey: 'public-prime-testnet-key', // project key - }); + // initializating Data service... + const dataService = new DataUtils('public-prime-testnet-key', graphqlEndpoints.QA) - const ETH_AAVE_ADDR = '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9'; - const ETH_MATIC_ADDR = '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0'; - const ETH_USDC_ADDR = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; - const TOKEN_LIST = [ETH_AAVE_ADDR, ETH_MATIC_ADDR, ETH_USDC_ADDR]; - const ETH_CHAIN_ID = 1; + const ETH_AAVE_ADDR = '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9'; + const ETH_MATIC_ADDR = '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0'; + const ETH_USDC_ADDR = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; + const TOKEN_LIST = [ETH_AAVE_ADDR, ETH_MATIC_ADDR, ETH_USDC_ADDR]; + const ETH_CHAIN_ID = 1; - const requestPayload = { - tokens: TOKEN_LIST, - chainId: ETH_CHAIN_ID, - }; + const requestPayload = { + tokens: TOKEN_LIST, + chainId: ETH_CHAIN_ID, + }; - const rates: RateData = await primeSdk.fetchExchangeRates(requestPayload); + const rates: RateData = await dataService.fetchExchangeRates(requestPayload); - console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet Rates:`, rates); + console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet Rates:`, rates); } main() - .catch(console.error) - .finally(() => process.exit()); + .catch(console.error) + .finally(() => process.exit()); diff --git a/examples/19-paymaster-validUntil-validAfter.ts b/examples/19-paymaster-validUntil-validAfter.ts index d0de48c..35fad8f 100644 --- a/examples/19-paymaster-validUntil-validAfter.ts +++ b/examples/19-paymaster-validUntil-validAfter.ts @@ -19,7 +19,7 @@ async function main() { chainId: Number(process.env.CHAIN_ID), projectKey: 'public-prime-testnet-key', }) - console.log('address: ', primeSdk.state.walletAddress) + console.log('address: ', primeSdk.state.EOAAddress) // get address of EtherspotWallet... const address: string = await primeSdk.getCounterFactualAddress(); diff --git a/examples/20-callDataLimit.ts b/examples/20-callDataLimit.ts index 477cb1c..e5f4d28 100644 --- a/examples/20-callDataLimit.ts +++ b/examples/20-callDataLimit.ts @@ -13,7 +13,7 @@ async function main() { // initializating sdk... const primeSdk = new PrimeSdk({ privateKey: process.env.WALLET_PRIVATE_KEY }, { chainId: Number(process.env.CHAIN_ID), projectKey: 'public-prime-testnet-key' }) - console.log('address: ', primeSdk.state.walletAddress) + console.log('address: ', primeSdk.state.EOAAddress) // get address of EtherspotWallet... const address: string = await primeSdk.getCounterFactualAddress(); diff --git a/package-lock.json b/package-lock.json index 359955c..7b646fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@etherspot/prime-sdk", - "version": "1.3.14", + "version": "1.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@etherspot/prime-sdk", - "version": "1.3.14", + "version": "1.4.0", "license": "MIT", "dependencies": { "@apollo/client": "3.8.6", diff --git a/package.json b/package.json index 9b24122..1d51676 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@etherspot/prime-sdk", - "version": "1.3.14", + "version": "1.4.0", "description": "Etherspot Prime (Account Abstraction) SDK", "keywords": [ "ether", diff --git a/src/sdk/account/__mocks__/account.service.ts b/src/sdk/account/__mocks__/account.service.ts deleted file mode 100644 index b5a0124..0000000 --- a/src/sdk/account/__mocks__/account.service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { mockService } from '../../../testing'; -import { SynchronizedSubject } from '../../common'; -import { Account, AccountMember } from '../classes'; - -const account$ = new SynchronizedSubject(); -const accountMember$ = new SynchronizedSubject(); -const accountAddress$ = account$.observeKey('address'); - -const mocked = { - account$, - accountMember$, - accountAddress$, - computeContractAccount: jest.fn(), - joinContractAccount: jest.fn(), - syncAccount: jest.fn(), - getConnectedAccounts: jest.fn(), - getAccount: jest.fn(), - getAccountBalances: jest.fn(), - getAccountMembers: jest.fn(), - getAccountInvestments: jest.fn(), -}; - -Object.defineProperty(mocked, 'account', { - get: jest.fn(() => account$.value), -}); - -Object.defineProperty(mocked, 'accountMember', { - get: jest.fn(() => accountMember$.value), -}); - -Object.defineProperty(mocked, 'accountAddress', { - get: jest.fn(() => account$?.value?.address), -}); - -export const AccountService = mockService(mocked); diff --git a/src/sdk/account/account.service.ts b/src/sdk/account/account.service.ts deleted file mode 100644 index c11bd22..0000000 --- a/src/sdk/account/account.service.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Observable, combineLatest } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { HeaderNames, Service, SynchronizedSubject, keccak256 } from '../common'; -import { - Account, -} from './classes'; -import { AccountTypes } from './constants'; - -export class AccountService extends Service { - readonly account$ = new SynchronizedSubject(); - readonly accountAddress$: Observable; - - constructor() { - super(); - - this.accountAddress$ = this.account$.observeKey('address'); - } - - get account(): Account { - return this.account$.value; - } - - get accountAddress(): string { - return this.account ? this.account.address : null; - } - - get headers(): { [key: string]: any } { - return this.services.walletService.walletAddress - ? { - [HeaderNames.AnalyticsToken]: keccak256(this.services.walletService.walletAddress), - } - : {}; - } - - joinContractAccount(address: string): void { - this.account$.next( - Account.fromPlain({ - address, - type: AccountTypes.Contract, - synchronizedAt: null, - }), - ); - - } - - isContractAccount(): boolean { - return this.account.type === AccountTypes.Contract; - } - - protected onInit(): void { - const { walletService, networkService } = this.services; - - this.addSubscriptions( - combineLatest([ - walletService.walletAddress$, // - networkService.chainId$, - ]) - .pipe( - map(([address, chainId]) => - !address || !chainId - ? null - : Account.fromPlain({ - address, - type: AccountTypes.Key, - synchronizedAt: null, - }), - ), - ) - .subscribe(this.account$), - ); - } -} diff --git a/src/sdk/account/classes/account.ts b/src/sdk/account/classes/account.ts deleted file mode 100644 index 53b10c4..0000000 --- a/src/sdk/account/classes/account.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { plainToClass } from 'class-transformer'; -import { Type } from 'class-transformer'; -import { Synchronized } from '../../common'; -import { AccountTypes, AccountStates } from '../constants'; - -export class Account extends Synchronized { - static fromPlain(plain: Partial): Account { - return plainToClass(Account, plain); - } - - address: string; - - type: AccountTypes; - - state: AccountStates; - - @Type(() => Date) - createdAt: Date; - - @Type(() => Date) - updatedAt: Date; -} diff --git a/src/sdk/account/classes/index.ts b/src/sdk/account/classes/index.ts deleted file mode 100644 index 8cf3132..0000000 --- a/src/sdk/account/classes/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './account'; \ No newline at end of file diff --git a/src/sdk/account/constants.ts b/src/sdk/account/constants.ts deleted file mode 100644 index 6081a75..0000000 --- a/src/sdk/account/constants.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum AccountTypes { - Contract = 'Contract', - Key = 'Key', -} - -export enum AccountStates { - UnDeployed = 'UnDeployed', - Deployed = 'Deployed', -} diff --git a/src/sdk/account/index.ts b/src/sdk/account/index.ts deleted file mode 100644 index 84a653d..0000000 --- a/src/sdk/account/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './account.service'; -export * from './classes'; -export * from './constants'; diff --git a/src/sdk/api/api.service.ts b/src/sdk/api/api.service.ts index ac85ce8..da0399c 100644 --- a/src/sdk/api/api.service.ts +++ b/src/sdk/api/api.service.ts @@ -4,24 +4,24 @@ import { WebSocketLink } from '@apollo/client/link/ws'; import { getMainDefinition } from '@apollo/client/utilities'; import fetch from 'cross-fetch'; import { BigNumber } from 'ethers'; -import { isBigNumber, Service } from '../common'; -import { HttpException, HttpExceptionCodes } from './exceptions'; +import { isBigNumber } from '../common'; import { ApiOptions, ApiRequestOptions, ApiRequestQueryOptions } from './interfaces'; import { buildApiUri, catchApiError, mapApiResult } from './utils'; -export class ApiService extends Service { +export class ApiService { private readonly options: ApiOptions; private apolloClient: ApolloClient; constructor(options: ApiOptions) { - super(); this.options = { port: null, useSsl: false, ...options, }; + + this.onInit(); } async query(query: DocumentNode, options?: ApiRequestQueryOptions): Promise { @@ -32,7 +32,6 @@ export class ApiService extends Service { }; const { - omitChainIdVariable, // variables, fetchPolicy, models, @@ -43,7 +42,7 @@ export class ApiService extends Service { this.apolloClient.query({ query, fetchPolicy, - variables: this.prepareApiVariables(variables, omitChainIdVariable), + variables: this.prepareApiVariables(variables), }), models, ); @@ -56,7 +55,6 @@ export class ApiService extends Service { }; const { - omitChainIdVariable, // variables, models, } = options; @@ -65,7 +63,7 @@ export class ApiService extends Service { () => this.apolloClient.mutate({ mutation, - variables: this.prepareApiVariables(variables, omitChainIdVariable), + variables: this.prepareApiVariables(variables), }), models, ); @@ -73,7 +71,6 @@ export class ApiService extends Service { subscribe(query: DocumentNode, options?: ApiRequestOptions): Observable { const { - omitChainIdVariable, // variables, models, } = options; @@ -81,7 +78,7 @@ export class ApiService extends Service { return this.apolloClient .subscribe({ query, - variables: this.prepareApiVariables(variables, omitChainIdVariable), + variables: this.prepareApiVariables(variables), }) .map(({ data }) => mapApiResult(data, models)); @@ -103,17 +100,10 @@ export class ApiService extends Service { }); const authLink = setContext(async () => { - const { - accountService, // - sessionService, - dataService, - } = this.services; return { headers: { - ...accountService.headers, - ...sessionService.headers, - ...dataService.headers, + ['x-project-key']: this.options.projectKey, }, }; }); @@ -158,20 +148,7 @@ export class ApiService extends Service { try { result = await wrapped(); } catch (err) { - if ( - err instanceof HttpException && - (err.code === HttpExceptionCodes.Forbidden || err.code === HttpExceptionCodes.Unauthorized) - ) { - // create new session - const { sessionService } = this.services; - const { sessionTtl } = sessionService; - await sessionService.createSession(sessionTtl); - - // re-call - result = await wrapped(); - } else { - throw err; - } + throw err; } return result; @@ -179,7 +156,6 @@ export class ApiService extends Service { private prepareApiVariables( variables: { [keys: string]: any }, - omitChainIdVariable: boolean, ): { [key: string]: any } { const result: { [key: string]: any } = {}; @@ -197,12 +173,6 @@ export class ApiService extends Service { result[key] = value; } - if (!omitChainIdVariable) { - const { chainId } = this.services.walletService; - result.chainId = chainId; - } - return result; } } - diff --git a/src/sdk/api/interfaces.ts b/src/sdk/api/interfaces.ts index 6bc20eb..63fcc1e 100644 --- a/src/sdk/api/interfaces.ts +++ b/src/sdk/api/interfaces.ts @@ -2,12 +2,12 @@ import { FetchPolicy } from '@apollo/client/core'; export interface ApiOptions { host: string; + projectKey: string; port?: number; useSsl?: boolean; } export interface ApiRequestOptions { - omitChainIdVariable?: boolean; variables?: { [key: string]: any }; models?: { [key in K]: { new (...args: any): T[K] }; diff --git a/src/sdk/base/BaseAccountAPI.ts b/src/sdk/base/BaseAccountAPI.ts index 5c72748..c9a3869 100644 --- a/src/sdk/base/BaseAccountAPI.ts +++ b/src/sdk/base/BaseAccountAPI.ts @@ -8,9 +8,8 @@ import { resolveProperties } from 'ethers/lib/utils'; import { PaymasterAPI } from './PaymasterAPI'; import { ErrorSubject, Exception, getUserOpHash, NotPromise, packUserOp } from '../common'; import { calcPreVerificationGas, GasOverheads } from './calcPreVerificationGas'; -import { AccountService, AccountTypes, ApiService, CreateSessionDto, Factory, isWalletProvider, Network, NetworkNames, NetworkService, SdkOptions, Session, SessionService, SignMessageDto, State, StateService, validateDto, WalletProviderLike, WalletService } from '..'; +import { Factory, isWalletProvider, Network, NetworkNames, NetworkService, SdkOptions, SignMessageDto, State, StateService, validateDto, WalletProviderLike, WalletService } from '..'; import { Context } from '../context'; -import { DataService } from '../data'; import { PaymasterResponse } from './VerifyingPaymasterAPI'; export interface BaseApiParams { @@ -74,36 +73,20 @@ export abstract class BaseAccountAPI { const { chainId, // - omitWalletProviderNetworkCheck, stateStorage, - sessionStorage, rpcProviderUrl, bundlerRpcUrl, - graphqlEndpoint, - projectKey, factoryWallet, } = optionsLike; - // const { networkOptions } = env; - this.services = { networkService: new NetworkService(chainId), walletService: new WalletService(params.walletProvider, { - omitProviderNetworkCheck: omitWalletProviderNetworkCheck, provider: rpcProviderUrl, }, bundlerRpcUrl, chainId), - sessionService: new SessionService({ - storage: sessionStorage, - }), - accountService: new AccountService(), stateService: new StateService({ storage: stateStorage, }), - apiService: new ApiService({ - host: graphqlEndpoint, - useSsl: true, - }), - dataService: new DataService(projectKey), }; this.context = new Context(this.services); @@ -165,21 +148,6 @@ export abstract class BaseAccountAPI { return this.services.walletService.signMessage(message); } - // session - - /** - * creates session - * @param dto - * @return Promise - */ - async createSession(dto: CreateSessionDto = {}): Promise { - const { ttl, fcmToken } = await validateDto(dto, CreateSessionDto); - - await this.require(); - - return this.services.sessionService.createSession(ttl, fcmToken); - } - async setPaymasterApi(paymaster: PaymasterAPI | null) { this.paymasterAPI = paymaster; } @@ -192,8 +160,6 @@ export abstract class BaseAccountAPI { options: { network?: boolean; wallet?: boolean; - session?: boolean; - contractAccount?: boolean; } = {}, ): Promise { options = { @@ -202,30 +168,16 @@ export abstract class BaseAccountAPI { ...options, }; - const { accountService, walletService, sessionService } = this.services; + const { walletService } = this.services; if (options.network && !walletService.chainId) { throw new Exception('Unknown network'); } - if (options.wallet && !walletService.walletAddress) { + if (options.wallet && !walletService.EOAAddress) { throw new Exception('Require wallet'); } - if (options.session) { - await sessionService.verifySession(); - } - - if (options.contractAccount && (!accountService.account || accountService.account.type !== AccountTypes.Contract)) { - throw new Exception('Require contract account'); - } - } - - prepareAccountAddress(account: string = null): string { - const { - accountService: { accountAddress }, - } = this.services; - return account || accountAddress; } getNetworkChainId(networkName: NetworkNames = null): number { @@ -327,13 +279,11 @@ export abstract class BaseAccountAPI { */ async getCounterFactualAddress(): Promise { const initCode = await this.getAccountInitCode(); - // console.log('initCode: ', initCode) // use entryPoint to query account address (factory can provide a helper method to do the same, but // this method attempts to be generic try { await this.entryPointView.callStatic.getSenderAddress(initCode); } catch (e: any) { - // console.log(e); return e.errorArgs.sender; } throw new Error('must handle revert'); diff --git a/src/sdk/base/EtherspotWalletAPI.ts b/src/sdk/base/EtherspotWalletAPI.ts index 0888df7..a71f798 100644 --- a/src/sdk/base/EtherspotWalletAPI.ts +++ b/src/sdk/base/EtherspotWalletAPI.ts @@ -66,18 +66,20 @@ export class EtherspotWalletAPI extends BaseAccountAPI { return hexConcat([ this.factoryAddress, this.factory.interface.encodeFunctionData('createAccount', [ - this.services.walletService.walletAddress, + this.services.walletService.EOAAddress, this.index, ]), ]); } async getCounterFactualAddress(): Promise { + if (!this.accountAddress) { this.factory = EtherspotWalletFactory__factory.connect(this.factoryAddress, this.provider); this.accountAddress = await this.factory.getAddress( - this.services.walletService.walletAddress, + this.services.walletService.EOAAddress, this.index, ); + } return this.accountAddress; } diff --git a/src/sdk/base/SimpleAccountWalletAPI.ts b/src/sdk/base/SimpleAccountWalletAPI.ts index 482c54d..d1b9dc7 100644 --- a/src/sdk/base/SimpleAccountWalletAPI.ts +++ b/src/sdk/base/SimpleAccountWalletAPI.ts @@ -59,25 +59,27 @@ export class SimpleAccountAPI extends BaseAccountAPI { return hexConcat([ this.factoryAddress, this.factory.interface.encodeFunctionData('createAccount', [ - this.services.walletService.walletAddress, + this.services.walletService.EOAAddress, this.index, ]), ]); } async getCounterFactualAddress(): Promise { - try { - const initCode = await this.getAccountInitCode(); - const entryPoint = EntryPoint__factory.connect(this.entryPointAddress, this.provider); - await entryPoint.callStatic.getSenderAddress(initCode); + if (!this.accountAddress) { + try { + const initCode = await this.getAccountInitCode(); + const entryPoint = EntryPoint__factory.connect(this.entryPointAddress, this.provider); + await entryPoint.callStatic.getSenderAddress(initCode); - throw new Error("getSenderAddress: unexpected result"); - } catch (error: any) { - const addr = error?.errorArgs?.sender; - if (!addr) throw error; - if (addr === ethers.constants.AddressZero) throw new Error('Unsupported chain_id/walletFactoryAddress'); - this.accountContract = new ethers.Contract(addr, SimpleAccountAbi, this.provider); - this.accountAddress = addr; + throw new Error("getSenderAddress: unexpected result"); + } catch (error: any) { + const addr = error?.errorArgs?.sender; + if (!addr) throw error; + if (addr === ethers.constants.AddressZero) throw new Error('Unsupported chain_id/walletFactoryAddress'); + this.accountContract = new ethers.Contract(addr, SimpleAccountAbi, this.provider); + this.accountAddress = addr; + } } return this.accountAddress; } diff --git a/src/sdk/base/ZeroDevWalletAPI.ts b/src/sdk/base/ZeroDevWalletAPI.ts index 64fb108..dda4aa1 100644 --- a/src/sdk/base/ZeroDevWalletAPI.ts +++ b/src/sdk/base/ZeroDevWalletAPI.ts @@ -69,7 +69,7 @@ export class ZeroDevWalletAPI extends BaseAccountAPI { "0xf048AD83CB2dfd6037A43902a2A5Be04e53cd2Eb", // Kernel Implementation Address new ethers.utils.Interface(KernelAccountAbi).encodeFunctionData( "initialize", - ["0xd9AB5096a832b9ce79914329DAEE236f8Eea0390", this.services.walletService.walletAddress], // Kernel Validation Address + ["0xd9AB5096a832b9ce79914329DAEE236f8Eea0390", this.services.walletService.EOAAddress], // Kernel Validation Address ), this.index, ], @@ -92,25 +92,27 @@ export class ZeroDevWalletAPI extends BaseAccountAPI { } async getCounterFactualAddress(): Promise { - try { - const initCode = await this.getAccountInitCode(); - const entryPoint = EntryPoint__factory.connect(this.entryPointAddress, this.provider); - await entryPoint.callStatic.getSenderAddress(initCode); - - throw new Error("getSenderAddress: unexpected result"); - } catch (error: any) { - const addr = error?.errorArgs?.sender; - if (!addr) throw error; - if (addr === ethers.constants.AddressZero) throw new Error('Unsupported chain_id'); - const chain = await this.provider.getNetwork().then((n) => n.chainId); - const ms = Safe.MultiSend[chain.toString()]; - if (!ms) - throw new Error( - `Multisend contract not deployed on network: ${chain.toString()}` - ); - this.multisend = new ethers.Contract(ms, MultiSendAbi, this.provider); - this.accountContract = new ethers.Contract(addr, KernelAccountAbi, this.provider); - this.accountAddress = addr; + if (!this.accountAddress) { + try { + const initCode = await this.getAccountInitCode(); + const entryPoint = EntryPoint__factory.connect(this.entryPointAddress, this.provider); + await entryPoint.callStatic.getSenderAddress(initCode); + + throw new Error("getSenderAddress: unexpected result"); + } catch (error: any) { + const addr = error?.errorArgs?.sender; + if (!addr) throw error; + if (addr === ethers.constants.AddressZero) throw new Error('Unsupported chain_id'); + const chain = await this.provider.getNetwork().then((n) => n.chainId); + const ms = Safe.MultiSend[chain.toString()]; + if (!ms) + throw new Error( + `Multisend contract not deployed on network: ${chain.toString()}` + ); + this.multisend = new ethers.Contract(ms, MultiSendAbi, this.provider); + this.accountContract = new ethers.Contract(addr, KernelAccountAbi, this.provider); + this.accountAddress = addr; + } } return this.accountAddress; } diff --git a/src/sdk/context.ts b/src/sdk/context.ts index 7cead4b..3c5357e 100644 --- a/src/sdk/context.ts +++ b/src/sdk/context.ts @@ -1,9 +1,5 @@ -import { AccountService } from './account'; -import { ApiService } from './api'; import { ErrorSubject, Service } from './common'; -import { DataService } from './data'; import { NetworkService } from './network'; -import { SessionService } from './session'; import { StateService } from './state'; import { WalletService } from './wallet'; @@ -14,13 +10,9 @@ export class Context { constructor( readonly services: { - accountService: AccountService; - sessionService: SessionService; stateService: StateService; walletService: WalletService; networkService: NetworkService; - apiService: ApiService; - dataService: DataService, }, ) { const items = [...Object.values(services)]; diff --git a/src/sdk/data/data.service.ts b/src/sdk/data/data.module.ts similarity index 90% rename from src/sdk/data/data.service.ts rename to src/sdk/data/data.module.ts index c8b85e1..3e824b7 100644 --- a/src/sdk/data/data.service.ts +++ b/src/sdk/data/data.module.ts @@ -1,15 +1,21 @@ import { gql } from '@apollo/client/core'; -import { HeaderNames, ObjectSubject, Service } from '../common'; +import { HeaderNames, ObjectSubject } from '../common'; import { Route } from '@lifi/sdk'; import { AccountBalances, AdvanceRoutesLiFi, BridgingQuotes, ExchangeOffer, ExchangeOffers, NftList, PaginatedTokens, RateData, StepTransaction, StepTransactions, TokenList, TokenListToken, TokenLists, Transaction } from './classes'; import { BigNumber } from 'ethers'; import { CrossChainServiceProvider, LiFiBridge } from './constants'; +import { ApiService } from '../api'; -export class DataService extends Service { +export class DataModule { readonly currentProject$ = new ObjectSubject(''); - - constructor(currentProject = '') { - super(); + private apiService: ApiService; + constructor(currentProject = '', graphqlEndpoint: string) { + // super(); + this.apiService = new ApiService({ + host: graphqlEndpoint, + useSsl: true, + projectKey: currentProject, + }); this.switchCurrentProject(currentProject); } @@ -37,9 +43,8 @@ export class DataService extends Service { } async getAccountBalances(account: string, tokens: string[], ChainId: number, provider?: string): Promise { - const { apiService } = this.services; - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: AccountBalances; }>( gql` @@ -69,15 +74,14 @@ export class DataService extends Service { return result; } - async getTransaction(hash: string): Promise { - const { apiService } = this.services; + async getTransaction(hash: string, ChainId: number): Promise { - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: Transaction; }>( gql` - query($chainId: Int, $hash: String!) { - result: transaction(chainId: $chainId, hash: $hash) { + query($ChainId: Int, $hash: String!) { + result: transaction(chainId: $ChainId, hash: $hash) { blockHash blockNumber from @@ -101,6 +105,7 @@ export class DataService extends Service { `, { variables: { + ChainId, hash, }, models: { @@ -113,9 +118,8 @@ export class DataService extends Service { } async getNftList(account: string, ChainId: number): Promise { - const { apiService } = this.services; - - const { result } = await apiService.query<{ + + const { result } = await this.apiService.query<{ result: NftList; }>( gql` @@ -155,10 +159,9 @@ export class DataService extends Service { } async getExchangeSupportedAssets(page: number = null, limit: number = null, ChainId: number, account: string): Promise { - const { apiService } = this.services; - + try { - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: PaginatedTokens; }>( gql` @@ -202,15 +205,14 @@ export class DataService extends Service { toTokenAddress: string, fromAmount: BigNumber, fromChainId: number, + fromAddress: string, toAddress?: string, - fromAddress?: string, showZeroUsd?: boolean, ): Promise { - const { apiService } = this.services; const account = fromAddress; - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: ExchangeOffers; }>( gql` @@ -278,13 +280,12 @@ export class DataService extends Service { fromAddress?: string, showZeroUsd?: boolean, ): Promise { - const { apiService } = this.services; const account = fromAddress; let data = null; - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: string; }>( gql` @@ -341,7 +342,6 @@ export class DataService extends Service { } async getStepTransaction(selectedRoute: Route, accountAddress: string): Promise { - const { apiService } = this.services; const account = accountAddress; @@ -349,7 +349,7 @@ export class DataService extends Service { try { const route = JSON.stringify(selectedRoute); - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: StepTransaction[]; }>( gql` @@ -398,11 +398,10 @@ export class DataService extends Service { fromAddress?: string, showZeroUsd?: boolean, ): Promise { - const { apiService } = this.services; const account = fromAddress; - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: BridgingQuotes; }>( gql` @@ -511,10 +510,9 @@ export class DataService extends Service { } async getTokenLists(): Promise { - const { apiService } = this.services; try { - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: TokenLists; }>( gql` @@ -545,10 +543,9 @@ export class DataService extends Service { } async getTokenListTokens(name: string = null): Promise { - const { apiService } = this.services; try { - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: TokenList; }>( gql` @@ -584,9 +581,8 @@ export class DataService extends Service { } async fetchExchangeRates(tokens: string[], ChainId: number): Promise { - const { apiService } = this.services; try { - const { result } = await apiService.query<{ + const { result } = await this.apiService.query<{ result: RateData; }>( gql` diff --git a/src/sdk/data/index.ts b/src/sdk/data/index.ts index a659a1e..2855550 100644 --- a/src/sdk/data/index.ts +++ b/src/sdk/data/index.ts @@ -1,3 +1,3 @@ -export * from './data.service'; +export * from './data.module'; export * from './classes'; export * from './constants'; diff --git a/src/sdk/dataUtils.ts b/src/sdk/dataUtils.ts new file mode 100644 index 0000000..cda3481 --- /dev/null +++ b/src/sdk/dataUtils.ts @@ -0,0 +1,232 @@ +import { BigNumber } from "ethers"; +import { AccountBalances, NftList, PaginatedTokens, ExchangeOffer, AdvanceRoutesLiFi, StepTransactions, BridgingQuotes, TokenList, TokenListToken, RateData, Transaction, DataModule } from "./data"; +import { GetAccountBalancesDto, validateDto, GetTransactionDto, GetNftListDto, GetExchangeSupportedAssetsDto, GetExchangeOffersDto, GetAdvanceRoutesLiFiDto, GetStepTransactionsLiFiDto, GetExchangeCrossChainQuoteDto, GetTokenListDto, FetchExchangeRatesDto } from "./dto"; +import { graphqlEndpoints } from "./interfaces"; + +export class DataUtils { + private dataModule: DataModule; + constructor(projectKey: string, endpoint: graphqlEndpoints) { + + this.dataModule = new DataModule(projectKey, endpoint) + } + + /** + * gets account balances + * @param dto + * @return Promise + */ + async getAccountBalances(dto: GetAccountBalancesDto): Promise { + const { account, tokens, chainId, provider } = await validateDto(dto, GetAccountBalancesDto, { + addressKeys: ['account', 'tokens'], + }); + + return this.dataModule.getAccountBalances( + account, + tokens, + chainId, + provider, + ); + } + + /** + * gets transaction + * @param dto + * @return Promise + */ + async getTransaction(dto: GetTransactionDto): Promise { + const { hash, chainId } = await validateDto(dto, GetTransactionDto); + + return this.dataModule.getTransaction(hash, chainId); + } + + /** + * gets NFT list belonging to account + * @param dto + * @return Promise + */ + async getNftList(dto: GetNftListDto): Promise { + const { account, chainId } = await validateDto(dto, GetNftListDto, { + addressKeys: ['account'], + }); + + return this.dataModule.getNftList( + account, + chainId, + ); + } + + /** + * gets exchange supported tokens + * @param dto + * @return Promise + */ + async getExchangeSupportedAssets(dto: GetExchangeSupportedAssetsDto): Promise { + const { page, limit, chainId, account } = await validateDto(dto, GetExchangeSupportedAssetsDto, { + addressKeys: ['account'] + }); + + return this.dataModule.getExchangeSupportedAssets(page, limit, chainId, account); + } + + /** + * gets exchange offers + * @param dto + * @return Promise + */ + async getExchangeOffers(dto: GetExchangeOffersDto): Promise { + const { fromTokenAddress, toTokenAddress, fromAmount, fromChainId, showZeroUsd, fromAddress } = await validateDto(dto, GetExchangeOffersDto, { + addressKeys: ['fromTokenAddress', 'toTokenAddress', 'fromAddress'], + }); + + let { toAddress } = dto; + + if (!toAddress) toAddress = fromAddress; + + return this.dataModule.getExchangeOffers( + fromTokenAddress, + toTokenAddress, + BigNumber.from(fromAmount), + fromChainId, + fromAddress, + toAddress, + showZeroUsd, + ); + } + + async getAdvanceRoutesLiFi(dto: GetAdvanceRoutesLiFiDto): Promise { + const { + fromChainId, + toChainId, + fromTokenAddress, + toTokenAddress, + fromAmount, + allowSwitchChain, + showZeroUsd, + fromAddress, + } = await validateDto(dto, GetAdvanceRoutesLiFiDto, { + addressKeys: ['fromTokenAddress', 'toTokenAddress', 'fromAddress'], + }); + + let { toAddress } = dto; + + if (!toAddress) toAddress = fromAddress; + + const data = await this.dataModule.getAdvanceRoutesLiFi( + fromTokenAddress, + toTokenAddress, + fromChainId, + toChainId, + BigNumber.from(fromAmount), + toAddress, + allowSwitchChain, + fromAddress, + showZeroUsd, + ); + + return data; + } + + async getStepTransaction(dto: GetStepTransactionsLiFiDto): Promise { + const { route, account } = await validateDto(dto, GetStepTransactionsLiFiDto, { + addressKeys: ['account'] + }) + + return this.dataModule.getStepTransaction(route, account); + } + + /** + * gets multi chain quotes + * @param dto + * @return Promise + */ + async getCrossChainQuotes(dto: GetExchangeCrossChainQuoteDto): Promise { + const { + fromChainId, + toChainId, + fromTokenAddress, + toTokenAddress, + fromAmount, + serviceProvider, + lifiBridges, + toAddress, + showZeroUsd, + fromAddress, + } = await validateDto(dto, GetExchangeCrossChainQuoteDto, { + addressKeys: ['fromTokenAddress', 'toTokenAddress', 'fromAddress'], + }); + + return this.dataModule.getCrossChainQuotes( + fromTokenAddress, + toTokenAddress, + fromChainId, + toChainId, + BigNumber.from(fromAmount), + serviceProvider, + lifiBridges, + toAddress, + fromAddress, + showZeroUsd, + ); + } + + /** + * gets token lists + * @return Promise + */ + async getTokenLists(): Promise { + + return this.dataModule.getTokenLists(); + } + + /** + * gets token list tokens + * @param dto + * @return Promise + */ + async getTokenListTokens(dto: GetTokenListDto = {}): Promise { + const { name } = await validateDto(dto, GetTokenListDto); + + return this.dataModule.getTokenListTokens(name); + } + + /** + * fetch exchange rates of tokens + * @param dto + * @return Promise + */ + async fetchExchangeRates(dto: FetchExchangeRatesDto): Promise { + const { tokens, chainId } = dto; + let data: RateData; + const promises = []; + + // Create a batch of 50 + const batches = [...Array(Math.ceil(tokens.length / 50))].map(() => tokens.splice(0, 50)); + batches.forEach((batch) => { + promises.push(this.dataModule.fetchExchangeRates(batch, chainId)); + }); + + // Fetch succeded results and merge + await (Promise as any) + .allSettled(promises) + .then((response) => + response?.forEach((result) => { + if (result?.status === 'fulfilled') { + !data + ? (data = result.value ? result.value : {}) + : (data.items = result?.value?.items ? [...data.items, ...result.value.items] : [...data.items]); + } + }), + ); + + // Return Unique tokens + if (data && data.items && data.items.length) { + data.error = '' + data.errored = false + data.items = [...new Map(data.items.map(item => [item['address'], item])).values()]; + } else { + data.items = []; + } + + return data; + } +} \ No newline at end of file diff --git a/src/sdk/dto/advance-routes-lifi.dto.ts b/src/sdk/dto/advance-routes-lifi.dto.ts index 5d1db47..06dfb8b 100644 --- a/src/sdk/dto/advance-routes-lifi.dto.ts +++ b/src/sdk/dto/advance-routes-lifi.dto.ts @@ -23,13 +23,12 @@ export class GetAdvanceRoutesLiFiDto { @IsBigNumberish() fromAmount: BigNumber; - @IsOptional() @IsAddress() - toAddress?: string; + fromAddress: string; @IsOptional() @IsAddress() - fromAddress?: string; + toAddress?: string; @IsOptional() @IsBoolean() diff --git a/src/sdk/dto/create-session.dto.ts b/src/sdk/dto/create-session.dto.ts deleted file mode 100644 index dc9999d..0000000 --- a/src/sdk/dto/create-session.dto.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { IsOptional, IsPositive, IsInt, IsString } from 'class-validator'; - -export class CreateSessionDto { - @IsOptional() - @IsPositive() - @IsInt() - ttl?: number = null; - - @IsOptional() - @IsString() - fcmToken?: string = null; -} diff --git a/src/sdk/dto/get-account-balances.dto.ts b/src/sdk/dto/get-account-balances.dto.ts index 15bf437..1c1c07e 100644 --- a/src/sdk/dto/get-account-balances.dto.ts +++ b/src/sdk/dto/get-account-balances.dto.ts @@ -2,21 +2,19 @@ import { IsOptional, IsPositive, IsString } from 'class-validator'; import { IsAddress } from './validators'; export class GetAccountBalancesDto { - @IsOptional() - @IsAddress() - account?: string = null; - @IsOptional() @IsAddress({ each: true, }) tokens?: string[] = []; - @IsOptional() - @IsPositive() - chainId?: number; - @IsOptional() @IsString() provider?: string = null; + + @IsAddress() + account: string = null; + + @IsPositive() + chainId: number; } diff --git a/src/sdk/dto/get-exchange-cross-chain-quote.dto.ts b/src/sdk/dto/get-exchange-cross-chain-quote.dto.ts index fc62c13..ec6cf5c 100644 --- a/src/sdk/dto/get-exchange-cross-chain-quote.dto.ts +++ b/src/sdk/dto/get-exchange-cross-chain-quote.dto.ts @@ -24,6 +24,9 @@ export class GetExchangeCrossChainQuoteDto { @IsBigNumberish() fromAmount: BigNumber; + @IsAddress() + fromAddress: string; + @IsOptional() serviceProvider?: CrossChainServiceProvider; @@ -31,10 +34,6 @@ export class GetExchangeCrossChainQuoteDto { @IsAddress() toAddress?: string; - @IsOptional() - @IsAddress() - fromAddress?: string; - @IsOptional() lifiBridges?: LiFiBridge[]; diff --git a/src/sdk/dto/get-exchange-offers.dto.ts b/src/sdk/dto/get-exchange-offers.dto.ts index 540a9dc..d5da4bf 100644 --- a/src/sdk/dto/get-exchange-offers.dto.ts +++ b/src/sdk/dto/get-exchange-offers.dto.ts @@ -14,16 +14,14 @@ export class GetExchangeOffersDto { }) fromAmount: BigNumberish; - @IsOptional() - fromChainId?: number; + fromChainId: number; - @IsOptional() @IsAddress() - toAddress?: string; + fromAddress: string; @IsOptional() @IsAddress() - fromAddress?: string; + toAddress?: string; @IsOptional() @IsBoolean() diff --git a/src/sdk/dto/get-exchange-supported-assets.dto.ts b/src/sdk/dto/get-exchange-supported-assets.dto.ts index 64df444..fe49721 100644 --- a/src/sdk/dto/get-exchange-supported-assets.dto.ts +++ b/src/sdk/dto/get-exchange-supported-assets.dto.ts @@ -1,8 +1,11 @@ -import { IsOptional, IsPositive } from 'class-validator'; +import { IsPositive } from 'class-validator'; import { PaginationDto } from './pagination.dto'; +import { IsAddress } from './validators'; export class GetExchangeSupportedAssetsDto extends PaginationDto { - @IsOptional() @IsPositive() - chainId?: number; + chainId: number; + + @IsAddress() + account: string; } diff --git a/src/sdk/dto/get-nft-list.dto.ts b/src/sdk/dto/get-nft-list.dto.ts index 59212f0..a5ee505 100644 --- a/src/sdk/dto/get-nft-list.dto.ts +++ b/src/sdk/dto/get-nft-list.dto.ts @@ -1,10 +1,9 @@ -import { IsOptional, IsPositive } from 'class-validator'; +import { IsPositive } from 'class-validator'; import { IsAddress } from './validators'; export class GetNftListDto { - @IsOptional() @IsPositive() - chainId?: number; + chainId: number; @IsAddress() account: string; diff --git a/src/sdk/dto/get-step-transactions-lifi.dto.ts b/src/sdk/dto/get-step-transactions-lifi.dto.ts index 2a354b8..37642c4 100644 --- a/src/sdk/dto/get-step-transactions-lifi.dto.ts +++ b/src/sdk/dto/get-step-transactions-lifi.dto.ts @@ -1,5 +1,9 @@ import { Route } from '@lifi/sdk'; +import { IsAddress } from './validators'; export class GetStepTransactionsLiFiDto { route: Route + + @IsAddress() + account: string; } diff --git a/src/sdk/dto/get-transaction.dto.ts b/src/sdk/dto/get-transaction.dto.ts index d21026f..c888320 100644 --- a/src/sdk/dto/get-transaction.dto.ts +++ b/src/sdk/dto/get-transaction.dto.ts @@ -1,6 +1,10 @@ +import { IsPositive } from 'class-validator'; import { IsHex32 } from './validators'; export class GetTransactionDto { @IsHex32() hash: string; + + @IsPositive() + chainId: number; } diff --git a/src/sdk/dto/index.ts b/src/sdk/dto/index.ts index c495041..0620d6c 100644 --- a/src/sdk/dto/index.ts +++ b/src/sdk/dto/index.ts @@ -1,11 +1,9 @@ export * from './sign-message.dto'; export * from './utils'; -export * from './create-session.dto'; export * from './onRamper.dto'; export * from './get-account-balances.dto'; export * from './get-transaction.dto'; export * from './get-nft-list.dto'; -export * from './join-contract-account.dto'; export * from './get-exchange-offers.dto'; export * from './advance-routes-lifi.dto'; export * from './get-step-transactions-lifi.dto'; diff --git a/src/sdk/dto/join-contract-account.dto.ts b/src/sdk/dto/join-contract-account.dto.ts deleted file mode 100644 index 313cd8d..0000000 --- a/src/sdk/dto/join-contract-account.dto.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { IsBoolean, IsOptional } from 'class-validator'; -import { IsAddress } from './validators'; - -export class JoinContractAccountDto { - @IsAddress() - address: string; - - @IsOptional() - @IsBoolean() - sync?: boolean = true; -} diff --git a/src/sdk/index.ts b/src/sdk/index.ts index cd04786..9967fe6 100644 --- a/src/sdk/index.ts +++ b/src/sdk/index.ts @@ -1,14 +1,13 @@ +import { DataUtils } from './dataUtils'; import { PrimeSdk } from './sdk'; -export * from './account'; export * from './api'; export * from './data'; export * from './dto'; export * from './interfaces'; export * from './network'; -export * from './session'; export * from './state'; export * from './wallet'; -export { PrimeSdk }; +export { PrimeSdk, DataUtils }; export default PrimeSdk; \ No newline at end of file diff --git a/src/sdk/interfaces.ts b/src/sdk/interfaces.ts index ed78c6e..5e7d964 100644 --- a/src/sdk/interfaces.ts +++ b/src/sdk/interfaces.ts @@ -1,5 +1,4 @@ import { StateStorage } from './state'; -import { SessionStorage } from './session'; export interface PaymasterApi { url: string; @@ -15,8 +14,6 @@ export enum Factory { export interface SdkOptions { chainId: number; stateStorage?: StateStorage; - sessionStorage?: SessionStorage; - omitWalletProviderNetworkCheck?: boolean; bundlerRpcUrl?: string; rpcProviderUrl?: string; graphqlEndpoint?: string; @@ -25,3 +22,8 @@ export interface SdkOptions { walletFactoryAddress?: string; entryPointAddress?: string; } + +export enum graphqlEndpoints { + QA = 'qa-etherspot.pillarproject.io', + PROD = 'etherspot.pillarproject.io' +} diff --git a/src/sdk/network/network.service.ts b/src/sdk/network/network.service.ts index 757f99e..4b6dccd 100644 --- a/src/sdk/network/network.service.ts +++ b/src/sdk/network/network.service.ts @@ -1,7 +1,7 @@ import { Observable } from 'rxjs'; import { NetworkConfig } from '.'; import { ObjectSubject, Service, Exception } from '../common'; -import { NetworkNames, Networks, CHAIN_ID_TO_NETWORK_NAME, SupportedNetworks } from './constants'; +import { Networks, CHAIN_ID_TO_NETWORK_NAME, SupportedNetworks, NetworkNames } from './constants'; import { Network } from './interfaces'; export class NetworkService extends Service { diff --git a/src/sdk/sdk.ts b/src/sdk/sdk.ts index 888afdd..09b8574 100644 --- a/src/sdk/sdk.ts +++ b/src/sdk/sdk.ts @@ -15,8 +15,7 @@ import { getNetworkConfig, Networks, onRamperAllNetworks } from './network/const import { UserOperationStruct } from './contracts/account-abstraction/contracts/core/BaseAccount'; import { EtherspotWalletAPI, HttpRpcClient, VerifyingPaymasterAPI } from './base'; import { TransactionDetailsForUserOp, TransactionGasInfoForUserOp } from './base/TransactionDetailsForUserOp'; -import { CreateSessionDto, OnRamperDto, GetAccountBalancesDto, GetAdvanceRoutesLiFiDto, GetExchangeCrossChainQuoteDto, GetExchangeOffersDto, GetNftListDto, GetStepTransactionsLiFiDto, GetTransactionDto, SignMessageDto, validateDto, FetchExchangeRatesDto, GetTokenListDto, GetExchangeSupportedAssetsDto } from './dto'; -import { AccountBalances, AdvanceRoutesLiFi, BridgingQuotes, ExchangeOffer, NftList, StepTransactions, Transaction, Session, RateData, TokenListToken, TokenList, PaginatedTokens } from './'; +import { OnRamperDto, SignMessageDto, validateDto } from './dto'; import { ZeroDevWalletAPI } from './base/ZeroDevWalletAPI'; import { SimpleAccountAPI } from './base/SimpleAccountWalletAPI'; import { ErrorHandler } from './errorHandler/errorHandler.service'; @@ -150,21 +149,6 @@ export class PrimeSdk { return this.etherspotWallet.services.walletService.signMessage(message); } - // session - - /** - * creates session - * @param dto - * @return Promise - */ - async createSession(dto: CreateSessionDto = {}): Promise { - const { ttl, fcmToken } = await validateDto(dto, CreateSessionDto); - - await this.etherspotWallet.require(); - - return this.etherspotWallet.services.sessionService.createSession(ttl, fcmToken); - } - async getCounterFactualAddress(): Promise { return this.etherspotWallet.getCounterFactualAddress(); } @@ -325,268 +309,4 @@ export class PrimeSdk { return url; } - - /** - * gets account balances - * @param dto - * @return Promise - */ - async getAccountBalances(dto: GetAccountBalancesDto = {}): Promise { - const { account, tokens, chainId, provider } = await validateDto(dto, GetAccountBalancesDto, { - addressKeys: ['account', 'tokens'], - }); - - await this.etherspotWallet.require({ - wallet: !account, - }); - - const ChainId = chainId ? chainId : this.etherspotWallet.services.walletService.chainId; - - return this.etherspotWallet.services.dataService.getAccountBalances( - this.etherspotWallet.prepareAccountAddress(account), - tokens, - ChainId, - provider, - ); - } - - /** - * gets transaction - * @param dto - * @return Promise - */ - async getTransaction(dto: GetTransactionDto): Promise { - const { hash } = await validateDto(dto, GetTransactionDto); - - await this.etherspotWallet.require({ - wallet: false, - }); - - return this.etherspotWallet.services.dataService.getTransaction(hash); - } - - /** - * gets NFT list belonging to account - * @param dto - * @return Promise - */ - async getNftList(dto: GetNftListDto): Promise { - const { account, chainId } = await validateDto(dto, GetNftListDto, { - addressKeys: ['account'], - }); - - await this.etherspotWallet.require({ - wallet: !account, - }); - - const ChainId = chainId ? chainId : this.etherspotWallet.services.walletService.chainId; - - return this.etherspotWallet.services.dataService.getNftList( - this.etherspotWallet.prepareAccountAddress(account), - ChainId, - ); - } - - /** - * gets exchange supported tokens - * @param dto - * @return Promise - */ - async getExchangeSupportedAssets(dto: GetExchangeSupportedAssetsDto = {}): Promise { - const { page, limit, chainId } = await validateDto(dto, GetExchangeSupportedAssetsDto); - - const account = await this.getCounterFactualAddress(); - - const getChainId = chainId ? chainId : this.etherspotWallet.services.walletService.chainId; - - return this.etherspotWallet.services.dataService.getExchangeSupportedAssets(page, limit, getChainId, account); - } - - /** - * gets exchange offers - * @param dto - * @return Promise - */ - async getExchangeOffers(dto: GetExchangeOffersDto): Promise { - const { fromTokenAddress, toTokenAddress, fromAmount, fromChainId, showZeroUsd } = await validateDto(dto, GetExchangeOffersDto, { - addressKeys: ['fromTokenAddress', 'toTokenAddress'], - }); - - let { toAddress, fromAddress } = dto; - - if (!fromAddress) fromAddress = await this.getCounterFactualAddress(); - - if (!toAddress) toAddress = fromAddress; - - this.etherspotWallet.services.accountService.joinContractAccount(fromAddress); - - await this.etherspotWallet.require({ - contractAccount: true, - }); - - let { chainId } = this.etherspotWallet.services.walletService; - chainId = fromChainId ? fromChainId : chainId; - - return this.etherspotWallet.services.dataService.getExchangeOffers( - fromTokenAddress, - toTokenAddress, - BigNumber.from(fromAmount), - chainId, - toAddress, - fromAddress, - showZeroUsd, - ); - } - - async getAdvanceRoutesLiFi(dto: GetAdvanceRoutesLiFiDto): Promise { - const { - fromChainId, - toChainId, - fromTokenAddress, - toTokenAddress, - fromAmount, - allowSwitchChain, - showZeroUsd, - } = await validateDto(dto, GetAdvanceRoutesLiFiDto, { - addressKeys: ['fromTokenAddress', 'toTokenAddress'], - }); - - let { toAddress, fromAddress } = dto; - - if (!fromAddress) fromAddress = await this.getCounterFactualAddress(); - if (!toAddress) toAddress = fromAddress; - - let { chainId } = this.etherspotWallet.services.walletService; - chainId = fromChainId ? fromChainId : chainId; - - const data = await this.etherspotWallet.services.dataService.getAdvanceRoutesLiFi( - fromTokenAddress, - toTokenAddress, - chainId, - toChainId, - BigNumber.from(fromAmount), - toAddress, - allowSwitchChain, - fromAddress, - showZeroUsd, - ); - - return data; - } - - async getStepTransaction(dto: GetStepTransactionsLiFiDto): Promise { - const accountAddress = await this.getCounterFactualAddress(); - - return this.etherspotWallet.services.dataService.getStepTransaction(dto.route, accountAddress); - } - - /** - * gets multi chain quotes - * @param dto - * @return Promise - */ - async getCrossChainQuotes(dto: GetExchangeCrossChainQuoteDto): Promise { - const { - fromChainId, - toChainId, - fromTokenAddress, - toTokenAddress, - fromAmount, - serviceProvider, - lifiBridges, - toAddress, - showZeroUsd, - } = await validateDto(dto, GetExchangeCrossChainQuoteDto, { - addressKeys: ['fromTokenAddress', 'toTokenAddress'], - }); - - let { fromAddress } = dto; - - if (!fromAddress) fromAddress = await this.getCounterFactualAddress(); - - let { chainId } = this.etherspotWallet.services.walletService; - - chainId = fromChainId ? fromChainId : chainId; - - return this.etherspotWallet.services.dataService.getCrossChainQuotes( - fromTokenAddress, - toTokenAddress, - chainId, - toChainId, - BigNumber.from(fromAmount), - serviceProvider, - lifiBridges, - toAddress, - fromAddress, - showZeroUsd, - ); - } - - /** - * gets token lists - * @return Promise - */ - async getTokenLists(): Promise { - await this.etherspotWallet.require({ - wallet: false, - }); - - return this.etherspotWallet.services.dataService.getTokenLists(); - } - - /** - * gets token list tokens - * @param dto - * @return Promise - */ - async getTokenListTokens(dto: GetTokenListDto = {}): Promise { - const { name } = await validateDto(dto, GetTokenListDto); - - await this.etherspotWallet.require({ - wallet: false, - }); - - return this.etherspotWallet.services.dataService.getTokenListTokens(name); - } - - /** - * fetch exchange rates of tokens - * @param dto - * @return Promise - */ - async fetchExchangeRates(dto: FetchExchangeRatesDto): Promise { - const { tokens, chainId } = dto; - let data: RateData; - const promises = []; - - // Create a batch of 50 - const batches = [...Array(Math.ceil(tokens.length / 50))].map(() => tokens.splice(0, 50)); - batches.forEach((batch) => { - promises.push(this.etherspotWallet.services.dataService.fetchExchangeRates(batch, chainId)); - }); - - // Fetch succeded results and merge - await (Promise as any) - .allSettled(promises) - .then((response) => - response?.forEach((result) => { - if (result?.status === 'fulfilled') { - !data - ? (data = result.value ? result.value : {}) - : (data.items = result?.value?.items ? [...data.items, ...result.value.items] : [...data.items]); - } - }), - ); - - // Return Unique tokens - if (data && data.items && data.items.length) { - data.error = '' - data.errored = false - data.items = [...new Map(data.items.map(item => [item['address'], item])).values()]; - } else { - data.items = []; - } - - return data; - } } diff --git a/src/sdk/session/__mocks__/session.service.ts b/src/sdk/session/__mocks__/session.service.ts deleted file mode 100644 index 08760f1..0000000 --- a/src/sdk/session/__mocks__/session.service.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { mockService } from '../../../testing'; - -export const SessionService = mockService({ - verifySession: jest.fn(), - createSession: jest.fn(), -}); diff --git a/src/sdk/session/classes/index.ts b/src/sdk/session/classes/index.ts deleted file mode 100644 index 1ae27f4..0000000 --- a/src/sdk/session/classes/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './session'; diff --git a/src/sdk/session/classes/session.ts b/src/sdk/session/classes/session.ts deleted file mode 100644 index 2a00f0f..0000000 --- a/src/sdk/session/classes/session.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Type } from 'class-transformer'; -import { Account } from '../../account'; -import { BaseClass } from '../../common'; -import { StoredSession } from '../interfaces'; - -export class Session extends BaseClass { - static fromStoredSession(storedSession: StoredSession): Session { - let result: Session; - - try { - const { token, ttl } = storedSession; - const expireAt = new Date(storedSession.expireAt); - - result = new Session({ - token, - ttl, - expireAt, - }); - } catch (err) { - result = null; - } - - return result; - } - - static TTL_MARGIN = 3000; - - token: string; - - ttl: number; - - @Type(() => Account) - account?: Account; - - @Type(() => Date) - expireAt?: Date; - - refresh?(): void { - const now = new Date(); - this.expireAt = new Date(now.getTime() + this.ttl * 1000); - } - - verify?(): boolean { - return this.expireAt.getTime() + Session.TTL_MARGIN > Date.now(); - } - - toStoredSession?(): StoredSession { - return { - token: this.token, - ttl: this.ttl, - expireAt: this.expireAt, - }; - } -} diff --git a/src/sdk/session/index.ts b/src/sdk/session/index.ts deleted file mode 100644 index 5b67889..0000000 --- a/src/sdk/session/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './classes'; -export * from './interfaces'; -export * from './session.service'; -export * from './session.storage'; diff --git a/src/sdk/session/interfaces.ts b/src/sdk/session/interfaces.ts deleted file mode 100644 index a3a3b4c..0000000 --- a/src/sdk/session/interfaces.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface StoredSession { - token: string; - ttl: number; - expireAt: D; -} - -export interface SessionOptions { - storage?: SessionStorageLike; -} - -export interface SessionStorageLike { - setSession(walletAddress: string, session: StoredSession): Promise; - - getSession(walletAddress: string): Promise; -} diff --git a/src/sdk/session/session.service.ts b/src/sdk/session/session.service.ts deleted file mode 100644 index 9b35f90..0000000 --- a/src/sdk/session/session.service.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { utils } from 'ethers'; -import { switchMap } from 'rxjs/operators'; -import { Service, HeaderNames } from '../common'; -import { Session } from './classes'; -import { createSessionMessage } from './utils'; -import { SessionOptions, SessionStorageLike } from './interfaces'; -import { SessionStorage } from './session.storage'; -import { gql } from '@apollo/client/core'; - -export class SessionService extends Service { - private readonly storage: SessionStorageLike; - private session: Session = null; - - constructor(options: SessionOptions = {}) { - super(); - - const { storage } = options; - - this.storage = storage ? storage : new SessionStorage(); - } - - get headers(): { [key: string]: any } { - return this.session - ? { - [HeaderNames.AuthToken]: this.session.token, - } - : {}; - } - - get sessionTtl(): number { - return this.session ? this.session.ttl : undefined; - } - - async verifySession(): Promise { - await this.restoreSession(); - - if (this.session && !this.session.verify()) { - this.session = null; - } - - if (!this.session) { - await this.createSession(); - } else { - await this.refreshSession(); - } - } - - async refreshSession(): Promise { - this.session.refresh(); - - await this.storeSession(); - } - - async createSession(ttl?: number, fcmToken?: string): Promise { - const { apiService, walletService } = this.services; - const { walletAddress } = walletService; - - let session: Session; - let error: Error; - let signerAddress: string; - - try { - const { code } = await apiService.mutate<{ - code: string; - }>( - gql` - mutation($chainId: Int, $account: String!) { - code: createSessionCode(chainId: $chainId, account: $account) - } - `, - { - variables: { - account: walletAddress, - }, - }, - ); - - const message = createSessionMessage(code); - const messageHash = utils.arrayify(utils.hashMessage(message)); - - const signature = await walletService.signMessage(message); - - signerAddress = utils.recoverAddress(messageHash, signature); - - ({ session } = await apiService.mutate<{ - session: Session; - }>( - gql` - mutation( - $chainId: Int - $account: String! - $code: String! - $signature: String! - $ttl: Int - $fcmToken: String - ) { - session: createSession( - chainId: $chainId - account: $account - code: $code - signature: $signature - ttl: $ttl - fcmToken: $fcmToken - ) { - token - ttl - account { - address - type - state - store - createdAt - updatedAt - } - } - } - `, - { - variables: { - code, - signature, - ttl, - account: walletAddress, - fcmToken, - }, - models: { - session: Session, - }, - }, - )); - } catch (err) { - session = null; - error = err; - } - - if (session) { - delete session.account; - - session.refresh(); - - if (signerAddress !== walletAddress) { - const { providerType } = walletService.wallet; - - walletService.wallet$.next({ - address: signerAddress, - providerType, - }); - } - } - - if (error) { - throw error; - } - - this.session = session; - - await this.storeSession(); - - return session; - } - - protected onInit() { - const { walletAddress$ } = this.services.walletService; - - this.addSubscriptions( - walletAddress$ - .pipe(switchMap(() => this.restoreSession())) // - .subscribe(), - ); - } - - private async storeSession(): Promise { - const { walletService } = this.services; - const { walletAddress } = walletService; - - await this.storage.setSession(walletAddress, this.session ? this.session.toStoredSession() : null); - } - - private async restoreSession(): Promise { - let session: Session = null; - - const { walletService } = this.services; - const { walletAddress } = walletService; - - if (walletAddress) { - const storedSession = await this.storage.getSession(walletAddress); - - session = storedSession ? Session.fromStoredSession(storedSession) : null; - } - - this.session = session; - } -} diff --git a/src/sdk/session/session.storage.ts b/src/sdk/session/session.storage.ts deleted file mode 100644 index fafc5b4..0000000 --- a/src/sdk/session/session.storage.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { StoredSession, SessionStorageLike } from './interfaces'; - -export class SessionStorage implements SessionStorageLike { - private data = new Map(); - - async setSession(walletAddress: string, session: StoredSession): Promise { - this.data.set(walletAddress, session); - } - - async getSession(walletAddress: string): Promise { - return this.data.get(walletAddress) || null; - } -} diff --git a/src/sdk/session/utils/create-session-message.ts b/src/sdk/session/utils/create-session-message.ts deleted file mode 100644 index 2bcb218..0000000 --- a/src/sdk/session/utils/create-session-message.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @ignore - */ -export function createSessionMessage(code: string): string { - return [ - 'ETHERspot Authentication 😎 ', // - '', - code, - '', - `it will expire in less than 30 seconds`, - ].join('\n'); -} diff --git a/src/sdk/session/utils/index.ts b/src/sdk/session/utils/index.ts deleted file mode 100644 index fa83124..0000000 --- a/src/sdk/session/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './create-session-message'; diff --git a/src/sdk/state/classes/state.ts b/src/sdk/state/classes/state.ts index 31b9c3b..72993e0 100644 --- a/src/sdk/state/classes/state.ts +++ b/src/sdk/state/classes/state.ts @@ -1,14 +1,9 @@ -import { Type } from 'class-transformer'; import { Network } from '../../network'; -import { Account } from '../../account'; import { Wallet } from '../../wallet'; export class State { wallet: Wallet; - @Type(() => Account) - account: Account; - network: Network; } diff --git a/src/sdk/state/interfaces.ts b/src/sdk/state/interfaces.ts index df89d38..53a84fc 100644 --- a/src/sdk/state/interfaces.ts +++ b/src/sdk/state/interfaces.ts @@ -4,8 +4,8 @@ import { State } from './classes'; export type StateStorageState = Omit; export interface StateStorage { - setState(walletAddress: string, networkName: NetworkNames, state: StateStorageState): Promise; - getState(walletAddress: string, networkName: NetworkNames): Promise; + setState(EOAAddress: string, networkName: NetworkNames, state: StateStorageState): Promise; + getState(EOAAddress: string, networkName: NetworkNames): Promise; } export interface StateOptions { diff --git a/src/sdk/state/state.service.ts b/src/sdk/state/state.service.ts index 082ac6b..e16aebe 100644 --- a/src/sdk/state/state.service.ts +++ b/src/sdk/state/state.service.ts @@ -2,7 +2,6 @@ import { plainToClass } from 'class-transformer'; import { BehaviorSubject, Observable, combineLatest } from 'rxjs'; import { filter, map, tap } from 'rxjs/operators'; import { Service } from '../common'; -import { Account } from '../account'; import { Wallet } from '../wallet'; import { State } from './classes'; import { StateOptions, StateStorageState } from './interfaces'; @@ -27,28 +26,12 @@ export class StateService extends Service implements State { return this.services.walletService.wallet; } - get walletAddress$(): Observable { - return this.services.walletService.walletAddress$; + get EOAAddress$(): Observable { + return this.services.walletService.EOAAddress$; } - get walletAddress(): string { - return this.services.walletService.walletAddress; - } - - get account$(): BehaviorSubject { - return this.services.accountService.account$; - } - - get account(): Account { - return this.services.accountService.account; - } - - get accountAddress$(): Observable { - return this.services.accountService.accountAddress$; - } - - get accountAddress(): string { - return this.services.accountService.accountAddress; + get EOAAddress(): string { + return this.services.walletService.EOAAddress; } get network(): Network { @@ -60,32 +43,19 @@ export class StateService extends Service implements State { } restore(state: StateStorageState): this { - const { - accountService: { account$ }, - } = this.services; if (state) { state = plainToClass(State, state); - const { account } = state; - - account$.next(account); } return this; } - dump(): StateStorageState { - return { - account: this.account, - }; - } - protected onInit() { const { storage } = this.options || {}; const { walletService: { wallet$, wallet }, - accountService: { account$ }, networkService: { network$, network }, } = this.services; @@ -93,22 +63,18 @@ export class StateService extends Service implements State { this.addSubscriptions( combineLatest([ wallet$, // - account$, network$, ]) .pipe( map( ([ wallet, // - account, network, ]: [ State['wallet'], // - State['account'], State['network'], ]) => ({ wallet, // - account, network, }), ), @@ -142,11 +108,11 @@ export class StateService extends Service implements State { if (storage) { this.error$.catch(async () => { - const walletAddress = wallet && wallet.address ? wallet.address : null; + const EOAAddress = wallet && wallet.address ? wallet.address : null; const networkName = network && network.name ? network.name : null; - if (walletAddress && networkName) { - const state = await storage.getState(walletAddress, networkName); + if (EOAAddress && networkName) { + const state = await storage.getState(EOAAddress, networkName); this.restore(state); } diff --git a/src/sdk/wallet/interfaces.ts b/src/sdk/wallet/interfaces.ts index 12d9a48..70e1f37 100644 --- a/src/sdk/wallet/interfaces.ts +++ b/src/sdk/wallet/interfaces.ts @@ -4,6 +4,5 @@ export interface Wallet { } export interface WalletOptions { - omitProviderNetworkCheck: boolean; provider?: string; } diff --git a/src/sdk/wallet/wallet.service.ts b/src/sdk/wallet/wallet.service.ts index 7519f8d..0db277f 100644 --- a/src/sdk/wallet/wallet.service.ts +++ b/src/sdk/wallet/wallet.service.ts @@ -7,7 +7,7 @@ import { Wallet, WalletOptions } from './interfaces'; export class WalletService extends Service { readonly wallet$ = new ObjectSubject(); - readonly walletAddress$: Observable; + readonly EOAAddress$: Observable; readonly rpcBundlerUrl: string; readonly chainId: number; @@ -17,7 +17,7 @@ export class WalletService extends Service { super(); this.rpcBundlerUrl = rpcUrl; this.chainId = chain; - this.walletAddress$ = this.wallet$.observeKey('address'); + this.EOAAddress$ = this.wallet$.observeKey('address'); } get wallet(): Wallet { @@ -28,7 +28,7 @@ export class WalletService extends Service { return this.wallet$.value; } - get walletAddress(): string { + get EOAAddress(): string { return this.wallet ? this.wallet.address : null; } @@ -72,6 +72,7 @@ export class WalletService extends Service { this.removeSubscriptions(); } else { + const { networkService } = this.services; const { type: providerType } = provider; const subscriptions: Subscription[] = []; @@ -97,6 +98,8 @@ export class WalletService extends Service { throw new Error('Invalid wallet address'); } + networkService.useDefaultNetwork(); + this.replaceSubscriptions(...subscriptions); }