diff --git a/.changeset/smooth-buses-travel.md b/.changeset/smooth-buses-travel.md new file mode 100644 index 00000000..ed1d8e02 --- /dev/null +++ b/.changeset/smooth-buses-travel.md @@ -0,0 +1,7 @@ +--- +"wagemos-graz-nextjs": patch +"@abstract-money/core": patch +"@abstract-money/react": patch +--- + +Add helpers to predict module address diff --git a/examples/wagemos-graz-nextjs/package.json b/examples/wagemos-graz-nextjs/package.json index 6b18800d..24f1df34 100644 --- a/examples/wagemos-graz-nextjs/package.json +++ b/examples/wagemos-graz-nextjs/package.json @@ -3,7 +3,7 @@ "version": "0.2.14", "private": true, "scripts": { - "dev": "next dev", + "dev": "NODE_OPTIONS='--inspect' next dev", "build": "next build", "start": "next start", "typecheck": "tsc --noEmit", @@ -48,7 +48,6 @@ "devDependencies": { "@abstract-money/cli": "workspace:*", "@keplr-wallet/types": "^0.12.44", - "@tanstack/react-query-devtools": "^5.17.1", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", diff --git a/examples/wagemos-graz-nextjs/src/app/authz-osmosis/page.tsx b/examples/wagemos-graz-nextjs/src/app/authz-osmosis/page.tsx index 524cc103..17724d24 100644 --- a/examples/wagemos-graz-nextjs/src/app/authz-osmosis/page.tsx +++ b/examples/wagemos-graz-nextjs/src/app/authz-osmosis/page.tsx @@ -13,30 +13,33 @@ import { useCreateAccountMonarchy, useSignAndBroadcast, } from '@abstract-money/react' +import { useModuleInstantiate2AddressFromApi } from '@abstract-money/react' import { useAccount } from 'graz' -import { useCallback, useEffect, useMemo } from 'react' +import React, { useCallback, useEffect, useMemo } from 'react' import { Button } from '../../components/ui/button' import { WalletButton } from '../_components/wallet-button' import { prepareInstantiateMsg } from './_utils/prepare-instantiate-msg' -const GRANTER = 'osmo1jzyqffltm2s5wxmnjyze5hzrpcady0gmpz738n' -const GRANTEE = 'osmo1ak64euh4tyzetkny6t0y0v5tw47n3y6y0ys3md' +const GRANTER = 'osmo18k2uq7srsr8lwrae6zr0qahpn29rsp7tswpc4g' +const CHAIN_NAME = 'osmosis' +const TEST_SAVINGS_ACCOUNT_ID = 'osmosis-48' +const SAVINGS_APP_MODULE_ID = 'abstract:carrot-app' export default function AuthzPage() { useEffect(() => { prepareInstantiateMsg() }, []) const { mutate: signAndBroadcast } = useSignAndBroadcast({ - args: { chainName: 'osmosis' }, + args: { chainName: CHAIN_NAME }, }) const { data: account } = useAccount({ chainId: 'osmosis-1' }) const { data: accountFactory, isLoading } = - useAccountFactoryQueryClientFromApi('osmosis') + useAccountFactoryQueryClientFromApi(CHAIN_NAME) const { mutate: createAccount } = useCreateAccountMonarchy({ - args: { chainName: 'osmosis' }, + args: { chainName: CHAIN_NAME }, }) const onCreateAccount = useCallback(async () => { @@ -50,14 +53,32 @@ export default function AuthzPage() { fee: 'auto', args: { name: 'funny-squid', - accountId: stringToAccountId(`local-${sequence}`, 'osmosis'), + accountId: stringToAccountId(`local-${sequence}`, CHAIN_NAME), owner: account.bech32Address, }, }) }, [accountFactory]) + const { data: savingsAppAddress } = useModuleInstantiate2AddressFromApi( + { + accountId: stringToAccountId(TEST_SAVINGS_ACCOUNT_ID, CHAIN_NAME), + moduleId: SAVINGS_APP_MODULE_ID, + }, + { + enabled: true, + }, + ) + + console.log('calculated savings app address', savingsAppAddress) + const onGrantAuthzClick = useMemo(() => { - if (!account) return undefined + if (!account) { + console.error('no account') + return undefined + } else if (!savingsAppAddress) { + console.error('no module grantee') + return undefined + } return () => { signAndBroadcast({ @@ -74,18 +95,18 @@ export default function AuthzPage() { ].map((typeUrl) => encodeAuthzGrantGenericAuthorizationMsg( account.bech32Address, - GRANTEE, + savingsAppAddress, typeUrl, ), ), encodeAuthzGrantGenericAuthorizationMsg( account.bech32Address, - GRANTEE, + savingsAppAddress, BankTransactionTypeUrl.Send, ), encodeAuthzGrantSendAuthorizationMsg( account.bech32Address, - GRANTEE, + savingsAppAddress, { spendLimit: [{ denom: 'uosmo', amount: '100' }] }, ), ], diff --git a/packages/core/src/actions/account/public/get-module-instantiate2-address-from-api.ts b/packages/core/src/actions/account/public/get-module-instantiate2-address-from-api.ts new file mode 100644 index 00000000..100fd4a3 --- /dev/null +++ b/packages/core/src/actions/account/public/get-module-instantiate2-address-from-api.ts @@ -0,0 +1,54 @@ +import { + ModuleId, + chainIdToName, + getInstantiate2Address, + toSha256, +} from '@abstract-money/core' +import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate' +import { VersionControlTypes } from '../../../codegen/abstract' +import { WithArgs } from '../../../types/with-args' +import { getVersionControlAddressFromApi } from '../../get-version-control-address-from-api' +import { getAbstractModuleAddressFromVersionControl } from '../../public/get-abstract-module-address-from-version-control' +import { getAppModuleCodeIdFromVersionControl } from '../../public/get-app-module-code-id-from-version-control' +import { getModuleFactoryAddressFromVersionControl } from '../../public/get-module-factory-address-from-version-control' + +export type GetModuleInstantiate2AddressFromApi = WithArgs<{ + accountId: VersionControlTypes.AccountId + moduleId: ModuleId + version?: string + cosmWasmClient: CosmWasmClient + apiUrl: string +}> + +export async function getModuleInstantiate2AddressFromApi({ + args: { accountId, cosmWasmClient, apiUrl, moduleId, version }, +}: GetModuleInstantiate2AddressFromApi): Promise { + const chainId = await cosmWasmClient.getChainId() + const chainName = chainIdToName(chainId) + + const versionControlAddress = await getVersionControlAddressFromApi({ + args: { + apiUrl, + chainName, + }, + }) + + const moduleFactoryAddress = await getModuleFactoryAddressFromVersionControl({ + args: { + cosmWasmClient, + versionControlAddress, + }, + }) + + const moduleCodeId = await getAppModuleCodeIdFromVersionControl({ + args: { moduleId, version, cosmWasmClient, versionControlAddress }, + }) + + const moduleCodeDetails = await cosmWasmClient.getCodeDetails(moduleCodeId) + + return await getInstantiate2Address( + moduleFactoryAddress, + moduleCodeDetails.checksum, + { ...accountId, chainName }, + ) +} diff --git a/packages/core/src/actions/public/get-abstract-module-address-from-version-control.ts b/packages/core/src/actions/public/get-abstract-module-address-from-version-control.ts index 16c5e6ad..23712c14 100644 --- a/packages/core/src/actions/public/get-abstract-module-address-from-version-control.ts +++ b/packages/core/src/actions/public/get-abstract-module-address-from-version-control.ts @@ -7,6 +7,7 @@ import { getVersionControlQueryClient } from './get-version-control-query-client export enum CommonModuleNames { ACCOUNT_FACTORY = 'account-factory', + MODULE_FACTORY = 'module-factory', ANS_HOST = 'ans-host', } diff --git a/packages/core/src/actions/public/get-app-module-code-id-from-version-control.ts b/packages/core/src/actions/public/get-app-module-code-id-from-version-control.ts new file mode 100644 index 00000000..13c1c950 --- /dev/null +++ b/packages/core/src/actions/public/get-app-module-code-id-from-version-control.ts @@ -0,0 +1,52 @@ +import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate' + +import { + ModuleId, + formatModuleIdWithVersion, + moduleIdToName, + moduleIdToNamespace, +} from '@abstract-money/core' +import { VersionControlTypes } from '../../codegen/abstract' +import { WithArgs } from '../../types/with-args' +import { versionControlModuleToCodeId } from '../../utils/version-control/version-control-module-to-code-id' +import { getVersionControlQueryClient } from './get-version-control-query-client' + +export type GetAppModuleCodeIdFromVersionControl = WithArgs<{ + moduleId: `${ModuleId}` + cosmWasmClient: CosmWasmClient + versionControlAddress: string + version?: string +}> + +export async function getAppModuleCodeIdFromVersionControl({ + args: { moduleId, cosmWasmClient, versionControlAddress, version }, +}: GetAppModuleCodeIdFromVersionControl) { + const versionControlQueryClient = getVersionControlQueryClient({ + args: { + cosmWasmClient, + versionControlAddress, + }, + }) + + const [moduleAddress] = await versionControlQueryClient + .modules({ + infos: [ + { + name: moduleIdToName(moduleId), + namespace: moduleIdToNamespace(moduleId), + version: version ? { version } : 'latest', + } satisfies VersionControlTypes.ModuleInfo, + ], + }) + .then(({ modules }) => + modules.map(({ module }) => versionControlModuleToCodeId(module)), + ) + + if (!moduleAddress) { + throw new Error( + `Could not fetch code id for app module ${moduleId} version ${version} from registry ${versionControlAddress}`, + ) + } + + return moduleAddress +} diff --git a/packages/core/src/actions/public/get-module-factory-address-from-version-control.ts b/packages/core/src/actions/public/get-module-factory-address-from-version-control.ts new file mode 100644 index 00000000..29e31aea --- /dev/null +++ b/packages/core/src/actions/public/get-module-factory-address-from-version-control.ts @@ -0,0 +1,25 @@ +import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate' + +import { WithArgs } from '../../types/with-args' +import { + CommonModuleNames, + getAbstractModuleAddressFromVersionControl, +} from './get-abstract-module-address-from-version-control' + +export type GetModuleFactoryAddressFromVersionControlParameters = WithArgs<{ + cosmWasmClient: CosmWasmClient + versionControlAddress: string + version?: string +}> +export async function getModuleFactoryAddressFromVersionControl({ + args: { cosmWasmClient, versionControlAddress, version }, +}: GetModuleFactoryAddressFromVersionControlParameters) { + return getAbstractModuleAddressFromVersionControl({ + args: { + moduleName: CommonModuleNames.MODULE_FACTORY, + cosmWasmClient, + versionControlAddress, + version, + }, + }) +} diff --git a/packages/core/src/clients/decorators/account-public.ts b/packages/core/src/clients/decorators/account-public.ts index d290424e..1ad1adcc 100644 --- a/packages/core/src/clients/decorators/account-public.ts +++ b/packages/core/src/clients/decorators/account-public.ts @@ -4,6 +4,7 @@ import { getAccountBaseAddressesFromApi } from '../../actions/account/public/get import { getBaseToken } from '../../actions/account/public/get-base-token' import { getManagerQueryClientFromApi } from '../../actions/account/public/get-manager-query-client-from-api' import { getModuleAddress } from '../../actions/account/public/get-module-address' +import { getModuleInstantiate2AddressFromApi } from '../../actions/account/public/get-module-instantiate2-address-from-api' import { getModules } from '../../actions/account/public/get-modules' import { getNamespace } from '../../actions/account/public/get-namespace' import { getOwner } from '../../actions/account/public/get-owner' @@ -48,6 +49,11 @@ export type AccountPublicActions = { getModules( args: CutSpecificArgsFromParameter, ): ReturnType + getModuleInstantiate2AddressFromApi( + args: CutSpecificArgsFromParameter< + typeof getModuleInstantiate2AddressFromApi + >, + ): ReturnType getNamespace( args: CutSpecificArgsFromParameter, ): ReturnType @@ -108,6 +114,11 @@ export function accountPublicActions( args: { ...args, accountId, cosmWasmClient, apiUrl }, ...rest, }), + getModuleInstantiate2AddressFromApi: ({ args, ...rest }) => + getModuleInstantiate2AddressFromApi({ + args: { ...args, accountId, cosmWasmClient, apiUrl }, + ...rest, + }), getNamespace: ({ args, ...rest }) => getNamespace({ args: { ...args, accountId, cosmWasmClient, apiUrl }, diff --git a/packages/core/src/utils/account-factory/get-instantiate2-account-address.test.ts b/packages/core/src/utils/account-factory/get-instantiate2-account-address.test.ts deleted file mode 100644 index 29a14cbf..00000000 --- a/packages/core/src/utils/account-factory/get-instantiate2-account-address.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { stringToAccountId } from '../account-id' -import { getInstantiate2AccountAddress } from './get-instantiate2-account-address' // Update the path to your logic file - -describe('getInstantiate2AccountAddress', () => { - it('returns the correct address', async () => { - const address = 'juno1jzyqffltm2s5wxmnjyze5hzrpcady0gmltw6ka' - const accountFactoryAddress = - 'juno1qtl43hzk7xd9xly9wc4qxnmtjmj0hdtymsnldsl736yh7vnfm3ys7t4a4y' - const checksum = new Uint8Array([ - 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, - 2, 3, 4, 5, 6, 7, 8, - ]) - const accountId = stringToAccountId('juno-5', 'juno') - - const result = await getInstantiate2AccountAddress( - address, - accountFactoryAddress, - checksum, - accountId, - ) - - expect(result).toBe( - 'juno1m8lz9cru30zugeas5tx9245kn6w4rv92y7t96gvcsl0ktve378tqkv60qs', - ) - }) -}) diff --git a/packages/core/src/utils/account-factory/get-instantiate2-account-address.ts b/packages/core/src/utils/account-factory/get-instantiate2-account-address.ts deleted file mode 100644 index 45e8362b..00000000 --- a/packages/core/src/utils/account-factory/get-instantiate2-account-address.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { instantiate2Address } from '@cosmjs/cosmwasm-stargate' -import { bech32 } from 'bech32' -import { AccountId, accountIdToString } from '../account-id' - -async function getSalt(accountId: AccountId) { - const encoder = new TextEncoder() - const hash = await crypto.subtle.digest( - 'SHA-256', - encoder.encode(accountIdToString(accountId)), - ) - return new Uint8Array([ - ...new Uint8Array(hash), - ...encoder.encode('abstract'), - ]) -} - -export async function getInstantiate2AccountAddress( - address: string, - accountFactoryAddress: string, - checksum: Uint8Array, - accountId: AccountId, -) { - const prefix = bech32.decode(address).prefix - - return instantiate2Address( - checksum, - accountFactoryAddress, - await getSalt(accountId), - prefix, - ) -} diff --git a/packages/core/src/utils/account-factory/get-instantiate2-address.test.ts b/packages/core/src/utils/account-factory/get-instantiate2-address.test.ts new file mode 100644 index 00000000..ae1b8061 --- /dev/null +++ b/packages/core/src/utils/account-factory/get-instantiate2-address.test.ts @@ -0,0 +1,48 @@ +import { describe, expect, it } from 'vitest' +import { stringToAccountId } from '../account-id' +import { getInstantiate2Address } from './get-instantiate2-address' // Update the path to your logic file + +describe('getInstantiate2AccountAddress', () => { + it('returns the correct address', async () => { + const moduleFactoryAddress = + 'juno1qtl43hzk7xd9xly9wc4qxnmtjmj0hdtymsnldsl736yh7vnfm3ys7t4a4y' + // TODO: Replace with the actual checksum + const checksum = new Uint8Array([ + 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, + 2, 3, 4, 5, 6, 7, 8, + ]).toString() + const accountId = stringToAccountId('juno-5', 'juno') + + const result = await getInstantiate2Address( + moduleFactoryAddress, + checksum, + accountId, + ) + + expect(result).toBe( + 'juno1m8lz9cru30zugeas5tx9245kn6w4rv92y7t96gvcsl0ktve378tqkv60qs', + ) + }) +}) + +describe('getInstantiate2AccountAddressCarrot', () => { + it('returns the correct address', async () => { + const moduleFactoryAddress = + 'osmo1n28c9mtw9ehcddpaffewq4sczv4q0y3pfl76ll9v9alxx37rqdyqk89zsv' + + const savingsChecksum = + '663B34ECF2287496D6CBD9CF5DFDD5BF23D4240325E688CA9FA809D8ECDCCF12' + + const accountId = stringToAccountId('osmosis-48', 'osmosis') + + const result = await getInstantiate2Address( + moduleFactoryAddress, + savingsChecksum, + accountId, + ) + + expect(result).toEqual( + 'osmo193zezfjwe0ndxyd0rcrw39rlqt2ulu4gvenner2vp8n5402vnhjq4t7pv0', + ) + }) +}) diff --git a/packages/core/src/utils/account-factory/get-instantiate2-address.ts b/packages/core/src/utils/account-factory/get-instantiate2-address.ts new file mode 100644 index 00000000..a9e8f1b6 --- /dev/null +++ b/packages/core/src/utils/account-factory/get-instantiate2-address.ts @@ -0,0 +1,34 @@ +import { instantiate2Address } from '@cosmjs/cosmwasm-stargate' +import { bech32 } from 'bech32' +import { AccountId, accountIdToString } from '../account-id' +import { toSha256 } from '../encoding' + +async function getAccountIdSalt(accountId: AccountId) { + const sha256 = await toSha256(accountIdToString(accountId)) + const encoder = new TextEncoder() + + return new Uint8Array([...sha256, ...encoder.encode('abstract')]) +} + +/** + * Returns the instantiate2 address for the given account factory address, codeIdChecksum and accountId + * @param moduleFactoryAddress - the module factory is the creator + * @param codeIdChecksum - checksum of the code id of the contract expected to be instantiated + * @param accountId + */ +export async function getInstantiate2Address( + moduleFactoryAddress: string, + codeIdChecksum: string, + accountId: AccountId, +) { + const prefix = bech32.decode(moduleFactoryAddress).prefix + + const checksumSha256 = await toSha256(codeIdChecksum) + + return instantiate2Address( + checksumSha256, + moduleFactoryAddress, + await getAccountIdSalt(accountId), + prefix, + ) +} diff --git a/packages/core/src/utils/account-factory/index.ts b/packages/core/src/utils/account-factory/index.ts index c4ad51c1..8a291646 100644 --- a/packages/core/src/utils/account-factory/index.ts +++ b/packages/core/src/utils/account-factory/index.ts @@ -1,2 +1,2 @@ export * from './parse-create-account-execute-result' -export * from './get-instantiate2-account-address' +export * from './get-instantiate2-address' diff --git a/packages/core/src/utils/encoding.ts b/packages/core/src/utils/encoding.ts index 19c63c35..ad5ca693 100644 --- a/packages/core/src/utils/encoding.ts +++ b/packages/core/src/utils/encoding.ts @@ -10,3 +10,10 @@ export const binaryToJson = (binary: string): string => fromUtf8(fromBase64(binary)) export const toUint8Array = (text: string) => Uint8Array.from(Array.from(text).map((letter) => letter.charCodeAt(0))) + +export const toSha256 = async (text: string): Promise => { + const encoder = new TextEncoder() + const data = encoder.encode(text) + const hash = await crypto.subtle.digest('SHA-256', data) + return new Uint8Array(hash) +} diff --git a/packages/core/src/utils/version-control/module-id/module-id-to-name.ts b/packages/core/src/utils/version-control/module-id/module-id-to-name.ts index 0756d8f3..5d07824f 100644 --- a/packages/core/src/utils/version-control/module-id/module-id-to-name.ts +++ b/packages/core/src/utils/version-control/module-id/module-id-to-name.ts @@ -1,8 +1,16 @@ import * as s from 'string-ts' import { MODULE_DELIMITER, type ModuleId } from './types' +/** + * Retrieve the namespace from a module id. + * abstract:module => module + */ export function moduleIdToName( id: TModuleId, -): s.Split[0] { - return s.split(id, MODULE_DELIMITER)[0] +): s.Split[1] { + const split = s.split(id, MODULE_DELIMITER) + if (split.length < 2 || !split[1]) { + throw new Error(`Cannot find name for module: ${id}`) + } + return split[1] } diff --git a/packages/core/src/utils/version-control/module-id/module-id-to-namespace.ts b/packages/core/src/utils/version-control/module-id/module-id-to-namespace.ts index 13e97ba9..410468eb 100644 --- a/packages/core/src/utils/version-control/module-id/module-id-to-namespace.ts +++ b/packages/core/src/utils/version-control/module-id/module-id-to-namespace.ts @@ -1,11 +1,16 @@ import * as s from 'string-ts' import { MODULE_DELIMITER, type ModuleId } from './types' +/** + * Retrieve the namespace from a module id. + * abstract:module => abstract + */ export function moduleIdToNamespace< const TModuleId extends ModuleId = ModuleId, ->(id: TModuleId): s.Split[1] { - const namespace = s.split(id, MODULE_DELIMITER)[0] - if (!namespace) { +>(id: TModuleId): s.Split[0] { + const split = s.split(id, MODULE_DELIMITER) + const namespace = split[0] + if (split.length < 2 || !namespace) { throw new Error(`Cannot find namespace for module: ${id}`) } return namespace diff --git a/packages/react/src/hooks/account/public/index.ts b/packages/react/src/hooks/account/public/index.ts index 12ec6bb4..9adcdce2 100644 --- a/packages/react/src/hooks/account/public/index.ts +++ b/packages/react/src/hooks/account/public/index.ts @@ -1 +1,2 @@ export * from './use-account-base-addresses-from-api' +export * from './use-module-instantiate2-address-from-api' diff --git a/packages/react/src/hooks/account/public/use-module-instantiate2-address-from-api.ts b/packages/react/src/hooks/account/public/use-module-instantiate2-address-from-api.ts new file mode 100644 index 00000000..e251be1c --- /dev/null +++ b/packages/react/src/hooks/account/public/use-module-instantiate2-address-from-api.ts @@ -0,0 +1,75 @@ +import { AccountId, AccountPublicClient } from '@abstract-money/core' +import { MODULE_DELIMITER } from '@abstract-money/core/.tsup/declaration' +import { + UseQueryOptions, + UseQueryResult, + useQuery, +} from '@tanstack/react-query' +import React from 'react' +import { useAccountId, useConfig } from '../../../contexts' + +type QueryFnData = Awaited< + ReturnType +> + +type ModuleId = `${string}${typeof MODULE_DELIMITER}${string}` +type QueryError = unknown +type QueryData = QueryFnData +type QueryKey = readonly [ + 'moduleInstantiate2AddressFromApi', + AccountPublicClient | undefined, + ModuleId, + string | undefined, +] + +type QueryOptions = Omit< + UseQueryOptions, + 'queryFn' +> +type QueryResult = UseQueryResult + +export function useModuleInstantiate2AddressFromApi( + args: { + accountId: AccountId | undefined + moduleId: ModuleId + version?: string + }, + options?: QueryOptions, +) { + const { accountId: accountIdParameter, moduleId, version } = args + + const { accountId } = useAccountId({ accountId: accountIdParameter }) + const config = useConfig() + const accountPublicClient = config.useAccountPublicClient({ + accountId, + chainName: accountId?.chainName, + }) + const queryKey = React.useMemo( + () => + [ + 'moduleInstantiate2AddressFromApi', + accountPublicClient, + moduleId, + version, + ] as const, + [accountPublicClient], + ) + + const enabled = React.useMemo( + () => Boolean(accountPublicClient && options?.enabled), + [options?.enabled, accountPublicClient], + ) + + const queryFn = React.useCallback(() => { + if (!accountPublicClient) throw new Error('No client') + + return accountPublicClient.getModuleInstantiate2AddressFromApi({ + args: { + moduleId, + version, + }, + }) + }, [accountPublicClient]) + + return useQuery(queryKey, queryFn, { ...options, enabled }) +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02340466..fdcac1e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + importers: .: @@ -331,9 +335,6 @@ importers: '@keplr-wallet/types': specifier: ^0.12.44 version: 0.12.44 - '@tanstack/react-query-devtools': - specifier: ^5.17.1 - version: 5.17.1(@tanstack/react-query@5.17.1)(react@18.2.0) '@types/node': specifier: ^20 version: 20.10.0 @@ -7455,25 +7456,6 @@ packages: /@tanstack/query-core@4.36.1: resolution: {integrity: sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==} - /@tanstack/query-core@5.17.1: - resolution: {integrity: sha512-kUXozQmU7NBtzX5dM6qfFNZN+YK/9Ct37hnG/ogdgI4mExIx7VH/qRepsPhKfNrJz2w81/JykmM3Uug6sVpUSw==} - dev: true - - /@tanstack/query-devtools@5.17.1: - resolution: {integrity: sha512-gNdt6PYzYlyjtSAoO8Jt9GIFq5VSLLDV2qq0TCi1t/PGnpAIlIHqNZGYkQTPsy0FyGUTX3pCq4bd7v5z/wzf3A==} - dev: true - - /@tanstack/react-query-devtools@5.17.1(@tanstack/react-query@5.17.1)(react@18.2.0): - resolution: {integrity: sha512-QWHqdEN2TJpj76r0yzdOJEopmPvdAHOJHAKXaygubRASqCqfcWGkOHGD9pqqHOfTu5eQdV1Csx97EuSjnHMKcA==} - peerDependencies: - '@tanstack/react-query': ^5.17.1 - react: ^18.0.0 - dependencies: - '@tanstack/query-devtools': 5.17.1 - '@tanstack/react-query': 5.17.1(react@18.2.0) - react: 18.2.0 - dev: true - /@tanstack/react-query@4.36.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw==} peerDependencies: @@ -7491,15 +7473,6 @@ packages: react-dom: 18.2.0(react@18.2.0) use-sync-external-store: 1.2.0(react@18.2.0) - /@tanstack/react-query@5.17.1(react@18.2.0): - resolution: {integrity: sha512-4JYgX0kU+pvwVQi5eRiHGvBK7WnahEl6lmaxd32ZVSKmByAxLgaewoxBR03cdDNse8lUD2zGOe0sx3M/EGRlmA==} - peerDependencies: - react: ^18.0.0 - dependencies: - '@tanstack/query-core': 5.17.1 - react: 18.2.0 - dev: true - /@terra-money/feather.js@1.2.1: resolution: {integrity: sha512-OyXkWriNwb0lCF45eMmtjdOPEmfGKJxgGSnxpM7VxD0Vqr1qqtlcYyQG9wOHXNQrExvZv+uo922B2ZA4S77HsQ==} engines: {node: '>=16'} @@ -17308,7 +17281,3 @@ packages: immer: 9.0.21 react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false