Skip to main content

Wallet client

The wallet module is a JSON-RPC 2.0 client for the Mintlayer wallet daemon (wallet-rpc-daemon). The daemon manages key storage, address derivation, signing and broadcasting.

use mintlayer_sdk::wallet;

let c = wallet::Client::new("http://127.0.0.1:3034");

// Or with options:
let c = wallet::Client::builder("http://127.0.0.1:3034")
.basic_auth("user", "pass") // optional
.timeout(std::time::Duration::from_secs(30)) // optional, default 30s
.build()?;

Default ports: 3034 (mainnet), 13034 (testnet).

Errors are returned as wallet::ErrorError::Rpc { code, message } for daemon errors, plus Http, Json, IdMismatch and ResponseTooLarge transport variants. Basic-auth credentials are redacted from Debug output; response bodies are capped at 64 MiB.


Transport security: loopback http:// is fine. For remote daemons use an https:// URL or an authenticated tunnel — basic-auth credentials and daemon-generated mnemonics otherwise transit in cleartext.

Wallet lifecycle

MethodRPC methodNotes
create_wallet(params: CreateWalletParams) -> Result<CreateWalletResult, Error>wallet_createReturns the mnemonic when the daemon generated one
recover_wallet(params: RecoverWalletParams) -> Result<(), Error>wallet_recoverRescans to recover balances
open_wallet(path: &str, password: Option<&str>) -> Result<(), Error>wallet_openNone password for unencrypted wallets
close_wallet() -> Result<(), Error>wallet_close
wallet_info() -> Result<WalletInfo, Error>wallet_infoId, account names, wallet kind
sync_wallet() -> Result<(), Error>wallet_syncSync to the tip
rescan_wallet() -> Result<(), Error>wallet_rescanFull rescan from genesis
best_block() -> Result<BestBlock, Error>wallet_best_block
encrypt_private_keys(password: &str) -> Result<(), Error>wallet_encrypt_private_keys
unlock_private_keys(password: &str) -> Result<(), Error>wallet_unlock_private_keys
lock_private_keys() -> Result<(), Error>wallet_lock_private_keys

CreateWalletParams { path, store_seed_phrase, mnemonic, passphrase, hardware_wallet } — set mnemonic: None to let the daemon generate a phrase. Mnemonic and passphrase fields are redacted from Debug output.

Accounts, addresses, balances

MethodRPC methodNotes
create_account(name: &str) -> Result<AccountInfo, Error>account_create
rename_account(account: u32, name: Option<&str>) -> Result<(), Error>account_renameNone clears the name
balance(account: u32) -> Result<Balance, Error>account_balanceConfirmed UTXOs only
new_address(account: u32) -> Result<String, Error>address_newFresh receive address
show_receive_addresses(account: u32) -> Result<Vec<AddressWithUsage>, Error>address_showUsage and balance per address
reveal_public_key(account: u32, address: &str) -> Result<RevealPublicKey, Error>address_reveal_public_key

Amount in requests typically sets only atoms (Amount::from_atoms(n)); daemon responses carry atoms and decimal.

Transactions

MethodRPC methodNotes
send(params: SendParams) -> Result<SendResult, Error>address_sendWallet selects UTXOs, computes fees
send_token(params: TokenSendParams) -> Result<SendResult, Error>token_send
sweep_spendable(params: SweepParams) -> Result<SendResult, Error>address_sweep_spendableall: true or explicit from_addresses
spend_utxo(params: UtxoSpendParams) -> Result<SendResult, Error>utxo_spendOptional htlc_secret
deposit_data(account: u32, data_hex: &str) -> Result<SendResult, Error>address_deposit_dataDataDeposit output
compose_transaction(params: ComposeParams) -> Result<ComposedTx, Error>transaction_composeUnsigned hex plus estimated fees
sign_raw_transaction(account: u32, raw_tx: &str) -> Result<SignedTx, Error>account_sign_raw_transactionCold-wallet flow
inspect_transaction(tx_hex: &str) -> Result<TxInspection, Error>transaction_inspectSignature stats and fees
submit_transaction(tx_hex: &str, do_not_store: bool) -> Result<SubmitResult, Error>node_submit_transactionSee the policy quirk below
list_transactions_by_address(account, address: Option<&str>, limit: u32) -> Result<Vec<WalletTx>, Error>transaction_list_by_addressNewest first
list_pending_transactions(account: u32) -> Result<Vec<String>, Error>transaction_list_pending
transaction(account: u32, tx_id: &str) -> Result<serde_json::Value, Error>transaction_getRaw JSON
abandon_transaction(account: u32, tx_id: &str) -> Result<(), Error>transaction_abandonUnconfirmed only

