Skip to content

Commit

Permalink
Merge pull request #50 from AbstractSDK/adair/ibcActions
Browse files Browse the repository at this point in the history
Add interchain account queries
  • Loading branch information
adairrr authored Feb 2, 2024
2 parents 73285c4 + 9f6274a commit 1750733
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/tricky-pianos-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@abstract-money/core": minor
---

Add interchain account queries
4 changes: 4 additions & 0 deletions packages/core/abstract.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const contractsConfig = [
name: 'account-factory',
version: '0.19',
},
{
name: 'ibc-client',
version: '0.20.0',
},
]

export default defineConfig({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
import {
IbcClientQueryClient,
VersionControlTypes,
} from '../../../codegen/abstract'
import { WithArgs } from '../../../types/with-args'
import { getManagerQueryClientFromApi } from './get-manager-query-client-from-api'
import { getModuleAddress } from './get-module-address'

export type GetModuleAddressParameters = WithArgs<{
accountId: VersionControlTypes.AccountId
cosmWasmClient: CosmWasmClient
apiUrl: string
}>

const IBC_CLIENT_MODULE_ID = 'abstract:ibc-client'

/**
* Retrieve the {@link IbcClientQueryClient} from the manager account.
* @throws if the IBC-client module is not installed
* @param accountId
* @param cosmWasmClient
* @param apiUrl
*/
export async function getIbcClientQueryClientFromManager({
args: { accountId, cosmWasmClient, apiUrl },
}: GetModuleAddressParameters) {
const ibcClientAddress = await getModuleAddress({
args: { accountId, cosmWasmClient, apiUrl, id: IBC_CLIENT_MODULE_ID },
})

if (!ibcClientAddress) {
throw new Error('IBC-client module not installed')
}

return new IbcClientQueryClient(cosmWasmClient, ibcClientAddress)
}
45 changes: 45 additions & 0 deletions packages/core/src/actions/account/public/get-remote-account-ids.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { AccountId, chainIdToName } from '@abstract-money/core'
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
import {
IbcClientQueryClient,
VersionControlTypes,
} from '../../../codegen/abstract'
import { WithArgs } from '../../../types/with-args'
import { getIbcClientQueryClientFromManager } from './get-ibc-client-query-client-from-manager'
import {
GetRemoteProxiesParameters,
getRemoteAccountProxies,
} from './get-remote-account-proxies'

export type GetRemoteAccountIdsParameters = GetRemoteProxiesParameters

/**
* Get the Account's remote Account ids.
* @param accountId
* @param cosmWasmClient
* @param apiUrl
*/
export async function getRemoteAccountIds({
args: { accountId, cosmWasmClient, apiUrl },
}: GetRemoteAccountIdsParameters): Promise<AccountId[]> {
const remoteProxies = await getRemoteAccountProxies({
args: { accountId, cosmWasmClient, apiUrl },
})

const chainId = await cosmWasmClient.getChainId()
const sourceChainName = chainIdToName(chainId)

return Object.keys(remoteProxies).map((remoteChainName) => {
// local accounts are now remote accounts, remote accounts are now one hop further
const remoteTrace =
accountId.trace === 'local'
? [sourceChainName]
: accountId.trace.remote.concat(sourceChainName)

return {
seq: accountId.seq,
trace: { remote: remoteTrace },
chainName: remoteChainName,
} satisfies AccountId
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
import {
IbcClientQueryClient,
VersionControlTypes,
} from '../../../codegen/abstract'
import { WithArgs } from '../../../types/with-args'
import { getIbcClientQueryClientFromManager } from './get-ibc-client-query-client-from-manager'

export type GetRemoteProxiesParameters = WithArgs<
{
accountId: VersionControlTypes.AccountId
cosmWasmClient: CosmWasmClient
apiUrl: string
} & Omit<
Parameters<
typeof IbcClientQueryClient.prototype.listRemoteProxiesByAccountId
>[0],
'accountId'
>
>

type ChainName = string
type MaybeProxyAddress = string | null

/**
* Get the remote proxies for the given account.
* @param accountId
* @param cosmWasmClient
* @param apiUrl
*/
export async function getRemoteAccountProxies({
args: { accountId, cosmWasmClient, apiUrl },
}: GetRemoteProxiesParameters): Promise<Record<ChainName, MaybeProxyAddress>> {
let ibcClient: IbcClientQueryClient
try {
ibcClient = await getIbcClientQueryClientFromManager({
args: { accountId, cosmWasmClient, apiUrl },
})
} catch (e) {
// IBC client not installed
return {}
}

const remoteProxies = await ibcClient.listRemoteProxiesByAccountId({
accountId,
})

return Object.fromEntries(remoteProxies.proxies)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AccountId } from '@abstract-money/core'
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
import {
ManagerQueryClient,
Expand All @@ -18,7 +19,7 @@ export type GetSubAccountIdsParameters = WithArgs<

export async function getSubAccountIds({
args: { accountId, cosmWasmClient, apiUrl, ...params },
}: GetSubAccountIdsParameters) {
}: GetSubAccountIdsParameters): Promise<AccountId[]> {
const chainId = await cosmWasmClient.getChainId()
const chainName = chainIdToName(chainId)
const sub_accounts = await getSubAccountSequences({
Expand Down
18 changes: 18 additions & 0 deletions packages/core/src/clients/decorators/account-public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { getModules } from '../../actions/account/public/get-modules'
import { getNamespace } from '../../actions/account/public/get-namespace'
import { getOwner } from '../../actions/account/public/get-owner'
import { getProxyQueryClientFromApi } from '../../actions/account/public/get-proxy-query-client-from-api'
import { getRemoteAccountIds } from '../../actions/account/public/get-remote-account-ids'
import { getRemoteAccountProxies } from '../../actions/account/public/get-remote-account-proxies'
import { getSubAccountIds } from '../../actions/account/public/get-sub-account-ids'
import { getSubAccountSequences } from '../../actions/account/public/get-sub-account-sequences'
import { getTotalValue } from '../../actions/account/public/get-total-value'
Expand Down Expand Up @@ -61,6 +63,12 @@ export type AccountPublicActions = {
getSubAccountSequences(
args: CutSpecificArgsFromParameter<typeof getSubAccountSequences>,
): ReturnType<typeof getSubAccountSequences>
getRemoteAccountProxies(
args: CutSpecificArgsFromParameter<typeof getRemoteAccountProxies>,
): ReturnType<typeof getRemoteAccountProxies>
getRemoteAccountIds(
args: CutSpecificArgsFromParameter<typeof getRemoteAccountIds>,
): ReturnType<typeof getRemoteAccountIds>
getTotalValue(
args: CutSpecificArgsFromParameter<typeof getTotalValue>,
): ReturnType<typeof getTotalValue>
Expand Down Expand Up @@ -125,6 +133,16 @@ export function accountPublicActions(
args: { ...args, accountId, cosmWasmClient, apiUrl },
...rest,
}),
getRemoteAccountProxies: ({ args, ...rest }) =>
getRemoteAccountProxies({
args: { ...args, accountId, cosmWasmClient, apiUrl },
...rest,
}),
getRemoteAccountIds: ({ args, ...rest }) =>
getRemoteAccountIds({
args: { ...args, accountId, cosmWasmClient, apiUrl },
...rest,
}),
getTotalValue: ({ args, ...rest }) =>
getTotalValue({
args: { ...args, accountId, cosmWasmClient, apiUrl },
Expand Down

0 comments on commit 1750733

Please sign in to comment.