Documentation

Build on Intertrain

Three packages, one protocol. Amounts are always whole units, addresses work in either form, and every write confirms before it returns.

Get started

The fastest path from nothing to a funded account that can send MNA is the CLI. It installs one binary, inter, shaped after Solana's so the commands are where you expect them.

bash
npm install -g @intertrain-network/cli

inter config set --url mainnet
inter keygen new
inter balance

keygen new prints a recovery phrase once and writes the key to ~/.intertrain/id.json with mode 600. The phrase is shown a single time and stored nowhere — write it down before moving on.

Building an application instead? Skip to the SDK. It is the same protocol code the CLI runs on.

Getting MNA

MNA is bought with USDC. Your USDC is locked on the chain it came from and the same amount appears here as wUSDC, which you then swap for MNA at a fixed 1 USDC = 1 MNA. Two steps, about two minutes.

Before you start

  • A browser wallet — Rabby is the smoother one on Intertrain today; MetaMask works but prices fees oddly on new chains.
  • USDC on Ethereum, and a little ETH for gas.
  • Bring at least $50. Ethereum charges the same gas whether you move $5 or $5,000, so small amounts lose most of their value to fees before they arrive. This is Ethereum's cost, not ours.

1 · Add Intertrain to your wallet

Open the wallet and connect. It offers to add the network for you. Everything below happens in the Bridge window.

2 · Deposit your USDC

On the Deposit USDC tab, choose the chain your USDC is on, enter an amount, and press Deposit USDC.

Your wallet asks you to sign twice: once to approve the bridge to move your USDC, then once for the deposit itself. That is normal for any token on Ethereum. Both cost gas.

Your wUSDC appears a minute or so after Ethereum confirms — the bridge waits for a few blocks before crediting, so a reorg cannot undo it. You can close the window; it arrives on its own.

3 · Swap wUSDC for MNA

Open the wUSDC → MNA tab, enter an amount, and press Swap to MNA.

This one is free. You sign a message rather than send a transaction, so there is no gas and you do not need to already hold MNA. That matters: otherwise your first purchase would need MNA you have no way to get.

Your MNA balance updates once the swap is included in a block, usually a couple of seconds. That is the whole process — you now hold MNA.

Going the other way

The same window reverses it. MNA → wUSDC converts back at the same rate, and Withdraw burns your wUSDC and releases real USDC to your address on Ethereum, usually within a minute.

Unlike the swap in, both of these are ordinary transactions, so keep a little MNA back to pay the fee. The wallet tells you the most you can convert if you try to use your whole balance.

If something looks wrong

  • wUSDC has not arrived. Give it a few minutes. The bridge waits for confirmations on the source chain before crediting.
  • Your wallet shows an error with no explanation. Try once more, and if it persists use Rabby, which reports the actual reason.
  • You cannot see your MNA. Check the network selector — wallets show one chain at a time, and MNA only exists on Intertrain.

CLI @intertrain-network/cli

Send MNA. Amounts are whole units and both address forms are accepted.

bash
inter transfer mna1q8nlmzn2hr9ux6n867gjqwxcgmcdm3eulcvhxzka 1.5
inter transfer 0x1af13cCFbA8B48f0A7E3C68768a313789e05B6Fc 1.5 --memo "invoice 12"

The command waits for the transaction to be included in a block before it prints the hash. A queued transaction is not an applied one, and a tool that reports success at submission will eventually report a success that did not happen.

Tokens

Issue a token, and get back the ERC-20 address it answers on so it can be added to MetaMask directly.

bash
inter token create --name "Example Coin" --symbol EXC --supply 1000000
inter token send EXC mna1q8nlmzn2hr9ux6n867gjqwxcgmcdm3eulcvhxzka 250
inter token list
inter token address EXC

Recover a key

Passed through the environment rather than as an argument, so the phrase never lands in shell history.

bash
INTER_PHRASE='word word …' inter keygen recover

All commands

CommandDoes
inter config get|setShow or change the network and keypair path
inter keygen new|pubkey|recoverCreate, show, or restore a key
inter address [--evm]Print your address in either form
inter balance [address]MNA and token balances
inter transfer <to> <amount>Send MNA
inter token create|send|list|addressToken operations
inter block [height]Inspect a block

SDK @intertrain-network/sdk

Runs in Node, in a browser, and under React Native. Two objects: a Client that reads, and a Wallet that signs.

