Skip to main content

How to use a single nominator pool

tip

Before proceeding with this tutorial, we recommend familiarizing yourself with the single nominator pool specification.

Set up single nominator mode

caution

Before starting, ensure you have topped up and activated the validator's wallet.

  1. Enable single nominator mode:
MyTonCtrl> enable_mode single-nominator
  1. Verify if single nominator mode is enabled:
MyTonCtrl> status_modes
Name Status Description
single-nominator enabled Orbs's single nominator pools.
  1. Create a pool:
MyTonCtrl> new_single_pool <pool-name> <owner_address>

If you have already created a pool, you can import it:

MyTonCtrl> import_pool <pool-name> <pool-addr>
  1. Display pool addresses using pools_list:
MyTonCtrl> pools_list
Name Status Balance Version Address
test-pool empty 0.0 spool_r2 kf_JcC5pn3etTAdwOnc16_tyMmKE8-ftNUnf0OnUjAIdDJpX
  1. Activate the pool:
MyTonCtrl> activate_single_pool <pool-name>

After successfully activating the pool:

MyTonCtrl> pools_list
Name Status Balance Version Address
test-pool active 0.99389 spool_r2 kf_JcC5pn3etTAdwOnc16_tyMmKE8-ftNUnf0OnUjAIdDJpX

You can manage this pool via MyTonCtrl like a standard nominator pool.

info

If the pool's balance is sufficient to participate in both rounds (balance > min_stake_amount * 2), MyTonCtrl will automatically participate in both rounds using stake = balance / 2, unless you manually set the stake using the set stake command. This behavior differs from using a nominator pool but resembles staking with a validator wallet.

Start without MyTonCtrl

Prepare a launched validator

If you have MyTonCtrl installed and a validator running:

  1. Stop validation and withdraw all funds.

Prepare from scratch

If you have no prior validator setup, follow these steps:

  1. Run a validator and ensure it is synced.
  2. Stop validation and withdraw all funds.

Prepare single nominator

  1. Install Node.js v.16 or later and npm (detailed instructions).
  2. Install ts-node and the arg module:
$ sudo apt install ts-node
$ sudo npm i arg -g
  1. Create symlinks for compilers:
$ sudo ln -s /usr/bin/ton/crypto/fift /usr/local/bin/fift
$ sudo ln -s /usr/bin/ton/crypto/func /usr/local/bin/func
  1. Run a test to verify the setup:
$ npm run test
  1. Replace MyTonCtrl nominator-pool scripts: Install pool scripts.

Create a single nominator pool

  1. Obtain a Toncenter API key from @tonapibot on Telegram.
  2. Set environment variables:
export OWNER_ADDRESS=<owner_address>
export VALIDATOR_ADDRESS=<validator_wallet_address>
export TON_ENDPOINT=https://toncenter.com/api/v2/jsonRPC
export TON_API_KEY=<toncenter_api_key>
  1. Create a deployer address:
$ npm run init-deploy-wallet
Insufficient Deployer [EQAo5U...yGgbvR] funds 0
  1. Top up the deployer address with 2.1 TON.
  2. Deploy the pool contract to get the pool address (Ef-kC0..._WLqgs):
$ npm run deploy
  1. Convert the address to .addr:
$ fift -s ./scripts/fift/str-to-addr.fif Ef-kC0..._WLqgs

(Saving address to file single-nominator.addr)

  1. Back up the deployer private key (./build/deploy.config.json) and single-nominator.addr files.
  2. Copy single-nominator.addr to mytoncore/pools/single-nominator-1.addr.
  3. Send a stake from the owner's address to the single nominator's address.

Withdrawals from the single nominator

Using wallets to withdraw

Fift:

  1. Create a withdraw.boc request with the desired amount:
$ fift -s ./scripts/fift/withdraw.fif <withdraw_amount>
  1. Create and sign the request from the owner's wallet:
$ fift -s wallet-v3.fif <my-wallet> <single_nominator_address> <sub_wallet_id> <seqno> <amount=1> -B withdraw.boc
  1. Broadcast the query:
$ lite-client -C global.config.json -c 'sendfile wallet-query.boc'

Tonkeeper:

  1. Create a withdraw.boc request with the desired amount:
$ fift -s ./scripts/fift/withdraw.fif <withdraw_amount>
  1. Send the request to the single nominator address:
$ tons wallet transfer <my-wallet> <single_nominator_address> <amount=1> --body withdraw.boc
  1. Link TypeScript:
npm link typescript
  1. Generate a deeplink:
npx ts-node scripts/ts/withdraw-deeplink.ts <single-nominator-addr> <withdraw-amount>
  1. Open the deeplink on the owner's phone.

Deposit to pool

You can deposit using MyTonCtrl with the following commands:

MyTonCtrl> mg <from-wallet-name> <pool-account-addr> <amount>

or

MyTonCtrl> deposit_to_pool <pool-addr> <amount>

Alternatively, follow these steps:

  1. Navigate to the pool’s page: https://tonscan.org/nominator/{pool_address}.
  2. Ensure the pool information is displayed correctly. If the pool has an incorrect smart contract, no information will appear.
  3. Click the ADD STAKE button or scan the QR code using Tonkeeper or another TON wallet.
  4. Enter the TON amount and send the transaction. The TON coins will then be added to staking.

