From 5728955e2a1c58ddbcd99eb9f64f35c5e9ec8d79 Mon Sep 17 00:00:00 2001 From: Vignesh Date: Fri, 22 Dec 2023 14:33:49 +0530 Subject: [PATCH] refactor the sdk --- 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 +- 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 +- 61 files changed, 441 insertions(+), 1097 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/examples/02-transfer-funds.ts b/examples/02-transfer-funds.ts index 8e6b9ab1..297dfedb 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 c3aa0d88..d5502798 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 68448ca5..2a2efb23 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 f52fa809..7aed7822 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 168e649d..94c15c46 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 10834396..d3e530c6 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 765e258c..486dec9c 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 1651a712..1ec772a0 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 0ab4a3ce..9245ad2f 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 1e1b8ee6..590e284c 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 2052c914..52a73060 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 57687357..8f0c35ce 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 f160d740..4ce48c95 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 bf25a937..b5d1e5a8 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 d0de48c5..35fad8f9 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 477cb1cc..e5f4d286 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/src/sdk/account/__mocks__/account.service.ts b/src/sdk/account/__mocks__/account.service.ts deleted file mode 100644 index b5a01246..00000000 --- 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 c11bd228..00000000 --- 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 53b10c4e..00000000 --- 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 8cf3132b..00000000 --- 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 6081a75d..00000000 --- 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 84a653d4..00000000 --- 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 ac85ce82..da0399ce 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 6bc20eb1..63fcc1e0 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 5c727485..c9a3869f 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 0888df7a..a71f7987 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 482c54d2..d1b9dc73 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 64fb1085..dda4aa16 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 7cead4b4..3c5357ef 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 c8b85e1a..3e824b78 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 a659a1ed..28555508 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 00000000..cda34816 --- /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 5d1db476..06dfb8b2 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 dc9999d4..00000000 --- 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 15bf4373..1c1c07ea 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 fc62c132..ec6cf5c6 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 540a9dcc..d5da4bf9 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 64df4443..fe49721c 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 59212f0c..a5ee505c 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 2a354b89..37642c47 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 d21026f2..c8883200 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 c4950412..0620d6c2 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 313cd8d4..00000000 --- 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 cd047860..9967fe6e 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 ed78c6ef..5e7d964c 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 757f99eb..4b6dccde 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 888afddf..09b85746 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 08760f1f..00000000 --- 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 1ae27f41..00000000 --- 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 2a00f0f7..00000000 --- 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 5b67889b..00000000 --- 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 a3a3b4ca..00000000 --- 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 9b35f904..00000000 --- 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 fafc5b4a..00000000 --- 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 2bcb218c..00000000 --- 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 fa831245..00000000 --- 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 31b9c3b5..72993e03 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 df89d389..53a84fc3 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 082ac6bb..e16aebe5 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 12d9a488..70e1f376 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 7519f8d0..0db277fd 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); }