From 117c9ab93b742211c50de1280873fd2dbf85e7f8 Mon Sep 17 00:00:00 2001 From: adairrr <32375605+adairrr@users.noreply.github.com> Date: Fri, 22 Nov 2024 10:12:57 -0500 Subject: [PATCH 1/5] Ensure non-async methods aren't async --- packages/core/abstract.config.ts | 10 +++++----- .../core/src/actions/wallet/get-ans-host-client.ts | 2 +- .../core/src/actions/wallet/get-registry-client.ts | 2 +- packages/core/src/actions/wallet/get-sender-address.ts | 2 +- .../src/actions/wallet/get-signing-cosm-wasm-client.ts | 2 +- packages/core/src/clients/create-wallet-client.ts | 8 ++++++-- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/core/abstract.config.ts b/packages/core/abstract.config.ts index 3fc5fef9..b849b099 100644 --- a/packages/core/abstract.config.ts +++ b/packages/core/abstract.config.ts @@ -4,23 +4,23 @@ import { registry, vanilla } from '@abstract-money/cli/plugins' const contractsConfig = [ { name: 'account', - version: '0.24.1', + version: '0.25.0', }, { name: 'registry', - version: '0.24.1', + version: '0.25.0', }, { name: 'ans-host', - version: '0.24.1', + version: '0.25.0', }, { name: 'ibc-client', - version: '0.24.1', + version: '0.25.0', }, { name: 'ica-client', - version: '0.24.1', + version: '0.25.0', }, ] diff --git a/packages/core/src/actions/wallet/get-ans-host-client.ts b/packages/core/src/actions/wallet/get-ans-host-client.ts index dd4fbec5..ee29fb24 100644 --- a/packages/core/src/actions/wallet/get-ans-host-client.ts +++ b/packages/core/src/actions/wallet/get-ans-host-client.ts @@ -8,7 +8,7 @@ export type GetAnsHostClientParameters = { ansHostAddress: string } -export async function getAnsHostClient({ +export function getAnsHostClient({ signingCosmWasmClient, sender, ansHostAddress, diff --git a/packages/core/src/actions/wallet/get-registry-client.ts b/packages/core/src/actions/wallet/get-registry-client.ts index 1f727076..b43d40f9 100644 --- a/packages/core/src/actions/wallet/get-registry-client.ts +++ b/packages/core/src/actions/wallet/get-registry-client.ts @@ -8,7 +8,7 @@ export type GetRegistryClientParameters = { registryAddress: string } -export async function getRegistryClient({ +export function getRegistryClient({ signingCosmWasmClient, sender, registryAddress, diff --git a/packages/core/src/actions/wallet/get-sender-address.ts b/packages/core/src/actions/wallet/get-sender-address.ts index 21c8a861..5422f2c6 100644 --- a/packages/core/src/actions/wallet/get-sender-address.ts +++ b/packages/core/src/actions/wallet/get-sender-address.ts @@ -2,6 +2,6 @@ export type GetSenderAddressParameters = { sender: string } -export async function getSenderAddress({ sender }: GetSenderAddressParameters) { +export function getSenderAddress({ sender }: GetSenderAddressParameters) { return sender } diff --git a/packages/core/src/actions/wallet/get-signing-cosm-wasm-client.ts b/packages/core/src/actions/wallet/get-signing-cosm-wasm-client.ts index 3125332c..062544c1 100644 --- a/packages/core/src/actions/wallet/get-signing-cosm-wasm-client.ts +++ b/packages/core/src/actions/wallet/get-signing-cosm-wasm-client.ts @@ -4,7 +4,7 @@ export type GetSigningCosmWasmClientParameters = { signingCosmWasmClient: SigningCosmWasmClient } -export async function getSigningCosmWasmClient({ +export function getSigningCosmWasmClient({ signingCosmWasmClient, }: GetSigningCosmWasmClientParameters) { return signingCosmWasmClient diff --git a/packages/core/src/clients/create-wallet-client.ts b/packages/core/src/clients/create-wallet-client.ts index baa1812e..698bedb9 100644 --- a/packages/core/src/clients/create-wallet-client.ts +++ b/packages/core/src/clients/create-wallet-client.ts @@ -2,7 +2,11 @@ import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate' import type { Evaluate } from '../types/utils' import { ABSTRACT_API_URL } from '../utils' import { type Client } from './create-client' -import { PublicClientConfig, createPublicClient } from './create-public-client' +import { + PublicClient, + PublicClientConfig, + createPublicClient, +} from './create-public-client' import { type WalletActions, walletActions } from './decorators/wallet' export type WalletClientConfig = Omit & { @@ -10,7 +14,7 @@ export type WalletClientConfig = Omit & { sender: string } -export type WalletClient = Evaluate> +export type WalletClient = Evaluate> /** * Create a signing client to interact with the Abstract infrastructure. From c136ce531584c292e55c049c998891ef483e0428 Mon Sep 17 00:00:00 2001 From: adairrr <32375605+adairrr@users.noreply.github.com> Date: Fri, 22 Nov 2024 12:01:22 -0500 Subject: [PATCH 2/5] Update to 0.25 and add tests for account-id-to-string and back --- .../core/src/actions/wallet/create-account.ts | 4 +- .../core/src/clients/create-wallet-client.ts | 3 +- .../account-id/account-id-to-string.test.ts | 92 +++++++++++++++++++ .../utils/account-id/account-id-to-string.ts | 31 +++++-- .../core/src/utils/account-id/account-id.ts | 4 + .../account-id/string-to-account-id.test.ts | 79 ++++++++++++++++ .../utils/account-id/string-to-account-id.ts | 19 +++- 7 files changed, 220 insertions(+), 12 deletions(-) create mode 100644 packages/core/src/utils/account-id/account-id-to-string.test.ts create mode 100644 packages/core/src/utils/account-id/string-to-account-id.test.ts diff --git a/packages/core/src/actions/wallet/create-account.ts b/packages/core/src/actions/wallet/create-account.ts index 5420ecc1..15780cda 100644 --- a/packages/core/src/actions/wallet/create-account.ts +++ b/packages/core/src/actions/wallet/create-account.ts @@ -30,7 +30,7 @@ export type CreateAccountParameters = WithCosmWasmSignOptions< install_modules?: MergedModuleInstallConfig[] } >, - 'owner' + 'owner' | 'code_id' > > > @@ -44,6 +44,7 @@ export async function createAccount({ namespace, authenticator, link, + codeId, accountId, enableIbc, owner, @@ -82,6 +83,7 @@ export async function createAccount({ }) const instantiateMsg: AccountTypes.InstantiateMsg = { + code_id: codeId ?? accountCodeId, owner: owner || { monarchy: { monarch: sender, diff --git a/packages/core/src/clients/create-wallet-client.ts b/packages/core/src/clients/create-wallet-client.ts index 698bedb9..5b1d32bf 100644 --- a/packages/core/src/clients/create-wallet-client.ts +++ b/packages/core/src/clients/create-wallet-client.ts @@ -7,6 +7,7 @@ import { PublicClientConfig, createPublicClient, } from './create-public-client' +import { PublicActions } from './decorators/public' import { type WalletActions, walletActions } from './decorators/wallet' export type WalletClientConfig = Omit & { @@ -14,7 +15,7 @@ export type WalletClientConfig = Omit & { sender: string } -export type WalletClient = Evaluate> +export type WalletClient = Evaluate> /** * Create a signing client to interact with the Abstract infrastructure. diff --git a/packages/core/src/utils/account-id/account-id-to-string.test.ts b/packages/core/src/utils/account-id/account-id-to-string.test.ts new file mode 100644 index 00000000..5282c687 --- /dev/null +++ b/packages/core/src/utils/account-id/account-id-to-string.test.ts @@ -0,0 +1,92 @@ +import { describe, expect, it } from 'vitest' +import { accountIdToString } from './account-id-to-string' + +describe('accountIdToString', () => { + it('should convert a local account ID object to string', () => { + const accountId = { + chainName: 'neutrontestnet', + seq: 42, + trace: 'local' as const, + } + const result = accountIdToString(accountId) + expect(result).toEqual('neutrontestnet-42') + }) + + it('should convert a simple chain account ID object to string', () => { + const accountId = { + chainName: 'neutrontestnet', + seq: 42, + trace: 'local' as const, + } + const result = accountIdToString(accountId) + expect(result).toEqual('neutrontestnet-42') + }) + + it('should convert a multi-hop chain account ID object to string', () => { + const accountId = { + chainName: 'neutron', + seq: 42, + trace: { + remote: ['osmosis'], + }, + } + const result = accountIdToString(accountId) + expect(result).toEqual('neutron>osmosis-42') + }) + + it('should convert a complex multi-hop chain account ID object to string', () => { + const accountId = { + chainName: 'neutron', + seq: 42, + trace: { + remote: ['juno', 'osmosis'], + }, + } + const result = accountIdToString(accountId) + expect(result).toEqual('neutron>osmosis>juno-42') + }) + + it('should throw an error if seq is not a valid number', () => { + const accountId = { + chainName: 'neutron', + seq: -1, + trace: 'local' as const, + } + expect(() => accountIdToString(accountId)).toThrow( + 'Invalid account sequence: -1', + ) + }) + + it('should throw an error if chainName is missing', () => { + const accountId = { + seq: 42, + trace: 'local' as const, + chainName: '', + } + expect(() => accountIdToString(accountId)).toThrow( + 'AccountId must have a chainName', + ) + }) + + it('should throw an error if trace is not valid', () => { + const accountId = { + chainName: 'neutron', + seq: 42, + trace: { remote: [] }, + } + expect(() => accountIdToString(accountId)).toThrow( + 'Invalid remote trace: []', + ) + }) + + it('should throw an error if trace is not valid', () => { + const accountId = { + chainName: 'neutron', + seq: 42, + trace: { remote: [''] }, + } + expect(() => accountIdToString(accountId)).toThrow( + 'Invalid remote trace: [""]', + ) + }) +}) diff --git a/packages/core/src/utils/account-id/account-id-to-string.ts b/packages/core/src/utils/account-id/account-id-to-string.ts index 76b41faf..1f82e6ed 100644 --- a/packages/core/src/utils/account-id/account-id-to-string.ts +++ b/packages/core/src/utils/account-id/account-id-to-string.ts @@ -14,16 +14,35 @@ import { export function accountIdToString( id: AccountId, ) { - const baseId = s.join( - [id.chainName, `${id.seq}`], - ACCOUNT_ID_SEQUENCE_DELIMITER, - ) + // Sequence check + if (id.seq < 0) { + throw new Error(`Invalid account sequence: ${id.seq}`) + } + + // ChainName check + if (!id.chainName) { + throw new Error('AccountId must have a chainName') + } + // Trace check if (id.trace === 'local') { - return baseId + if (!id.chainName) { + throw new Error('chainName must be provided for local account ids') + } + return s.join([id.chainName, `${id.seq}`], ACCOUNT_ID_SEQUENCE_DELIMITER) } - return `${id.trace.remote.join( + if (!id.trace.remote.length || id.trace.remote.some((s) => !s)) { + throw new Error(`Invalid remote trace: ${JSON.stringify(id.trace.remote)}`) + } + const sourceChain = id.trace.remote[0]! + + const baseId = s.join( + [sourceChain, `${id.seq}`], + ACCOUNT_ID_SEQUENCE_DELIMITER, + ) + + return `${[id.chainName, ...id.trace.remote.slice(1).reverse()].join( ACCOUNT_ID_CHAIN_DELIMITER, )}${ACCOUNT_ID_CHAIN_DELIMITER}${baseId}` as const } diff --git a/packages/core/src/utils/account-id/account-id.ts b/packages/core/src/utils/account-id/account-id.ts index 865b1e83..488453e2 100644 --- a/packages/core/src/utils/account-id/account-id.ts +++ b/packages/core/src/utils/account-id/account-id.ts @@ -1,5 +1,9 @@ import { RegistryTypes } from '../../codegen/abstract' +/** + * AccountId is a globally unique identifier for an account. + * The chainName is the name of the chain where the account is located. + */ export type AccountId = { chainName: TChainName } & RegistryTypes.AccountId diff --git a/packages/core/src/utils/account-id/string-to-account-id.test.ts b/packages/core/src/utils/account-id/string-to-account-id.test.ts new file mode 100644 index 00000000..ceef10f5 --- /dev/null +++ b/packages/core/src/utils/account-id/string-to-account-id.test.ts @@ -0,0 +1,79 @@ +import { describe, expect, it } from 'vitest' +import { stringToAccountId } from './string-to-account-id' + +describe('stringToAccountId', () => { + it('should parse a local account ID with chainName', () => { + const result = stringToAccountId('local-42', 'neutrontestnet') + expect(result).toEqual({ + chainName: 'neutrontestnet', + seq: 42, + trace: 'local', + }) + }) + + it('should throw an error for a local account ID without chainName', () => { + expect(() => stringToAccountId('local-42')).toThrow( + 'chainName must be provided for local account ids', + ) + }) + + it('should parse a simple chain account ID', () => { + const result = stringToAccountId('neutrontestnet-42') + expect(result).toEqual({ + chainName: 'neutrontestnet', + seq: 42, + trace: 'local', + }) + }) + + it('should parse a multi-hop chain account ID', () => { + const result = stringToAccountId('osmosis>neutron-42') + expect(result).toEqual({ + chainName: 'osmosis', + seq: 42, + trace: { + remote: ['neutron'], + }, + }) + }) + + it('should parse a multi-hop chain account ID with provided chain', () => { + const result = stringToAccountId('osmosis>neutron-42', 'osmosis') + expect(result).toEqual({ + chainName: 'osmosis', + seq: 42, + trace: { + remote: ['neutron'], + }, + }) + }) + + it('should parse a complex multi-hop chain account ID', () => { + const result = stringToAccountId('neutron>juno>osmosis-42') + expect(result).toEqual({ + chainName: 'neutron', + seq: 42, + trace: { + remote: ['osmosis', 'juno'], + }, + }) + }) + + it('should throw an error when the account string is invalid', () => { + expect(() => stringToAccountId('invalidString')).toThrow( + 'Cannot find chain or sequence for account: invalidString', + ) + }) + + it('should throw an error when source chain does not match provided chainName', () => { + expect(() => stringToAccountId('neutrontestnet-42', 'osmosis')).toThrow( + 'chainName osmosis does not match chain in account id neutrontestnet-42', + ) + }) + + it('should throw an error when account has no source chain in non-local accounts', () => { + expect(() => stringToAccountId('>osmosis-42')).toThrow( + 'Invalid chain string in account id >osmosis-42', + ) + }) +}) diff --git a/packages/core/src/utils/account-id/string-to-account-id.ts b/packages/core/src/utils/account-id/string-to-account-id.ts index 2adf7803..e17b3121 100644 --- a/packages/core/src/utils/account-id/string-to-account-id.ts +++ b/packages/core/src/utils/account-id/string-to-account-id.ts @@ -15,12 +15,22 @@ export function stringToAccountId( const accountSequence = Number.parseInt(sequenceStr) - if (chainString === 'local' && !chainName) { - throw new Error('chainName must be provided for local account ids') + if (chainString === 'local') { + if (!chainName) + throw new Error('chainName must be provided for local account ids') + return { + chainName, + seq: accountSequence, + trace: 'local', + } } const splitChainString = chainString.split(ACCOUNT_ID_CHAIN_DELIMITER) - const accountSourceChain = splitChainString[splitChainString.length - 1] + if (splitChainString.some((s) => !s)) { + throw new Error(`Invalid chain string in account id ${value}`) + } + const accountSourceChain = + splitChainString.length > 1 ? splitChainString[0] : chainString if (!accountSourceChain) { throw new Error( `Account must have source chain when not a local one: ${value}`, @@ -44,7 +54,8 @@ export function stringToAccountId( chainName: accountSourceChain, seq: accountSequence, trace: { - remote: splitChainString.slice(0, splitChainString.length - 1), + // The remote trace is reversed + remote: splitChainString.slice(1, splitChainString.length).reverse(), }, } } From 6560491ec3b0e20f776ef42a30a0175bd56822ce Mon Sep 17 00:00:00 2001 From: adairrr <32375605+adairrr@users.noreply.github.com> Date: Fri, 22 Nov 2024 13:03:48 -0500 Subject: [PATCH 3/5] ensure that proper module data query key is used --- .../public/get-registry-module-data.ts | 32 ++++++++++++++++--- .../src/client/MultiqueryCosmWasmClient.ts | 3 -- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/packages/core/src/actions/public/get-registry-module-data.ts b/packages/core/src/actions/public/get-registry-module-data.ts index af20f952..08791e3c 100644 --- a/packages/core/src/actions/public/get-registry-module-data.ts +++ b/packages/core/src/actions/public/get-registry-module-data.ts @@ -57,9 +57,31 @@ export async function getRegistryModuleData< return null } - return await rawQuery({ - client: cosmWasmClient, - address: firstInstantiation, - key: 'module_data', - }) + let moduleData: ModuleData | null = null + try { + moduleData = await rawQuery({ + client: cosmWasmClient, + address: firstInstantiation, + key: 'mod', + }) + } catch (error) { + try { + moduleData = await rawQuery({ + client: cosmWasmClient, + address: firstInstantiation, + key: 'module_data', + }) + } catch (error2) { + console.debug( + `Could not retrieve module_data for ${formatModuleIdWithVersion( + module.info.namespace, + module.info.name, + module.info.version, + )}`, + error, + error2, + ) + } + } + return moduleData } diff --git a/packages/cosmwasm-utils/src/client/MultiqueryCosmWasmClient.ts b/packages/cosmwasm-utils/src/client/MultiqueryCosmWasmClient.ts index f86b9fd0..c66a24ea 100644 --- a/packages/cosmwasm-utils/src/client/MultiqueryCosmWasmClient.ts +++ b/packages/cosmwasm-utils/src/client/MultiqueryCosmWasmClient.ts @@ -153,9 +153,6 @@ export class MultiqueryCosmWasmClient extends CosmWasmClient { data: jsonToBinary(queryMsg), })) - console.log('calls length', calls.length) - console.log('calls', calls) - const result = (await super.queryContractSmart( this.multiqueryContractAddress, { From 83cd666774aa33d60e41fe404fa920a53b2e465b Mon Sep 17 00:00:00 2001 From: adairrr <32375605+adairrr@users.noreply.github.com> Date: Fri, 22 Nov 2024 18:58:02 -0500 Subject: [PATCH 4/5] Changeset --- .changeset/smooth-walls-compare.md | 6 ++++++ packages/abstraxion-utils/actions/package.json | 4 ++++ packages/abstraxion-utils/decorators/package.json | 4 ++++ 3 files changed, 14 insertions(+) create mode 100644 .changeset/smooth-walls-compare.md create mode 100644 packages/abstraxion-utils/actions/package.json create mode 100644 packages/abstraxion-utils/decorators/package.json diff --git a/.changeset/smooth-walls-compare.md b/.changeset/smooth-walls-compare.md new file mode 100644 index 00000000..178f4451 --- /dev/null +++ b/.changeset/smooth-walls-compare.md @@ -0,0 +1,6 @@ +--- +"@abstract-money/core": minor +"@abstract-money/cosmwasm-utils": patch +--- + +Update Abstract to 0.25 with account instantiation changes diff --git a/packages/abstraxion-utils/actions/package.json b/packages/abstraxion-utils/actions/package.json new file mode 100644 index 00000000..a8b0aa4b --- /dev/null +++ b/packages/abstraxion-utils/actions/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "main": "../dist/actions/index.js" +} \ No newline at end of file diff --git a/packages/abstraxion-utils/decorators/package.json b/packages/abstraxion-utils/decorators/package.json new file mode 100644 index 00000000..fa15b6b8 --- /dev/null +++ b/packages/abstraxion-utils/decorators/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "main": "../dist/decorators/index.js" +} \ No newline at end of file From b21bebd919c5e1a390decc11f4bcbbd40d82947d Mon Sep 17 00:00:00 2001 From: adairrr <32375605+adairrr@users.noreply.github.com> Date: Fri, 22 Nov 2024 18:59:10 -0500 Subject: [PATCH 5/5] Remove abstraxion-utils from this change --- packages/abstraxion-utils/actions/package.json | 4 ---- packages/abstraxion-utils/decorators/package.json | 4 ---- 2 files changed, 8 deletions(-) delete mode 100644 packages/abstraxion-utils/actions/package.json delete mode 100644 packages/abstraxion-utils/decorators/package.json diff --git a/packages/abstraxion-utils/actions/package.json b/packages/abstraxion-utils/actions/package.json deleted file mode 100644 index a8b0aa4b..00000000 --- a/packages/abstraxion-utils/actions/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "module", - "main": "../dist/actions/index.js" -} \ No newline at end of file diff --git a/packages/abstraxion-utils/decorators/package.json b/packages/abstraxion-utils/decorators/package.json deleted file mode 100644 index fa15b6b8..00000000 --- a/packages/abstraxion-utils/decorators/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "module", - "main": "../dist/decorators/index.js" -} \ No newline at end of file