Repository: unionlabs/union
File: app2/src/lib/services/aptos/balances.ts (TypeScript)

Code before:

export type FetchAptosBalanceError = FetchAptosTokenBalanceError

export class FetchAptosTokenBalanceError extends Data.TaggedError("FetchAptosTokenBalanceError")<{
  cause: unknown
}> {}

const fetchFABalance = ({
  aptosClient,
  tokenAddress,
  walletAddress
}: {
  aptosClient: Aptos
  tokenAddress: TokenRawDenom
  walletAddress: string
}) =>
  Effect.tryPromise({
    try: () =>
      aptosClient.view({
        payload: {
          function: `0x1::primary_fungible_store::balance`,
          typeArguments: ["0x1::fungible_asset::Metadata"],
          functionArguments: [walletAddress.toString(), tokenAddress.toString()]
        }
      }),
    catch: err => new FetchAptosTokenBalanceError({ cause: err as ReadContractErrorType })
  })

/**
 * createAptosBalanceQuery
 *
 * This function creates an effect-based pipeline that repeatedly fetches the balance for a given Aptos token.
 * It takes the same parameters as the EVM version.
 *
 * - If `tokenAddress` is `"native"`, it fetches the native (gas) balance from an Aptos fullnode REST API.
 * - Otherwise, it uses a GraphQL query (similar to your old updateBalancesAptos logic) to fetch token balances,
 *   then filters for tokens with metadata.token_standard === "v2", and extracts the balance for the given token.
 *
 * The fetched balance is then passed to the provided `writeData` callback (wrapped in your RawTokenBalance schema)
 * and any errors are reported via `writeError`.
 */
export const fetchAptosBalance = ({
  chain,
  tokenAddress,
  walletAddress
}: {
  chain: Chain
  tokenAddress: TokenRawDenom
  walletAddress: string
}) => {
  return Effect.gen(function* (_) {

Review comment (bug):
this is incorrect, as this is a type from viem (see imports). check the aptos lib if they export an error type. also whenever wrapping errors from external libs use extractErrorDetails

Code after:

export type FetchAptosBalanceError = FetchAptosTokenBalanceError

export class FetchAptosTokenBalanceError extends Data.TaggedError("FetchAptosTokenBalanceError")<{
  cause: unknown
}> {}

const fetchFABalance = ({
  aptosClient,
  tokenAddress,
  walletAddress
}: {
  aptosClient: Aptos
  tokenAddress: TokenRawDenom
  walletAddress: string
}) =>
  Effect.tryPromise({
    try: () =>
      aptosClient.view({
        payload: {
          function: `0x1::primary_fungible_store::balance`,
          typeArguments: ["0x1::fungible_asset::Metadata"],
          functionArguments: [walletAddress.toString(), tokenAddress.toString()]
        }
      }),
    catch: err =>
      new FetchAptosTokenBalanceError({ cause: extractErrorDetails(err as AptosApiError) })
  })

/**
 * createAptosBalanceQuery
 *
 * This function creates an effect-based pipeline that repeatedly fetches the balance for a given Aptos token.
 * It takes the same parameters as the EVM version.
 *
 * - If `tokenAddress` is `"native"`, it fetches the native (gas) balance from an Aptos fullnode REST API.
 * - Otherwise, it uses a GraphQL query (similar to your old updateBalancesAptos logic) to fetch token balances,
 *   then filters for tokens with metadata.token_standard === "v2", and extracts the balance for the given token.
 *
 * The fetched balance is then passed to the provided `writeData` callback (wrapped in your RawTokenBalance schema)
 * and any errors are reported via `writeError`.
 */
export const fetchAptosBalance = ({
  chain,
  tokenAddress,
  walletAddress
}: {
  chain: Chain
  tokenAddress: TokenRawDenom
  walletAddress: string
}) => {