diff --git a/move/interchain_token_service/sources/interchain_token_service.move b/move/interchain_token_service/sources/interchain_token_service.move index efa73f95..a2b9b627 100644 --- a/move/interchain_token_service/sources/interchain_token_service.move +++ b/move/interchain_token_service/sources/interchain_token_service.move @@ -7,6 +7,7 @@ use interchain_token_service::coin_management::CoinManagement; use interchain_token_service::interchain_transfer_ticket::{Self, InterchainTransferTicket}; use interchain_token_service::interchain_token_service_v0::{Self, InterchainTokenService_v0}; use interchain_token_service::owner_cap::{Self, OwnerCap}; +use interchain_token_service::creator_cap::{Self, CreatorCap}; use interchain_token_service::operator_cap::{Self, OperatorCap}; use interchain_token_service::token_id::TokenId; use interchain_token_service::trusted_addresses::TrustedAddresses; @@ -37,10 +38,28 @@ public struct InterchainTokenService has key { // Setup // ----- fun init(ctx: &mut TxContext) { + transfer::public_transfer( + owner_cap::create(ctx), + ctx.sender(), + ); + + transfer::public_transfer( + operator_cap::create(ctx), + ctx.sender(), + ); + + transfer::public_transfer( + creator_cap::create(ctx), + ctx.sender(), + ); +} + +public fun setup(creator_cap: CreatorCap, chain_name: String, ctx: &mut TxContext) { let inner = versioned::create( DATA_VERSION, interchain_token_service_v0::new( version_control(), + chain_name, ctx, ), ctx, @@ -52,15 +71,7 @@ fun init(ctx: &mut TxContext) { inner, }); - transfer::public_transfer( - owner_cap::create(ctx), - ctx.sender(), - ); - - transfer::public_transfer( - operator_cap::create(ctx), - ctx.sender(), - ); + creator_cap.destroy(); } // ------ @@ -412,6 +423,7 @@ public fun create_for_testing(ctx: &mut TxContext): InterchainTokenService { let mut value = interchain_token_service_v0::new( version_control, + b"chain name".to_ascii_string(), ctx, ); value.set_trusted_address( @@ -976,8 +988,26 @@ fun test_init() { ts.next_tx(@0x0); let owner_cap = ts.take_from_sender(); - let its = ts.take_shared(); + let operator_cap = ts.take_from_sender(); + ts.return_to_sender(owner_cap); + ts.return_to_sender(operator_cap); + ts.end(); +} + +#[test] +fun test_setup() { + let mut ts = sui::test_scenario::begin(@0x0); + let creator_cap = creator_cap::create(ts.ctx()); + let chain_name = b"chain name".to_ascii_string(); + + setup(creator_cap, chain_name, ts.ctx()); + ts.next_tx(@0x0); + + let its = ts.take_shared(); + let chain_name_hash = axelar_gateway::bytes32::from_bytes(sui::hash::keccak256(&chain_name.into_bytes())); + assert!(its.value!(b"send_interchain_transfer").chain_name_hash() == chain_name_hash); + sui::test_scenario::return_shared(its); ts.end(); } diff --git a/move/interchain_token_service/sources/types/creator_cap.move b/move/interchain_token_service/sources/types/creator_cap.move new file mode 100644 index 00000000..84e372bb --- /dev/null +++ b/move/interchain_token_service/sources/types/creator_cap.move @@ -0,0 +1,19 @@ +module interchain_token_service::creator_cap; + +// ----- +// Types +// ----- +public struct CreatorCap has key, store { + id: UID, +} + +public(package) fun create(ctx: &mut TxContext): CreatorCap { + CreatorCap { + id: object::new(ctx), + } +} + +public(package) fun destroy(self: CreatorCap) { + let CreatorCap { id } = self; + id.delete(); +} diff --git a/move/interchain_token_service/sources/types/token_id.move b/move/interchain_token_service/sources/types/token_id.move index f2aba8a7..c51285e9 100644 --- a/move/interchain_token_service/sources/types/token_id.move +++ b/move/interchain_token_service/sources/types/token_id.move @@ -1,5 +1,6 @@ module interchain_token_service::token_id; +use axelar_gateway::bytes32::Bytes32; use interchain_token_service::coin_info::CoinInfo; use interchain_token_service::coin_management::CoinManagement; use std::ascii; @@ -34,6 +35,7 @@ public fun to_u256(token_id: &TokenId): u256 { } public fun from_info( + chain_name_hash: &Bytes32, name: &String, symbol: &ascii::String, decimals: &u8, @@ -41,6 +43,7 @@ public fun from_info( has_treasury: &bool, ): TokenId { let mut vec = address::from_u256(PREFIX_SUI_TOKEN_ID).to_bytes(); + vec.append(bcs::to_bytes(chain_name_hash)); vec.append(bcs::to_bytes(&type_name::get())); vec.append(bcs::to_bytes(name)); vec.append(bcs::to_bytes(symbol)); @@ -51,10 +54,12 @@ public fun from_info( } public(package) fun from_coin_data( + chain_name_hash: &Bytes32, coin_info: &CoinInfo, coin_management: &CoinManagement, ): TokenId { from_info( + chain_name_hash, &coin_info.name(), &coin_info.symbol(), &coin_info.decimals(), diff --git a/move/interchain_token_service/sources/versioned/interchain_token_service_v0.move b/move/interchain_token_service/sources/versioned/interchain_token_service_v0.move index 96581440..4240d61b 100644 --- a/move/interchain_token_service/sources/versioned/interchain_token_service_v0.move +++ b/move/interchain_token_service/sources/versioned/interchain_token_service_v0.move @@ -1,6 +1,7 @@ module interchain_token_service::interchain_token_service_v0; use abi::abi::{Self, AbiReader}; +use axelar_gateway::bytes32::{Self, Bytes32}; use axelar_gateway::channel::{Channel, ApprovedMessage}; use axelar_gateway::gateway; use axelar_gateway::message_ticket::MessageTicket; @@ -22,6 +23,7 @@ use sui::address; use sui::bag::{Self, Bag}; use sui::clock::Clock; use sui::coin::{Self, TreasuryCap, CoinMetadata, Coin}; +use sui::hash::keccak256; use sui::table::{Self, Table}; use version_control::version_control::VersionControl; @@ -29,14 +31,11 @@ use version_control::version_control::VersionControl; // Errors // ------ #[error] -const EUnregisteredCoin: vector = - b"trying to find a coin that doesn't exist"; +const EUnregisteredCoin: vector = b"trying to find a coin that doesn't exist"; #[error] -const EUntrustedAddress: vector = - b"the sender that sent this message is not trusted"; +const EUntrustedAddress: vector = b"the sender that sent this message is not trusted"; #[error] -const EInvalidMessageType: vector = - b"the message type received is not supported"; +const EInvalidMessageType: vector = b"the message type received is not supported"; #[error] const EWrongDestination: vector = b"the channel trying to receive this call is not the destination"; @@ -47,8 +46,7 @@ const EInterchainTransferHasData: vector = const EInterchainTransferHasNoData: vector = b"interchain transfer trying to be proccessed as an interchain transfer"; #[error] -const EModuleNameDoesNotMatchSymbol: vector = - b"the module name does not match the symbol"; +const EModuleNameDoesNotMatchSymbol: vector = b"the module name does not match the symbol"; #[error] const ENotDistributor: vector = b"only the distributor can mint"; #[error] @@ -90,6 +88,7 @@ public struct InterchainTokenService_v0 has store { registered_coin_types: Table, registered_coins: Bag, relayer_discovery_id: ID, + chain_name_hash: Bytes32, version_control: VersionControl, } @@ -98,6 +97,7 @@ public struct InterchainTokenService_v0 has store { // ----------------- public(package) fun new( version_control: VersionControl, + chain_name: String, ctx: &mut TxContext, ): InterchainTokenService_v0 { InterchainTokenService_v0 { @@ -109,6 +109,7 @@ public(package) fun new( registered_coin_types: table::new(ctx), unregistered_coins: bag::new(ctx), unregistered_coin_types: table::new(ctx), + chain_name_hash: bytes32::from_bytes(keccak256(&chain_name.into_bytes())), relayer_discovery_id: object::id_from_address(@0x0), version_control, } @@ -202,7 +203,7 @@ public(package) fun register_coin( coin_info: CoinInfo, coin_management: CoinManagement, ): TokenId { - let token_id = token_id::from_coin_data(&coin_info, &coin_management); + let token_id = token_id::from_coin_data(&self.chain_name_hash, &coin_info, &coin_management); self.add_registered_coin(token_id, coin_management, coin_info); @@ -258,9 +259,7 @@ public(package) fun send_interchain_transfer( ) = ticket.destroy(); assert!(version <= current_version, ENewerTicket); - let amount = self - .coin_management_mut(token_id) - .take_balance(balance, clock); + let amount = self.coin_management_mut(token_id).take_balance(balance, clock); let (_version, data) = its_utils::decode_metadata(metadata); let mut writer = abi::new_writer(6); @@ -294,10 +293,7 @@ public(package) fun receive_interchain_transfer( approved_message, ); let mut reader = abi::new_reader(payload); - assert!( - reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER, - EInvalidMessageType, - ); + assert!(reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER, EInvalidMessageType); let token_id = token_id::from_u256(reader.read_u256()); let source_address = reader.read_bytes(); @@ -307,9 +303,7 @@ public(package) fun receive_interchain_transfer( assert!(data.is_empty(), EInterchainTransferHasData); - let coin = self - .coin_management_mut(token_id) - .give_coin(amount, clock, ctx); + let coin = self.coin_management_mut(token_id).give_coin(amount, clock, ctx); transfer::public_transfer(coin, destination_address); @@ -335,10 +329,7 @@ public(package) fun receive_interchain_transfer_with_data( approved_message, ); let mut reader = abi::new_reader(payload); - assert!( - reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER, - EInvalidMessageType, - ); + assert!(reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER, EInvalidMessageType); let token_id = token_id::from_u256(reader.read_u256()); @@ -371,10 +362,7 @@ public(package) fun receive_deploy_interchain_token( ) { let (_, payload, _) = self.decode_approved_message(approved_message); let mut reader = abi::new_reader(payload); - assert!( - reader.read_u256() == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, - EInvalidMessageType, - ); + assert!(reader.read_u256() == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, EInvalidMessageType); let token_id = token_id::from_u256(reader.read_u256()); let name = string::utf8(reader.read_bytes()); @@ -404,10 +392,7 @@ public(package) fun give_unregistered_coin( mut coin_metadata: CoinMetadata, ) { assert!(treasury_cap.total_supply() == 0, ENonZeroTotalSupply); - assert!( - coin::get_icon_url(&coin_metadata).is_none(), - EUnregisteredCoinHasUrl, - ); + assert!(coin::get_icon_url(&coin_metadata).is_none(), EUnregisteredCoinHasUrl); treasury_cap.update_description(&mut coin_metadata, string::utf8(b"")); @@ -415,10 +400,7 @@ public(package) fun give_unregistered_coin( let symbol = coin_metadata.get_symbol(); let module_name = type_name::get_module(&type_name::get()); - assert!( - &module_name == &its_utils::module_from_symbol(&symbol), - EModuleNameDoesNotMatchSymbol, - ); + assert!(&module_name == &its_utils::module_from_symbol(&symbol), EModuleNameDoesNotMatchSymbol); let token_id = token_id::unregistered_token_id(&symbol, decimals); @@ -565,9 +547,7 @@ fun remove_unregistered_coin( self: &mut InterchainTokenService_v0, token_id: UnregisteredTokenId, ): (TreasuryCap, CoinMetadata) { - let unregistered_coins: UnregisteredCoinData = self - .unregistered_coins - .remove(token_id); + let unregistered_coins: UnregisteredCoinData = self.unregistered_coins.remove(token_id); let (treasury_cap, coin_metadata) = unregistered_coins.destroy(); remove_unregistered_coin_type(self, token_id); @@ -637,10 +617,7 @@ fun prepare_message( // Prevent sending directly to the InterchainTokenService Hub chain. This is not supported yet, // so fail early to prevent the user from having their funds stuck. - assert!( - destination_chain.into_bytes() != ITS_HUB_CHAIN_NAME, - EUntrustedChain, - ); + assert!(destination_chain.into_bytes() != ITS_HUB_CHAIN_NAME, EUntrustedChain); // Check whether the InterchainTokenService call should be routed via InterchainTokenService hub for this // destination chain @@ -671,17 +648,11 @@ fun decode_approved_message( .channel .consume_approved_message(approved_message); - assert!( - self.is_trusted_address(source_chain, source_address), - EUntrustedAddress, - ); + assert!(self.is_trusted_address(source_chain, source_address), EUntrustedAddress); let mut reader = abi::new_reader(payload); if (reader.read_u256() == MESSAGE_TYPE_RECEIVE_FROM_HUB) { - assert!( - source_chain.into_bytes() == ITS_HUB_CHAIN_NAME, - EUntrustedChain, - ); + assert!(source_chain.into_bytes() == ITS_HUB_CHAIN_NAME, EUntrustedChain); source_chain = ascii::string(reader.read_bytes()); payload = reader.read_bytes(); @@ -691,10 +662,7 @@ fun decode_approved_message( EUntrustedChain, ); } else { - assert!( - source_chain.into_bytes() != ITS_HUB_CHAIN_NAME, - EUntrustedChain, - ); + assert!(source_chain.into_bytes() != ITS_HUB_CHAIN_NAME, EUntrustedChain); }; (source_chain, payload, message_id) @@ -716,7 +684,11 @@ use interchain_token_service::coin::COIN; #[test_only] fun create_for_testing(ctx: &mut TxContext): InterchainTokenService_v0 { - let mut self = new(version_control::version_control::new(vector[]), ctx); + let mut self = new( + version_control::version_control::new(vector[]), + b"chain name".to_ascii_string(), + ctx, + ); self.set_trusted_address( std::ascii::string(b"Chain Name"), @@ -733,7 +705,10 @@ public fun create_unregistered_coin( decimals: u8, ctx: &mut TxContext, ) { - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -788,6 +763,13 @@ public(package) fun trusted_address_for_testing( *self.address_tracker.trusted_address(chain_name) } +#[test_only] +public(package) fun chain_name_hash( + self: &InterchainTokenService_v0, +): Bytes32 { + self.chain_name_hash +} + // ----- // Tests // ----- @@ -968,9 +950,7 @@ fun test_prepare_message_to_hub() { let message_ticket = self.prepare_message(destination_chain, payload); - assert!( - message_ticket.destination_chain() == ascii::string(ITS_HUB_CHAIN_NAME), - ); + assert!(message_ticket.destination_chain() == ascii::string(ITS_HUB_CHAIN_NAME)); assert!(message_ticket.destination_address() == hub_address); sui::test_utils::destroy(self); @@ -992,9 +972,7 @@ fun test_prepare_message_to_hub_direct() { let message_ticket = self.prepare_message(destination_chain, payload); - assert!( - message_ticket.destination_chain() == ascii::string(ITS_HUB_CHAIN_NAME), - ); + assert!(message_ticket.destination_chain() == ascii::string(ITS_HUB_CHAIN_NAME)); assert!(message_ticket.destination_address() == hub_address); sui::test_utils::destroy(self); @@ -1142,9 +1120,7 @@ fun test_receive_interchain_transfer_with_data_invalid_message_type() { payload, ); - let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data< - COIN, - >( + let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data( approved_message, &channel, &clock, @@ -1201,9 +1177,7 @@ fun test_receive_interchain_transfer_with_data_wrong_destination() { payload, ); - let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data< - COIN, - >( + let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data( approved_message, &channel, &clock, @@ -1260,9 +1234,7 @@ fun test_receive_interchain_transfer_with_data_no_data() { payload, ); - let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data< - COIN, - >( + let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data( approved_message, &channel, &clock, @@ -1440,7 +1412,10 @@ fun test_give_unregistered_coin_module_name_missmatch() { let ctx = &mut tx_context::dummy(); let mut self = create_for_testing(ctx); - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -1459,7 +1434,10 @@ fun test_mint_as_distributor_not_distributor() { let symbol = b"COIN"; let decimals = 9; - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -1508,7 +1486,10 @@ fun test_mint_to_as_distributor_not_distributor() { let symbol = b"COIN"; let decimals = 9; - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -1589,7 +1570,9 @@ fun test_send_interchain_transfer_newer_ticket() { let current_version = 0; let invalid_version = 1; - let interchain_transfer_ticket = interchain_token_service::interchain_transfer_ticket::new( + let interchain_transfer_ticket = interchain_token_service::interchain_transfer_ticket::new< + COIN, + >( token_id, coin.into_balance(), source_channel.to_address(), diff --git a/package.json b/package.json index def60a32..7c71b48e 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "test-move": "./scripts/run.sh test", "test-js": "npx mocha", "test": "npm run test-move && npm run test-js", + "update-interfaces": "GOLDEN_TESTS=true npx mocha test/packages.js", "coverage": "./scripts/coverage.sh", "release": "npm run build && changeset publish", "release-snapshot": "npm run build && npm version 0.0.0-snapshot.$(git rev-parse --short HEAD) --git-tag-version=false && npm publish --no-git-checks --tag snapshot --access public", diff --git a/test/its.js b/test/its.js index 3073ac33..add291ff 100644 --- a/test/its.js +++ b/test/its.js @@ -56,6 +56,7 @@ describe('ITS', () => { const nonce = 0; // Parameters for Trusted Addresses + const chainName = 'Chain Name'; const trustedSourceChain = 'Avalanche'; const trustedSourceAddress = hexlify(randomBytes(20)); @@ -89,6 +90,20 @@ describe('ITS', () => { discoveryInfo.discovery = objectIds.relayerDiscovery; } + async function setupIts() { + const itsSetupTxBuilder = new TxBuilder(client); + + await itsSetupTxBuilder.moveCall({ + target: `${deployments.interchain_token_service.packageId}::interchain_token_service::setup`, + arguments: [objectIds.itsCreatorCap, chainName], + }); + + const itsSetupReceipt = await itsSetupTxBuilder.signAndExecute(deployer); + + objectIds.its = findObjectId(itsSetupReceipt, 'interchain_token_service::InterchainTokenService'); + objectIds.itsV0 = findObjectId(itsSetupReceipt, 'interchain_token_service_v0::InterchainTokenService_v0'); + } + async function registerItsTransaction() { const registerTransactionBuilder = new TxBuilder(client); @@ -119,8 +134,6 @@ describe('ITS', () => { singleton: findObjectId(deployments.example.publishTxn, 'its::Singleton'), tokenTreasuryCap: findObjectId(deployments.example.publishTxn, `TreasuryCap<${coinType}>`), tokenCoinMetadata: findObjectId(deployments.example.publishTxn, `CoinMetadata<${coinType}>`), - its: findObjectId(deployments.interchain_token_service.publishTxn, 'interchain_token_service::InterchainTokenService'), - itsV0: findObjectId(deployments.interchain_token_service.publishTxn, 'interchain_token_service_v0::InterchainTokenService_v0'), relayerDiscovery: findObjectId( deployments.relayer_discovery.publishTxn, `${deployments.relayer_discovery.packageId}::discovery::RelayerDiscovery`, @@ -131,6 +144,10 @@ describe('ITS', () => { deployments.interchain_token_service.publishTxn, `${deployments.interchain_token_service.packageId}::owner_cap::OwnerCap`, ), + itsCreatorCap: findObjectId( + deployments.interchain_token_service.publishTxn, + `${deployments.interchain_token_service.packageId}::creator_cap::CreatorCap`, + ), }; // Mint some coins for tests const tokenTxBuilder = new TxBuilder(client); @@ -142,6 +159,8 @@ describe('ITS', () => { const mintReceipt = await tokenTxBuilder.signAndExecute(deployer); + await setupIts(); + // Find the object ids from the publish transactions objectIds = { ...objectIds, diff --git a/test/squid.js b/test/squid.js index 562e1749..c67961f2 100644 --- a/test/squid.js +++ b/test/squid.js @@ -51,6 +51,7 @@ describe('Squid', () => { const nonce = 0; // Parameters for Trusted Addresses + const chainName = 'Chain Name'; const trustedSourceChain = 'Avalanche'; const trustedSourceAddress = hexlify(randomBytes(20)); const coins = {}; @@ -88,6 +89,20 @@ describe('Squid', () => { gatewayInfo.discovery = objectIds.relayerDiscovery; } + async function setupIts() { + const itsSetupTxBuilder = new TxBuilder(client); + + await itsSetupTxBuilder.moveCall({ + target: `${deployments.interchain_token_service.packageId}::interchain_token_service::setup`, + arguments: [objectIds.itsCreatorCap, chainName], + }); + + const itsSetupReceipt = await itsSetupTxBuilder.signAndExecute(deployer); + + objectIds.its = findObjectId(itsSetupReceipt, 'interchain_token_service::InterchainTokenService'); + objectIds.itsV0 = findObjectId(itsSetupReceipt, 'interchain_token_service_v0::InterchainTokenService_v0'); + } + // Registers the ITS in relayer discovery async function registerItsTransaction() { const registerTransactionBuilder = new TxBuilder(client); @@ -385,8 +400,6 @@ describe('Squid', () => { ...objectIds, squid: findObjectId(deployments.squid.publishTxn, 'squid::Squid'), squidV0: findObjectId(deployments.squid.publishTxn, 'squid_v0::Squid_v0'), - its: findObjectId(deployments.interchain_token_service.publishTxn, 'interchain_token_service::InterchainTokenService'), - itsV0: findObjectId(deployments.interchain_token_service.publishTxn, 'interchain_token_service_v0::InterchainTokenService_v0'), relayerDiscovery: findObjectId( deployments.relayer_discovery.publishTxn, `${deployments.relayer_discovery.packageId}::discovery::RelayerDiscovery`, @@ -397,11 +410,18 @@ describe('Squid', () => { deployments.interchain_token_service.publishTxn, `${deployments.interchain_token_service.packageId}::owner_cap::OwnerCap`, ), + itsCreatorCap: findObjectId( + deployments.interchain_token_service.publishTxn, + `${deployments.interchain_token_service.packageId}::creator_cap::CreatorCap`, + ), gateway: findObjectId( deployments.interchain_token_service.publishTxn, `${deployments.axelar_gateway.packageId}::gateway::Gateway`, ), }; + + await setupIts(); + // Find the object ids from the publish transactions objectIds = { ...objectIds, diff --git a/test/testdata/interface_interchain_token_service_creator_cap.json b/test/testdata/interface_interchain_token_service_creator_cap.json new file mode 100644 index 00000000..52e2bed7 --- /dev/null +++ b/test/testdata/interface_interchain_token_service_creator_cap.json @@ -0,0 +1,18 @@ +{ + "structs": { + "CreatorCap": { + "name": "CreatorCap", + "abilities": [ + "store", + "key" + ], + "fields": [ + { + "name": "id", + "type": "UID" + } + ] + } + }, + "publicFunctions": {} +} diff --git a/test/testdata/interface_interchain_token_service_interchain_token_service_v0.json b/test/testdata/interface_interchain_token_service_interchain_token_service_v0.json index f850013e..39ca1f4b 100644 --- a/test/testdata/interface_interchain_token_service_interchain_token_service_v0.json +++ b/test/testdata/interface_interchain_token_service_interchain_token_service_v0.json @@ -34,6 +34,10 @@ "name": "relayer_discovery_id", "type": "ID" }, + { + "name": "chain_name_hash", + "type": "Bytes32" + }, { "name": "version_control", "type": "VersionControl" diff --git a/test/testdata/interface_interchain_token_service_token_id.json b/test/testdata/interface_interchain_token_service_token_id.json index 4c92bbc9..d701c09b 100644 --- a/test/testdata/interface_interchain_token_service_token_id.json +++ b/test/testdata/interface_interchain_token_service_token_id.json @@ -58,6 +58,7 @@ "name": "from_info", "visibility": "public", "params": { + "chain_name_hash#0#0": "&Bytes32", "name#0#0": "&String", "symbol#0#0": "&String", "decimals#0#0": "&u8",