Cosmos
The Cosmos part carries out the practice using @cosmjs. Please prepare by installing the package.
Create Signed transaction
For a signed transaction, there are three essential steps.
- Create a raw transaction first.
 - Make a raw transaction signature.
 - Convert a raw transaction into a signed transaction by adding a signature.
 
1. getCosmosTx
Transaction and signature are needed. We first develop a getCosmosTx function to generate raw transaction because it is necessary to have a raw transaction to receive a signature via kms.
import { Account, CHAIN } from '@dsrv/kms/lib/types';
import { Cosmos } from '@dsrv/kms/lib/blockchains/cosmos';
import {
  Registry,
  makeAuthInfoBytes,
  makeSignDoc,
  encodePubkey,
  makeSignBytes,
  DirectSecp256k1HdWallet,
  TxBodyEncodeObject,
} from '@cosmjs/proto-signing';
import { encodeSecp256k1Pubkey } from '@cosmjs/amino';
import { StargateClient, defaultRegistryTypes } from '@cosmjs/stargate';
import { Int53 } from '@cosmjs/math';
import { SignDoc } from 'cosmjs-types/cosmos/tx/v1beta1/tx';
interface RawTransaction {
  unSignedTx: SignDoc;
  serializedTx: string;
}
const getTxBodyBytes = (transaction) => {
  const registry = new Registry(defaultRegistryTypes);
  const txBodyEncodeObjectTxBodyEncodeObject = {
    typeUrl: '/cosmos.tx.v1beta1.TxBody',
    value: {
      messages: transaction.msgs,
      memo: transaction.memo,
    },
  };
  const txBodyBytes = registry.encode(txBodyEncodeObject);
  return txBodyBytes;
};
const getAuthInfoBytes = (transaction, pubkey) => {
  const gasLimit = Int53.fromString(transaction.fee.gas).toNumber();
  const authInfoBytes = makeAuthInfoBytes(
    [
      {
        pubkey: encodePubkey(encodeSecp256k1Pubkey(pubkey)),
        sequence: transaction.signerData.sequence,
      },
    ],
    transaction.fee.amount,
    gasLimit,
    undefined,
    undefined,
    // 1,
  );
  return authInfoBytes;
};
export const getCosmosTx = async (mnemonic: string): Promise<RawTransaction> => {
  /* 1. get Account */
  const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic);
  const [{ address, pubkey }] = await wallet.getAccounts();
  /* 2. make raw transaction */
  const rpcUrl = 'https://cosmos-testnet-rpc.allthatnode.com:26657';
  const client = await StargateClient.connect(rpcUrl);
  const sequence = await client.getSequence(address);
  const chainId = await client.getChainId();
  const transaction = {
    signerData: {
      accountNumber: sequence.accountNumber,
      sequence: sequence.sequence,
      chainId,
    },
    fee: {
      amount: [
        {
          denom: 'uatom',
          amount: '10000',
        },
      ],
      gas: '180000', // 180k
    },
    memo: 'dsrv/kms',
    msgs: [
      {
        typeUrl: '/cosmos.bank.v1beta1.MsgSend',
        value: {
          fromAddress: address,
          toAddress: address, // send to yourself
          amount: [{ denom: 'uatom', amount: '10000' }],
        },
      },
    ],
    sequence: sequence.sequence,
  };
  /* create signDoc */
  const txBodyBytes = getTxBodyBytes(transaction);
  const authInfoBytes = getAuthInfoBytes(transaction, pubkey);
  const signDoc = makeSignDoc(
    txBodyBytes,
    authInfoBytes,
    transaction.signerData.chainId,
    Number(transaction.signerData.accountNumber),
  );
  /* serialized singDoc */
  const uint8SignDoc = makeSignBytes(signDoc);
  const serializedTx = `0x${Buffer.from(uint8SignDoc).toString('hex')}`;
  return {
    unSignedTx: signDoc,
    serializedTx,
  };
};
2. getCosmosSignature
We then develop a method called getCosmosSignature that produces a signature by using serializedTx as a factor in order to gain a signature for the transaction.
import { CHAIN } from '@dsrv/kms/lib/types';
import { Cosmos } from '@dsrv/kms/lib/blockchains/cosmos';
export const getCosmosSignature = (serializedTx: string): string => {
  const { signature } = Cosmos.signTx(
    {
      mnemonic,
      path: { type: CHAIN.COSMOS, account: 0, index: 0 },
    },
    serializedTx,
  );
  return signature;
};
3. createCosmosSignedTx
Finally, we develop the createCosmosSignedTx function, which takes an unsignedTx and a signature generated earlier and returns a signed transaction.
import { TxRaw, SignDoc } from 'cosmjs-types/cosmos/tx/v1beta1/tx';
interface createCosmosSignedTxProps {
  unSignedTx: SignDoc;
  signature: string;
}
/* create singedTx by combining tx and signature */
export const createCosmosSignedTx = ({
  unSignedTx,
  signature,
}: createCosmosSignedTxProps): string => {
  const txRaw = TxRaw.fromPartial({
    bodyBytes: unSignedTx.bodyBytes,
    authInfoBytes: unSignedTx.authInfoBytes,
    signatures: [new Uint8Array(Buffer.from(signature.replace('0x', ''), 'hex'))],
  });
  const txByte = TxRaw.encode(txRaw).finish();
  const signedTx = `0x${Buffer.from(txByte).toString('hex')}`;
  return signedTx;
};
Finally, you can construct a getCosmosSignedTx function that returns a signed transaction by combining the functions you made before, getCosmosTx, getCosmosSignature, and createCosmosSignedTx.
export const getCosmosSignedTx = async (mnemonic: string) => {
  /* 1. get rawTransaction */
  const { serializedTx, unSignedTx } = await getCosmosTx(mnemonic);
  /* 2. get signature */
  const cosmosSignature = getCosmosSignature(serializedTx);
  /* 3. create singedTx by combining rawTransaction and signature */
  const cosmosSignedTx = createCosmosSignedTx({
    unSignedTx,
    signature: cosmosSignature,
  });
  return cosmosSignedTx;
};
Send Signed transaction
You can transmit the transaction using a signed transaction you've prepared.
import { StargateClient, DeliverTxResponse } from '@cosmjs/stargate';
export const sendCosmosTransaction = async (serializedTx: string): Promise<DeliverTxResponse> => {
  const rpcUrl = 'https://cosmos-testnet-rpc.allthatnode.com:26657';
  const client = await StargateClient.connect(rpcUrl);
  const txResult = await client.broadcastTx(
    Uint8Array.from(Buffer.from(serializedTx.replace('0x', ''), 'hex')),
  );
  return txResult;
};
const mnemonic = 'sample mnemonic';
const main = async () => {
  const cosmosSignedTx = await getCosmosSignedTx(mnemonic);
  const cosmosTxResult = await sendCosmosTransaction(cosmosSignedTx);
  console.log('Cosmos Tx Result : ', cosmosTxResult);
};
main();
Examples
To complete the transaction, follow the steps outlined below. A faucet is required to transmit a transaction. You can request faucet through the FAUCET tab in the wallet.
The loss of all cryptocurrency holdings is possible if mnemonic is revealed. To execute the following example, use a test or development mnemonic.