Contractless/docs/TOKEN_SWAPS.md

17 KiB

Tokens and Swaps

Contractless supports native fungible tokens and native two-party swaps. Token creation, additional issuance, token burns, token lookup, and swap creation are handled by CLI tools that create or inspect native transaction types.

This guide covers:

  • Creating tokens with create_tokens_tx
  • Issuing more tokens with create_issue_token_tx
  • Burning tokens with create_burn_tx
  • Looking up tokens with lookup_token and lookup_token_list
  • Creating and second-signing swaps with create_swap_tx and verify_sign_swap_tx

On Windows, add .exe to each command name.

When a tool asks for a wallet path or transaction file path, press <Tab> to search and auto-complete files and folders.

Important Token Model

Contractless token creation tools mint tokens directly to the wallet that creates the token transaction.

These are not smart-contract tokens. They are not released by programmable vesting rules, bonding curves, administrator contracts, or contract-controlled supply schedules. When a token creation transaction confirms, the full initial supply is credited to the creator wallet. When an issue-more transaction confirms, the additional supply is credited directly to the original creator wallet.

If a creator wants a timed release, public sale, treasury distribution, or external business rule, that must be handled outside the token creation transaction. The chain records the native token supply and balances; it does not run token-sale contract logic.

Token amounts are entered in display units but stored in atomic units. One display token equals 100000000 atomic units.

Example:

1 token      = 100000000 atomic units
1000 tokens = 100000000000 atomic units

The CLI tools usually ask for display units and then write atomic units into the saved transaction JSON.

CLI Tools

Tool Purpose
create_tokens_tx Creates and signs a new token creation transaction.
create_issue_token_tx Creates and signs an additional-issuance transaction for an existing token.
create_swap_tx Creates the first-signed side of a two-party swap.
verify_sign_swap_tx Lets the counterparty verify terms, sign the second side, and save the completed swap.
create_burn_tx Creates and signs a token or NFT burn transaction.
lookup_token Looks up one token by ticker/name.
lookup_token_list Lists known tokens from the connected node.

Creation tools save signed transaction JSON under:

./transactions/<hash>.json

Saving a transaction file does not broadcast it. Submit saved transactions with broadcast_transaction or with the GUI wallet import/broadcast flow.

Token Creation

Use create_tokens_tx to create a new fungible token.

Usage:

create_tokens_tx

The transaction type is 3.

Token Creation Fields

Field Size Meaning
txtype 1 byte Transaction type. For token creation this is 3.
time / timestamp 4 bytes UTC timestamp when the transaction is created.
creator 22 bytes Creator short address. The initial supply is credited here.
ticker 15 bytes Unique token ticker/name, padded to 15 bytes.
number 8 bytes Initial token supply in atomic units.
hard_limit 1 byte 1 means hard capped forever; 0 means the creator may issue more later.
txfee 8 bytes Base-currency transaction fee. Minimum is 500 CLC or CLTC.
signature 666 bytes Creator signature.

Prompts

create_tokens_tx asks for:

Prompt What To Enter
Ticker / token name A unique 3 to 15 character alphanumeric token name.
Amount to create Initial supply in display tokens, such as 1, 1000, or 100000.
Hard cap 1 for yes, 0 for no.
Fee Minimum 500 CLC or CLTC.
Wallet path Path to the creator wallet file.
Wallet key Creator wallet decryption key.

Token names are normalized to lowercase alphanumeric identifiers and stored in a fixed 15-byte field. The name must be globally unique. The first confirmed transaction for a ticker owns that ticker.

The base coin ticker is reserved and cannot be created as a custom token.

Hard Cap

The hard cap choice is permanent.

If hard_limit = 1, no future create_issue_token_tx transaction can issue more supply for that token.

If hard_limit = 0, only the original creator wallet may issue more supply later.

Output Shape

The saved JSON includes a hash field so the file can be named and later broadcast:

{
  "txtype": 3,
  "timestamp": 1780000000,
  "creator": "creator_short_address.cltc",
  "ticker": "example        ",
  "number": 100000000000,
  "hard_limit": 0,
  "txfee": 50000000000,
  "hash": "transaction_hash",
  "signature": "creator_signature"
}

In this example, number = 100000000000 means 1000 display tokens.

Issuing More Tokens

Use create_issue_token_tx to issue more units of an existing token.

Usage:

create_issue_token_tx

The transaction type is 11.

Additional issuance is only valid when:

  • The token already exists.
  • The token was created with hard_limit = 0.
  • The signing wallet is the original token creator.
  • The creator has enough base currency for the issue-token fee.

When the transaction confirms, the newly issued tokens are credited directly to the original creator wallet.

Issue More Fields

Field Size Meaning
txtype 1 byte Transaction type. For issue-more this is 11.
time / timestamp 4 bytes UTC timestamp when the transaction is created.
creator 22 bytes Original creator short address. New supply is credited here.
ticker 15 bytes Existing token ticker/name, padded to 15 bytes.
number 8 bytes Additional supply in atomic units.
txfee 8 bytes Base-currency transaction fee. Minimum is 100 CLC or CLTC.
signature 666 bytes Creator signature.