javascript
import { Client, Wallet } from '@intertrain-network/sdk';

const client = new Client('mainnet');
const wallet = Wallet.fromMnemonic(process.env.PHRASE, client);

await wallet.balance();                        // '12.5'
await wallet.transfer('mna1q8nlmzn…', '1.5');  // resolves once it is in a block

Reading

javascript
await client.chainInfo();
await client.account(address);       // raw: base units, nonce, assets
await client.balance(address);       // whole MNA, as a string
await client.holdings(address);      // tokens with symbols and whole amounts
await client.tokens();
await client.token('EXC');           // by symbol or token id
await client.tokenAddress(tokenId);  // its ERC-20 address
await client.block();                // latest, or block(height)
await client.transaction(hash);

Writing

javascript
await wallet.transfer(to, '1.5', { memo: 'invoice 12' });

const token = await wallet.createToken({
  name: 'Example Coin',
  symbol: 'EXC',
  supply: '1000000',
  decimals: 6,
});
token.evmAddress;  // paste this into MetaMask

await wallet.transferToken('EXC', to, '250');

Write methods resolve when the transaction is in a block, not when the node accepts it. Pass { wait: false } to get the hash immediately and poll yourself.

Creating an account

javascript
const { mnemonic, wallet } = Wallet.create(client);
// hand the phrase to the user once; nothing here writes it down
Amounts are whole units. transfer(to, '100') sends one hundred MNA, never one hundred base units. Conversion happens inside the SDK.

Wallet core @intertrain-network/wallet-core

No fs, no fetch, no crypto.subtle, no React. Reach for it directly when you need key handling without a network connection — a hardware signer, an offline tool, or a mobile app with its own storage. The SDK re-exports the common parts, so most applications need only one dependency.

Randomness

Node, browsers, and Hermes disagree about which crypto globals exist, so the host supplies the source and the package never guesses. In a browser the default finds crypto.getRandomValues and no setup is needed.

javascript
import { setRandomSource } from '@intertrain-network/wallet-core';
import { randomBytes } from 'node:crypto';

setRandomSource((n) => new Uint8Array(randomBytes(n)));

Keys and addresses

javascript
import { generate, fromMnemonic, normalize, toEvm } from '@intertrain-network/wallet-core';

const { mnemonic, keypair } = generate();
keypair.address;     // mna1q8nlmzn2hr9ux6n867gjqwxcgmcdm3eulcvhxzka
keypair.evmAddress;  // 0xe7fd8a6ab8cbc36a67d7912038d846f0ddc73cfe
keypair.sign(bytes);

normalize('0xe7fd8a6a…');  // → mna1q8nlmzn…, the same account

An address is a version byte followed by twenty bytes of a domain-separated hash of the public key. Those twenty bytes are the EVM address, so the two forms are two renderings of one account rather than a conversion between two things.

Amounts

javascript
import { toBase, fromBase } from '@intertrain-network/wallet-core';

toBase('1.5', 6);       // 1500000n
fromBase(1500000n, 6);  // '1.5'

toBase throws on more precision than the decimals can hold rather than silently truncating an amount that cannot be taken back.

Vaults

PBKDF2-SHA256 at 210,000 rounds plus AES-GCM-256, byte-compatible with the Intertrain web wallet.

javascript
const record = seal({ mnemonic }, password);
unseal(record, password);
On mobile, use this for export and import only. The iOS Keychain and the Android Keystore already protect secrets in hardware, and 210,000 rounds of pure-JS PBKDF2 blocks the JS thread for seconds on every unlock.

Networks

NameChainEVM chain idRPC
mainnetintertrain-14683rpc.intertrain.online/rpc
devnetworldstreet-devnet-14685rpc-worldstreet.watchup.space/rpc

MNA is 6 decimals natively and 18 at the EVM boundary. Both packages handle the factor internally; it matters only if you are encoding calldata by hand.

JSON-RPC

Nothing above is required. Every read and write path is a single POST /rpc call, and the EVM layer answers standard Ethereum methods, so viem, ethers, and foundry work against it unchanged.

bash
curl -s https://rpc.intertrain.online/rpc \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"chain_info","params":{}}'
bash
cast block-number --rpc-url https://rpc.intertrain.online
forge create --rpc-url https://rpc.intertrain.online src/Token.sol:Token