@routerprotocol/router-chain-sdk-ts
TypeScript icon, indicating that this package has built-in type declarations

0.8.69 • Public • Published

Overview

SDK for Router chain.

Refer to the documentation of Router chain SDK (ts): https://router-protocol.github.io/router-chain-ts-sdk/modules.html

Features

With this SDK, broadly following things can be done on Router chain -

  • Create a transaction.
  • Sign a transaction.
  • Broadcast a transaction.
  • Read any data and state.

Installation

yarn add @routerprotocol/router-chain-sdk-ts

or

npm i @routerprotocol/router-chain-sdk-ts

Code Snippets

Fetch an account's balance.

import {
  getEndpointsForNetwork,
  Network,
} from '@routerprotocol/router-chain-sdk-ts';

const endpoint = getEndpointsForNetwork(Network.Devnet);
const bankClient = new ChainGrpcBankApi(endpoint.grpcEndpoint);

// Fetch all balances of an account
const accountBalances = await bankClient.fetchBalances(
  'router16sqwdtdxjl6zdvx49rvayhkyelfrhavpmknxh9'
);
console.log(accountBalances);

// Fetch particular coin's balance of an account
const routersBalances = await bankClient.fetchBalance({
  accountAddress: 'router16sqwdtdxjl6zdvx49rvayhkyelfrhavpmknxh9',
  denom: 'route',
});
console.log(routersBalances);

Sample response -

{
	balances: [ { denom: 'route', amount: '1000000000000000000000' } ],
	pagination: { total: 1, next: '' }
}

{ denom: 'route', amount: '1000000000000000000000' }
Create a raw transaction.

createTransaction returns the raw transaction and signed bytes. The signbytes can be signed and broadcasted to the chain.

const {
  DEFAULT_STD_FEE,
  createTransaction,
} = require('@routerprotocol/router-chain-sdk-ts');

const { signBytes, txRaw } = createTransaction({
  message: message.toDirectSign(),
  memo: '',
  fee: DEFAULT_STD_FEE,
  pubKey: publicKey,
  sequence: parseInt(aliceAccount.account.base_account.sequence, 10),
  accountNumber: parseInt(aliceAccount.account.base_account.account_number, 10),
  chainId: CHAIN_ID,
});
Transfer funds.

Given below is an example of bank transaction which can be used to send transfer funds -

const {
  getEndpointsForNetwork,
  Network,
  ChainRestAuthApi,
  PrivateKey,
  DEFAULT_STD_FEE,
  TxRestClient,
  createTransaction,
  MsgSend,
  privateKeyToPublicKeyBase64,
  isValidAddress,
  devnetChainInfo,
} = require('@routerprotocol/router-chain-sdk-ts');

const ROUTER_TO_SEND = '10';

const amount = {
  amount: expandDecimals(ROUTER_TO_SEND, 18).toString(),
  denom: 'route',
};

const endpoint = getEndpointsForNetwork(Network.Devnet);
const privateKeyHash = FAUCET_ACCOUNT_KEY;

/** Intializing Faucet wallet from the private key */
const privateKey = PrivateKey.fromPrivateKey(privateKeyHash);
const alice = privateKey.toBech32();
const alice_pubkey = privateKey.toPublicKey();

const publicKey = privateKeyToPublicKeyBase64(
  Buffer.from(privateKeyHash, 'hex')
);

/** Prepare the Message */
const message = MsgSend.fromJSON({
  amount,
  srcRouterAddress: alice,
  dstRouterAddress: destinationAddress,
});

/** Get Faucet Accounts details */
const aliceAccount = await new ChainRestAuthApi(
  endpoint.lcdEndpoint
).fetchAccount(alice);

/** Create Raw Transaction */
const { signBytes, txRaw } = createTransaction({
  message: message.toDirectSign(),
  memo: '',
  fee: DEFAULT_STD_FEE,
  pubKey: publicKey,
  sequence: parseInt(aliceAccount.account.base_account.sequence, 10),
  accountNumber: parseInt(aliceAccount.account.base_account.account_number, 10),
  chainId: devnetChainInfo.chainId,
});

/** Sign transaction */
const signature = await privateKey.sign(signBytes);

/** Append Signatures */
txRaw.setSignaturesList([signature]);

const txService = new TxRestClient(endpoint.lcdEndpoint);

/** Broadcast transaction */
const txResponse = await txService.broadcast(txRaw);

console.log(
  `Broadcasted transaction hash: ${JSON.stringify(txResponse.txhash)}`
);