Prompts

create_issue_token_tx asks for:

Prompt What To Enter
Ticker / token name Existing token name.
Additional tokens Amount to add in display tokens.
Fee Minimum 100 CLC or CLTC.
Wallet path Path to the original creator wallet file.
Wallet key Creator wallet decryption key.

Output Shape

{
  "txtype": 11,
  "timestamp": 1780000000,
  "creator": "creator_short_address.cltc",
  "ticker": "example        ",
  "number": 50000000000,
  "txfee": 10000000000,
  "hash": "transaction_hash",
  "signature": "creator_signature"
}

In this example, number = 50000000000 means 500 additional display tokens.

Burning Tokens

Use create_burn_tx to permanently destroy a token or NFT balance.

Usage:

create_burn_tx

The transaction type is 10.

The base coin cannot be burned with this transaction type.

Burn Fields

Field Size Meaning
txtype 1 byte Transaction type. For burn this is 10.
time / timestamp 4 bytes UTC timestamp when the transaction is created.
address 22 bytes Wallet address burning the asset.
coin 15 bytes Token or NFT base name, padded to 15 bytes.
nft_series 4 bytes 0 for fungible tokens or one-of-one NFTs; series item number for numbered NFTs.
value 8 bytes Amount to burn in atomic units. NFT burns must use exactly 100000000.
txfee 8 bytes Base-currency transaction fee. Minimum is 0.0001 CLC or CLTC.
signature 666 bytes Burner signature.

Prompts

create_burn_tx asks for:

Prompt What To Enter
Token or NFT name Asset name to burn. Base coin is rejected.
NFT series number 0 for standard tokens or one-of-one NFTs; item number for collection NFTs.
Burn amount Token amount in display units. Use 1.0 for NFTs.
Fee Minimum 0.0001 CLC or CLTC.
Wallet path Path to the wallet that owns the asset.
Wallet key Wallet decryption key.

For fungible tokens, value may be any positive amount the wallet owns.

For NFTs, the burn must destroy exactly one full NFT unit. The CLI prompt says to use 1.0; internally that becomes 100000000.

Token Lookup

Use lookup_token to inspect one token by name.

Usage:

lookup_token <token_name>

Example:

lookup_token example

The tool asks for a wallet path and wallet key for authenticated RPC handshake. The lookup does not spend funds.

Expected output:

{
  "token_name": "example",
  "genesis": "creation_transaction_hash",
  "creator": "creator_short_address.cltc",
  "token_count": 1500.0,
  "token_spread": "2 addresses",
  "hard_limit": false,
  "issued_hashes": [
    "issue_transaction_hash"
  ],
  "burned_hashes": [
    "burn_transaction_hash"
  ]
}

Field meanings:

Field Meaning
token_name Token ticker/name.
genesis Token creation transaction hash.
creator Original creator wallet.
token_count Current supply after issuance and burns, displayed in whole-token units.
token_spread Number of addresses holding the token.
hard_limit Whether additional issuance is permanently blocked.
issued_hashes Confirmed issue-more transaction hashes.
burned_hashes Confirmed burn transaction hashes.

Token List

Use lookup_token_list to list known tokens from the connected node.

Usage:

lookup_token_list

The tool asks for a wallet path and wallet key for authenticated RPC handshake. The lookup does not spend funds.

Expected output:

{
  "tokens": [
    {
      "token": "example",
      "hash": "creation_transaction_hash"
    }
  ]
}

If the connected node has no token entries, the output is:

{
  "tokens": []
}

Swaps

Contractless swaps are native two-party transactions. A swap has one shared unsigned transaction body and two signatures:

  • signature1 from sender1
  • signature2 from sender2

There is no automatic match-making service in the CLI tools. Before creating a swap, the two parties must already agree on the trade terms off-chain. The first signer creates the offer, saves the transaction file, and sends that file to the counterparty. The counterparty verifies the terms, signs the second half, and then the completed transaction can be broadcast.

The CLI does not find counterparties for you.

The transaction type is 6.

Creating a Swap Offer

Use create_swap_tx to create the first-signed swap offer.

Usage:

create_swap_tx

The active wallet becomes sender1.

Swap Fields

Field Size Meaning
txtype 1 byte Transaction type. For swaps this is 6.
timestamp 4 bytes UTC time when the offer is created.
offer_expiration 4 bytes UTC expiration timestamp. Must not be earlier than timestamp or more than 30 days later.
ticker1 15 bytes Asset offered by sender1.
nft_series1 4 bytes 0 for fungible assets and one-of-one NFTs; numbered NFT item for series NFTs.
value1 8 bytes Amount offered by sender1, in atomic units.
ticker2 15 bytes Asset expected from sender2.
nft_series2 4 bytes 0 for fungible assets and one-of-one NFTs; numbered NFT item for series NFTs.
value2 8 bytes Amount expected from sender2, in atomic units.
sender1 22 bytes First signer short address.
sender2 22 bytes Counterparty short address.
tip1 8 bytes Miner tip paid from sender1 asset side.
tip2 8 bytes Miner tip paid from sender2 asset side.
txfee1 8 bytes Base-currency fee paid by sender1. Minimum is 1 CLC or CLTC.
txfee2 8 bytes Base-currency fee paid by sender2. Minimum is 1 CLC or CLTC.
signature1 666 bytes Sender1 signature.
signature2 666 bytes Sender2 signature. Present only after the counterparty signs.

