Skip to content

Commit

Permalink
fix(app): cleanup balance fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
cor committed Feb 4, 2025
1 parent 330b828 commit 55da7d1
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 40 deletions.
5 changes: 4 additions & 1 deletion app/src/lib/components/TransferFrom/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ validation.subscribe(async data => {
})
</script>

<pre>
{#each $balances as balance}{JSON.stringify(balance.data, null, 2)}{/each}
</pre>
<Cube>
<div slot="intent" let:rotateTo class="w-full h-full">
<Intent transferArgs={$transferArgs} {stores} {rotateTo}/>
Expand Down Expand Up @@ -105,4 +108,4 @@ validation.subscribe(async data => {
{#if TRANSFER_DEBUG}
<DebugBox {stores}/>
{/if}
</div>
</div>
2 changes: 0 additions & 2 deletions app/src/lib/components/token.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export let expanded = false
console.log(denom)
$: chain = chains.find(c => c.chain_id === chainId) ?? null
$: graphqlToken =
chain?.tokens.find(t => t.denom?.toLowerCase() === (denom ?? "").toLowerCase()) ?? null
$: tokenInfo = tokenInfoQuery(chainId, (denom ?? "").toLowerCase(), chains)
</script>

Expand Down
5 changes: 4 additions & 1 deletion app/src/lib/queries/balance/evm/multicall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { raise } from "$lib/utilities/index.ts"
import { config } from "$lib/wallet/evm/config.ts"
import { erc20Abi, getAddress, type Address } from "viem"
import type { NoRepetition } from "$lib/utilities/types.ts"
import { ResultAsync } from "neverthrow"

/**
* @example
Expand Down Expand Up @@ -54,7 +55,9 @@ export async function erc20ReadMulticall({
const currentResult = accumulator.at(-1)
const fn = functionNames[index % functionNames.length]
if (!currentResult) return accumulator
currentResult[fn === "balanceOf" ? "balance" : fn] = result ?? (fn === "decimals" ? 0 : "")
if (result !== undefined) {
currentResult[fn === "balanceOf" ? "balance" : fn] = result ?? (fn === "decimals" ? 0 : "")
}
return accumulator
},
[] as Array<Record<string, any>>
Expand Down
88 changes: 52 additions & 36 deletions app/src/lib/queries/balance/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { erc20ReadMulticall } from "./evm/multicall.ts"
import { getCosmosChainBalances } from "./cosmos.ts"
import { getAptosChainBalances } from "./aptos.ts"
import { createQueries } from "@tanstack/svelte-query"
import { errAsync, ok, ResultAsync, type Result } from "neverthrow"

export type AssetMetadata = {
denom: string
Expand Down Expand Up @@ -144,6 +145,9 @@ function getAddressForChain(chain: Chain, addresses: UserAddresses): string | nu
}
}

export type Denom = string
export type RawBalances = Record<Denom, string>

export function userBalancesQuery({
userAddr,
chains
Expand All @@ -165,48 +169,60 @@ export function userBalancesQuery({
enabled: Boolean(getAddressForChain(chain, userAddr)),
refetchInterval: 4_000,
refetchOnWindowFocus: false,
queryFn: async () => {
queryFn: async (): Promise<Result<RawBalances, Error>> => {
const address = getAddressForChain(chain, userAddr)
if (!address) return null

let rawBalances: Record<string, string> = {}
if (!address) return errAsync(new Error(`no user address for chain ${chain.chain_id}`))

if (chain.rpc_type === "evm") {
const tokenList = chain.tokens.filter(tokens => isAddress(tokens.denom))
const multicallResults = await erc20ReadMulticall({
chainId: chain.chain_id,
functionNames: ["balanceOf"],
address: address as Address,
contractAddresses: tokenList.map(asset => asset.denom) as Array<Address>
})

multicallResults.forEach((result, index) => {
rawBalances[tokenList[index].denom] = result.balance?.toString() ?? "0"
})
} else if (chain.rpc_type === "cosmos") {
const url = chain.rpcs.find(rpc => rpc.type === "rest")?.url
if (!url) throw new Error(`No REST RPC available for chain ${chain.chain_id}`)

const bech32Address = bech32ToBech32Address({
toPrefix: chain.addr_prefix,
address: address
})

const cosmosBalances = await getCosmosChainBalances({ url, walletAddress: bech32Address })
cosmosBalances.forEach(balance => {
rawBalances[balance.address] = balance.balance.toString()
})
} else if (chain.rpc_type === "aptos") {
const url = chain.rpcs.find(rpc => rpc.type === "rpc")?.url
if (!url) throw new Error(`No RPC available for chain ${chain.chain_id}`)

const aptosBalances = await getAptosChainBalances({ url, walletAddress: address })
aptosBalances.forEach(balance => {
rawBalances[balance.address] = balance.balance.toString()
})
return await ResultAsync.fromPromise(
erc20ReadMulticall({
chainId: chain.chain_id,
functionNames: ["balanceOf"],
address: address as Address,
contractAddresses: tokenList.map(asset => asset.denom) as Array<Address>
}),
error => new Error("error fetching evm balances", { cause: error })
).andThen(multicallResultss =>
ok(
multicallResultss.reduce((acc, curr, index) => {
console.log({ curr })
if (curr.balance) {
acc[tokenList[index].denom] = curr.balance.toString()
}
return acc
}, {})
)
)
}

return { chain_id: chain.chain_id, balances: rawBalances }
return errAsync(new Error("unimplemented"))

// if (chain.rpc_type === "cosmos") {
// const url = chain.rpcs.find(rpc => rpc.type === "rest")?.url
// if (!url) throw new Error(`No REST RPC available for chain ${chain.chain_id}`)

// const bech32Address = bech32ToBech32Address({
// toPrefix: chain.addr_prefix,
// address: address
// })

// const cosmosBalances = await getCosmosChainBalances({ url, walletAddress: bech32Address })
// cosmosBalances.forEach(balance => {
// rawBalances[balance.address] = balance.balance.toString()
// })
// }
// if (chain.rpc_type === "aptos") {
// const url = chain.rpcs.find(rpc => rpc.type === "rpc")?.url
// if (!url) throw new Error(`No RPC available for chain ${chain.chain_id}`)

// const aptosBalances = await getAptosChainBalances({ url, walletAddress: address })
// aptosBalances.forEach(balance => {
// rawBalances[balance.address] = balance.balance.toString()
// })
// }

// return { chain_id: chain.chain_id, balances: rawBalances }
}
}))
})
Expand Down

0 comments on commit 55da7d1

Please sign in to comment.