From c7be52124646dde1a5fbe87d1d36b677af2424ce Mon Sep 17 00:00:00 2001 From: M-Picco Date: Fri, 8 Sep 2023 16:12:24 -0300 Subject: [PATCH] wip --- package-lock.json | 183 ++-- package.json | 1 + sdk/package.json | 2 +- sdk/src/config/MAINNET.ts | 20 + sdk/src/config/TESTNET.ts | 26 + sdk/src/contexts/cosmos/context.ts | 79 +- sdk/src/contexts/cosmos/utils.ts | 11 +- wormhole-connect/package.json | 2 +- wormhole-connect/src/config/index.ts | 6 + wormhole-connect/src/config/mainnet.ts | 62 ++ wormhole-connect/src/config/testnet.ts | 62 ++ wormhole-connect/src/config/types.ts | 2 + wormhole-connect/src/icons/TokenIcons.tsx | 470 +--------- wormhole-connect/src/icons/Tokens/ATOM.tsx | 74 ++ wormhole-connect/src/icons/Tokens/BONK.tsx | 13 + wormhole-connect/src/icons/Tokens/EVMOS.tsx | 22 + wormhole-connect/src/icons/Tokens/OSMO.tsx | 370 ++++++++ wormhole-connect/src/icons/Tokens/SEI.tsx | 1 + wormhole-connect/src/icons/Tokens/TBTC.tsx | 38 + wormhole-connect/src/icons/Tokens/WSTETH.tsx | 56 ++ wormhole-connect/src/utils/index.ts | 2 +- .../routes/{ => cosmos}/cosmosGateway.ts | 231 ++++- .../routes/cosmos/extensions/tokenfactory.ts | 44 + .../src/utils/routes/cosmos/index.ts | 1 + .../src/utils/routes/cosmos/types/helpers.ts | 271 ++++++ .../tokenfactory/v1beta1/authorityMetadata.ts | 66 ++ .../osmosis/tokenfactory/v1beta1/genesis.ts | 171 ++++ .../osmosis/tokenfactory/v1beta1/params.ts | 95 ++ .../osmosis/tokenfactory/v1beta1/query.ts | 434 +++++++++ .../types/osmosis/tokenfactory/v1beta1/tx.ts | 863 ++++++++++++++++++ wormhole-connect/src/utils/routes/index.ts | 2 +- wormhole-connect/src/utils/routes/operator.ts | 2 +- 32 files changed, 3109 insertions(+), 573 deletions(-) create mode 100644 wormhole-connect/src/icons/Tokens/ATOM.tsx create mode 100644 wormhole-connect/src/icons/Tokens/BONK.tsx create mode 100644 wormhole-connect/src/icons/Tokens/EVMOS.tsx create mode 100644 wormhole-connect/src/icons/Tokens/OSMO.tsx create mode 100644 wormhole-connect/src/icons/Tokens/TBTC.tsx create mode 100644 wormhole-connect/src/icons/Tokens/WSTETH.tsx rename wormhole-connect/src/utils/routes/{ => cosmos}/cosmosGateway.ts (77%) create mode 100644 wormhole-connect/src/utils/routes/cosmos/extensions/tokenfactory.ts create mode 100644 wormhole-connect/src/utils/routes/cosmos/index.ts create mode 100644 wormhole-connect/src/utils/routes/cosmos/types/helpers.ts create mode 100644 wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/authorityMetadata.ts create mode 100644 wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/genesis.ts create mode 100644 wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/params.ts create mode 100644 wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/query.ts create mode 100644 wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/tx.ts diff --git a/package-lock.json b/package-lock.json index c16b100f2..be3989e82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "builder" ], "dependencies": { + "@certusone/wormhole-sdk": "file:.yalc/@certusone/wormhole-sdk", "tss-react": "^4.7.7" }, "devDependencies": { @@ -19,6 +20,71 @@ "prettier": "^2.8.2" } }, + ".yalc/@certusone/wormhole-sdk": { + "version": "0.10.2+ac75d067", + "license": "Apache-2.0", + "dependencies": { + "@certusone/wormhole-sdk-proto-web": "0.0.6", + "@certusone/wormhole-sdk-wasm": "^0.0.1", + "@coral-xyz/borsh": "0.2.6", + "@mysten/sui.js": "0.32.2", + "@project-serum/anchor": "^0.25.0", + "@solana/spl-token": "^0.3.5", + "@solana/web3.js": "^1.66.2", + "@terra-money/terra.js": "3.1.9", + "@xpla/xpla.js": "^0.2.1", + "algosdk": "^2.4.0", + "aptos": "1.5.0", + "axios": "^0.24.0", + "bech32": "^2.0.0", + "binary-parser": "^2.2.1", + "bs58": "^4.0.1", + "elliptic": "^6.5.4", + "js-base64": "^3.6.1", + "near-api-js": "^1.0.0" + }, + "optionalDependencies": { + "@injectivelabs/networks": "1.10.12", + "@injectivelabs/sdk-ts": "1.10.72", + "@injectivelabs/utils": "1.10.12" + } + }, + ".yalc/@certusone/wormhole-sdk/node_modules/algosdk": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.5.0.tgz", + "integrity": "sha512-MlbPjjx4utq5sETOE0okF7/Lz0fgoBtRJRvSbRu3GnoybLTq/n6To2ojDAjJMqi+qMDyUBE9fWu+8jdSvozavA==", + "dependencies": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.3", + "cross-fetch": "^4.0.0", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "tweetnacl": "^1.0.3", + "vlq": "^2.0.4" + }, + "engines": { + "node": ">=16.0.0" + } + }, + ".yalc/@certusone/wormhole-sdk/node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, + ".yalc/@certusone/wormhole-sdk/node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "builder": { "name": "wormhole-connect-builder", "version": "0.1.0", @@ -1781,34 +1847,8 @@ } }, "node_modules/@certusone/wormhole-sdk": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.10.2.tgz", - "integrity": "sha512-e1pEd82EzGW1vN3w0rkF7CocEydj/CPqdR6U1NN5uRXR9vNwSxafwuZfYe5Wn4otSXIGp3lKPGhqzOGXr82rcg==", - "dependencies": { - "@certusone/wormhole-sdk-proto-web": "0.0.6", - "@certusone/wormhole-sdk-wasm": "^0.0.1", - "@coral-xyz/borsh": "0.2.6", - "@mysten/sui.js": "0.32.2", - "@project-serum/anchor": "^0.25.0", - "@solana/spl-token": "^0.3.5", - "@solana/web3.js": "^1.66.2", - "@terra-money/terra.js": "3.1.9", - "@xpla/xpla.js": "^0.2.1", - "algosdk": "^2.4.0", - "aptos": "1.5.0", - "axios": "^0.24.0", - "bech32": "^2.0.0", - "binary-parser": "^2.2.1", - "bs58": "^4.0.1", - "elliptic": "^6.5.4", - "js-base64": "^3.6.1", - "near-api-js": "^1.0.0" - }, - "optionalDependencies": { - "@injectivelabs/networks": "1.10.12", - "@injectivelabs/sdk-ts": "1.10.72", - "@injectivelabs/utils": "1.10.12" - } + "resolved": ".yalc/@certusone/wormhole-sdk", + "link": true }, "node_modules/@certusone/wormhole-sdk-proto-web": { "version": "0.0.6", @@ -1831,41 +1871,6 @@ "version": "18.16.1", "license": "MIT" }, - "node_modules/@certusone/wormhole-sdk/node_modules/algosdk": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.5.0.tgz", - "integrity": "sha512-MlbPjjx4utq5sETOE0okF7/Lz0fgoBtRJRvSbRu3GnoybLTq/n6To2ojDAjJMqi+qMDyUBE9fWu+8jdSvozavA==", - "dependencies": { - "algo-msgpack-with-bigint": "^2.1.1", - "buffer": "^6.0.3", - "cross-fetch": "^4.0.0", - "hi-base32": "^0.5.1", - "js-sha256": "^0.9.0", - "js-sha3": "^0.8.0", - "js-sha512": "^0.8.0", - "json-bigint": "^1.0.0", - "tweetnacl": "^1.0.3", - "vlq": "^2.0.4" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@certusone/wormhole-sdk/node_modules/axios": { - "version": "0.24.0", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.14.4" - } - }, - "node_modules/@certusone/wormhole-sdk/node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/@chainsafe/as-sha256": { "version": "0.4.1", "license": "Apache-2.0" @@ -30604,7 +30609,7 @@ "version": "0.1.0-beta.0", "license": "ISC", "dependencies": { - "@certusone/wormhole-sdk": "^0.10.2", + "@certusone/wormhole-sdk": "file:.yalc/@certusone/wormhole-sdk", "@cosmjs/cosmwasm-stargate": "^0.31.0", "@cosmjs/proto-signing": "^0.31.0", "@cosmjs/stargate": "^0.31.0", @@ -30641,6 +30646,11 @@ "typescript": "^4.9.4" } }, + "sdk/.yalc/@certusone/wormhole-sdk": {}, + "sdk/node_modules/@certusone/wormhole-sdk": { + "resolved": "sdk/.yalc/@certusone/wormhole-sdk", + "link": true + }, "sdk/node_modules/@cosmjs/amino": { "version": "0.29.5", "license": "Apache-2.0", @@ -31067,7 +31077,7 @@ "name": "@wormhole-foundation/wormhole-connect-app", "version": "0.0.1-beta.0", "dependencies": { - "@certusone/wormhole-sdk": "^0.10.2", + "@certusone/wormhole-sdk": "file:.yalc/@certusone/wormhole-sdk", "@cosmjs/cosmwasm-stargate": "^0.31.0", "@cosmjs/stargate": "^0.31.0", "@cosmjs/tendermint-rpc": "^0.31.0", @@ -31136,6 +31146,36 @@ "react-dom": "^18.2.0" } }, + "wormhole-connect/.yalc/@certusone/wormhole-sdk": { + "version": "0.10.2+ac75d067", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "@certusone/wormhole-sdk-proto-web": "0.0.6", + "@certusone/wormhole-sdk-wasm": "^0.0.1", + "@coral-xyz/borsh": "0.2.6", + "@mysten/sui.js": "0.32.2", + "@project-serum/anchor": "^0.25.0", + "@solana/spl-token": "^0.3.5", + "@solana/web3.js": "^1.66.2", + "@terra-money/terra.js": "3.1.9", + "@xpla/xpla.js": "^0.2.1", + "algosdk": "^2.4.0", + "aptos": "1.5.0", + "axios": "^0.24.0", + "bech32": "^2.0.0", + "binary-parser": "^2.2.1", + "bs58": "^4.0.1", + "elliptic": "^6.5.4", + "js-base64": "^3.6.1", + "near-api-js": "^1.0.0" + }, + "optionalDependencies": { + "@injectivelabs/networks": "1.10.12", + "@injectivelabs/sdk-ts": "1.10.72", + "@injectivelabs/utils": "1.10.12" + } + }, "wormhole-connect/node_modules/@blocto/sdk": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/@blocto/sdk/-/sdk-0.3.6.tgz", @@ -32355,9 +32395,7 @@ } }, "@certusone/wormhole-sdk": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.10.2.tgz", - "integrity": "sha512-e1pEd82EzGW1vN3w0rkF7CocEydj/CPqdR6U1NN5uRXR9vNwSxafwuZfYe5Wn4otSXIGp3lKPGhqzOGXr82rcg==", + "version": "file:.yalc/@certusone/wormhole-sdk", "requires": { "@certusone/wormhole-sdk-proto-web": "0.0.6", "@certusone/wormhole-sdk-wasm": "^0.0.1", @@ -32401,6 +32439,8 @@ }, "axios": { "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", "requires": { "follow-redirects": "^1.14.4" } @@ -38492,7 +38532,7 @@ "version": "file:wormhole-connect", "requires": { "@babel/preset-env": "^7.20.2", - "@certusone/wormhole-sdk": "^0.10.2", + "@certusone/wormhole-sdk": "file:.yalc/@certusone/wormhole-sdk", "@cosmjs/cosmwasm-stargate": "^0.31.0", "@cosmjs/stargate": "^0.31.0", "@cosmjs/tendermint-rpc": "^0.31.0", @@ -38763,7 +38803,7 @@ "@wormhole-foundation/wormhole-connect-sdk": { "version": "file:sdk", "requires": { - "@certusone/wormhole-sdk": "^0.10.2", + "@certusone/wormhole-sdk": "file:.yalc/@certusone/wormhole-sdk", "@cosmjs/cosmwasm-stargate": "^0.31.0", "@cosmjs/proto-signing": "^0.31.0", "@cosmjs/stargate": "^0.31.0", @@ -38798,6 +38838,9 @@ "typescript": "^4.9.4" }, "dependencies": { + "@certusone/wormhole-sdk": { + "version": "file:sdk/.yalc/@certusone/wormhole-sdk" + }, "@cosmjs/amino": { "version": "0.29.5", "requires": { diff --git a/package.json b/package.json index c54a3a2fc..00b8a2827 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "prepare": "husky install" }, "dependencies": { + "@certusone/wormhole-sdk": "file:.yalc/@certusone/wormhole-sdk", "tss-react": "^4.7.7" }, "devDependencies": { diff --git a/sdk/package.json b/sdk/package.json index 63cdad61f..73c15b120 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -5,7 +5,7 @@ "main": "dist/src/index.js", "types": "dist/src/index.d.ts", "dependencies": { - "@certusone/wormhole-sdk": "^0.10.2", + "@certusone/wormhole-sdk": "file:.yalc/@certusone/wormhole-sdk", "@cosmjs/cosmwasm-stargate": "^0.31.0", "@cosmjs/proto-signing": "^0.31.0", "@cosmjs/stargate": "^0.31.0", diff --git a/sdk/src/config/MAINNET.ts b/sdk/src/config/MAINNET.ts index 26a8ddb01..08d81c1c0 100644 --- a/sdk/src/config/MAINNET.ts +++ b/sdk/src/config/MAINNET.ts @@ -19,6 +19,8 @@ export const MAINNET_CHAINS = { sei: 32, wormchain: 3104, osmosis: 20, + cosmoshub: 4000, + evmos: 4001, } as const; /** @@ -205,6 +207,22 @@ const MAINNET: { [chain in MainnetChainName]: ChainConfig } = { finalityThreshold: 0, nativeTokenDecimals: 6, }, + cosmoshub: { + key: 'cosmoshub', + id: 4000, + context: Context.COSMOS, + contracts: {}, + finalityThreshold: 0, + nativeTokenDecimals: 6, + }, + evmos: { + key: 'evmos', + id: 4001, + context: Context.COSMOS, + contracts: {}, + finalityThreshold: 0, + nativeTokenDecimals: 6, + }, }; const env: Environment = 'MAINNET'; @@ -228,6 +246,8 @@ const MAINNET_CONFIG: WormholeConfig = { sei: '', // TODO: fill in wormchain: '', osmosis: 'https://osmosis-rpc.polkachu.com', + cosmoshub: 'https://cosmos-rpc.polkachu.com', + evmos: 'https://evmos-rpc.polkachu.com', }, rest: { sei: '', diff --git a/sdk/src/config/TESTNET.ts b/sdk/src/config/TESTNET.ts index 5ca3a0a18..8533972bc 100644 --- a/sdk/src/config/TESTNET.ts +++ b/sdk/src/config/TESTNET.ts @@ -19,6 +19,8 @@ export const TESTNET_CHAINS = { sei: 32, wormchain: 3104, osmosis: 20, + cosmoshub: 4000, + evmos: 4001, } as const; /** @@ -212,6 +214,28 @@ const TESTNET: { [chain in TestnetChainName]: ChainConfig } = { finalityThreshold: 0, nativeTokenDecimals: 6, }, + cosmoshub: { + key: 'cosmoshub', + id: 4000, + context: Context.COSMOS, + contracts: { + core: '', + token_bridge: '', + }, + finalityThreshold: 0, + nativeTokenDecimals: 6, + }, + evmos: { + key: 'evmos', + id: 4001, + context: Context.COSMOS, + contracts: { + core: '', + token_bridge: '', + }, + finalityThreshold: 0, + nativeTokenDecimals: 6, + }, }; const env: Environment = 'TESTNET'; @@ -235,6 +259,8 @@ const TESTNET_CONFIG: WormholeConfig = { sei: 'https://rpc.atlantic-2.seinetwork.io', wormchain: '', osmosis: 'https://rpc.osmotest5.osmosis.zone', + cosmoshub: 'https://rpc.sentry-02.theta-testnet.polypore.xyz', + evmos: 'https://evmos-testnet-rpc.polkachu.com', }, rest: { sei: 'https://rest.atlantic-2.seinetwork.io', diff --git a/sdk/src/contexts/cosmos/context.ts b/sdk/src/contexts/cosmos/context.ts index 2cf004fbd..7e4da79fe 100644 --- a/sdk/src/contexts/cosmos/context.ts +++ b/sdk/src/contexts/cosmos/context.ts @@ -1,5 +1,10 @@ import { + CosmWasmChainId, + WormholeWrappedInfo, cosmos, + hexToUint8Array, + isCosmWasmChain, + isNativeCosmWasmDenom, parseTokenTransferPayload, parseVaa, } from '@certusone/wormhole-sdk'; @@ -46,16 +51,24 @@ interface WrappedRegistryResponse { address: string; } -const NATIVE_DENOMS: Record = { +const MAINNET_NATIVE_DENOMS: Record = { osmosis: 'uosmo', wormchain: 'uworm', terra2: 'uluna', + cosmoshub: 'uatom', + evmos: 'aevmos', +}; +const TESTNET_NATIVE_DENOMS: Record = { + ...MAINNET_NATIVE_DENOMS, + evmos: 'atevmos', }; const PREFIXES: Record = { osmosis: 'osmo', - wormchain: 'wormchain', + wormchain: 'wormhole', terra2: 'terra', + cosmoshub: 'cosmos', + evmos: 'evmos', }; const MSG_EXECUTE_CONTRACT_TYPE_URL = '/cosmwasm.wasm.v1.MsgExecuteContract'; @@ -141,7 +154,10 @@ export class CosmosContext< } private buildTokenId(address: string): string { - const isNative = !!NATIVE_DENOMS[address]; + const isNative = + this.context.conf.env === 'TESTNET' + ? !!TESTNET_NATIVE_DENOMS[address] + : !!MAINNET_NATIVE_DENOMS[address]; return ( (isNative ? '01' : '00') + keccak256(Buffer.from(address, 'utf-8')).substring(4) @@ -225,7 +241,7 @@ export class CosmosContext< const client = await this.getCosmWasmClient(name); const { amount } = await client.getBalance( walletAddress, - asset || NATIVE_DENOMS[name], + asset || this.getNativeDenom(name), ); return BigNumber.from(amount); } @@ -251,9 +267,13 @@ export class CosmosContext< private getNativeDenom(chain: ChainName | ChainId): string { const name = this.context.toChainName(chain); - const denom = NATIVE_DENOMS[name]; - if (!denom) + const denom = + this.context.conf.env === 'TESTNET' + ? TESTNET_NATIVE_DENOMS[name] + : MAINNET_NATIVE_DENOMS[name]; + if (!denom) { throw new Error(`Native denomination not found for chain ${chain}`); + } return denom; } @@ -341,15 +361,15 @@ export class CosmosContext< const logs = cosmosLogs.parseRawLog(tx.rawLog); // extract information wormhole contract logs - // - message.message: the vaa payload (i.e. the transfer information) - // - message.sequence: the vaa's sequence number - // - message.sender: the vaa's emitter address - const tokenTransferPayload = searchCosmosLogs('message.message', logs); + // - wasm.message.message: the vaa payload (i.e. the transfer information) + // - wasm.message.sequence: the vaa's sequence number + // - wasm.message.sender: the vaa's emitter address + const tokenTransferPayload = searchCosmosLogs('wasm.message.message', logs); if (!tokenTransferPayload) throw new Error('message/transfer payload not found'); - const sequence = searchCosmosLogs('message.sequence', logs); + const sequence = searchCosmosLogs('wasm.message.sequence', logs); if (!sequence) throw new Error('sequence not found'); - const emitterAddress = searchCosmosLogs('message.sender', logs); + const emitterAddress = searchCosmosLogs('wasm.message.sender', logs); if (!emitterAddress) throw new Error('emitter not found'); const parsed = parseTokenTransferPayload( @@ -429,4 +449,39 @@ export class CosmosContext< const client = await this.getCosmWasmClient(this.chain); return client.getHeight(); } + + async getOriginalAsset( + chain: ChainName | ChainId, + wrappedAddress: string, + ): Promise { + const chainId = this.context.toChainId(chain) as CosmWasmChainId; + if (!isCosmWasmChain(chainId)) { + throw new Error(`${chain} is not a cosmos chain`); + } + if (isNativeCosmWasmDenom(chainId, wrappedAddress)) { + return { + isWrapped: false, + chainId, + assetAddress: hexToUint8Array(this.buildTokenId(wrappedAddress)), + }; + } + try { + const client = await this.getCosmWasmClient(chain); + const response = await client.queryContractSmart(wrappedAddress, { + wrapped_asset_info: {}, + }); + return { + isWrapped: true, + chainId: response.asset_chain, + assetAddress: new Uint8Array( + Buffer.from(response.asset_address, 'base64'), + ), + }; + } catch {} + return { + isWrapped: false, + chainId: chainId, + assetAddress: hexToUint8Array(this.buildTokenId(wrappedAddress)), + }; + } } diff --git a/sdk/src/contexts/cosmos/utils.ts b/sdk/src/contexts/cosmos/utils.ts index d971fe758..88c504e40 100644 --- a/sdk/src/contexts/cosmos/utils.ts +++ b/sdk/src/contexts/cosmos/utils.ts @@ -9,10 +9,19 @@ export const searchCosmosLogs = ( key: string, logs: readonly cosmosLogs.Log[], ): string | null => { + const parts = key.split('.'); + + // if event, search for the first attribute with the given key + const [event, attribute] = + parts.length > 1 + ? [parts[0], parts.slice(1).join('.')] + : [undefined, parts[0]]; + for (const log of logs) { for (const ev of log.events) { + if (event && ev.type !== event) continue; for (const attr of ev.attributes) { - if (attr.key === key) { + if (attr.key === attribute) { return attr.value; } } diff --git a/wormhole-connect/package.json b/wormhole-connect/package.json index e7e56bf03..f2681a2a0 100644 --- a/wormhole-connect/package.json +++ b/wormhole-connect/package.json @@ -7,7 +7,7 @@ "access": "restricted" }, "dependencies": { - "@certusone/wormhole-sdk": "^0.10.2", + "@certusone/wormhole-sdk": "file:.yalc/@certusone/wormhole-sdk", "@cosmjs/cosmwasm-stargate": "^0.31.0", "@cosmjs/stargate": "^0.31.0", "@cosmjs/tendermint-rpc": "^0.31.0", diff --git a/wormhole-connect/src/config/index.ts b/wormhole-connect/src/config/index.ts index be9618840..d041057e6 100644 --- a/wormhole-connect/src/config/index.ts +++ b/wormhole-connect/src/config/index.ts @@ -99,6 +99,8 @@ const mainnetRpcs = { base: process.env.REACT_APP_BASE_RPC || conf.rpcs.base, osmosis: process.env.REACT_APP_OSMOSIS_RPC || conf.rpcs.osmosis, wormchain: process.env.REACT_APP_WORMCHAIN_RPC || conf.rpcs.wormchain, + cosmoshub: process.env.REACT_APP_COSMOSHUB_RPC || conf.rpcs.cosmoshub, + evmos: process.env.REACT_APP_EVMOS_RPC || conf.rpcs.evmos, }; const testnetRpcs = { goerli: process.env.REACT_APP_GOERLI_RPC || conf.rpcs.goerli, @@ -115,6 +117,8 @@ const testnetRpcs = { basegoerli: process.env.REACT_APP_BASE_GOERLI_RPC || conf.rpcs.basegoerli, osmosis: process.env.REACT_APP_OSMOSIS_TESTNET_RPC || conf.rpcs.osmosis, wormchain: process.env.REACT_APP_WORMCHAIN_TESTNET_RPC || conf.rpcs.wormchain, + cosmoshub: process.env.REACT_APP_COSMOSHUB_TESTNET_RPC || conf.rpcs.cosmoshub, + evmos: process.env.REACT_APP_EVMOS_TESTNET_RPC || conf.rpcs.evmos, }; const devnetRpcs = { ethereum: process.env.REACT_APP_ETHEREUM_DEVNET_RPC || conf.rpcs.ethereum, @@ -180,4 +184,6 @@ export const TESTNET_TO_MAINNET_CHAIN_NAMES: { sei: 'sei', wormchain: 'wormchain', osmosis: 'osmosis', + cosmoshub: 'cosmoshub', + evmos: 'evmos', }; diff --git a/wormhole-connect/src/config/mainnet.ts b/wormhole-connect/src/config/mainnet.ts index c7a4f42d4..01670a094 100644 --- a/wormhole-connect/src/config/mainnet.ts +++ b/wormhole-connect/src/config/mainnet.ts @@ -146,6 +146,28 @@ export const MAINNET_NETWORKS: NetworksConfig = { automaticRelayer: false, maxBlockSearch: 0, }, + // cosmoshub: { + // ...chains.cosmoshub!, + // displayName: 'Cosmos Hub', + // explorerUrl: 'https://www.mintscan.io/cosmos', + // explorerName: 'MintScan', + // gasToken: 'ATOM', + // chainId: 'cosmoshub-4', + // icon: Icon.ATOM, + // automaticRelayer: false, + // maxBlockSearch: 0, + // }, + evmos: { + ...chains.evmos!, + displayName: 'Evmos', + explorerUrl: 'https://www.mintscan.io/evmos/', + explorerName: 'MintScan', + gasToken: 'EVMOS', + chainId: 'evmos_9001-2', + icon: Icon.EVMOS, + automaticRelayer: false, + maxBlockSearch: 0, + }, }; export const MAINNET_TOKENS: { [key: string]: TokenConfig } = { @@ -632,6 +654,36 @@ export const MAINNET_TOKENS: { [key: string]: TokenConfig } = { default: 5, }, }, + // ATOM: { + // key: 'ATOM', + // symbol: 'ATOM', + // nativeNetwork: 'cosmoshub', + // tokenId: { + // chain: 'cosmoshub', + // address: 'uatom', + // }, + // icon: Icon.ATOM, + // coinGeckoId: 'cosmos-hub', + // color: '#6f7390', + // decimals: { + // default: 6, + // }, + // }, + EVMOS: { + key: 'EVMOS', + symbol: 'EVMOS', + nativeNetwork: 'evmos', + tokenId: { + chain: 'evmos', + address: 'atevmos', + }, + icon: Icon.EVMOS, + coinGeckoId: 'evmos', + color: '#ed4e33', + decimals: { + default: 6, + }, + }, }; export const MAINNET_GAS_ESTIMATES: GasEstimates = { @@ -725,4 +777,14 @@ export const MAINNET_GAS_ESTIMATES: GasEstimates = { sendToken: 0, claim: 0, }, + // cosmoshub: { + // sendNative: 0, + // sendToken: 0, + // claim: 0, + // }, + evmos: { + sendNative: 0, + sendToken: 0, + claim: 0, + }, }; diff --git a/wormhole-connect/src/config/testnet.ts b/wormhole-connect/src/config/testnet.ts index f21cb8f61..5ebd85fcc 100644 --- a/wormhole-connect/src/config/testnet.ts +++ b/wormhole-connect/src/config/testnet.ts @@ -156,6 +156,28 @@ export const TESTNET_NETWORKS: NetworksConfig = { automaticRelayer: false, maxBlockSearch: 0, }, + cosmoshub: { + ...chains.cosmoshub!, + displayName: 'Cosmoshub', + explorerUrl: 'https://testnet.mintscan.io/cosmoshub-testnet/', + explorerName: 'MintScan', + gasToken: 'ATOM', + chainId: 'theta-testnet-001', + icon: Icon.ATOM, + automaticRelayer: false, + maxBlockSearch: 0, + }, + evmos: { + ...chains.evmos!, + displayName: 'Evmos', + explorerUrl: 'https://testnet.mintscan.io/evmos-testnet/', + explorerName: 'MintScan', + gasToken: 'EVMOS', + chainId: 'evmos_9000-4', + icon: Icon.EVMOS, + automaticRelayer: false, + maxBlockSearch: 0, + }, }; export const TESTNET_TOKENS: { [key: string]: TokenConfig } = { @@ -563,6 +585,36 @@ export const TESTNET_TOKENS: { [key: string]: TokenConfig } = { default: 6, }, }, + ATOM: { + key: 'ATOM', + symbol: 'ATOM', + nativeNetwork: 'cosmoshub', + tokenId: { + chain: 'cosmoshub', + address: 'uatom', + }, + icon: Icon.ATOM, + coinGeckoId: 'cosmos-hub', + color: '#6f7390', + decimals: { + default: 6, + }, + }, + EVMOS: { + key: 'EVMOS', + symbol: 'EVMOS', + nativeNetwork: 'evmos', + tokenId: { + chain: 'evmos', + address: 'atevmos', + }, + icon: Icon.EVMOS, + coinGeckoId: 'evmos', + color: '#ed4e33', + decimals: { + default: 6, + }, + }, tBTC: { key: 'tBTC', symbol: 'tBTC', @@ -703,4 +755,14 @@ export const TESTNET_GAS_ESTIMATES: GasEstimates = { sendToken: 0, claim: 0, }, + cosmoshub: { + sendNative: 0, + sendToken: 0, + claim: 0, + }, + evmos: { + sendNative: 0, + sendToken: 0, + claim: 0, + }, }; diff --git a/wormhole-connect/src/config/types.ts b/wormhole-connect/src/config/types.ts index 67b4f8ca3..44e7671cb 100644 --- a/wormhole-connect/src/config/types.ts +++ b/wormhole-connect/src/config/types.ts @@ -83,6 +83,8 @@ export enum Icon { 'BONK', 'TBTC', 'WSTETH', + 'ATOM', + 'EVMOS', } export type GasEstimates = { diff --git a/wormhole-connect/src/icons/TokenIcons.tsx b/wormhole-connect/src/icons/TokenIcons.tsx index 5b2b24f7e..899a58a9b 100644 --- a/wormhole-connect/src/icons/TokenIcons.tsx +++ b/wormhole-connect/src/icons/TokenIcons.tsx @@ -22,6 +22,12 @@ import MATIC from './Tokens/MATIC'; import BSC from './Tokens/BSC'; import USDC from './Tokens/USDC'; import noIcon from './Tokens/noIcon'; +import OSMO from './Tokens/OSMO'; +import BONK from './Tokens/BONK'; +import TBTC from './Tokens/TBTC'; +import WSTETH from './Tokens/WSTETH'; +import ATOM from './Tokens/ATOM'; +import EVMOS from './Tokens/EVMOS'; const useStyles = makeStyles<{ size: number }>()((theme, { size }) => ({ container: { @@ -92,466 +98,22 @@ export const getIcon = (icon: Icon) => { return BASE; } case Icon.OSMO: { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); + return OSMO; } case Icon.BONK: { - return ( - BONK token - ); + return BONK; } case Icon.TBTC: { - return ( - - - - - - - - - ); + return TBTC; } case Icon.WSTETH: { - return ( - - - - - - - - - - - - ); + return WSTETH; + } + case Icon.ATOM: { + return ATOM; + } + case Icon.EVMOS: { + return EVMOS; } default: { return noIcon; diff --git a/wormhole-connect/src/icons/Tokens/ATOM.tsx b/wormhole-connect/src/icons/Tokens/ATOM.tsx new file mode 100644 index 000000000..3f79f164f --- /dev/null +++ b/wormhole-connect/src/icons/Tokens/ATOM.tsx @@ -0,0 +1,74 @@ +import React from 'react'; + +function ATOM() { + return ( + + + + + + + + + + + + ); +} + +export default ATOM; diff --git a/wormhole-connect/src/icons/Tokens/BONK.tsx b/wormhole-connect/src/icons/Tokens/BONK.tsx new file mode 100644 index 000000000..585461ed6 --- /dev/null +++ b/wormhole-connect/src/icons/Tokens/BONK.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +function BONK() { + return ( + BONK token + ); +} + +export default BONK; diff --git a/wormhole-connect/src/icons/Tokens/EVMOS.tsx b/wormhole-connect/src/icons/Tokens/EVMOS.tsx new file mode 100644 index 000000000..a2a0ec006 --- /dev/null +++ b/wormhole-connect/src/icons/Tokens/EVMOS.tsx @@ -0,0 +1,22 @@ +import React from 'react'; + +function EVMOS() { + return ( + + + + + ); +} + +export default EVMOS; diff --git a/wormhole-connect/src/icons/Tokens/OSMO.tsx b/wormhole-connect/src/icons/Tokens/OSMO.tsx new file mode 100644 index 000000000..5e4380077 --- /dev/null +++ b/wormhole-connect/src/icons/Tokens/OSMO.tsx @@ -0,0 +1,370 @@ +import React from 'react'; + +function OSMO() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +export default OSMO; diff --git a/wormhole-connect/src/icons/Tokens/SEI.tsx b/wormhole-connect/src/icons/Tokens/SEI.tsx index 0c23095e5..7856992c8 100644 --- a/wormhole-connect/src/icons/Tokens/SEI.tsx +++ b/wormhole-connect/src/icons/Tokens/SEI.tsx @@ -3,6 +3,7 @@ import React from 'react'; function SEI() { return ( + + + + + + + + ); +} + +export default TBTC; diff --git a/wormhole-connect/src/icons/Tokens/WSTETH.tsx b/wormhole-connect/src/icons/Tokens/WSTETH.tsx new file mode 100644 index 000000000..dc8cd82f9 --- /dev/null +++ b/wormhole-connect/src/icons/Tokens/WSTETH.tsx @@ -0,0 +1,56 @@ +import React from 'react'; + +function WSTETH() { + return ( + + + + + + + + + + + + ); +} + +export default WSTETH; diff --git a/wormhole-connect/src/utils/index.ts b/wormhole-connect/src/utils/index.ts index 7dbd3f90b..0015edb7d 100644 --- a/wormhole-connect/src/utils/index.ts +++ b/wormhole-connect/src/utils/index.ts @@ -203,4 +203,4 @@ export function toNormalizedDecimals( export async function sleep(timeout: number) { return new Promise((resolve) => setTimeout(resolve, timeout)); -} \ No newline at end of file +} diff --git a/wormhole-connect/src/utils/routes/cosmosGateway.ts b/wormhole-connect/src/utils/routes/cosmos/cosmosGateway.ts similarity index 77% rename from wormhole-connect/src/utils/routes/cosmosGateway.ts rename to wormhole-connect/src/utils/routes/cosmos/cosmosGateway.ts index 881bc29ab..08fadb7c8 100644 --- a/wormhole-connect/src/utils/routes/cosmosGateway.ts +++ b/wormhole-connect/src/utils/routes/cosmos/cosmosGateway.ts @@ -1,4 +1,6 @@ import { + CHAIN_ID_COSMOSHUB, + CHAIN_ID_EVMOS, CHAIN_ID_OSMOSIS, CHAIN_ID_SEI, CHAIN_ID_SOLANA, @@ -27,21 +29,22 @@ import { searchCosmosLogs, SolanaContext, WormholeContext, + CosmosContext, } from '@wormhole-foundation/wormhole-connect-sdk'; import { MsgTransfer } from 'cosmjs-types/ibc/applications/transfer/v1/tx'; import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; import { BigNumber, utils } from 'ethers'; import { arrayify, base58 } from 'ethers/lib/utils.js'; -import { toChainId, wh } from 'utils/sdk'; -import { MAX_DECIMALS, getTokenDecimals, toNormalizedDecimals } from '..'; -import { CHAINS, CONFIG, TOKENS } from '../../config'; -import { Route } from '../../store/transferInput'; -import { isCosmWasmChain } from '../../utils/cosmos'; -import { toDecimals, toFixedDecimals } from '../balance'; -import { estimateSendGasFees } from '../gasEstimates'; -import { TransferWallet, signAndSendTransaction } from '../wallet'; -import { BaseRoute } from './baseRoute'; -import { adaptParsedMessage } from './common'; +import { ParsedMessage, toChainId, wh } from 'utils/sdk'; +import { MAX_DECIMALS, getTokenDecimals, toNormalizedDecimals } from '../..'; +import { CHAINS, CONFIG, ENV, TOKENS } from '../../../config'; +import { Route } from '../../../store/transferInput'; +import { isCosmWasmChain } from '../../cosmos'; +import { toDecimals, toFixedDecimals } from '../../balance'; +import { estimateSendGasFees } from '../../gasEstimates'; +import { TransferWallet, signAndSendTransaction } from '../../wallet'; +import { BaseRoute } from '../baseRoute'; +import { adaptParsedMessage } from '../common'; import { RelayTransferMessage, SignedRelayTransferMessage, @@ -49,22 +52,26 @@ import { TokenTransferMessage, TransferDisplayData, isSignedWormholeMessage, -} from './types'; +} from '../types'; import { UnsignedMessage, SignedMessage, TransferDestInfoBaseParams, TransferInfoBaseParams, -} from './types'; -import { calculateGas } from '../gas'; +} from '../types'; +import { calculateGas } from '../../gas'; import { Tendermint34Client, Tendermint37Client, TendermintClient, } from '@cosmjs/tendermint-rpc'; -import { BridgeRoute } from './bridge'; -import { TokenConfig } from '../../config/types'; -import { fetchVaa } from '../vaa'; +import { BridgeRoute } from '../bridge'; +import { TokenConfig } from '../../../config/types'; +import { fetchVaa } from '../../vaa'; +import { + TokenFactoryExtension, + setupTokenFactoryExtension, +} from './extensions/tokenfactory'; interface GatewayTransferMsg { gateway_transfer: { @@ -84,6 +91,15 @@ interface IBCTransferInfo { timeout: string; srcChannel: string; dstChannel: string; + data: string; +} + +interface IBCTransferData { + amount: string; + denom: string; + memo: string; + receiver: string; + sender: string; } const IBC_MSG_TYPE = '/ibc.applications.transfer.v1.MsgTransfer'; @@ -229,7 +245,9 @@ export class CosmosGatewayRoute extends BaseRoute { const destContext = wh.getContext(recipientChainId); const recipient = Buffer.from( - destContext.formatAddress(recipientAddress), + isCosmWasmChain(recipientChainId) + ? recipientAddress + : destContext.formatAddress(recipientAddress), ).toString('base64'); const payloadObject: FromCosmosPayload = { @@ -445,6 +463,10 @@ export class CosmosGatewayRoute extends BaseRoute { return denom === 'uworm'; case CHAIN_ID_OSMOSIS: return denom === 'uosmo'; + case CHAIN_ID_COSMOSHUB: + return denom === 'uatom'; + case CHAIN_ID_EVMOS: + return ENV === 'MAINNET' ? denom === 'aevmos' : denom === 'atevmos'; default: return false; } @@ -480,7 +502,7 @@ export class CosmosGatewayRoute extends BaseRoute { // add check here in case the token is a native cosmos denom // in such cases there's no need to look for in the wormchain network - if (tokenId.chain === chain) return tokenId.address; + if (isCosmWasmChain(tokenId.chain)) return tokenId.address; const wrappedAsset = await wh.getForeignAsset(tokenId, CHAIN_ID_WORMCHAIN); if (!wrappedAsset) return null; return this.isNativeDenom(wrappedAsset, chain) @@ -528,9 +550,13 @@ export class CosmosGatewayRoute extends BaseRoute { private async getQueryClient( chain: ChainId | ChainName, - ): Promise { + ): Promise { const tmClient = await this.getTmClient(chain); - return QueryClient.withExtensions(tmClient, setupIbcExtension); + return QueryClient.withExtensions( + tmClient, + setupIbcExtension, + setupTokenFactoryExtension, + ); } private async getTmClient( @@ -595,6 +621,17 @@ export class CosmosGatewayRoute extends BaseRoute { async getSignedMessage( message: TokenTransferMessage | RelayTransferMessage, ): Promise { + // if both chains are cosmos gateway chains, no vaa is emitted + if ( + isCosmWasmChain(message.fromChain) && + isCosmWasmChain(message.toChain) + ) { + return { + ...message, + vaa: '', + }; + } + const vaa = await fetchVaa({ ...message, // transfers from cosmos vaas are emitted by wormchain and not by the source chain @@ -661,7 +698,7 @@ export class CosmosGatewayRoute extends BaseRoute { if (!sender) throw new Error('Missing sender in transaction logs'); // Extract IBC transfer info initiated on the source chain - const ibcInfo = this.getIBCTransferInfoFromLogs(tx); + const ibcInfo = this.getIBCTransferInfoFromLogs(tx, 'send_packet'); // Look for the matching IBC receive on wormchain // The IBC hooks middleware will execute the translator contract @@ -677,8 +714,14 @@ export class CosmosGatewayRoute extends BaseRoute { ); } - const message = await wh.getMessage(destTx.hash, CHAIN_ID_WORMCHAIN); - const parsed = await adaptParsedMessage(message); + // TODO: refactor these two lines (repeated in parseWormchainIBCForwardMessage) + const data: IBCTransferData = JSON.parse(ibcInfo.data); + const payload: FromCosmosPayload = JSON.parse(data.memo); + const parsed = await (isCosmWasmChain( + payload.gateway_ibc_token_bridge_payload.gateway_transfer.chain, + ) + ? this.parseWormchainIBCForwardMessage(destTx) + : this.parseWormchainBridgeMessage(destTx)); return { ...parsed, @@ -690,6 +733,88 @@ export class CosmosGatewayRoute extends BaseRoute { }; } + private async parseWormchainBridgeMessage( + wormchainTx: IndexedTx, + ): Promise { + const message = await wh.getMessage(wormchainTx.hash, CHAIN_ID_WORMCHAIN); + return adaptParsedMessage(message); + } + + private async parseWormchainIBCForwardMessage( + wormchainTx: IndexedTx, + ): Promise { + // get the information of the ibc transfer relayed by the packet forwarding middleware + const ibcFromSourceInfo = this.getIBCTransferInfoFromLogs( + wormchainTx, + 'recv_packet', + ); + + const data: IBCTransferData = JSON.parse(ibcFromSourceInfo.data); + const payload: FromCosmosPayload = JSON.parse(data.memo); + + const destChain = wh.toChainName( + payload.gateway_ibc_token_bridge_payload.gateway_transfer.chain, + ); + const ibcToDestInfo = this.getIBCTransferInfoFromLogs( + wormchainTx, + 'send_packet', + ); + const destTx = await this.findDestinationIBCTransferTx( + destChain, + ibcToDestInfo, + ); + if (!destTx) { + throw new Error(`Transaction on destination ${destChain} not found`); + } + + // transfer ibc denom follows the scheme {port}/{channel}/{denom} + // with denom as {tokenfactory}/{ibc shim}/{bas58 cw20 address} + // so 5 elements total + const parts = data.denom.split('/'); + if (parts.length !== 5) { + throw new Error(`Unexpected transfer denom ${data.denom}`); + } + const denom = parts.slice(2).join('/'); + const cw20 = this.factoryToCW20(denom); + const context = wh.getContext( + CHAIN_ID_WORMCHAIN, + ) as CosmosContext; + const { chainId, assetAddress: tokenAddressBytes } = + await context.getOriginalAsset(CHAIN_ID_WORMCHAIN, cw20); + const tokenChain = wh.toChainName(chainId as ChainId); // wormhole-sdk adds 0 (unset) as a chainId + const tokenContext = wh.getContext(tokenChain); + const tokenAddress = await tokenContext.parseAssetAddress( + utils.hexlify(tokenAddressBytes), + ); + + return adaptParsedMessage({ + fromChain: wh.toChainName(CHAIN_ID_WORMCHAIN), // gets replaced later + sendTx: wormchainTx.hash, // gets replaced later + toChain: destChain, + amount: BigNumber.from(data.amount), + recipient: data.receiver, + block: destTx.height, + sender: data.sender, + gasFee: BigNumber.from(destTx.gasUsed.toString()), + payloadID: 3, // should not be required for this case + tokenChain, + tokenAddress, + tokenId: { + address: tokenAddress, + chain: tokenChain, + }, + emitterAddress: '', + sequence: BigNumber.from(0), + }); + } + + private factoryToCW20(denom: string): string { + if (!denom.startsWith('factory/')) return ''; + const encoded = denom.split('/')[2]; + if (!encoded) return ''; + return cosmos.humanAddress('wormhole', base58.decode(encoded)); + } + async fetchRedeemedEvent( message: SignedTokenTransferMessage | SignedRelayTransferMessage, ): Promise { @@ -724,7 +849,7 @@ export class CosmosGatewayRoute extends BaseRoute { } // extract the ibc transfer info from the transaction logs - const ibcInfo = this.getIBCTransferInfoFromLogs(txs[0]); + const ibcInfo = this.getIBCTransferInfoFromLogs(txs[0], 'send_packet'); // find the transaction on the target chain based on the ibc transfer info const destTx = await this.findDestinationIBCTransferTx( @@ -739,17 +864,31 @@ export class CosmosGatewayRoute extends BaseRoute { return destTx.hash; } - private getIBCTransferInfoFromLogs(tx: IndexedTx): IBCTransferInfo { + private getIBCTransferInfoFromLogs( + tx: IndexedTx, + event: 'send_packet' | 'recv_packet', + ): IBCTransferInfo { const logs = cosmosLogs.parseRawLog(tx.rawLog); - const packetSeq = searchCosmosLogs('packet_sequence', logs); - const packetTimeout = searchCosmosLogs('packet_timeout_timestamp', logs); - const packetSrcChannel = searchCosmosLogs('packet_src_channel', logs); - const packetDstChannel = searchCosmosLogs('packet_dst_channel', logs); + const packetSeq = searchCosmosLogs(`${event}.packet_sequence`, logs); + const packetTimeout = searchCosmosLogs( + `${event}.packet_timeout_timestamp`, + logs, + ); + const packetSrcChannel = searchCosmosLogs( + `${event}.packet_src_channel`, + logs, + ); + const packetDstChannel = searchCosmosLogs( + `${event}.packet_dst_channel`, + logs, + ); + const packetData = searchCosmosLogs(`${event}.packet_data`, logs); if ( !packetSeq || !packetTimeout || !packetSrcChannel || - !packetDstChannel + !packetDstChannel || + !packetData ) { throw new Error('Missing packet information in transaction logs'); } @@ -759,6 +898,7 @@ export class CosmosGatewayRoute extends BaseRoute { timeout: packetTimeout, srcChannel: packetSrcChannel, dstChannel: packetDstChannel, + data: packetData, }; } @@ -787,7 +927,36 @@ export class CosmosGatewayRoute extends BaseRoute { private async fetchRedeemedEventCosmosSource( message: SignedTokenTransferMessage | SignedRelayTransferMessage, ): Promise { - throw new Error('Not implemented'); + if (!isCosmWasmChain(message.toChain)) { + throw new Error( + `Fetch redeem tx not supported by this route for chain ${message.toChain}`, + ); + } + + // find tx in the source chain and extract the ibc transfer to wormchain + const sourceClient = await this.getCosmWasmClient(message.fromChain); + const tx = await sourceClient.getTx(message.sendTx); + if (!tx) return null; + const sourceIbcInfo = this.getIBCTransferInfoFromLogs(tx, 'send_packet'); + + // find tx in the ibc receive in wormchain and extract the ibc transfer to the dest tx + const wormchainTx = await this.findDestinationIBCTransferTx( + CHAIN_ID_WORMCHAIN, + sourceIbcInfo, + ); + if (!wormchainTx) return null; + const wormchainToDestIbcInfo = this.getIBCTransferInfoFromLogs( + wormchainTx, + 'send_packet', + ); + + // find the tx that deposits the funds in the final recipient + const destTx = await this.findDestinationIBCTransferTx( + message.toChain, + wormchainToDestIbcInfo, + ); + if (!destTx) return null; + return destTx.hash; } async getTransferSourceInfo({ diff --git a/wormhole-connect/src/utils/routes/cosmos/extensions/tokenfactory.ts b/wormhole-connect/src/utils/routes/cosmos/extensions/tokenfactory.ts new file mode 100644 index 000000000..ab1790e23 --- /dev/null +++ b/wormhole-connect/src/utils/routes/cosmos/extensions/tokenfactory.ts @@ -0,0 +1,44 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { + QueryDenomAuthorityMetadataResponse, + QueryDenomsFromCreatorResponse, + QueryParamsResponse, + QueryClientImpl as TokenFactoryQuery, +} from '../types/osmosis/tokenfactory/v1beta1/query'; + +import { createProtobufRpcClient, QueryClient } from '@cosmjs/stargate'; + +export interface TokenFactoryExtension { + readonly tokenfactory: { + readonly params: () => Promise; + denomAuthorityMetadata: ( + denom: string, + ) => Promise; + denomsFromCreator: ( + creator: string, + ) => Promise; + }; +} + +export function setupTokenFactoryExtension( + base: QueryClient, +): TokenFactoryExtension { + const rpc = createProtobufRpcClient(base); + // Use these services to get easy typed access to query methods + // These cannot be used for proof verification + const query = new TokenFactoryQuery(rpc); + + return { + tokenfactory: { + params: async () => query.Params({}), + denomAuthorityMetadata: async (denom: string) => + query.DenomAuthorityMetadata({ + denom, + }), + denomsFromCreator: async (creator: string) => + query.DenomsFromCreator({ + creator, + }), + }, + }; +} diff --git a/wormhole-connect/src/utils/routes/cosmos/index.ts b/wormhole-connect/src/utils/routes/cosmos/index.ts new file mode 100644 index 000000000..10550992c --- /dev/null +++ b/wormhole-connect/src/utils/routes/cosmos/index.ts @@ -0,0 +1 @@ +export * from './cosmosGateway'; diff --git a/wormhole-connect/src/utils/routes/cosmos/types/helpers.ts b/wormhole-connect/src/utils/routes/cosmos/types/helpers.ts new file mode 100644 index 000000000..93fc2bcf6 --- /dev/null +++ b/wormhole-connect/src/utils/routes/cosmos/types/helpers.ts @@ -0,0 +1,271 @@ +/* eslint-disable */ +/** + * This file and any referenced files were automatically generated by @osmonauts/telescope@0.94.1 + * DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain + * and run the transpile command or yarn proto command to regenerate this bundle. + */ + +import * as _m0 from 'protobufjs/minimal'; +import Long from 'long'; + +// @ts-ignore +if (_m0.util.Long !== Long) { + _m0.util.Long = Long as any; + + _m0.configure(); +} + +export { Long }; + +declare var self: any | undefined; +declare var window: any | undefined; +declare var global: any | undefined; +var globalThis: any = (() => { + if (typeof globalThis !== 'undefined') return globalThis; + if (typeof self !== 'undefined') return self; + if (typeof window !== 'undefined') return window; + if (typeof global !== 'undefined') return global; + throw 'Unable to locate global object'; +})(); + +const atob: (b64: string) => string = + globalThis.atob || + ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); + +export function bytesFromBase64(b64: string): Uint8Array { + const bin = atob(b64); + const arr = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; ++i) { + arr[i] = bin.charCodeAt(i); + } + return arr; +} + +const btoa: (bin: string) => string = + globalThis.btoa || + ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); + +export function base64FromBytes(arr: Uint8Array): string { + const bin: string[] = []; + arr.forEach((byte) => { + bin.push(String.fromCharCode(byte)); + }); + return btoa(bin.join('')); +} + +export interface AminoHeight { + readonly revision_number?: string; + readonly revision_height?: string; +} + +export function omitDefault( + input: T, +): T | undefined { + if (typeof input === 'string') { + return input === '' ? undefined : input; + } + + if (typeof input === 'number') { + return input === 0 ? undefined : input; + } + + if (Long.isLong(input)) { + return input.isZero() ? undefined : input; + } + + throw new Error(`Got unsupported type ${typeof input}`); +} + +interface Duration { + /** + * Signed seconds of the span of time. Must be from -315,576,000,000 + * to +315,576,000,000 inclusive. Note: these bounds are computed from: + * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + */ + seconds: Long; + /** + * Signed fractions of a second at nanosecond resolution of the span + * of time. Durations less than one second are represented with a 0 + * `seconds` field and a positive or negative `nanos` field. For durations + * of one second or more, a non-zero value for the `nanos` field must be + * of the same sign as the `seconds` field. Must be from -999,999,999 + * to +999,999,999 inclusive. + */ + + nanos: number; +} + +export function toDuration(duration: string): Duration { + return { + seconds: Long.fromNumber(Math.floor(parseInt(duration) / 1000000000)), + nanos: parseInt(duration) % 1000000000, + }; +} + +export function fromDuration(duration: Duration): string { + return ( + parseInt(duration.seconds.toString()) * 1000000000 + + duration.nanos + ).toString(); +} + +export function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export function isObject(value: any): boolean { + return typeof value === 'object' && value !== null; +} + +export interface PageRequest { + key: Uint8Array; + offset: Long; + limit: Long; + countTotal: boolean; + reverse: boolean; +} + +export interface PageRequestParams { + 'pagination.key'?: string; + 'pagination.offset'?: string; + 'pagination.limit'?: string; + 'pagination.count_total'?: boolean; + 'pagination.reverse'?: boolean; +} + +export interface Params { + params: PageRequestParams; +} + +export const setPaginationParams = ( + options: Params, + pagination?: PageRequest, +) => { + if (!pagination) { + return options; + } + + if (typeof pagination?.countTotal !== 'undefined') { + options.params['pagination.count_total'] = pagination.countTotal; + } + if (typeof pagination?.key !== 'undefined') { + // String to Uint8Array + // let uint8arr = new Uint8Array(Buffer.from(data,'base64')); + + // Uint8Array to String + options.params['pagination.key'] = Buffer.from(pagination.key).toString( + 'base64', + ); + } + if (typeof pagination?.limit !== 'undefined') { + options.params['pagination.limit'] = pagination.limit.toString(); + } + if (typeof pagination?.offset !== 'undefined') { + options.params['pagination.offset'] = pagination.offset.toString(); + } + if (typeof pagination?.reverse !== 'undefined') { + options.params['pagination.reverse'] = pagination.reverse; + } + + return options; +}; + +type Builtin = + | Date + | Function + | Uint8Array + | string + | number + | boolean + | undefined; + +export type DeepPartial = T extends Builtin + ? T + : T extends Long + ? string | number | Long + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends {} + ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin + ? P + : P & { [K in keyof P]: Exact } & Record< + Exclude>, + never + >; + +export interface Rpc { + request( + service: string, + method: string, + data: Uint8Array, + ): Promise; +} + +interface Timestamp { + /** + * Represents seconds of UTC time since Unix epoch + * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + * 9999-12-31T23:59:59Z inclusive. + */ + seconds: Long; + /** + * Non-negative fractions of a second at nanosecond resolution. Negative + * second values with fractions must still have non-negative nanos values + * that count forward in time. Must be from 0 to 999,999,999 + * inclusive. + */ + + nanos: number; +} + +export function toTimestamp(date: Date): Timestamp { + const seconds = numberToLong(date.getTime() / 1_000); + const nanos = (date.getTime() % 1000) * 1000000; + return { + seconds, + nanos, + }; +} + +export function fromTimestamp(t: Timestamp): Date { + let millis = t.seconds.toNumber() * 1000; + millis += t.nanos / 1000000; + return new Date(millis); +} + +/* @ts-ignore */ +const fromJSON = (object: any): Timestamp => { + return { + seconds: isSet(object.seconds) + ? Long.fromString(object.seconds) + : Long.ZERO, + nanos: isSet(object.nanos) ? Number(object.nanos) : 0, + }; +}; + +const timestampFromJSON = (object: any): Timestamp => { + return { + seconds: isSet(object.seconds) ? Long.fromValue(object.seconds) : Long.ZERO, + nanos: isSet(object.nanos) ? Number(object.nanos) : 0, + }; +}; + +export function fromJsonTimestamp(o: any): Timestamp { + if (o instanceof Date) { + return toTimestamp(o); + } else if (typeof o === 'string') { + return toTimestamp(new Date(o)); + } else { + return timestampFromJSON(o); + } +} + +function numberToLong(number: number) { + return Long.fromNumber(number); +} diff --git a/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/authorityMetadata.ts b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/authorityMetadata.ts new file mode 100644 index 000000000..ac0721bad --- /dev/null +++ b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/authorityMetadata.ts @@ -0,0 +1,66 @@ +/* eslint-disable */ +import * as _m0 from 'protobufjs/minimal'; +import { isSet, DeepPartial, Exact } from '../../../helpers'; +export const protobufPackage = 'osmosis.tokenfactory.v1beta1'; +/** + * DenomAuthorityMetadata specifies metadata for addresses that have specific + * capabilities over a token factory denom. Right now there is only one Admin + * permission, but is planned to be extended to the future. + */ +export interface DenomAuthorityMetadata { + /** Can be empty for no admin, or a valid osmosis address */ + admin: string; +} +function createBaseDenomAuthorityMetadata(): DenomAuthorityMetadata { + return { + admin: '', + }; +} +export const DenomAuthorityMetadata = { + encode( + message: DenomAuthorityMetadata, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.admin !== '') { + writer.uint32(10).string(message.admin); + } + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): DenomAuthorityMetadata { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDenomAuthorityMetadata(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.admin = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): DenomAuthorityMetadata { + return { + admin: isSet(object.admin) ? String(object.admin) : '', + }; + }, + toJSON(message: DenomAuthorityMetadata): unknown { + const obj: any = {}; + message.admin !== undefined && (obj.admin = message.admin); + return obj; + }, + fromPartial, I>>( + object: I, + ): DenomAuthorityMetadata { + const message = createBaseDenomAuthorityMetadata(); + message.admin = object.admin ?? ''; + return message; + }, +}; diff --git a/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/genesis.ts b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/genesis.ts new file mode 100644 index 000000000..49da8284b --- /dev/null +++ b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/genesis.ts @@ -0,0 +1,171 @@ +/* eslint-disable */ +import { Params } from './params'; +import { DenomAuthorityMetadata } from './authorityMetadata'; +import * as _m0 from 'protobufjs/minimal'; +import { isSet, DeepPartial, Exact } from '../../../helpers'; +export const protobufPackage = 'osmosis.tokenfactory.v1beta1'; +/** GenesisState defines the tokenfactory module's genesis state. */ +export interface GenesisState { + /** params defines the paramaters of the module. */ + params?: Params; + factoryDenoms: GenesisDenom[]; +} +/** + * GenesisDenom defines a tokenfactory denom that is defined within genesis + * state. The structure contains DenomAuthorityMetadata which defines the + * denom's admin. + */ +export interface GenesisDenom { + denom: string; + authorityMetadata?: DenomAuthorityMetadata; +} +function createBaseGenesisState(): GenesisState { + return { + params: undefined, + factoryDenoms: [], + }; +} +export const GenesisState = { + encode( + message: GenesisState, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.params !== undefined) { + Params.encode(message.params, writer.uint32(10).fork()).ldelim(); + } + for (const v of message.factoryDenoms) { + GenesisDenom.encode(v!, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): GenesisState { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGenesisState(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.params = Params.decode(reader, reader.uint32()); + break; + case 2: + message.factoryDenoms.push( + GenesisDenom.decode(reader, reader.uint32()), + ); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): GenesisState { + return { + params: isSet(object.params) ? Params.fromJSON(object.params) : undefined, + factoryDenoms: Array.isArray(object?.factoryDenoms) + ? object.factoryDenoms.map((e: any) => GenesisDenom.fromJSON(e)) + : [], + }; + }, + toJSON(message: GenesisState): unknown { + const obj: any = {}; + message.params !== undefined && + (obj.params = message.params ? Params.toJSON(message.params) : undefined); + if (message.factoryDenoms) { + obj.factoryDenoms = message.factoryDenoms.map((e) => + e ? GenesisDenom.toJSON(e) : undefined, + ); + } else { + obj.factoryDenoms = []; + } + return obj; + }, + fromPartial, I>>( + object: I, + ): GenesisState { + const message = createBaseGenesisState(); + message.params = + object.params !== undefined && object.params !== null + ? Params.fromPartial(object.params) + : undefined; + message.factoryDenoms = + object.factoryDenoms?.map((e) => GenesisDenom.fromPartial(e)) || []; + return message; + }, +}; +function createBaseGenesisDenom(): GenesisDenom { + return { + denom: '', + authorityMetadata: undefined, + }; +} +export const GenesisDenom = { + encode( + message: GenesisDenom, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.denom !== '') { + writer.uint32(10).string(message.denom); + } + if (message.authorityMetadata !== undefined) { + DenomAuthorityMetadata.encode( + message.authorityMetadata, + writer.uint32(18).fork(), + ).ldelim(); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): GenesisDenom { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGenesisDenom(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.denom = reader.string(); + break; + case 2: + message.authorityMetadata = DenomAuthorityMetadata.decode( + reader, + reader.uint32(), + ); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): GenesisDenom { + return { + denom: isSet(object.denom) ? String(object.denom) : '', + authorityMetadata: isSet(object.authorityMetadata) + ? DenomAuthorityMetadata.fromJSON(object.authorityMetadata) + : undefined, + }; + }, + toJSON(message: GenesisDenom): unknown { + const obj: any = {}; + message.denom !== undefined && (obj.denom = message.denom); + message.authorityMetadata !== undefined && + (obj.authorityMetadata = message.authorityMetadata + ? DenomAuthorityMetadata.toJSON(message.authorityMetadata) + : undefined); + return obj; + }, + fromPartial, I>>( + object: I, + ): GenesisDenom { + const message = createBaseGenesisDenom(); + message.denom = object.denom ?? ''; + message.authorityMetadata = + object.authorityMetadata !== undefined && + object.authorityMetadata !== null + ? DenomAuthorityMetadata.fromPartial(object.authorityMetadata) + : undefined; + return message; + }, +}; diff --git a/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/params.ts b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/params.ts new file mode 100644 index 000000000..61cdaf921 --- /dev/null +++ b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/params.ts @@ -0,0 +1,95 @@ +/* eslint-disable */ +import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin'; +import { Long, isSet, DeepPartial, Exact } from '../../../helpers'; +import * as _m0 from 'protobufjs/minimal'; +export const protobufPackage = 'osmosis.tokenfactory.v1beta1'; +/** Params defines the parameters for the tokenfactory module. */ +export interface Params { + denomCreationFee: Coin[]; + /** + * if denom_creation_fee is an empty array, then this field is used to add more gas consumption + * to the base cost. + * https://github.com/CosmWasm/token-factory/issues/11 + */ + denomCreationGasConsume: Long; +} +function createBaseParams(): Params { + return { + denomCreationFee: [], + /* @ts-ignore */ + denomCreationGasConsume: undefined, + }; +} +export const Params = { + encode( + message: Params, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + for (const v of message.denomCreationFee) { + Coin.encode(v!, writer.uint32(10).fork()).ldelim(); + } + if (message.denomCreationGasConsume !== undefined) { + writer.uint32(16).uint64(message.denomCreationGasConsume); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): Params { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseParams(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.denomCreationFee.push(Coin.decode(reader, reader.uint32())); + break; + case 2: + message.denomCreationGasConsume = reader.uint64() as Long; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): Params { + return { + denomCreationFee: Array.isArray(object?.denomCreationFee) + ? object.denomCreationFee.map((e: any) => Coin.fromJSON(e)) + : [], + /* @ts-ignore */ + denomCreationGasConsume: isSet(object.denomCreationGasConsume) + ? Long.fromValue(object.denomCreationGasConsume) + : undefined, + }; + }, + toJSON(message: Params): unknown { + const obj: any = {}; + if (message.denomCreationFee) { + obj.denomCreationFee = message.denomCreationFee.map((e) => + e ? Coin.toJSON(e) : undefined, + ); + } else { + obj.denomCreationFee = []; + } + message.denomCreationGasConsume !== undefined && + (obj.denomCreationGasConsume = ( + message.denomCreationGasConsume || undefined + ).toString()); + return obj; + }, + fromPartial, I>>(object: I): Params { + const message = createBaseParams(); + message.denomCreationFee = + /* @ts-ignore */ + object.denomCreationFee?.map((e) => Coin.fromPartial(e)) || []; + /* @ts-ignore */ + message.denomCreationGasConsume = + object.denomCreationGasConsume !== undefined && + object.denomCreationGasConsume !== null + ? Long.fromValue(object.denomCreationGasConsume) + : undefined; + return message; + }, +}; diff --git a/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/query.ts b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/query.ts new file mode 100644 index 000000000..55a1632cf --- /dev/null +++ b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/query.ts @@ -0,0 +1,434 @@ +/* eslint-disable */ +import { Params } from './params'; +import { DenomAuthorityMetadata } from './authorityMetadata'; +import * as _m0 from 'protobufjs/minimal'; +import { DeepPartial, Exact, isSet, Rpc } from '../../../helpers'; +export const protobufPackage = 'osmosis.tokenfactory.v1beta1'; +/** QueryParamsRequest is the request type for the Query/Params RPC method. */ +export interface QueryParamsRequest {} +/** QueryParamsResponse is the response type for the Query/Params RPC method. */ +export interface QueryParamsResponse { + /** params defines the parameters of the module. */ + params?: Params; +} +/** + * QueryDenomAuthorityMetadataRequest defines the request structure for the + * DenomAuthorityMetadata gRPC query. + */ +export interface QueryDenomAuthorityMetadataRequest { + denom: string; +} +/** + * QueryDenomAuthorityMetadataResponse defines the response structure for the + * DenomAuthorityMetadata gRPC query. + */ +export interface QueryDenomAuthorityMetadataResponse { + authorityMetadata?: DenomAuthorityMetadata; +} +/** + * QueryDenomsFromCreatorRequest defines the request structure for the + * DenomsFromCreator gRPC query. + */ +export interface QueryDenomsFromCreatorRequest { + creator: string; +} +/** + * QueryDenomsFromCreatorRequest defines the response structure for the + * DenomsFromCreator gRPC query. + */ +export interface QueryDenomsFromCreatorResponse { + denoms: string[]; +} +function createBaseQueryParamsRequest(): QueryParamsRequest { + return {}; +} +export const QueryParamsRequest = { + encode( + _: QueryParamsRequest, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): QueryParamsRequest { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryParamsRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(_: any): QueryParamsRequest { + return {}; + }, + toJSON(_: QueryParamsRequest): unknown { + const obj: any = {}; + return obj; + }, + fromPartial, I>>( + _: I, + ): QueryParamsRequest { + const message = createBaseQueryParamsRequest(); + return message; + }, +}; +function createBaseQueryParamsResponse(): QueryParamsResponse { + return { + params: undefined, + }; +} +export const QueryParamsResponse = { + encode( + message: QueryParamsResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.params !== undefined) { + Params.encode(message.params, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): QueryParamsResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryParamsResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.params = Params.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): QueryParamsResponse { + return { + params: isSet(object.params) ? Params.fromJSON(object.params) : undefined, + }; + }, + toJSON(message: QueryParamsResponse): unknown { + const obj: any = {}; + message.params !== undefined && + (obj.params = message.params ? Params.toJSON(message.params) : undefined); + return obj; + }, + fromPartial, I>>( + object: I, + ): QueryParamsResponse { + const message = createBaseQueryParamsResponse(); + message.params = + object.params !== undefined && object.params !== null + ? Params.fromPartial(object.params) + : undefined; + return message; + }, +}; +function createBaseQueryDenomAuthorityMetadataRequest(): QueryDenomAuthorityMetadataRequest { + return { + denom: '', + }; +} +export const QueryDenomAuthorityMetadataRequest = { + encode( + message: QueryDenomAuthorityMetadataRequest, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.denom !== '') { + writer.uint32(10).string(message.denom); + } + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): QueryDenomAuthorityMetadataRequest { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryDenomAuthorityMetadataRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.denom = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): QueryDenomAuthorityMetadataRequest { + return { + denom: isSet(object.denom) ? String(object.denom) : '', + }; + }, + toJSON(message: QueryDenomAuthorityMetadataRequest): unknown { + const obj: any = {}; + message.denom !== undefined && (obj.denom = message.denom); + return obj; + }, + fromPartial< + I extends Exact, I>, + >(object: I): QueryDenomAuthorityMetadataRequest { + const message = createBaseQueryDenomAuthorityMetadataRequest(); + message.denom = object.denom ?? ''; + return message; + }, +}; +function createBaseQueryDenomAuthorityMetadataResponse(): QueryDenomAuthorityMetadataResponse { + return { + authorityMetadata: undefined, + }; +} +export const QueryDenomAuthorityMetadataResponse = { + encode( + message: QueryDenomAuthorityMetadataResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.authorityMetadata !== undefined) { + DenomAuthorityMetadata.encode( + message.authorityMetadata, + writer.uint32(10).fork(), + ).ldelim(); + } + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): QueryDenomAuthorityMetadataResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryDenomAuthorityMetadataResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.authorityMetadata = DenomAuthorityMetadata.decode( + reader, + reader.uint32(), + ); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): QueryDenomAuthorityMetadataResponse { + return { + authorityMetadata: isSet(object.authorityMetadata) + ? DenomAuthorityMetadata.fromJSON(object.authorityMetadata) + : undefined, + }; + }, + toJSON(message: QueryDenomAuthorityMetadataResponse): unknown { + const obj: any = {}; + message.authorityMetadata !== undefined && + (obj.authorityMetadata = message.authorityMetadata + ? DenomAuthorityMetadata.toJSON(message.authorityMetadata) + : undefined); + return obj; + }, + fromPartial< + I extends Exact, I>, + >(object: I): QueryDenomAuthorityMetadataResponse { + const message = createBaseQueryDenomAuthorityMetadataResponse(); + message.authorityMetadata = + object.authorityMetadata !== undefined && + object.authorityMetadata !== null + ? DenomAuthorityMetadata.fromPartial(object.authorityMetadata) + : undefined; + return message; + }, +}; +function createBaseQueryDenomsFromCreatorRequest(): QueryDenomsFromCreatorRequest { + return { + creator: '', + }; +} +export const QueryDenomsFromCreatorRequest = { + encode( + message: QueryDenomsFromCreatorRequest, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.creator !== '') { + writer.uint32(10).string(message.creator); + } + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): QueryDenomsFromCreatorRequest { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryDenomsFromCreatorRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.creator = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): QueryDenomsFromCreatorRequest { + return { + creator: isSet(object.creator) ? String(object.creator) : '', + }; + }, + toJSON(message: QueryDenomsFromCreatorRequest): unknown { + const obj: any = {}; + message.creator !== undefined && (obj.creator = message.creator); + return obj; + }, + fromPartial, I>>( + object: I, + ): QueryDenomsFromCreatorRequest { + const message = createBaseQueryDenomsFromCreatorRequest(); + message.creator = object.creator ?? ''; + return message; + }, +}; +function createBaseQueryDenomsFromCreatorResponse(): QueryDenomsFromCreatorResponse { + return { + denoms: [], + }; +} +export const QueryDenomsFromCreatorResponse = { + encode( + message: QueryDenomsFromCreatorResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + for (const v of message.denoms) { + writer.uint32(10).string(v!); + } + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): QueryDenomsFromCreatorResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryDenomsFromCreatorResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.denoms.push(reader.string()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): QueryDenomsFromCreatorResponse { + return { + denoms: Array.isArray(object?.denoms) + ? object.denoms.map((e: any) => String(e)) + : [], + }; + }, + toJSON(message: QueryDenomsFromCreatorResponse): unknown { + const obj: any = {}; + if (message.denoms) { + obj.denoms = message.denoms.map((e) => e); + } else { + obj.denoms = []; + } + return obj; + }, + fromPartial, I>>( + object: I, + ): QueryDenomsFromCreatorResponse { + const message = createBaseQueryDenomsFromCreatorResponse(); + message.denoms = object.denoms?.map((e) => e) || []; + return message; + }, +}; +/** Query defines the gRPC querier service. */ +export interface Query { + /** + * Params defines a gRPC query method that returns the tokenfactory module's + * parameters. + */ + Params(request?: QueryParamsRequest): Promise; + /** + * DenomAuthorityMetadata defines a gRPC query method for fetching + * DenomAuthorityMetadata for a particular denom. + */ + DenomAuthorityMetadata( + request: QueryDenomAuthorityMetadataRequest, + ): Promise; + /** + * DenomsFromCreator defines a gRPC query method for fetching all + * denominations created by a specific admin/creator. + */ + DenomsFromCreator( + request: QueryDenomsFromCreatorRequest, + ): Promise; +} +export class QueryClientImpl implements Query { + private readonly rpc: Rpc; + constructor(rpc: Rpc) { + this.rpc = rpc; + this.Params = this.Params.bind(this); + this.DenomAuthorityMetadata = this.DenomAuthorityMetadata.bind(this); + this.DenomsFromCreator = this.DenomsFromCreator.bind(this); + } + Params(request: QueryParamsRequest = {}): Promise { + const data = QueryParamsRequest.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Query', + 'Params', + data, + ); + return promise.then((data) => + QueryParamsResponse.decode(new _m0.Reader(data)), + ); + } + DenomAuthorityMetadata( + request: QueryDenomAuthorityMetadataRequest, + ): Promise { + const data = QueryDenomAuthorityMetadataRequest.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Query', + 'DenomAuthorityMetadata', + data, + ); + return promise.then((data) => + QueryDenomAuthorityMetadataResponse.decode(new _m0.Reader(data)), + ); + } + DenomsFromCreator( + request: QueryDenomsFromCreatorRequest, + ): Promise { + const data = QueryDenomsFromCreatorRequest.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Query', + 'DenomsFromCreator', + data, + ); + return promise.then((data) => + QueryDenomsFromCreatorResponse.decode(new _m0.Reader(data)), + ); + } +} diff --git a/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/tx.ts b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/tx.ts new file mode 100644 index 000000000..a7d6fa541 --- /dev/null +++ b/wormhole-connect/src/utils/routes/cosmos/types/osmosis/tokenfactory/v1beta1/tx.ts @@ -0,0 +1,863 @@ +/* eslint-disable */ +import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin'; +import { Metadata } from 'cosmjs-types/cosmos/bank/v1beta1/bank'; +import * as _m0 from 'protobufjs/minimal'; +import { isSet, DeepPartial, Exact, Rpc } from '../../../helpers'; +export const protobufPackage = 'osmosis.tokenfactory.v1beta1'; +/** + * MsgCreateDenom defines the message structure for the CreateDenom gRPC service + * method. It allows an account to create a new denom. It requires a sender + * address and a sub denomination. The (sender_address, sub_denomination) tuple + * must be unique and cannot be re-used. + * + * The resulting denom created is defined as + * . The resulting denom's admin is + * originally set to be the creator, but this can be changed later. The token + * denom does not indicate the current admin. + */ +export interface MsgCreateDenom { + sender: string; + /** subdenom can be up to 44 "alphanumeric" characters long. */ + subdenom: string; +} +/** + * MsgCreateDenomResponse is the return value of MsgCreateDenom + * It returns the full string of the newly created denom + */ +export interface MsgCreateDenomResponse { + newTokenDenom: string; +} +/** + * MsgMint is the sdk.Msg type for allowing an admin account to mint + * more of a token. For now, we only support minting to the sender account + */ +export interface MsgMint { + sender: string; + amount?: Coin; + mintToAddress: string; +} +export interface MsgMintResponse {} +/** + * MsgBurn is the sdk.Msg type for allowing an admin account to burn + * a token. For now, we only support burning from the sender account. + */ +export interface MsgBurn { + sender: string; + amount?: Coin; + burnFromAddress: string; +} +export interface MsgBurnResponse {} +/** + * MsgChangeAdmin is the sdk.Msg type for allowing an admin account to reassign + * adminship of a denom to a new account + */ +export interface MsgChangeAdmin { + sender: string; + denom: string; + newAdmin: string; +} +/** + * MsgChangeAdminResponse defines the response structure for an executed + * MsgChangeAdmin message. + */ +export interface MsgChangeAdminResponse {} +/** + * MsgSetDenomMetadata is the sdk.Msg type for allowing an admin account to set + * the denom's bank metadata + */ +export interface MsgSetDenomMetadata { + sender: string; + metadata?: Metadata; +} +/** + * MsgSetDenomMetadataResponse defines the response structure for an executed + * MsgSetDenomMetadata message. + */ +export interface MsgSetDenomMetadataResponse {} +export interface MsgForceTransfer { + sender: string; + amount?: Coin; + transferFromAddress: string; + transferToAddress: string; +} +export interface MsgForceTransferResponse {} +function createBaseMsgCreateDenom(): MsgCreateDenom { + return { + sender: '', + subdenom: '', + }; +} +export const MsgCreateDenom = { + encode( + message: MsgCreateDenom, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.sender !== '') { + writer.uint32(10).string(message.sender); + } + if (message.subdenom !== '') { + writer.uint32(18).string(message.subdenom); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): MsgCreateDenom { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgCreateDenom(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.sender = reader.string(); + break; + case 2: + message.subdenom = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): MsgCreateDenom { + return { + sender: isSet(object.sender) ? String(object.sender) : '', + subdenom: isSet(object.subdenom) ? String(object.subdenom) : '', + }; + }, + toJSON(message: MsgCreateDenom): unknown { + const obj: any = {}; + message.sender !== undefined && (obj.sender = message.sender); + message.subdenom !== undefined && (obj.subdenom = message.subdenom); + return obj; + }, + fromPartial, I>>( + object: I, + ): MsgCreateDenom { + const message = createBaseMsgCreateDenom(); + message.sender = object.sender ?? ''; + message.subdenom = object.subdenom ?? ''; + return message; + }, +}; +function createBaseMsgCreateDenomResponse(): MsgCreateDenomResponse { + return { + newTokenDenom: '', + }; +} +export const MsgCreateDenomResponse = { + encode( + message: MsgCreateDenomResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.newTokenDenom !== '') { + writer.uint32(10).string(message.newTokenDenom); + } + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): MsgCreateDenomResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgCreateDenomResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.newTokenDenom = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): MsgCreateDenomResponse { + return { + newTokenDenom: isSet(object.newTokenDenom) + ? String(object.newTokenDenom) + : '', + }; + }, + toJSON(message: MsgCreateDenomResponse): unknown { + const obj: any = {}; + message.newTokenDenom !== undefined && + (obj.newTokenDenom = message.newTokenDenom); + return obj; + }, + fromPartial, I>>( + object: I, + ): MsgCreateDenomResponse { + const message = createBaseMsgCreateDenomResponse(); + message.newTokenDenom = object.newTokenDenom ?? ''; + return message; + }, +}; +function createBaseMsgMint(): MsgMint { + return { + sender: '', + amount: undefined, + mintToAddress: '', + }; +} +export const MsgMint = { + encode( + message: MsgMint, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.sender !== '') { + writer.uint32(10).string(message.sender); + } + if (message.amount !== undefined) { + Coin.encode(message.amount, writer.uint32(18).fork()).ldelim(); + } + if (message.mintToAddress !== '') { + writer.uint32(26).string(message.mintToAddress); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): MsgMint { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgMint(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.sender = reader.string(); + break; + case 2: + message.amount = Coin.decode(reader, reader.uint32()); + break; + case 3: + message.mintToAddress = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): MsgMint { + return { + sender: isSet(object.sender) ? String(object.sender) : '', + amount: isSet(object.amount) ? Coin.fromJSON(object.amount) : undefined, + mintToAddress: isSet(object.mintToAddress) + ? String(object.mintToAddress) + : '', + }; + }, + toJSON(message: MsgMint): unknown { + const obj: any = {}; + message.sender !== undefined && (obj.sender = message.sender); + message.amount !== undefined && + (obj.amount = message.amount ? Coin.toJSON(message.amount) : undefined); + message.mintToAddress !== undefined && + (obj.mintToAddress = message.mintToAddress); + return obj; + }, + fromPartial, I>>(object: I): MsgMint { + const message = createBaseMsgMint(); + message.sender = object.sender ?? ''; + message.amount = + object.amount !== undefined && object.amount !== null + ? Coin.fromPartial(object.amount) + : undefined; + message.mintToAddress = object.mintToAddress ?? ''; + return message; + }, +}; +function createBaseMsgMintResponse(): MsgMintResponse { + return {}; +} +export const MsgMintResponse = { + encode( + _: MsgMintResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): MsgMintResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgMintResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(_: any): MsgMintResponse { + return {}; + }, + toJSON(_: MsgMintResponse): unknown { + const obj: any = {}; + return obj; + }, + fromPartial, I>>( + _: I, + ): MsgMintResponse { + const message = createBaseMsgMintResponse(); + return message; + }, +}; +function createBaseMsgBurn(): MsgBurn { + return { + sender: '', + amount: undefined, + burnFromAddress: '', + }; +} +export const MsgBurn = { + encode( + message: MsgBurn, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.sender !== '') { + writer.uint32(10).string(message.sender); + } + if (message.amount !== undefined) { + Coin.encode(message.amount, writer.uint32(18).fork()).ldelim(); + } + if (message.burnFromAddress !== '') { + writer.uint32(26).string(message.burnFromAddress); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): MsgBurn { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgBurn(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.sender = reader.string(); + break; + case 2: + message.amount = Coin.decode(reader, reader.uint32()); + break; + case 3: + message.burnFromAddress = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): MsgBurn { + return { + sender: isSet(object.sender) ? String(object.sender) : '', + amount: isSet(object.amount) ? Coin.fromJSON(object.amount) : undefined, + burnFromAddress: isSet(object.burnFromAddress) + ? String(object.burnFromAddress) + : '', + }; + }, + toJSON(message: MsgBurn): unknown { + const obj: any = {}; + message.sender !== undefined && (obj.sender = message.sender); + message.amount !== undefined && + (obj.amount = message.amount ? Coin.toJSON(message.amount) : undefined); + message.burnFromAddress !== undefined && + (obj.burnFromAddress = message.burnFromAddress); + return obj; + }, + fromPartial, I>>(object: I): MsgBurn { + const message = createBaseMsgBurn(); + message.sender = object.sender ?? ''; + message.amount = + object.amount !== undefined && object.amount !== null + ? Coin.fromPartial(object.amount) + : undefined; + message.burnFromAddress = object.burnFromAddress ?? ''; + return message; + }, +}; +function createBaseMsgBurnResponse(): MsgBurnResponse { + return {}; +} +export const MsgBurnResponse = { + encode( + _: MsgBurnResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): MsgBurnResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgBurnResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(_: any): MsgBurnResponse { + return {}; + }, + toJSON(_: MsgBurnResponse): unknown { + const obj: any = {}; + return obj; + }, + fromPartial, I>>( + _: I, + ): MsgBurnResponse { + const message = createBaseMsgBurnResponse(); + return message; + }, +}; +function createBaseMsgChangeAdmin(): MsgChangeAdmin { + return { + sender: '', + denom: '', + newAdmin: '', + }; +} +export const MsgChangeAdmin = { + encode( + message: MsgChangeAdmin, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.sender !== '') { + writer.uint32(10).string(message.sender); + } + if (message.denom !== '') { + writer.uint32(18).string(message.denom); + } + if (message.newAdmin !== '') { + writer.uint32(26).string(message.newAdmin); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): MsgChangeAdmin { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgChangeAdmin(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.sender = reader.string(); + break; + case 2: + message.denom = reader.string(); + break; + case 3: + message.newAdmin = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): MsgChangeAdmin { + return { + sender: isSet(object.sender) ? String(object.sender) : '', + denom: isSet(object.denom) ? String(object.denom) : '', + newAdmin: isSet(object.newAdmin) ? String(object.newAdmin) : '', + }; + }, + toJSON(message: MsgChangeAdmin): unknown { + const obj: any = {}; + message.sender !== undefined && (obj.sender = message.sender); + message.denom !== undefined && (obj.denom = message.denom); + message.newAdmin !== undefined && (obj.newAdmin = message.newAdmin); + return obj; + }, + fromPartial, I>>( + object: I, + ): MsgChangeAdmin { + const message = createBaseMsgChangeAdmin(); + message.sender = object.sender ?? ''; + message.denom = object.denom ?? ''; + message.newAdmin = object.newAdmin ?? ''; + return message; + }, +}; +function createBaseMsgChangeAdminResponse(): MsgChangeAdminResponse { + return {}; +} +export const MsgChangeAdminResponse = { + encode( + _: MsgChangeAdminResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): MsgChangeAdminResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgChangeAdminResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(_: any): MsgChangeAdminResponse { + return {}; + }, + toJSON(_: MsgChangeAdminResponse): unknown { + const obj: any = {}; + return obj; + }, + fromPartial, I>>( + _: I, + ): MsgChangeAdminResponse { + const message = createBaseMsgChangeAdminResponse(); + return message; + }, +}; +function createBaseMsgSetDenomMetadata(): MsgSetDenomMetadata { + return { + sender: '', + metadata: undefined, + }; +} +export const MsgSetDenomMetadata = { + encode( + message: MsgSetDenomMetadata, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.sender !== '') { + writer.uint32(10).string(message.sender); + } + if (message.metadata !== undefined) { + Metadata.encode(message.metadata, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): MsgSetDenomMetadata { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgSetDenomMetadata(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.sender = reader.string(); + break; + case 2: + message.metadata = Metadata.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): MsgSetDenomMetadata { + return { + sender: isSet(object.sender) ? String(object.sender) : '', + metadata: isSet(object.metadata) + ? Metadata.fromJSON(object.metadata) + : undefined, + }; + }, + toJSON(message: MsgSetDenomMetadata): unknown { + const obj: any = {}; + message.sender !== undefined && (obj.sender = message.sender); + message.metadata !== undefined && + (obj.metadata = message.metadata + ? Metadata.toJSON(message.metadata) + : undefined); + return obj; + }, + fromPartial, I>>( + object: I, + ): MsgSetDenomMetadata { + const message = createBaseMsgSetDenomMetadata(); + message.sender = object.sender ?? ''; + message.metadata = + object.metadata !== undefined && object.metadata !== null + ? Metadata.fromPartial(object.metadata) + : undefined; + return message; + }, +}; +function createBaseMsgSetDenomMetadataResponse(): MsgSetDenomMetadataResponse { + return {}; +} +export const MsgSetDenomMetadataResponse = { + encode( + _: MsgSetDenomMetadataResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): MsgSetDenomMetadataResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgSetDenomMetadataResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(_: any): MsgSetDenomMetadataResponse { + return {}; + }, + toJSON(_: MsgSetDenomMetadataResponse): unknown { + const obj: any = {}; + return obj; + }, + fromPartial, I>>( + _: I, + ): MsgSetDenomMetadataResponse { + const message = createBaseMsgSetDenomMetadataResponse(); + return message; + }, +}; +function createBaseMsgForceTransfer(): MsgForceTransfer { + return { + sender: '', + amount: undefined, + transferFromAddress: '', + transferToAddress: '', + }; +} +export const MsgForceTransfer = { + encode( + message: MsgForceTransfer, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.sender !== '') { + writer.uint32(10).string(message.sender); + } + if (message.amount !== undefined) { + Coin.encode(message.amount, writer.uint32(18).fork()).ldelim(); + } + if (message.transferFromAddress !== '') { + writer.uint32(26).string(message.transferFromAddress); + } + if (message.transferToAddress !== '') { + writer.uint32(34).string(message.transferToAddress); + } + return writer; + }, + decode(input: _m0.Reader | Uint8Array, length?: number): MsgForceTransfer { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgForceTransfer(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.sender = reader.string(); + break; + case 2: + message.amount = Coin.decode(reader, reader.uint32()); + break; + case 3: + message.transferFromAddress = reader.string(); + break; + case 4: + message.transferToAddress = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(object: any): MsgForceTransfer { + return { + sender: isSet(object.sender) ? String(object.sender) : '', + amount: isSet(object.amount) ? Coin.fromJSON(object.amount) : undefined, + transferFromAddress: isSet(object.transferFromAddress) + ? String(object.transferFromAddress) + : '', + transferToAddress: isSet(object.transferToAddress) + ? String(object.transferToAddress) + : '', + }; + }, + toJSON(message: MsgForceTransfer): unknown { + const obj: any = {}; + message.sender !== undefined && (obj.sender = message.sender); + message.amount !== undefined && + (obj.amount = message.amount ? Coin.toJSON(message.amount) : undefined); + message.transferFromAddress !== undefined && + (obj.transferFromAddress = message.transferFromAddress); + message.transferToAddress !== undefined && + (obj.transferToAddress = message.transferToAddress); + return obj; + }, + fromPartial, I>>( + object: I, + ): MsgForceTransfer { + const message = createBaseMsgForceTransfer(); + message.sender = object.sender ?? ''; + message.amount = + object.amount !== undefined && object.amount !== null + ? Coin.fromPartial(object.amount) + : undefined; + message.transferFromAddress = object.transferFromAddress ?? ''; + message.transferToAddress = object.transferToAddress ?? ''; + return message; + }, +}; +function createBaseMsgForceTransferResponse(): MsgForceTransferResponse { + return {}; +} +export const MsgForceTransferResponse = { + encode( + _: MsgForceTransferResponse, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + return writer; + }, + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): MsgForceTransferResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgForceTransferResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + fromJSON(_: any): MsgForceTransferResponse { + return {}; + }, + toJSON(_: MsgForceTransferResponse): unknown { + const obj: any = {}; + return obj; + }, + fromPartial, I>>( + _: I, + ): MsgForceTransferResponse { + const message = createBaseMsgForceTransferResponse(); + return message; + }, +}; +/** Msg defines the tokefactory module's gRPC message service. */ +export interface Msg { + CreateDenom(request: MsgCreateDenom): Promise; + Mint(request: MsgMint): Promise; + Burn(request: MsgBurn): Promise; + ChangeAdmin(request: MsgChangeAdmin): Promise; + SetDenomMetadata( + request: MsgSetDenomMetadata, + ): Promise; + ForceTransfer(request: MsgForceTransfer): Promise; +} +export class MsgClientImpl implements Msg { + private readonly rpc: Rpc; + constructor(rpc: Rpc) { + this.rpc = rpc; + this.CreateDenom = this.CreateDenom.bind(this); + this.Mint = this.Mint.bind(this); + this.Burn = this.Burn.bind(this); + this.ChangeAdmin = this.ChangeAdmin.bind(this); + this.SetDenomMetadata = this.SetDenomMetadata.bind(this); + this.ForceTransfer = this.ForceTransfer.bind(this); + } + CreateDenom(request: MsgCreateDenom): Promise { + const data = MsgCreateDenom.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Msg', + 'CreateDenom', + data, + ); + return promise.then((data) => + MsgCreateDenomResponse.decode(new _m0.Reader(data)), + ); + } + Mint(request: MsgMint): Promise { + const data = MsgMint.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Msg', + 'Mint', + data, + ); + return promise.then((data) => MsgMintResponse.decode(new _m0.Reader(data))); + } + Burn(request: MsgBurn): Promise { + const data = MsgBurn.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Msg', + 'Burn', + data, + ); + return promise.then((data) => MsgBurnResponse.decode(new _m0.Reader(data))); + } + ChangeAdmin(request: MsgChangeAdmin): Promise { + const data = MsgChangeAdmin.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Msg', + 'ChangeAdmin', + data, + ); + return promise.then((data) => + MsgChangeAdminResponse.decode(new _m0.Reader(data)), + ); + } + SetDenomMetadata( + request: MsgSetDenomMetadata, + ): Promise { + const data = MsgSetDenomMetadata.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Msg', + 'SetDenomMetadata', + data, + ); + return promise.then((data) => + MsgSetDenomMetadataResponse.decode(new _m0.Reader(data)), + ); + } + ForceTransfer(request: MsgForceTransfer): Promise { + const data = MsgForceTransfer.encode(request).finish(); + const promise = this.rpc.request( + 'osmosis.tokenfactory.v1beta1.Msg', + 'ForceTransfer', + data, + ); + return promise.then((data) => + MsgForceTransferResponse.decode(new _m0.Reader(data)), + ); + } +} diff --git a/wormhole-connect/src/utils/routes/index.ts b/wormhole-connect/src/utils/routes/index.ts index 0fe5c572c..6553b14bd 100644 --- a/wormhole-connect/src/utils/routes/index.ts +++ b/wormhole-connect/src/utils/routes/index.ts @@ -7,4 +7,4 @@ export * from './relay'; export * from './hashflow'; export * from './types'; export * from './utils'; -export * from './cosmosGateway'; +export * from './cosmos/cosmosGateway'; diff --git a/wormhole-connect/src/utils/routes/operator.ts b/wormhole-connect/src/utils/routes/operator.ts index 2d2d2151a..14e488e9d 100644 --- a/wormhole-connect/src/utils/routes/operator.ts +++ b/wormhole-connect/src/utils/routes/operator.ts @@ -11,7 +11,7 @@ import { BridgeRoute } from './bridge'; import { RelayRoute } from './relay'; import { HashflowRoute } from './hashflow'; import { CCTPRelayRoute } from './cctpRelay'; -import { CosmosGatewayRoute } from './cosmosGateway'; +import { CosmosGatewayRoute } from './cosmos/cosmosGateway'; import { ParsedMessage, PayloadType, getMessage, wh } from '../sdk'; import { isCosmWasmChain } from '../cosmos'; import RouteAbstract from './routeAbstract';