Swap Prompts

create_swap_tx asks for:

Prompt What To Enter
Coin or token to send Base coin or token/NFT name offered by sender1.
NFT series number to send 0 for coins/tokens/one-of-one NFTs; item number for series NFTs.
Amount to send Amount in display units. Use 1 for NFTs.
Coin or token to receive Base coin or token/NFT name expected from sender2.
NFT series number to receive 0 for coins/tokens/one-of-one NFTs; item number for series NFTs.
Amount to receive Amount in display units. Use 1 for NFTs.
Wallet path Path to sender1 wallet.
Wallet key Sender1 wallet decryption key.
Counterparty address Sender2 short address or vanity address.
First miner tip Tip paid from sender1 asset side.
Second miner tip Tip paid from sender2 asset side.
Fee you will pay Sender1 base-currency fee. Minimum 1.
Fee other party will pay Sender2 base-currency fee. Minimum 1.
Hours until offer expires Expiration window in hours. Maximum effective window is 30 days.

Swap Fees and Tips

Each party pays:

  • A base-currency swap fee of at least 1 CLC or CLTC.
  • A miner tip for their offered asset side.

For fungible assets, the tip must be at least 1% of the offered amount. The tip is paid in the asset being offered by that side.

For NFT sides, the tip must be 0 because NFTs cannot be fractionally tipped.

Each party must have enough balance for:

  • The offered amount.
  • The offered-side tip.
  • The base-currency transaction fee.

Swap Expiration

Swap offers expire. The expiration timestamp must be:

  • Not earlier than the creation timestamp.
  • Not more than 30 days after the creation timestamp.
  • Still in the future when the completed transaction is broadcast.

The transaction timestamp must also be within the normal 30-day transaction window.

Output Shape

create_swap_tx creates a partially signed transaction:

{
  "txtype": 6,
  "timestamp": 1780000000,
  "offer_expiration": 1780259200,
  "ticker1": "example        ",
  "nft_series1": 0,
  "value1": 100000000000,
  "ticker2": "CLTC           ",
  "nft_series2": 0,
  "value2": 5000000000,
  "sender1": "sender1_short_address.cltc",
  "sender2": "sender2_short_address.cltc",
  "tip1": 1000000000,
  "tip2": 50000000,
  "txfee1": 100000000,
  "txfee2": 100000000,
  "hash": "swap_hash",
  "signature1": "sender1_signature"
}

This file is not ready to broadcast yet because it has no signature2.

Counterparty Signing

The counterparty uses verify_sign_swap_tx to inspect and sign the offer.

Usage:

verify_sign_swap_tx <path/to/file.json>

The tool:

  1. Loads the swap JSON file.
  2. Loads the counterparty wallet.
  3. Confirms the active wallet matches sender2.
  4. Shows the received amount, sent amount, fee, and tip.
  5. Asks yes/no verification questions.
  6. Recomputes the swap hash.
  7. Signs only if the included hash matches the transaction body.
  8. Saves a completed transaction JSON with both signature1 and signature2.

The completed file is saved under:

./transactions/<hash>.json

After both signatures exist, either party can broadcast the transaction.

Swap Safety Checklist

Before signing the second half of a swap, the counterparty should verify:

  • The wallet address is their wallet address.
  • The asset they receive is correct.
  • The amount they receive is correct.
  • The asset they send is correct.
  • The amount they send is correct.
  • The fee they pay is acceptable.
  • The tip they pay is acceptable.
  • The offer has not expired.
  • The file came from the expected counterparty.

Because there is no match-making service, the transaction file must be exchanged manually. Common methods include email, direct message, file sharing, or another off-chain communication channel.

Broadcasting

All creation tools in this guide create transaction JSON files. They do not mine or confirm the transaction by themselves.

To finish a transaction:

  1. Create and sign the JSON file.
  2. For swaps, have the counterparty verify and second-sign the JSON file.
  3. Broadcast the completed file with broadcast_transaction or the GUI wallet.
  4. Wait for confirmation.

Common Problems

Problem Likely Cause
Token creation rejected Ticker already exists, ticker is reserved, creator wallet is not registered, or fee is below 500.
Issue-more rejected Token is hard capped, token does not exist, signer is not the original creator, amount is zero, or fee is below 100.
Burn rejected Asset does not exist, base coin was selected, wallet lacks balance, NFT value is not exactly 1.0, or fee is below 0.0001.
Swap rejected Missing second signature, bad signature, insufficient balance, expired offer, bad asset name, missing token/NFT, fee below 1, or tip below the required amount.
Counterparty cannot sign swap The active wallet does not match sender2, or the transaction hash no longer matches the file contents.