From 1952a43fb0018ba6ee99abc5e63fffa2cb97f48f Mon Sep 17 00:00:00 2001 From: Kaan Caglan Date: Thu, 27 Feb 2025 10:23:10 +0300 Subject: [PATCH] chore(app): adding aptos balance fetcher wip Signed-off-by: Kaan Caglan --- app/src/lib/stores/balances.ts | 79 ++++++++++++++++++- .../playground/union-to-movement.ts | 2 +- .../src/query/offchain/ucs03-channels.ts | 22 ++++-- 3 files changed, 96 insertions(+), 7 deletions(-) diff --git a/app/src/lib/stores/balances.ts b/app/src/lib/stores/balances.ts index 13447f0f9f..a5b83fccc4 100644 --- a/app/src/lib/stores/balances.ts +++ b/app/src/lib/stores/balances.ts @@ -55,12 +55,89 @@ export async function queryBalances(chain: Chain, address: string) { await updateBalancesCosmos(chain, address) break case "aptos": - console.error("aptos balance fetching currently unsupported") + await updateBalancesAptos(chain, address) + // console.error("aptos balance fetching currently unsupported") break default: console.error("invalid rpc type in balance fetching") } } +export async function updateBalancesAptos(chain: Chain, address: string) { + // Optionally mark expected tokens as "loading" (if chain.tokens exists) + if (chain.tokens && chain.tokens.length) { + chain.tokens.forEach(token => + updateBalance(chain.chain_id, token.denom, { kind: "loading", timestamp: Date.now() }) + ); + } + + // Define the GraphQL query and variables. + const query = ` + query CoinsData($owner_address: String, $limit: Int, $offset: Int) { + current_fungible_asset_balances( + where: {owner_address: {_eq: $owner_address}} + limit: $limit + offset: $offset + ) { + amount + asset_type + metadata { + name + decimals + symbol + token_standard + } + } + } + `; + const variables = { + owner_address: address, + limit: 100, + offset: 0, + }; + + // Set up the fetch options with appropriate headers. + const fetchOptions: RequestInit = { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-Indexer-Client": "movement-explorer", + "X-Aptos-Client": "aptos-typescript-sdk/1.35.0", + "X-Aptos-Typescript-Sdk-Origin-Method": "queryIndexer", + }, + body: JSON.stringify({ query, variables }), + }; + + try { + // Send the request to the Aptos indexer. + const response = await fetchJson("https://indexer.testnet.movementnetwork.xyz/v1/graphql", fetchOptions); + if (response.isErr()) { + throw new Error(response.error.message); + } + + const data = response.value.data; + if (!data || !data.current_fungible_asset_balances) { + throw new Error("Invalid response data"); + } + + // Process each token balance from the response. + data.current_fungible_asset_balances.forEach((token: any) => { + // Here, asset_type can be used as the key for storing the balance. + const tokenKey = token.asset_type; + const amount = token.amount; + updateBalance(chain.chain_id, tokenKey, { kind: "balance", amount, timestamp: Date.now() }); + }); + } catch (error: any) { + console.error("Error fetching Aptos balances", error); + // On error, update the balances for all tokens with an error state. + if (chain.tokens && chain.tokens.length) { + chain.tokens.forEach(token => + updateBalance(chain.chain_id, token.denom, { kind: "error", error: error.message, timestamp: Date.now() }) + ); + } + } +} + + export async function updateBalancesEvm(chain: Chain, address: Address) { const denoms = chain.tokens.filter(tokens => isAddress(tokens.denom)).map(token => token.denom) diff --git a/typescript-sdk/playground/union-to-movement.ts b/typescript-sdk/playground/union-to-movement.ts index bd995db061..94b1279b42 100644 --- a/typescript-sdk/playground/union-to-movement.ts +++ b/typescript-sdk/playground/union-to-movement.ts @@ -48,7 +48,7 @@ const cliArgs = parseArgs({ }) const PRIVATE_KEY = cliArgs.values["private-key"] -const MUNO_DENOM = "muno" +const MUNO_DENOM = "0x6d756e6f" const AMOUNT = 15n const RECEIVER = "0x4d8a66ece11f6352224942bd1dabc456b4bb5316124f02b9a7b6292ad61f7777" const SOURCE_CHAIN_ID = "union-testnet-9" diff --git a/typescript-sdk/src/query/offchain/ucs03-channels.ts b/typescript-sdk/src/query/offchain/ucs03-channels.ts index b62d9df9dd..2cf39d770b 100644 --- a/typescript-sdk/src/query/offchain/ucs03-channels.ts +++ b/typescript-sdk/src/query/offchain/ucs03-channels.ts @@ -201,7 +201,21 @@ export const getQuoteToken = async ( // const functionCall = // Build the transaction payload. - const receiverVec = MoveVector.U8("0x6d756e6f") + const receiverVec = MoveVector.U8(base_token) + const sending_Data = { + payload: { + function: `${channel.destination_port_id}::ibc_app::predict_wrapped_token`, + typeArguments: [], + // Adjust functionArguments as needed. + functionArguments: [ + 0, // path + channel.destination_channel_id, // channel + receiverVec + ] + } + } + console.info("sending_Data:", sending_Data) + console.info("receiverVec:", receiverVec) const output = await aptos.experimental.viewBinary({ payload: { function: `${channel.destination_port_id}::ibc_app::predict_wrapped_token`, @@ -217,16 +231,14 @@ export const getQuoteToken = async ( console.info("base_token:", base_token) console.info("transaction:", output) + console.info("output.length::", output.length) console.info("channel.destination_channel_id:", channel.destination_channel_id) console.info("channel.destination_port_id:", channel.destination_port_id) const deserializer = new Deserializer(output.slice(1)) + console.info("deserializer.remaining(): ", deserializer.remaining()) const addressBytes = deserializer.deserializeFixedBytes(32) const wrappedAddressHex = "0x" + Buffer.from(addressBytes).toString("hex") - // // 2) The second return value is the salt (vector) - // const saltBytes = deserializer.deserializeBytes() - // const saltHex = "0x" + Buffer.from(saltBytes).toString("hex") - console.log("Wrapped address:", wrappedAddressHex) return ok({ type: "NEW_WRAPPED", quote_token: wrappedAddressHex }) }