Given below is an example of how MsgStoreCode can be used to upload a wasm contract file to router chain -

import {
  getEndpointsForNetwork,
  Network,
  getNetworkType,
  MsgStoreCode,
  PrivateKey,
  privateKeyToPublicKeyBase64,
  ChainRestAuthApi,
  createTransaction,
  DEFAULT_STD_FEE,
	BigNumberInBase,
  TxGrpcClient,
  TxRestClient,
  MsgInstantiateContract,
} from '../../router-chain-ts-sdk/src/';
import { sha256 } from '@cosmjs/crypto';
import { logs } from '@cosmjs/stargate';
import pako from 'pako';
import _m0 from 'protobufjs/minimal';
import * as fs from 'fs';

const privateKey = PrivateKey.fromPrivateKey(privateKeyHash);

const alice = privateKey.toBech32();
const alice_pubkey = privateKey.toPublicKey();

const publicKey = privateKeyToPublicKeyBase64(
	Buffer.from(privateKeyHash, "hex")
);

const endpoint =  getEndpointsForNetwork(Network.Devnet);

const restClient = new TxRestClient(endpoint.lcdEndpoint);

/** Get Faucet Accounts details */
  const aliceAccount = await new ChainRestAuthApi(
    endpoint.lcdEndpoint
  ).fetchAccount(alice);
  console.log(`aliceAccount => ${JSON.stringify(aliceAccount)}`);

  const compressed = pako.gzip(wasmCode, { level: 9 });

  const storeCodeMsg = MsgStoreCode.fromJSON({
    sender: alice,
    wasm: wasmCode,
  });

  const { signBytes, txRaw } = createTransaction({
		message: storeCodeMsg.toDirectSign(),
		memo: "",
		fee: {
			amount: [
				{
					amount: new BigNumberInBase(4000000000)
						.times(500000000)
						.toString(),
					denom: "route",
				},
			],
			gas: (500000000).toString(),
		},
		pubKey: publicKey,
		sequence: parseInt(aliceAccount.account.base_account.sequence, 10),
		accountNumber: parseInt(
			aliceAccount.account.base_account.account_number,
			10
		),
		chainId: "router-1",
	});

  /** Sign transaction */
  const signature = await privateKey.sign(signBytes);

  /** Append Signatures */
  txRaw.setSignaturesList([signature]);

  /** Broadcast transaction */
  let txxResponse = await restClient.broadcast(txRaw);
	let txResponse = await restClient. waitTxBroadcast(txxResponse.txhash);
	console.log(`txResponse =>`, JSON.stringify(txResponse));

  const parsedLogs = logs.parseRawLog(txResponse.raw_log);
  const codeIdAttr = logs.findAttribute(parsedLogs, 'store_code', 'code_id');
  const codeId = Number.parseInt(codeIdAttr.value, 10),
  console.log(`deployedContract code id  =>`, codeId);
Instantiate a contract.

With MsgInstantiateContract we can instantiate the deployed contract with codeId -

import {
  getEndpointsForNetwork,
  getNetworkType,
  MsgStoreCode,
  PrivateKey,
  privateKeyToPublicKeyBase64,
  ChainRestAuthApi,
  createTransaction,
  DEFAULT_STD_FEE,
  BigNumberInBase,
  TxGrpcClient,
  TxRestClient,
  MsgInstantiateContract,
} from '../../router-chain-ts-sdk/src/';
import { sha256 } from '@cosmjs/crypto';
import { logs } from '@cosmjs/stargate';
import pako from 'pako';
import _m0 from 'protobufjs/minimal';
import * as fs from 'fs';

const privateKey = PrivateKey.fromPrivateKey(privateKeyHash);

const alice = privateKey.toBech32();
const alice_pubkey = privateKey.toPublicKey();

const publicKey = privateKeyToPublicKeyBase64(
  Buffer.from(privateKeyHash, 'hex')
);

const endpoint = getEndpointsForNetwork(Network.Devnet);

const restClient = new TxRestClient(endpoint.lcdEndpoint);
const aliceAccount = await new ChainRestAuthApi(
  endpoint.lcdEndpoint
).fetchAccount(alice);
console.log(`aliceAccount => ${JSON.stringify(aliceAccount)}`);

const intantiateContractMsg = MsgInstantiateContract.fromJSON({
  sender: alice,
  admin: alice,
  codeId: deployedContract.codeId,
  label: 'Mayank! Hello World',
  msg: {},
});

