Skip to content

Commit

Permalink
feat: useAccountBalanceFromApi hook
Browse files Browse the repository at this point in the history
  • Loading branch information
dalechyn committed Jan 30, 2024
1 parent 1864200 commit bb7def0
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changeset/beige-houses-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@abstract-money/core": patch
"@abstract-money/react": patch
---

useAccountBalanceFromApi hook
34 changes: 34 additions & 0 deletions packages/core/src/actions/get-account-balance-from-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import request from 'graphql-request'
import { tokenFromApi } from 'src/utils/tokens/token-from-api'
import { tokenToAsset } from '..'
import { gql } from '../codegen/gql'
import { WithArgs } from '../types/with-args'
import { AccountId, accountIdToApiFormat } from '../utils/account-id'

export type GetAccountBalancesFromApi = WithArgs<{
apiUrl: string
accountId: AccountId
}>

export async function getAccountBalancesFromApi({
args: { apiUrl, accountId },
}: GetAccountBalancesFromApi) {
const result = await request(
apiUrl,
gql(/* GraphQL */ `
query Balances($ids: [AccountIdWithChain!]!) {
accountsByIds(ids: $ids) {
balances {
amount
type
denom
}
}
}
`),
{ ids: [accountIdToApiFormat(accountId)] },
)
return result.accountsByIds[0]?.balances.map(({ amount, type, denom }) =>
tokenToAsset(tokenFromApi({ type, denom }), amount),
)
}
9 changes: 9 additions & 0 deletions packages/core/src/clients/decorators/api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getAccountBalancesFromApi } from '../../actions/get-account-balance-from-api'
import { getAccountFactoryAddressFromApi } from '../../actions/get-account-factory-address-from-api'
import { getAccountsByOwnerFromApi } from '../../actions/get-accounts-by-owner-from-api'
import { getAnsHostAddressFromApi } from '../../actions/get-ans-host-address-from-api'
Expand Down Expand Up @@ -32,10 +33,18 @@ export type ApiActions = {
getVersionControlAddressFromApi(
args: CutSpecificArgsFromParameter<typeof getVersionControlAddressFromApi>,
): ReturnType<typeof getVersionControlAddressFromApi>
getAccountBalancesFromApi(
args: CutSpecificArgsFromParameter<typeof getAccountBalancesFromApi>,
): ReturnType<typeof getAccountBalancesFromApi>
}

export function apiActions(apiUrl: string): ApiActions {
return {
getAccountBalancesFromApi: ({ args, ...rest }) =>
getAccountBalancesFromApi({
args: { ...args, apiUrl },
...rest,
}),
getAccountFactoryAddressFromApi: ({ args, ...rest }) =>
getAccountFactoryAddressFromApi({
args: { ...args, apiUrl },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AccountId } from './account-id'

export function accountIdToApiFormat(id: AccountId) {
return {
sea: id.seq,
sequence: id.seq,
trace: id.trace === 'local' ? null : id.trace.remote,
chain: id.chainName,
}
Expand Down
24 changes: 24 additions & 0 deletions packages/core/src/utils/tokens/token-from-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { AssetType, BalancesQuery } from '../../codegen/gql/graphql'
import { Token } from './token'

export function tokenFromApi(
token: Pick<
BalancesQuery['accountsByIds'][number]['balances'][number],
'type' | 'denom'
>,
): Token {
if (token.type === AssetType.Cw1155)
throw new Error('CW1155 tokens are not supported')

if (token.type === AssetType.Cw20) {
return {
type: 'cw20',
address: token.denom,
} satisfies Token
}

return {
type: 'native',
denom: token.denom,
} satisfies Token
}
1 change: 1 addition & 0 deletions packages/react/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './public'
export * from './wallet'
export * from './use-accounts'
export * from './use-ans-token-from-api'
export * from './use-account-balance-from-api'
46 changes: 46 additions & 0 deletions packages/react/src/hooks/use-account-balance-from-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ApiClient } from '@abstract-money/core'
import { UseQueryOptions, useQuery } from '@tanstack/react-query'
import React from 'react'
import { useConfig } from '../contexts'
import { WithArgs } from '../types/utils'

export function useAccountBalancesFromAPI(
{
args,
}: WithArgs<Parameters<ApiClient['getAccountBalancesFromApi']>[0]['args']>,
{
enabled: enabled_ = true,
...rest
}: UseQueryOptions<
Awaited<ReturnType<ApiClient['getAccountBalancesFromApi']>> | undefined,
unknown,
Awaited<ReturnType<ApiClient['getAccountBalancesFromApi']>> | undefined,
readonly [
'accountBalancesFromApi',
WithArgs<Parameters<ApiClient['getAccountBalancesFromApi']>[0]['args']>,
ApiClient | undefined,
]
> = {},
) {
const config = useConfig()
const client = config.useApiClient()
const queryKey = React.useMemo(
() => ['accountBalancesFromApi', { args }, client] as const,
[args, client],
)

const enabled = React.useMemo(
() => Boolean(client && args?.accountId && enabled_),
[enabled_, client, args],
)

const queryFn = React.useCallback(() => {
if (!client || !args?.accountId) throw new Error('No client or accountid')

return client.getAccountBalancesFromApi({
args: { accountId: args.accountId },
})
}, [client, args])

return useQuery(queryKey, queryFn, { enabled, ...rest })
}

0 comments on commit bb7def0

Please sign in to comment.