If the wallet does not open automatically, manually send the transaction by copying the pool address and using any TON wallet. Note that 1 TON will be deducted as a commission for processing the deposit.

Withdraw funds

You can withdraw funds using the following command:

MyTonCtrl> withdraw_from_pool <pool-addr> <amount>

Alternatively, create and send the transaction manually:

import { Address, beginCell, internal, storeMessageRelaxed, toNano } from "@ton/core";

async function main() {
const single_nominator_address = Address.parse('single nominator address');
const WITHDRAW_OP = 0x1000;
const amount = 50000;

const messageBody = beginCell()
.storeUint(WITHDRAW_OP, 32) // op code for withdrawal
.storeUint(0, 64) // query_id
.storeCoins(amount) // amount to withdraw
.endCell();

const internalMessage = internal({
to: single_nominator_address,
value: toNano('1'),
bounce: true,
body: messageBody
});
}

Election process

Set up a single nominator pool

Configure the single nominator pool contract using the following instructions.

Join the elections

Deposit the minimum stake amount into the single nominator pool.

MyTonCtrl will automatically join the elections. You can set the stake amount that MyTonCtrl sends to the elector contract approximately every 18 hours on Mainnet and 2 hours on Testnet.

MyTonCtrl> set stake 90000

Find the minimum stake amount using the status command.

You can set stake to null, which will calculate based on the stakePercent value (check with status_settings).

Verify if the election has started:

MyTonCtrl> status

For Testnet:

MyTonCtrl> status fast

Example:

If the election has started and the single nominator pool is activated, the validator will automatically send an ElectorNewStake message to the elector contract at the beginning of the next round.

Check the validator wallet:

MyTonCtrl> wl
Name Status Balance Ver Wch Address
validator_wallet_001 active 995.828585374 v1 -1 kf_dctjwS4tqWdeG4GcCLJ53rkgxZOGGrdDzHJ_mxPkm_Xct

Check the transaction history:

MyTonCtrl> vas kf_dctjwS4tqWdeG4GcCLJ53rkgxZOGGrdDzHJ_mxPkm_Xct
Address Status Balance Version
kf_dctjwS4tqWdeG4GcCLJ53rkgxZOGGrdDzHJ_mxPkm_Xct active 995.828585374 v1r3

Code hash
c3b9bb03936742cfbb9dcdd3a5e1f3204837f613ef141f273952aa41235d289e

Time Coins From/To
39 minutes ago >>> 1.3 kf_hz3BIXrn5npis1cPX5gE9msp1nMTYKZ3l4obzc8phrBfF

This ElectorNewStake transaction appears in the single nominator contract history on Tonviewer:

In this example, MyTonCtrl automatically staked 90000 Toncoins on the elector contract.

Check validator status

At the beginning of the next round, check the validator status with the status command (status fast on Testnet).

Confirm if your node has become a full validator by checking:

  1. Validator efficiency – The local validator's efficiency should be green and not n/a.
  2. Validator index – The validator index should be greater than -1.

Check profit

At the end of the round, MyTonCtrl sends an ElectorRecoverStakeRequest message to the elector contract. It returns stake + profit to your single nominator pool.

You can also check the pool's transaction history with the vas command:

Stop participating

If you no longer wish to participate in validation:

  1. Disable validator mode:
MyTonCtrl> disable_mode validator
  1. Withdraw all funds from the single nominator contract to the owner wallet.

Transitioning a regular validator to nominator pool mode

  1. Disable the validator mode to stop participating in elections.
  2. Wait for both stakes to return from the elector.
  3. Follow the steps to set up a single nominator pool.

Single nominator pool client

Run a single nominator pool with a vesting contract

Initially, the owner of the vesting contract manages it with their wallet contract. This scheme involves managing interactions between multiple contracts.

ContractsInterface for managing
validator_walletMyTonCtrl
vestingvesting.ton.org
owner_walletApps like Tonkeeper or MyTonWallet
single_nominator_poolMyTonCtrl
  • owner_wallet – The TON wallet that owns the vesting.
caution

Ensure you have backed up the vesting owner_wallet recovery phrase. If you lose access to the owner_wallet, you will also lose access to managing the vesting funds, and recovery will be impossible.

  1. Run a full node and wait for it to sync.
  2. Enable validator mode and retrieve the wallet_v1 address created during installation using MyTonCtrl wl.
  3. Send 200 TON (for monthly expenses) to the validator_wallet.
  4. Create a single_nominator_pool:
MyTonCtrl> new_single_pool <pool-name> <vesting>

Example:

MyTonCtrl> new_single_pool my_s_pool EQD...lme-D
  1. Activate the single_nominator_pool:
MyTonCtrl> activate_single_pool <pool-name>

Example:

MyTonCtrl> activate_single_pool my_s_pool
  1. After the single_nominator_pool address appears on-chain, request whitelisting from the person who provided the vesting contract.
  2. Once whitelisted, you can send locked tokens from the vesting contract to the single_nominator_pool using vesting.ton.org:
    • a. Connect the owner_wallet on vesting.ton.org.
    • b. Test by sending 10 TON from vesting to the single_nominator_pool.
    • c. Return the remaining funds (~8 TON) to vesting with a message [amount 0, comment w] via the vesting.ton.org interface.
    • d. Confirm the remaining funds are received in vesting.
  3. Transfer the required TON amount from vesting to single_nominator_pool for both cycles.
  4. Wait for the validators’ voting.