const instantiateTx = createTransaction({
  message: intantiateContractMsg.toDirectSign(),
  memo: '',
  fee: {
    amount: [
      {
        amount: new BigNumberInBase(4000000000).times(500000000).toString(),
        denom: 'route',
      },
    ],
    gas: (500000000).toString(),
  },
  pubKey: publicKey,
  sequence: parseInt(aliceAccount.account.base_account.sequence, 10),
  accountNumber: parseInt(aliceAccount.account.base_account.account_number, 10),
  chainId: 'router-1',
});

/** Sign transaction */
const signature = await privateKey.sign(instantiateTx.signBytes);

/** Append Signatures */
instantiateTx.txRaw.setSignaturesList([signature]);
const txService = new TxGrpcClient(endpoint.grpcEndpoint);

/** Broadcast transaction */
const txResponse = await restClient.broadcast(instantiateTx.txRaw);
console.log(
  `Broadcasted Instantiate transaction hash: ${JSON.stringify(
    txResponse.txhash
  )}`
);
``;
const parsedLogs = logs.parseRawLog(txResponse1.raw_log);
const contractAddressAttr = logs.findAttribute(
  parsedLogs,
  'instantiate',
  '_contract_address'
);
console.log(`Deployed contract address =>`, contractAddressAttr);
Query a contract.

import {
  toUtf8,
  ChainGrpcWasmApi,
  getEndpointsForNetwork,
  getNetworkType,
  ChainGrpcBankApi,
} from '../../router-chain-ts-sdk/src';

const endpoint = getEndpointsForNetwork(Network.Devnet);

const wasmClient = new ChainGrpcWasmApi(endpoint.grpcEndpoint);
const bankClient = new ChainGrpcBankApi(endpoint.grpcEndpoint);
const request = {
  address: 'router1aaf9r6s7nxhysuegqrxv0wpm27ypyv4886medd3mrkrw6t4yfcns8a2l0y',
  queryData: toUtf8(JSON.stringify({ fetch_white_listed_contract: {} })),
};
const fetchRawContractStateResult = await wasmClient.fetchRawContractState(
  request.address,
  request.queryData
);
console.log('fetchRawContractState DATA =>', fetchRawContractStateResult);

const fetchContractCodeResult = await wasmClient.fetchContractCode(7);
console.log('fetchContractCodeResult =>', fetchContractCodeResult);

const fetchContractCodesResult = await wasmClient.fetchContractCodes();
console.log('fetchContractCodesResult =>', fetchContractCodesResult);

const fetchContractCodeContractsResult = await wasmClient.fetchContractCodeContracts(
  7
);
console.log(
  'fetchContractCodeContractsResult =>',
  fetchContractCodeContractsResult
);

const fetchContractHistoryResult = await wasmClient.fetchContractHistory(
  request.address
);
console.log('fetchContractHistoryResult =>', fetchContractHistoryResult);

const fetchContractInfoResult = await wasmClient.fetchContractInfo(
  request.address
);
console.log('fetchContractInfoResult =>', fetchContractInfoResult);

const fetchSmartContractStateResult = await wasmClient.fetchSmartContractState(
  request.address,
  request.queryData
);
console.log('fetchSmartContractStateResult =>', fetchSmartContractStateResult);

const fetchBalanceResult = await bankClient.fetchBalance({
  accountAddress: 'router1m0s0544sgdczf2sm6l8v6py7rrpr8a2cvnjezx',
  denom: 'route',
});
console.log('fetchBalanceResult =>', fetchBalanceResult);
Execute a query.

With MsgExecuteContract you can execute any query on Router Chain.

import {
  getEndpointsForNetwork,
  getNetworkType,
  MsgStoreCode,
  PrivateKey,
  privateKeyToPublicKeyBase64,
  ChainRestAuthApi,
  createTransaction,
  DEFAULT_STD_FEE,
  BigNumberInBase,
  TxGrpcClient,
  TxRestClient,
  MsgInstantiateContract,
} from '../../router-chain-ts-sdk/src/';
import { sha256 } from '@cosmjs/crypto';
import { logs } from '@cosmjs/stargate';
import pako from 'pako';
import _m0 from 'protobufjs/minimal';
import { MsgExecuteContract } from '@routerprotocol/router-chain-sdk-ts';

const privateKey = PrivateKey.fromPrivateKey(privateKeyHash);

const alice = privateKey.toBech32();
const alice_pubkey = privateKey.toPublicKey();

