import {
TokenService,
UiBankTransformer,
cosmosChainTokenMetaMap,
} from "@injectivelabs/sdk-ui-ts";
import {
MsgTransfer,
ChainGrpcBankApi,
MsgBroadcasterWithPk,
ChainRestTendermintApi,
makeTimeoutTimestampInNs,
} from "@injectivelabs/sdk-ts";
import { toChainFormat, toBigNumber } from "@injectivelabs/utils";
import { ChainId, CosmosChainId } from "@injectivelabs/ts-types";
import { getNetworkEndpoints, Network } from "@injectivelabs/networks";
import { IbcToken, Token } from "@injectivelabs/token-metadata";
const tokenService = new TokenService({
chainId: ChainId.Mainnet,
network: Network.Mainnet,
});
const destinationChainId = CosmosChainId["Cosmoshub"];
const injectiveChainId = CosmosChainId["Injective"];
const endpointsForNetwork = getNetworkEndpoints(Network.Mainnet);
const bankService = new ChainGrpcBankApi(endpointsForNetwork.grpc);
// fetch ibc assets in bank module and format to token
const { supply } = await bankService.fetchTotalSupply();
const uiSupply = UiBankTransformer.supplyToUiSupply(supply);
const ibcSupplyWithToken = (await tokenService.getIbcSupplyWithToken(
uiSupply.ibcBankSupply
)) as IbcToken[];
/* get metadata for canonical denoms available for transfer between chains */
const cosmosHubBaseDenom = "uatom";
const tokenMeta = cosmosChainTokenMetaMap[destinationChainId];
const atomToken = (
Array.isArray(tokenMeta)
? tokenMeta.find((token) => token.denom === cosmosHubBaseDenom)
: tokenMeta
) as Token;
/* find the ibd denom hash for the canonical denom */
const injectiveToCosmosHubChannelId = "channel-1";
const atomDenomFromSupply = ibcSupplyWithToken.find(
({ channelId, baseDenom }) =>
channelId === injectiveToCosmosHubChannelId && baseDenom === atomToken.denom
) as IbcToken;
const canonicalDenomHash = atomDenomFromSupply.denom;
/* format amount for transfer */
const amount = {
denom: canonicalDenomHash,
amount: toChainFormat(0.001, atomDenomFromSupply.decimals).toFixed(),
};
const injectiveAddress = "inj...";
const destinationAddress = "cosmos...";
const port = "transfer";
const timeoutTimestamp = makeTimeoutTimestampInNs();
/* get the latestBlock from the origin chain */
const tendermintRestApi = new ChainRestTendermintApi(endpointsForNetwork.rest);
/* Block details from the origin chain */
const latestBlock = await tendermintRestApi.fetchLatestBlock();
const latestHeight = latestBlock.header.height;
const timeoutHeight = toBigNumber(latestHeight).plus(
30 // default block timeout height
);
/* create message in proto format */
const msg = MsgTransfer.fromJSON({
port,
memo: `IBC transfer from ${injectiveChainId} to ${destinationChainId}`,
sender: injectiveAddress,
receiver: destinationAddress,
channelId: injectiveToCosmosHubChannelId,
timeout: timeoutTimestamp,
height: {
revisionHeight: timeoutHeight.toNumber(),
revisionNumber: parseInt(latestBlock.header.version.block, 10),
},
amount,
});
const privateKey = "0x...";
/* broadcast transaction */
const txHash = await new MsgBroadcasterWithPk({
privateKey,
network: Network.Mainnet,
}).broadcast({
msgs: msg,
});
console.log(txHash);