IBC Transfers
XPLA Chain has full IBC transfer capabilities through xplajs. Although IBC functionality is not readily exposed through XPLA Vault’s front-end, it can be fully incorporated into any dApp. It is up to a dApp’s front end to initiate IBC transfers.
MsgTransfer
xpla.js exports a MsgTransfer class that can be used to construct IBC transfers.
const msgTransfer = MsgTransfer.fromPartial({
sourcePort: "transfer", // IBC port
sourceChannel: "channel-0", // Outbound channel (Axelar)
token: {denom: "axpla", amount: "1000000000000000000"}, // 1 XPLA
sender: "xpla1npvwllfr9dqr8erajqqr6s0vxnk2ak55hh2h5f", // Source Address on XPLA Chain
receiver: "axelar1npvwllfr9dqr8erajqqr6s0vxnk2ak55d7yr5m", // Destination address on Axelar network
memo: "",
timeoutTimestamp: BigInt(Date.now() + 60 * 60 * 10 ** 3) * (10n ** 6n) // Timeout timestamp (in nanoseconds) relative to the current block timestamp.
})
Supported Channels
Channels are defined when a relayer is set up between XPLA Chain and an external chain. For each new connected chain the channel ID is incremented.
You can use Mintscan to find the available channels and their IDs.
Derive Cosmos Chain Addresses from a XPLA Chain Address
Cosmos SDK based blockchains use bech32 to encode the public key for display. Assuming the same private key is used on multiple Cosmos SDK chains it is possible to decode a XPLA Chain address and generate the corresponding public key on another chain.
Here’s a quick example using the @interchainjs/encoding JavaScript library:
import { fromBech32, toBech32 } from "@interchainjs/encoding/bech32";
const xplaAddress = 'xpla1npvwllfr9dqr8erajqqr6s0vxnk2ak55hh2h5f';
const {prefix, data: hex} = fromBech32(address)
const axelarAddress = toBech32("axelar", hex)
Complete Example
The following example demonstrates how to send 1 XPLA from XPLA Chain to the Axelar network.
import { EthSecp256k1HDWallet } from "@xpla/xpla"
import { HDPath } from "@interchainjs/types"
import { DirectSigner } from "@interchainjs/cosmos"
import { createCosmosQueryClient } from "@interchainjs/cosmos"
import { DEFAULT_COSMOS_EVM_SIGNER_CONFIG, encodeCosmosEvmPublicKey } from "@xpla/xpla/signers/config";
import { MsgTransfer } from "@xpla/xplajs";
import { fromBech32, toBech32 } from "@interchainjs/encoding/bech32";
import { transfer } from "@xpla/xplajs"
const queryClient = await createCosmosQueryClient("https://cube-rpc.xpla.io");
const mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
const wallet = await EthSecp256k1HDWallet.fromMnemonic(mnemonic, {derivations: [{
prefix: "xpla",
hdPath: HDPath.eth().toString()
}]});
const baseSignConfig = {
queryClient: queryClient,
chainId: "cube_47-5",
addressPrefix: "xpla",
}
const signerConfig = {
...DEFAULT_COSMOS_EVM_SIGNER_CONFIG,
...baseSignConfig
}
const signer = new DirectSigner(wallet, signerConfig);
const signerAddress = (await signer.getAddresses())[0]
const {prefix, data: hex} = fromBech32(signerAddress)
const receiver = toBech32("axelar", hex)
const tx = await transfer(
signer,
signerAddress,
MsgTransfer.fromPartial({
sourcePort: "transfer", // IBC port
sourceChannel: "channel-0", // Outbound channel (Axelar)
token: {denom: "axpla", amount: "1000000000000000000"},
sender: signerAddress, // Source Address on XPLA Chain
receiver: receiver, // Destination address on Axelar network
memo: "",
timeoutTimestamp: BigInt(Date.now() + 60 * 60 * 10 ** 3) * (10n ** 6n) // Timeout timestamp (in nanoseconds) relative to the current block timestamp.
}),
{
amount: [{denom: "axpla", amount: "56000000000000000"}],
gas: "200000",
},
""
)
const res = await tx.wait()
console.log(res)