const publicKey = privateKeyToPublicKeyBase64(
  Buffer.from(privateKeyHash, 'hex')
);
const restClient = new TxRestClient(endpoint.lcdEndpoint);

/** Get Faucet Accounts details */
const aliceAccount = await new ChainRestAuthApi(
  endpoint.lcdEndpoint
).fetchAccount(alice);

const executeContractMsg = MsgExecuteContract.fromJSON({
  sender: alice,
  action: 'white_list_application_contract',
  contractAddress:
    'router1aaf9r6s7nxhysuegqrxv0wpm27ypyv4886medd3mrkrw6t4yfcns8a2l0y',
  msg: {
    chain_id: '80001',
    chain_type: 0,
    contract_address: [
      171,
      132,
      131,
      246,
      77,
      156,
      109,
      30,
      207,
      155,
      132,
      154,
      230,
      119,
      221,
      51,
      21,
      131,
      92,
      178,
    ],
  },
});

const { signBytes, txRaw } = createTransaction({
  message: executeContractMsg.toDirectSign(),
  memo: '',
  fee: {
    amount: [
      {
        amount: new BigNumberInBase(4000000000).times(500000000).toString(),
        denom: 'route',
      },
    ],
    gas: (500000000).toString(),
  },
  pubKey: publicKey,
  sequence: parseInt(aliceAccount.account.base_account.sequence, 10),
  accountNumber: parseInt(aliceAccount.account.base_account.account_number, 10),
  chainId: 'router-1',
});

/** Sign transaction */
const signature = await privateKey.sign(signBytes);

/** Append Signatures */
txRaw.setSignaturesList([signature]);

/** Broadcast transaction */
let txxResponse = await restClient.broadcast(txRaw);
let txResponse = await restClient.waitTxBroadcast(txxResponse.txhash);
console.log(`txResponse =>`, txResponse);
Interact with router chain using Metamask

For send chain transaction messages like MsgSend for bank transfer -

import { ROUTER_DENOM, Network, MsgSend } from "@routerprotocol/router-chain-sdk-ts";

const amount = {
      amount: "10000000000000000000",
      denom: ROUTER_DENOM,
    };

const msgSendMsg = MsgSend.fromJSON({
  amount,
  srcRouterAddress: getRouterSignerAddress(window.ethereum.selectedAddress),
  dstRouterAddress: destinationAddress,
});
const RPC = getEndpointsForNetwork(Network.Testnet).lcdEndpoint
const tx = await sendEthTxnToRouterChain({
  networkEnv: Network.testnet,
  txMsg: msgSendMsg,
  nodeUrl: RPC,
  ethereumAddress: accountAddress,
  injectedSigner: window.ethereum,
});
const txHash = tx.tx_response.txhash
const restClient = new TxRestClient(RPC);
const txResponse = await restClient.waitTxBroadcast(txHash);

Executing a query on cosmwasm smart contract -

import {
  ROUTER_DENOM,
  Network,
  MsgExecuteCwContract,
} from '@routerprotocol/router-chain-sdk-ts';

const restClient = new TxRestClient(
  getEndpointsForNetwork(Network.Testnet).lcdEndpoint
);

const tx = await executeQueryInjected({
  networkEnv: Network.Testnet,
  contractAddress: 'router10390.......',
  executeMsg: yourQueryJSON,
  nodeUrl: getEndpointsForNetwork(Network.Testnet).lcdEndpoint,
  ethereumAddress: window.ethereum.selectedAddress,
  injectedSigner: window.ethereum,
});
const txHash = tx.tx_response.txhash;
const txResponse = await restClient.waitTxBroadcast(txHash);
Execute a query.

With MsgExecuteContract you can execute any query on Router Chain.

import {
  getEndpointsForNetwork,
  getNetworkType,
  MsgStoreCode,
  PrivateKey,
  privateKeyToPublicKeyBase64,
  ChainRestAuthApi,
  createTransaction,
  DEFAULT_STD_FEE,
  BigNumberInBase,
  TxGrpcClient,
  TxRestClient,
  MsgInstantiateContract,
} from '../../router-chain-ts-sdk/src/';
import { sha256 } from '@cosmjs/crypto';
import { logs } from '@cosmjs/stargate';
import pako from 'pako';
import _m0 from 'protobufjs/minimal';
import { MsgExecuteContract } from '@routerprotocol/router-chain-sdk-ts';

const privateKey = PrivateKey.fromPrivateKey(privateKeyHash);

