Skip to content

Appendix F · Tooling cheatsheet

The shortest path from "I have an empty terminal" to "I have queried the chain". Mainnet endpoint shown — swap to the Porcini testnet if you don't want to spend XRP on gas.

RPC probes (curl)

bash
# Block height (Substrate JSON-RPC)
curl -s -H 'content-type: application/json' \
  https://root.rootnet.live/archive \
  -d '{"jsonrpc":"2.0","id":1,"method":"chain_getHeader","params":[]}' | jq

# EVM chainId (should be 7668)
curl -s -H 'content-type: application/json' \
  https://root.rootnet.live/archive \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}' | jq

# Account balance (EVM side, returns wei)
curl -s -H 'content-type: application/json' \
  https://root.rootnet.live/archive \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getBalance","params":["0x000…","latest"]}' | jq

viem (EVM, browser/node)

ts
import { createPublicClient, http } from 'viem';
import { defineChain } from 'viem/utils';

const root = defineChain({
  id: 7668,
  name: 'Root',
  nativeCurrency: { name: 'XRP', symbol: 'XRP', decimals: 18 },
  rpcUrls: { default: { http: ['https://root.rootnet.live/archive'] } },
  blockExplorers: { default: { name: 'Rootscan', url: 'https://rootscan.io' } },
});

const client = createPublicClient({ chain: root, transport: http() });
console.log(await client.getBlockNumber());

polkadot.js + @therootnetwork/api (Substrate, node)

ts
import { ApiPromise, WsProvider } from '@polkadot/api';
import { typesBundle } from '@therootnetwork/api-types';

const api = await ApiPromise.create({
  provider: new WsProvider('wss://root.rootnet.live/archive/ws'),
  typesBundle,
});

const head = await api.rpc.chain.getHeader();
console.log('block', head.number.toNumber());

// Query an asset's balance for an account
const xrpBalance = await api.query.assets.account(2 /* XRP id */, '0x000…');
console.log(xrpBalance.toHuman());

Hardhat (deploy a contract on Porcini)

hardhat.config.ts:

ts
import { HardhatUserConfig } from 'hardhat/config';
import '@nomicfoundation/hardhat-toolbox';

const config: HardhatUserConfig = {
  solidity: '0.8.24',
  networks: {
    porcini: {
      url: 'https://porcini.rootnet.app/archive',
      chainId: 7672,
      accounts: [process.env.PRIVATE_KEY!],
    },
  },
};
export default config;

Then:

bash
npx hardhat compile
npx hardhat run --network porcini scripts/deploy.ts

Reading an NFT collection (precompile)

ts
import { erc721Abi, getContract } from 'viem';

const collectionId = 1234;
const address =
  '0xAAAAAAAA' + collectionId.toString(16).padStart(24, '0');

const nft = getContract({ abi: erc721Abi, address: address as `0x${string}`, client });
console.log(await nft.read.name(), await nft.read.symbol());

Submitting via FuturePass proxy (substrate)

ts
const futurepass = await api.query.futurepass.holders(ownerAddress);

const inner = api.tx.assets.transfer(2 /* XRP */, recipient, 1_000_000n);
const proxied = api.tx.futurepass.proxyExtrinsic(futurepass, inner);

await proxied.signAndSend(signer);

See also

Curated independently by Codeology. Source-attributed reference for The Root Network. Not affiliated with Futureverse / TRN Labs.