From 3d9dcaf8647a0c6b0a1cbf8e6f9437c7979a5ab7 Mon Sep 17 00:00:00 2001 From: BeroBurny Date: Thu, 29 Aug 2024 16:14:39 +0200 Subject: [PATCH 1/7] implement native token fetch methods --- packages/sdk/src/api.ts | 16 ++++++++++++++++ packages/sdk/src/index.ts | 28 ++++++++++++++++++++-------- packages/sdk/src/types.ts | 6 +++++- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/packages/sdk/src/api.ts b/packages/sdk/src/api.ts index e62e6ea..0098a3e 100644 --- a/packages/sdk/src/api.ts +++ b/packages/sdk/src/api.ts @@ -7,6 +7,7 @@ import type { FetchOptions, FungibleToken, FungibleTokenBalance, + NativeTokenBalance, Solution, SolutionOptions, SolutionResponse, @@ -88,6 +89,21 @@ export async function getUserFungibleTokens( return response.data; } +export async function getUserNativeTokens( + address: Address, + { baseUrl, signal }: FetchOptions = {}, +): Promise { + const url = new URL( + `/accounts/${address}/assets/native`, + baseUrl || BASE_URL, + ); + const response = await fetch(url, { signal }).then( + (response) => response.json() as unknown as { data: NativeTokenBalance[] }, + ); + + return response.data; +} + export async function getSolution( { account, diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 7e6c8fd..3eb4b6b 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -6,6 +6,7 @@ import { getContractSolution, getSupportedChains, getUserFungibleTokens, + getUserNativeTokens, setBaseUrl, BASE_URL, } from "./api"; @@ -15,9 +16,9 @@ import type { ContractSolutionOptions, FetchOptions, FungibleToken, - FungibleTokenBalance, SolutionOptions, SolutionResponse, + TokenBalance, TokenSymbol, } from "./types"; @@ -62,7 +63,7 @@ class Sprinter { tokens?: FungibleToken[], options: FetchOptions = {}, ): Promise<{ - [sybol: TokenSymbol]: { balances: FungibleTokenBalance[]; total: string }; + [sybol: TokenSymbol]: { balances: TokenBalance[]; total: string }; }> { const account = await this.getAccount(); @@ -70,13 +71,17 @@ class Sprinter { const balances = await Promise.all( tokenList.map((token) => - getUserFungibleTokens(account, token.symbol).then((balances) => ({ - symbol: token.symbol, - balances, - })), + getUserFungibleTokens(account, token.symbol, options).then( + (balances) => ({ + symbol: token.symbol, + balances, + }), + ), ), ); + const nativeTokens = await getUserNativeTokens(account, options); + return balances.reduce( (previousValue, { symbol, balances }) => { previousValue[symbol] = { @@ -87,9 +92,16 @@ class Sprinter { }; return previousValue; }, - {} as { + { + ["native"]: { + total: nativeTokens + .reduce((prev, cur) => prev + BigInt(cur.balance), 0n) + .toString(), + balances: nativeTokens, + }, + } as { [symbol: TokenSymbol]: { - balances: FungibleTokenBalance[]; + balances: TokenBalance[]; total: string; }; }, diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 8431f4a..4246351 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -22,12 +22,16 @@ export interface Chain { rpcurls: string[]; } -export interface FungibleTokenBalance { +export interface TokenBalance { balance: string /* big number as string*/; chainId: ChainID; tokenDecimals: number; } +export type FungibleTokenBalance = TokenBalance; + +export type NativeTokenBalance = TokenBalance; + export interface SolutionOptions { account: Address; destinationChain: ChainID; From dfdb33a0c13bbe5c22c5349a2e4113761274980e Mon Sep 17 00:00:00 2001 From: BeroBurny Date: Mon, 2 Sep 2024 11:51:01 +0200 Subject: [PATCH 2/7] displaying eth at portfolio --- web/src/lib/components/Portfolio.svelte | 67 +++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/web/src/lib/components/Portfolio.svelte b/web/src/lib/components/Portfolio.svelte index 404cb58..bf283c7 100644 --- a/web/src/lib/components/Portfolio.svelte +++ b/web/src/lib/components/Portfolio.svelte @@ -11,13 +11,24 @@ const balances = $sprinter.getUserBalances(); const chains = $sprinter.getAvailableChains(); - $: total = balances.then((b) => - Object.values(b).reduce( - (p, c) => (p += Number(fromWei(c.total, c.balances[0].tokenDecimals))), + $: totalTokens = balances.then((b) => + Object.keys(b).filter(sybols => !["WETH", "native"].includes(sybols)).reduce( + (p, cKey) => { + const token = b[cKey]; + return (p += Number(fromWei(token.total, token.balances[0].tokenDecimals)))}, 0 ) ); + $: totalNative = balances.then((b) => + Object.keys(b).filter(sybols => ["WETH", "native"].includes(sybols)).reduce( + (p, cKey) => { + const token = b[cKey]; + return (p += Number(fromWei(token.total, token.balances[0].tokenDecimals)))}, + 0 + ) + ); + async function handleListClick(index: number) { const networks = await chains; const token = (await tokens)[index]; @@ -33,6 +44,22 @@ }; modalStore.trigger(modal); } + + const ethLogo = "https://scan.buildwithsygma.com/assets/icons/evm.svg"; + async function handleNativeClick() { + const networks = await chains; + const selectedBalances = (await balances)["native"]; + + const modal: ModalSettings = { + type: 'component', + component: { ref: TokenModal }, + title: "Ethereum", + buttonTextCancel: 'close', + value: { networks, balances: selectedBalances.balances }, + meta: { icon: ethLogo, sybol: "ETH", decimals: 18 } + }; + modalStore.trigger(modal); + }
@@ -40,8 +67,8 @@
Balance
-
- {#await total} +
+ {#await totalTokens}
{:then result} ${result.toFixed(2)} @@ -49,6 +76,15 @@ - {JSON.stringify(error)} {/await}
+
+ {#await totalNative} +
+ {:then result} + {result.toFixed(2)} ETH + {:catch error} + - {JSON.stringify(error)} + {/await} +
{/each} {:then [tokens, balances, chains]} + handleNativeClick()} + > + +
+ {`ETH-LOGO`} +
+
+
Ethereum
+
+ + + {fromWei(balances["native"].total, 18)} ETH + + + + + {#each tokens as token, i} Date: Mon, 2 Sep 2024 13:50:55 +0200 Subject: [PATCH 3/7] fix: refactor native to eth --- packages/sdk/src/index.ts | 2 +- web/src/lib/components/Portfolio.svelte | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 3eb4b6b..9109f14 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -93,7 +93,7 @@ class Sprinter { return previousValue; }, { - ["native"]: { + ["ETH"]: { total: nativeTokens .reduce((prev, cur) => prev + BigInt(cur.balance), 0n) .toString(), diff --git a/web/src/lib/components/Portfolio.svelte b/web/src/lib/components/Portfolio.svelte index bf283c7..c58314f 100644 --- a/web/src/lib/components/Portfolio.svelte +++ b/web/src/lib/components/Portfolio.svelte @@ -12,7 +12,7 @@ const chains = $sprinter.getAvailableChains(); $: totalTokens = balances.then((b) => - Object.keys(b).filter(sybols => !["WETH", "native"].includes(sybols)).reduce( + Object.keys(b).filter(sybols => !["WETH", "ETH"].includes(sybols)).reduce( (p, cKey) => { const token = b[cKey]; return (p += Number(fromWei(token.total, token.balances[0].tokenDecimals)))}, @@ -21,7 +21,7 @@ ); $: totalNative = balances.then((b) => - Object.keys(b).filter(sybols => ["WETH", "native"].includes(sybols)).reduce( + Object.keys(b).filter(sybols => ["WETH", "ETH"].includes(sybols)).reduce( (p, cKey) => { const token = b[cKey]; return (p += Number(fromWei(token.total, token.balances[0].tokenDecimals)))}, @@ -48,7 +48,7 @@ const ethLogo = "https://scan.buildwithsygma.com/assets/icons/evm.svg"; async function handleNativeClick() { const networks = await chains; - const selectedBalances = (await balances)["native"]; + const selectedBalances = (await balances)["ETH"]; const modal: ModalSettings = { type: 'component', @@ -131,10 +131,10 @@
- {fromWei(balances["native"].total, 18)} ETH + {fromWei(balances["ETH"].total, 18)} ETH - + {#each tokens as token, i} From fad568a42a2f5a6bfe116cc0316198854ced397a Mon Sep 17 00:00:00 2001 From: BeroBurny Date: Mon, 2 Sep 2024 14:12:02 +0200 Subject: [PATCH 4/7] add native to transfer drawer --- web/src/lib/components/SendTokensDrawer.svelte | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/web/src/lib/components/SendTokensDrawer.svelte b/web/src/lib/components/SendTokensDrawer.svelte index b60c392..954d377 100644 --- a/web/src/lib/components/SendTokensDrawer.svelte +++ b/web/src/lib/components/SendTokensDrawer.svelte @@ -13,9 +13,18 @@ import { fromWei, toWei } from 'web3-utils'; import { sprinter } from '$lib/stores/sprinter'; import { getNetworkByChainId, getTokenBySymbol } from '$lib/utils'; - import { type FungibleToken, type FungibleTokenBalance } from '@chainsafe/sprinter-sdk'; + import { + type FungibleToken, + type FungibleTokenBalance, + } from '@chainsafe/sprinter-sdk'; - const tokens = $sprinter.getAvailableTokens(); + const tokens = $sprinter.getAvailableTokens().then(tokens => [...tokens, { + addresses: [], + decimals: 18, + logoURI: "https://scan.buildwithsygma.com/assets/icons/evm.svg", + name: "Ethereum", + symbol: 'ETH', + }]); const allBalances = $sprinter.getUserBalances(); const chains = $sprinter.getAvailableChains(); From 8095d3853e7e59fc6e9a505497d420e39d2cebff Mon Sep 17 00:00:00 2001 From: BeroBurny Date: Fri, 6 Sep 2024 13:47:55 +0200 Subject: [PATCH 5/7] optimize network calls --- packages/sdk/src/index.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 9109f14..8e6cff7 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -69,18 +69,19 @@ class Sprinter { const tokenList = tokens || (await this.getAvailableTokens(options)); - const balances = await Promise.all( - tokenList.map((token) => - getUserFungibleTokens(account, token.symbol, options).then( - (balances) => ({ - symbol: token.symbol, - balances, - }), + const [balances, nativeTokens] = await Promise.all([ + Promise.all( + tokenList.map((token) => + getUserFungibleTokens(account, token.symbol, options).then( + (balances) => ({ + symbol: token.symbol, + balances, + }), + ), ), ), - ); - - const nativeTokens = await getUserNativeTokens(account, options); + getUserNativeTokens(account, options), + ]); return balances.reduce( (previousValue, { symbol, balances }) => { From 3acc8683bbf1909f9b873f88e651988003d4a3ff Mon Sep 17 00:00:00 2001 From: BeroBurny Date: Tue, 10 Sep 2024 14:43:06 +0200 Subject: [PATCH 6/7] lint --- web/src/lib/components/Portfolio.svelte | 40 +++++++++---------- .../lib/components/SendTokensDrawer.svelte | 22 +++++----- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/web/src/lib/components/Portfolio.svelte b/web/src/lib/components/Portfolio.svelte index c58314f..b60f585 100644 --- a/web/src/lib/components/Portfolio.svelte +++ b/web/src/lib/components/Portfolio.svelte @@ -12,21 +12,21 @@ const chains = $sprinter.getAvailableChains(); $: totalTokens = balances.then((b) => - Object.keys(b).filter(sybols => !["WETH", "ETH"].includes(sybols)).reduce( - (p, cKey) => { + Object.keys(b) + .filter((sybols) => !['WETH', 'ETH'].includes(sybols)) + .reduce((p, cKey) => { const token = b[cKey]; - return (p += Number(fromWei(token.total, token.balances[0].tokenDecimals)))}, - 0 - ) + return (p += Number(fromWei(token.total, token.balances[0].tokenDecimals))); + }, 0) ); $: totalNative = balances.then((b) => - Object.keys(b).filter(sybols => ["WETH", "ETH"].includes(sybols)).reduce( - (p, cKey) => { - const token = b[cKey]; - return (p += Number(fromWei(token.total, token.balances[0].tokenDecimals)))}, - 0 - ) + Object.keys(b) + .filter((sybols) => ['WETH', 'ETH'].includes(sybols)) + .reduce((p, cKey) => { + const token = b[cKey]; + return (p += Number(fromWei(token.total, token.balances[0].tokenDecimals))); + }, 0) ); async function handleListClick(index: number) { @@ -45,18 +45,18 @@ modalStore.trigger(modal); } - const ethLogo = "https://scan.buildwithsygma.com/assets/icons/evm.svg"; + const ethLogo = 'https://scan.buildwithsygma.com/assets/icons/evm.svg'; async function handleNativeClick() { const networks = await chains; - const selectedBalances = (await balances)["ETH"]; + const selectedBalances = (await balances)['ETH']; const modal: ModalSettings = { type: 'component', component: { ref: TokenModal }, - title: "Ethereum", + title: 'Ethereum', buttonTextCancel: 'close', value: { networks, balances: selectedBalances.balances }, - meta: { icon: ethLogo, sybol: "ETH", decimals: 18 } + meta: { icon: ethLogo, sybol: 'ETH', decimals: 18 } }; modalStore.trigger(modal); } @@ -117,12 +117,12 @@ {/each} {:then [tokens, balances, chains]} handleNativeClick()} + class="pt-2 bg-white dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 cursor-pointer" + on:click={() => handleNativeClick()} >
{`ETH-LOGO`}
@@ -131,10 +131,10 @@
- {fromWei(balances["ETH"].total, 18)} ETH + {fromWei(balances['ETH'].total, 18)} ETH - + {#each tokens as token, i} diff --git a/web/src/lib/components/SendTokensDrawer.svelte b/web/src/lib/components/SendTokensDrawer.svelte index 954d377..7803738 100644 --- a/web/src/lib/components/SendTokensDrawer.svelte +++ b/web/src/lib/components/SendTokensDrawer.svelte @@ -13,18 +13,18 @@ import { fromWei, toWei } from 'web3-utils'; import { sprinter } from '$lib/stores/sprinter'; import { getNetworkByChainId, getTokenBySymbol } from '$lib/utils'; - import { - type FungibleToken, - type FungibleTokenBalance, - } from '@chainsafe/sprinter-sdk'; + import { type FungibleToken, type FungibleTokenBalance } from '@chainsafe/sprinter-sdk'; - const tokens = $sprinter.getAvailableTokens().then(tokens => [...tokens, { - addresses: [], - decimals: 18, - logoURI: "https://scan.buildwithsygma.com/assets/icons/evm.svg", - name: "Ethereum", - symbol: 'ETH', - }]); + const tokens = $sprinter.getAvailableTokens().then((tokens) => [ + ...tokens, + { + addresses: [], + decimals: 18, + logoURI: 'https://scan.buildwithsygma.com/assets/icons/evm.svg', + name: 'Ethereum', + symbol: 'ETH' + } + ]); const allBalances = $sprinter.getUserBalances(); const chains = $sprinter.getAvailableChains(); From 4d22a600730f9c9b80176777dc21b20dfa364e86 Mon Sep 17 00:00:00 2001 From: BeroBurny Date: Tue, 10 Sep 2024 16:30:23 +0200 Subject: [PATCH 7/7] param fix --- docs/docs/03-sdk/03-class-reference.md | 8 +++++++- packages/sdk/src/index.ts | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/docs/03-sdk/03-class-reference.md b/docs/docs/03-sdk/03-class-reference.md index 70e23b7..d8935cb 100644 --- a/docs/docs/03-sdk/03-class-reference.md +++ b/docs/docs/03-sdk/03-class-reference.md @@ -54,10 +54,16 @@ sprinter.getAvailableChains().then(chains => { }); ``` -### `getUserBalances(tokens?: FungibleToken[]): Promise<{ [symbol: TokenSymbol]: { balances: FungibleTokenBalance[]; total: string } }>` +### `getUserBalances(tokens?: FungibleToken[], targetAccount?: Address): Promise<{ [symbol: TokenSymbol]: { balances: TokenBalance[]; total: string } }>` Fetches the user's balances for specified tokens across multiple blockchains. If no tokens are specified, it fetches balances for all available tokens. +:::note + +Method will always return native tokens under `ETH` key + +::: + #### Parameters - `tokens`: An optional array of fungible token objects. diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 15a9d28..11d9cbb 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -62,11 +62,12 @@ class Sprinter { public async getUserBalances( tokens?: FungibleToken[], + targetAccount?: Address, options: FetchOptions = {}, ): Promise<{ [sybol: TokenSymbol]: { balances: TokenBalance[]; total: string }; }> { - const account = await this.getAccount(); + const account = targetAccount || (await this.getAccount()); const tokenList = tokens || (await this.getAvailableTokens(options));