const alice = privateKey.toBech32();
const alice_pubkey = privateKey.toPublicKey();

const publicKey = privateKeyToPublicKeyBase64(
  Buffer.from(privateKeyHash, 'hex')
);
const restClient = new TxRestClient(endpoint.lcdEndpoint);

/** Get Faucet Accounts details */
const aliceAccount = await new ChainRestAuthApi(
  endpoint.lcdEndpoint
).fetchAccount(alice);

const executeContractMsg = MsgExecuteContract.fromJSON({
  sender: alice,
  action: 'white_list_application_contract',
  contractAddress:
    'router1aaf9r6s7nxhysuegqrxv0wpm27ypyv4886medd3mrkrw6t4yfcns8a2l0y',
  msg: {
    chain_id: '80001',
    chain_type: 0,
    contract_address: [
      171,
      132,
      131,
      246,
      77,
      156,
      109,
      30,
      207,
      155,
      132,
      154,
      230,
      119,
      221,
      51,
      21,
      131,
      92,
      178,
    ],
  },
});

const { signBytes, txRaw } = createTransaction({
  message: executeContractMsg.toDirectSign(),
  memo: '',
  fee: {
    amount: [
      {
        amount: new BigNumberInBase(4000000000).times(500000000).toString(),
        denom: 'route',
      },
    ],
    gas: (500000000).toString(),
  },
  pubKey: publicKey,
  sequence: parseInt(aliceAccount.account.base_account.sequence, 10),
  accountNumber: parseInt(aliceAccount.account.base_account.account_number, 10),
  chainId: 'router-1',
});

/** Sign transaction */
const signature = await privateKey.sign(signBytes);

/** Append Signatures */
txRaw.setSignaturesList([signature]);

/** Broadcast transaction */
let txxResponse = await restClient.broadcast(txRaw);
let txResponse = await restClient.waitTxBroadcast(txxResponse.txhash);
console.log(`txResponse =>`, txResponse);

Common Errors

For using the SDK with UI it is recommended to use node version v18.12.1 or above.

If you get webpack errors when using with create-react-app, follow these steps -

  1. Install craco and required packages.
yarn add -D @craco/craco
yarn add -D path-browserify stream-browserify stream-http https-browserify os-browserify assert url buffer process crypto-browsify fs
  1. Add craco.config.js file in your project root.
//craco.config.js

const { ProvidePlugin } = require('webpack');
module.exports = {
  webpack: {
    configure: webpackConfig => {
      return {
        ...webpackConfig,
        resolve: {
          ...webpackConfig.resolve,
          fallback: {
            ...(webpackConfig.resolve?.fallback ?? {}),
            path: require.resolve('path-browserify'),
            stream: require.resolve('stream-browserify'),
            buffer: require.resolve('buffer/'),
            crypto: require.resolve('crypto-browserify'),
            http: require.resolve('stream-http'),
            https: require.resolve('https-browserify'),
            os: require.resolve('os-browserify/browser'),
            assert: require.resolve('assert/'),
            url: require.resolve('url/'),
          },
        },
        plugins: [
          ...(webpackConfig.plugins ?? []),
          new ProvidePlugin({
            Buffer: ['buffer', 'Buffer'],
          }),
          new ProvidePlugin({
            process: 'process/browser',
          }),
        ],
      };
    },
  },
};
  1. Replace these scripts in package.json.
"scripts": {
		-  ~~"start": "react-scripts start"~~
		+  "start": "craco start"
		-  ~~"build": "react-scripts build"~~
		+  "build": "craco build"
		-  ~~"test": "react-scripts test"~~
		+  "test": "craco test"
}
  1. yarn start and the webpack errors should be gone.

If you get webpack errors when using vue’s nuxt framework, do this small change in nuxt.config.js build key -

build: {
    extend(config, ctx) {
      config.module.rules.push({
        test: /\.js$/, // apply this rule to .js files
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"], // use the preset-env preset
          },
        },
      });
    },
  }

Readme

Keywords

none

Package Sidebar

Install

npm i @routerprotocol/router-chain-sdk-ts

Weekly Downloads

578

Version

0.8.69

License

MIT

Unpacked Size

10.3 MB

Total Files

1502

Last publish

Collaborators

  • gaurav_agarwal
  • shivam7828
  • kunalroute
  • mynk_s_rwt
  • mankenavenkatesh5389
  • joydeep_router
  • ss-sonic
  • vatsal.eth
  • harsh-at-router