From b109ab3e1a91ac09af1fc7c214472ceb312d46b8 Mon Sep 17 00:00:00 2001 From: hotwater Date: Fri, 29 Mar 2024 18:55:45 +0200 Subject: [PATCH] feat: add hook to retrieve subaccount ids by module id --- .../get-sub-account-ids-by-module-id.ts | 51 +++++++++++++++++++ packages/core/src/actions/index.ts | 1 + packages/core/src/clients/decorators/api.ts | 11 ++++ packages/react/src/hooks/index.ts | 1 + .../use-sub-account-ids-by-module-from-api.ts | 45 ++++++++++++++++ 5 files changed, 109 insertions(+) create mode 100644 packages/core/src/actions/get-sub-account-ids-by-module-id.ts create mode 100644 packages/react/src/hooks/use-sub-account-ids-by-module-from-api.ts diff --git a/packages/core/src/actions/get-sub-account-ids-by-module-id.ts b/packages/core/src/actions/get-sub-account-ids-by-module-id.ts new file mode 100644 index 00000000..37cf9dfb --- /dev/null +++ b/packages/core/src/actions/get-sub-account-ids-by-module-id.ts @@ -0,0 +1,51 @@ +import { + AccountId, + accountIdApiFormatToAccountId, + accountIdToApiFormat, + accountIdToString, +} from '@abstract-money/core' +import request from 'graphql-request' +import { gql } from '../codegen/gql' + +export type GetSubAccountIdsByModuleIdFromApiParameters = { + accountId: AccountId + apiUrl: string + moduleId: string +} + +export async function getSubAccountIdsByModuleIdFromApi({ + accountId, + moduleId, + apiUrl, +}: GetSubAccountIdsByModuleIdFromApiParameters): Promise { + const subAccountsByModules = await request( + apiUrl, + gql(/* GraphQL */ ` + query SubAccountsByModules($ids: [AccountIdWithChain!]!) { + accountsByIds(ids: $ids) { + subAccounts { + accountId { + chainName + trace + sequence + } + modules { + id + } + } + } + } + `), + { + ids: accountIdToApiFormat(accountId), + }, + ) + + const accountData = subAccountsByModules.accountsByIds[0] + if (!accountData) + throw new Error(`account id ${accountIdToString(accountId)} does not exist`) + + return accountData.subAccounts + .filter(({ modules }) => modules.some((module) => module.id === moduleId)) + .map(({ accountId }) => accountIdApiFormatToAccountId(accountId)) +} diff --git a/packages/core/src/actions/index.ts b/packages/core/src/actions/index.ts index 0defba84..5384927d 100644 --- a/packages/core/src/actions/index.ts +++ b/packages/core/src/actions/index.ts @@ -5,6 +5,7 @@ export * from './get-ans-host-address-from-api' export * from './get-ans-token-from-api' export * from './get-ans-tokens-from-api' export * from './get-version-control-address-from-api' +export * from './get-sub-account-ids-by-module-id' export * from './account/public/get-account-base-addresses-from-api' export * from './account/public/get-base-token' diff --git a/packages/core/src/clients/decorators/api.ts b/packages/core/src/clients/decorators/api.ts index fa955d1f..1e08a148 100644 --- a/packages/core/src/clients/decorators/api.ts +++ b/packages/core/src/clients/decorators/api.ts @@ -1,3 +1,4 @@ +import { getSubAccountIdsByModuleIdFromApi } from 'src/actions' 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' @@ -47,6 +48,11 @@ export type ApiActions = { typeof getAccountBalancesFromApi >, ): ReturnType + getSubAccountIdsByModuleIdFromApi( + parameters: ExtractAndOmitDecoratedParametersFromParameters< + typeof getSubAccountIdsByModuleIdFromApi + >, + ): ReturnType } export function apiActions(apiUrl: string): ApiActions { @@ -86,5 +92,10 @@ export function apiActions(apiUrl: string): ApiActions { ...parameters, apiUrl, }), + getSubAccountIdsByModuleIdFromApi: (parameters) => + getSubAccountIdsByModuleIdFromApi({ + ...parameters, + apiUrl, + }), } } diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index 0356db5d..1c2a2887 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -4,3 +4,4 @@ export * from './wallet' export * from './use-accounts' export * from './use-ans-token-from-api' export * from './use-account-balance-from-api' +export * from './use-sub-account-ids-by-module-from-api' diff --git a/packages/react/src/hooks/use-sub-account-ids-by-module-from-api.ts b/packages/react/src/hooks/use-sub-account-ids-by-module-from-api.ts new file mode 100644 index 00000000..f1e3d968 --- /dev/null +++ b/packages/react/src/hooks/use-sub-account-ids-by-module-from-api.ts @@ -0,0 +1,45 @@ +import { ApiClient } from '@abstract-money/core/clients' +import React from 'react' +import { useConfig } from '../contexts' +import { WithArgs } from '../types/args' +import { UseQueryParameters, useQuery } from '../types/queries' + +export type UseSubAccountIdsByModuleIdFromApiParameters = WithArgs< + Parameters[0] +> & { + query?: UseQueryParameters< + Awaited>, + unknown, + Awaited>, + readonly [ + 'subAccountIdsByModuleIdFromApi', + WithArgs[0]>, + ApiClient | undefined, + ] + > +} + +export function useSubAccountIdsByModuleIdFromApi({ + args, + query = {}, +}: UseSubAccountIdsByModuleIdFromApiParameters) { + const config = useConfig() + const client = config.useApiClient() + const queryKey = React.useMemo( + () => ['subAccountIdsByModuleIdFromApi', { args }, client] as const, + [args, client], + ) + + const enabled = Boolean(client && args?.accountId && (query.enabled ?? true)) + + const queryFn = React.useCallback(() => { + if (!client || !args?.accountId) throw new Error('No client or accountid') + + return client.getSubAccountIdsByModuleIdFromApi({ + accountId: args.accountId, + moduleId: args.moduleId, + }) + }, [client, args]) + + return useQuery({ queryKey, queryFn, ...query, enabled }) +}