Skip to main content
The nexus-contract-template includes a production-ready NEP-20 implementation. Clone it, set your token name and symbol, build, and deploy.

Step 1: Clone the Template

git clone https://github.com/yattacorp/nexus-contract-template
cd nexus-contract-template
Install the WASM build target if you haven’t already:
rustup target add wasm32-unknown-unknown

Step 2: Set Your Token Name and Symbol

Open src/lib.rs and find the token constants near the top:
const TOKEN_NAME: &str = "My Token";
const TOKEN_SYMBOL: &str = "MTK";
const TOKEN_DECIMALS: u8 = 18;
Change TOKEN_NAME and TOKEN_SYMBOL to your token’s values. Leave TOKEN_DECIMALS at 18 unless you have a specific reason to change it.
You do not need to write the NEP-20 logic yourself. The template already implements transfer, approve, transferFrom, balanceOf, allowance, mint, and all standard events.

Step 3: Build

cargo build --target wasm32-unknown-unknown --release
Output: target/wasm32-unknown-unknown/release/my_nexus_contract.wasm

Step 4: Test Locally

cargo test
The template includes tests for transfer, approval, and minting. All tests run against a local TestEnv — no network required.

Step 5: Deploy with TypeScript

Install the SDK:
npm install @yattacorp/nexus-sdk
Create a deploy script (deploy.ts):
import { NexusClient, Wallet } from '@yattacorp/nexus-sdk';
import { readFileSync } from 'fs';

const wallet = Wallet.fromMnemonic(process.env.MNEMONIC!, 'mainnet', undefined, 'zcash');
const client = new NexusClient(
  { rpcUrl: 'https://api.yattacorp.xyz', network: 'mainnet', chain: 'zcash' },
  wallet
);

// Deploy the WASM binary
const wasm = readFileSync(
  './target/wasm32-unknown-unknown/release/my_nexus_contract.wasm'
);
const { contractId } = await client.deployContract(wasm);
console.log('Token deployed at:', contractId);

// Initialize — sets name, symbol, decimals, and mints initial supply to deployer
await client.callContract(contractId, 'init_token', [
  'My Token',                    // name
  'MTK',                         // symbol
  18,                            // decimals
  '1000000000000000000000000',   // initial supply (1,000,000 × 10^18)
]);

console.log('Token initialized');
Run it:
npx ts-node deploy.ts
init_token can only be called once — it reverts if called again. Call it immediately after deployment in the same script.

Step 6: Interact with Your Token

const tokenId = contractId; // from deployment above

// Check balance (returns raw integer string)
const balance = await client.queryContract(tokenId, 'balanceOf', [wallet.getAddress()]);
console.log('Balance:', balance);

// Transfer tokens to another address
await client.callContract(tokenId, 'transfer', [
  recipientAddress,
  '1000000000000000000', // 1 token (18 decimals)
]);

// Approve a spender
await client.callContract(tokenId, 'approve', [
  spenderAddress,
  '5000000000000000000', // 5 tokens
]);

// Query total supply
const supply = await client.queryContract(tokenId, 'totalSupply', []);
console.log('Total supply:', supply);

NEP-20 Function Reference

FunctionArgsDescription
init_tokenname, symbol, decimals, supplyInitialize token (once)
transferto, amountTransfer to address
approvespender, amountApprove spender
transferFromfrom, to, amountSpend approved tokens
balanceOfaddressQuery balance
allowanceowner, spenderQuery allowance
totalSupplyTotal supply
nameToken name
symbolToken symbol
decimalsDecimal places
mintto, amountMint new tokens (owner only)