Skip to content

Abstract 0.25 #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/smooth-walls-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@abstract-money/core": minor
"@abstract-money/cosmwasm-utils": patch
---

Update Abstract to 0.25 with account instantiation changes
10 changes: 5 additions & 5 deletions packages/core/abstract.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
},
]

Expand Down
32 changes: 27 additions & 5 deletions packages/core/src/actions/public/get-registry-module-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,31 @@ export async function getRegistryModuleData<
return null
}

return await rawQuery<ModuleData | null>({
client: cosmWasmClient,
address: firstInstantiation,
key: 'module_data',
})
let moduleData: ModuleData | null = null
try {
moduleData = await rawQuery<ModuleData | null>({
client: cosmWasmClient,
address: firstInstantiation,
key: 'mod',
})
} catch (error) {
try {
moduleData = await rawQuery<ModuleData | null>({
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
}
4 changes: 3 additions & 1 deletion packages/core/src/actions/wallet/create-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export type CreateAccountParameters = WithCosmWasmSignOptions<
install_modules?: MergedModuleInstallConfig[]
}
>,
'owner'
'owner' | 'code_id'
>
>
>
Expand All @@ -44,6 +44,7 @@ export async function createAccount({
namespace,
authenticator,
link,
codeId,
accountId,
enableIbc,
owner,
Expand Down Expand Up @@ -82,6 +83,7 @@ export async function createAccount({
})

const instantiateMsg: AccountTypes.InstantiateMsg = {
code_id: codeId ?? accountCodeId,
owner: owner || {
monarchy: {
monarch: sender,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/actions/wallet/get-ans-host-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type GetAnsHostClientParameters = {
ansHostAddress: string
}

export async function getAnsHostClient({
export function getAnsHostClient({
signingCosmWasmClient,
sender,
ansHostAddress,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/actions/wallet/get-registry-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type GetRegistryClientParameters = {
registryAddress: string
}

export async function getRegistryClient({
export function getRegistryClient({
signingCosmWasmClient,
sender,
registryAddress,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/actions/wallet/get-sender-address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ export type GetSenderAddressParameters = {
sender: string
}

export async function getSenderAddress({ sender }: GetSenderAddressParameters) {
export function getSenderAddress({ sender }: GetSenderAddressParameters) {
return sender
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export type GetSigningCosmWasmClientParameters = {
signingCosmWasmClient: SigningCosmWasmClient
}

export async function getSigningCosmWasmClient({
export function getSigningCosmWasmClient({
signingCosmWasmClient,
}: GetSigningCosmWasmClientParameters) {
return signingCosmWasmClient
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/clients/create-wallet-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ 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 { PublicActions } from './decorators/public'
import { type WalletActions, walletActions } from './decorators/wallet'

export type WalletClientConfig = Omit<PublicClientConfig, 'cosmWasmClient'> & {
Expand Down
92 changes: 92 additions & 0 deletions packages/core/src/utils/account-id/account-id-to-string.test.ts
Original file line number Diff line number Diff line change
@@ -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: [""]',
)
})
})
31 changes: 25 additions & 6 deletions packages/core/src/utils/account-id/account-id-to-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,35 @@ import {
export function accountIdToString<TChainName extends string = string>(
id: AccountId<TChainName>,
) {
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
}
4 changes: 4 additions & 0 deletions packages/core/src/utils/account-id/account-id.ts
Original file line number Diff line number Diff line change
@@ -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<TChainName extends string = string> = {
chainName: TChainName
} & RegistryTypes.AccountId
Expand Down
79 changes: 79 additions & 0 deletions packages/core/src/utils/account-id/string-to-account-id.test.ts
Original file line number Diff line number Diff line change
@@ -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',
)
})
})
Loading
Loading