Quirk: submit_transaction always sends the hard-coded Trusted trust policy to the node, so the transaction must be fully valid against the current chainstate. There is no Untrusted variant; broadcast externally sourced transactions through the node client instead (node::Client::broadcast_transaction).

Most send methods take TxOptions { in_top_x_mb, broadcast_to_mempool }: in_top_x_mb targets the top X MB of the mempool for fee estimation; broadcast_to_mempool: Some(false) builds and signs without broadcasting while still returning the transaction hex.

Staking

See Staking for the full guide.

MethodRPC methodNotes
create_stake_pool(params: CreatePoolParams) -> Result<SendResult, Error>staking_create_pool
decommission_stake_pool(params: DecommissionParams) -> Result<SendResult, Error>staking_decommission_pool
list_owned_pools(account: u32) -> Result<Vec<OwnedPool>, Error>staking_list_pools
pool_balance(pool_id: &str) -> Result<Option<Amount>, Error>staking_pool_balance
start_staking(account: u32) -> Result<(), Error>staking_start
stop_staking(account: u32) -> Result<(), Error>staking_stop
staking_status(account: u32) -> Result<StakingStatus, Error>staking_statusStaking or NotStaking
create_delegation(params: CreateDelegationParams) -> Result<CreateDelegationResult, Error>delegation_create
delegate_staking(params: DelegateParams) -> Result<SendResult, Error>delegation_stake
withdraw_from_delegation(params: WithdrawParams) -> Result<SendResult, Error>delegation_withdraw
list_delegations(account: u32) -> Result<Vec<DelegationInfo>, Error>delegation_list_ids

Tokens and NFTs

See Tokens and NFTs for the full guide.

MethodRPC methodNotes
issue_token(params: IssueTokenParams) -> Result<IssueTokenResult, Error>token_issue_new
issue_nft(params: IssueNftParams) -> Result<IssueTokenResult, Error>token_nft_issue_new
mint_tokens(params: MintParams) -> Result<SendResult, Error>token_mint
unmint_tokens(params: UnmintParams) -> Result<SendResult, Error>token_unmint
lock_token_supply(params: LockSupplyParams) -> Result<SendResult, Error>token_lock_supplyIrreversible; note the field name below
freeze_token(params: FreezeParams) -> Result<SendResult, Error>token_freeze
unfreeze_token(params: UnfreezeParams) -> Result<SendResult, Error>token_unfreeze
change_token_authority(params: ChangeAuthorityParams) -> Result<SendResult, Error>token_change_authority

Quirk: LockSupplyParams names its account field account_index, not account — every other wallet params struct uses account.

Orders

See Tokens and NFTs for order creation outputs via crypto.

MethodRPC methodNotes
create_order(params: CreateOrderParams) -> Result<OrderCreated, Error>order_create
conclude_order(params: ConcludeOrderParams) -> Result<SendResult, Error>order_conclude
fill_order(params: FillOrderParams) -> Result<SendResult, Error>order_fillAmount is in the ask currency
freeze_order(params: FreezeOrderParams) -> Result<SendResult, Error>order_freeze
list_own_orders(account: u32) -> Result<Vec<OwnOrder>, Error>order_list_own
list_all_active_orders(params: ListOrdersParams) -> Result<Vec<ActiveOrder>, Error>order_list_all_activeOptional currency filters

Example

use mintlayer_sdk::wallet::{self, Amount, SendParams, TxOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let c = wallet::Client::new("http://127.0.0.1:3034");

c.open_wallet("/path/to/wallet.dat", None).await?;
c.sync_wallet().await?;

let balance = c.balance(0).await?;
println!("coins: {:?}", balance.coins.atoms());

let result = c.send(SendParams {
account: 0,
address: "mtc1q...".into(),
amount: Amount::from_atoms(100_000_000_000), // 1 ML
selected_utxos: vec![],
options: TxOptions::default(),
}).await?;
println!("tx {} broadcast: {}", result.tx_id, result.broadcasted);
Ok(())
}