diff --git a/CHANGELOG.md b/CHANGELOG.md index 7200e9a8..b983c068 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 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/package-lock.json b/package-lock.json index 359955c2..7b646fa8 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 9b241221..1d51676f 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 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); }