Skip to content

Repository files navigation

Mintlayer Go SDK

A Go SDK for the Mintlayer blockchain.

go get github.com/mintlayer/go-sdk

Requires Go 1.21+. No CGO. The WASM cryptography runtime is embedded in the binary.


Documentation

GuideDescription
docs/indexer.mdFull indexer client reference: chain, blocks, transactions, addresses, pools, tokens, orders, statistics
docs/node.mdFull node client reference: chainstate, mempool, P2P, block submission
docs/wallet.mdFull wallet client reference: lifecycle, accounts, balances, transactions
docs/wasm.mdFull WASM client reference: keys, addresses, inputs, outputs, signing, fees
docs/transactions.mdStep-by-step guide to building and signing transactions without the wallet daemon
docs/staking.mdStaking pools and delegations: creation, funding, withdrawal, and read queries
docs/tokens.mdFungible token and NFT lifecycle: issuance, minting, freezing, authority, manual encoding

Overview

The SDK is organised as four independent sub-clients plus a top-level Client that wires them together.

PackagePurposeDefault port
github.com/mintlayer/go-sdk/nodeJSON-RPC 2.0 client for the node daemon3030 (mainnet)
github.com/mintlayer/go-sdk/indexerREST client for the indexer (api-web-server)3000
github.com/mintlayer/go-sdk/walletJSON-RPC 2.0 client for the wallet daemon3034 (mainnet)
github.com/mintlayer/go-sdk/wasmCryptography & transaction-building via WASM

Use the top-level client when you need multiple sub-clients, or import sub-packages directly when you only need one.


Quick start

package main
import (
"context""fmt""log"
sdk "github.com/mintlayer/go-sdk"
)
funcmain() {
client:=sdk.New(sdk.Config{
NodeURL: "http://127.0.0.1:3030",
IndexerURL: "http://127.0.0.1:3000",
WalletURL: "http://127.0.0.1:3034",
})
ctx:=context.Background()
// Query the chain tip from the indexer.tip, err:=client.Indexer.GetTip(ctx)
iferr!=nil {
log.Fatal(err)
}
fmt.Printf("chain tip: height=%d id=%s\n", tip.BlockHeight, tip.BlockID)
// Optionally initialise the embedded WASM cryptography runtime (~400 ms).iferr:=client.InitWASM(ctx); err!=nil {
log.Fatal(err)
}
deferclient.Close()
privKey, err:=client.WASM.MakePrivateKey()
iferr!=nil {
log.Fatal(err)
}
pubKey, err:=client.WASM.PublicKeyFromPrivateKey(privKey)
iferr!=nil {
log.Fatal(err)
}
addr, err:=client.WASM.PubkeyToPubkeyHashAddress(pubKey, sdk.Mainnet)
iferr!=nil {
log.Fatal(err)
}
fmt.Println("address:", addr)
}

Node client (node/)

JSON-RPC 2.0 client for the Mintlayer node daemon. Supports Basic Auth for nodes with authentication enabled.

import"github.com/mintlayer/go-sdk/node"c:=node.New("http://127.0.0.1:3030",
node.WithBasicAuth("user", "pass"), // optionalnode.WithTimeout(10*time.Second), // optional
)
ctx:=context.Background()
// Chain stateinfo, err:=c.ChainstateInfo(ctx)
height, err:=c.BestBlockHeight(ctx)
blockID, err:=c.BestBlockID(ctx)
// Look up a blockblockHex, err:=c.GetBlock(ctx, blockID)
blockJSON, err:=c.GetBlockJSON(ctx, blockID)
// Token / order infotokenInfo, err:=c.TokenInfo(ctx, "ttml1...")
orderInfo, err:=c.OrderInfo(ctx, "order1...")
// Mempoolerr=c.SubmitTransaction(ctx, signedTxHex, node.TrustPolicyUntrusted)
feeRate, err:=c.GetFeeRate(ctx, 1)
// P2PpeerCount, err:=c.GetPeerCount(ctx)
peers, err:=c.GetConnectedPeers(ctx)

Errors from the daemon are returned as *node.RPCError with a numeric Code and Message.


Indexer client (indexer/)

REST client for api-web-server. All paths are relative to /api/v2/.

import"github.com/mintlayer/go-sdk/indexer"c:=indexer.New("http://127.0.0.1:3000",
indexer.WithTimeout(15*time.Second), // optional
)
ctx:=context.Background()
// Chaintip, err:=c.GetTip(ctx)
blockIDAtHeight, err:=c.GetBlockIDAtHeight(ctx, 100_000)
// Blockblock, err:=c.GetBlock(ctx, "00000000...")
txIDs, err:=c.GetBlockTransactionIDs(ctx, "00000000...")
// Transactiontx, err:=c.GetTransaction(ctx, "aabbcc...")
txID, err:=c.SubmitTransaction(ctx, signedTxHex) // requires --enable-post-routes// Addressutxos, err:=c.GetSpendableUTXOs(ctx, "mxtc1...")
info, err:=c.GetAddressInfo(ctx, "mxtc1...")
// Pool / stakingpools, err:=c.ListPools(ctx, indexer.PoolListOpts{Sort: "by_pledge"})
pool, err:=c.GetPool(ctx, "pool1...")
// Tokenstoken, err:=c.GetToken(ctx, "ttml1...")
tokens, err:=c.FindTokensByTicker(ctx, "MYTOKEN", indexer.PageOpts{Items: 10})
// Ordersorders, err:=c.ListOrders(ctx, indexer.PageOpts{Offset: 0, Items: 20})
order, err:=c.GetOrder(ctx, "order1...")
// Statisticsstats, err:=c.GetCoinStatistics(ctx)

Non-2xx responses are returned as *indexer.HTTPError with a StatusCode field.


Wallet client (wallet/)

JSON-RPC 2.0 client for wallet-rpc-daemon. The wallet daemon manages key storage, signing, and broadcasting.

import"github.com/mintlayer/go-sdk/wallet"c:=wallet.New("http://127.0.0.1:3034",
wallet.WithBasicAuth("user", "pass"), // optional
)
ctx:=context.Background()
// Wallet lifecycleerr=c.OpenWallet(ctx, "/path/to/wallet.dat", "")
deferc.CloseWallet(ctx)
err=c.SyncWallet(ctx)
// Accounts and addressesinfo, err:=c.GetWalletInfo(ctx)
addr, err:=c.NewAddress(ctx, 0/*account*/)
balance, err:=c.GetBalance(ctx, 0)
// Send coins (account 0, auto fee)result, err:=c.AddressSend(ctx, wallet.SendParams{
Account: 0,
Address: "mxtc1...",
Amount: wallet.Amount{Atoms: "100000000000"}, // 1 MLSelectedUtxos: nil,
ChangeAddress: nil,
Options: nil,
})
fmt.Println("tx id:", result.TxID)
// Token operationsissueResult, err:=c.IssueToken(ctx, wallet.IssueTokenParams{
Account: 0,
Ticker: "MYTOKEN",
NumberOfDecimals: 2,
MetadataUri: "https://example.com/token",
DestinationAddress: addr,
TotalSupply: wallet.TokenTotalSupplyParams{Type: "Lockable"},
IsFreezable: "No",
Options: nil,
})
mintResult, err:=c.MintTokens(ctx, wallet.MintParams{
Account: 0,
TokenID: issueResult.TokenID,
Address: addr,
Amount: wallet.Amount{Atoms: "1000"},
Options: nil,
})
// Stakingerr=c.StartStaking(ctx, 0)
pools, err:=c.ListOwnedPools(ctx, 0)
// Compose and sign a raw transaction (cold wallet flow)composed, err:=c.ComposeTransaction(ctx, wallet.ComposeParams{...})
signed, err:=c.SignRawTransaction(ctx, 0, composed.Hex)
submitResult, err:=c.SubmitTransaction(ctx, signed.Hex, false)

WASM client (wasm/)

Cryptographic primitives and binary transaction encoding via an embedded WebAssembly module. Initialisation takes ~400 ms; use sync.Once or Client.InitWASM to call it once per process.

import (
"context"
mintlayer "github.com/mintlayer/go-sdk/wasm"
)
ctx:=context.Background()
c, err:=mintlayer.New(ctx)
iferr!=nil {
log.Fatal(err)
}
deferc.Close()
// Key derivation (BIP-44 path 44'/mintlayer_coin_type'/0')mnemonic:="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"accountKey, err:=c.MakeDefaultAccountPrivkey(mnemonic, mintlayer.Mainnet)
recvKey, err:=c.MakeReceivingAddress(accountKey, 0)
pubKey, err:=c.PublicKeyFromPrivateKey(recvKey)
addr, err:=c.PubkeyToPubkeyHashAddress(pubKey, mintlayer.Mainnet)
// Transaction buildingsrcID, err:=c.EncodeOutpointSourceId(txIDBytes, mintlayer.SourceTransaction)
input, err:=c.EncodeInputForUtxo(srcID, outputIndex)
output, err:=c.EncodeOutputTransfer(
mintlayer.NewAmount("100000000000"), // 1 MLdestAddr,
mintlayer.Mainnet,
)
tx, err:=c.EncodeTransaction(input, output, 0/*flags*/)
txID, err:=c.GetTransactionID(tx, true)
// Signingwitness, err:=c.EncodeWitness(
mintlayer.SigHashAll,
recvKey,
addr,
tx,
utxoBytes, // see examples/send-coins for encoding details0, // input index
mintlayer.TxAdditionalInfo{},
blockHeight,
mintlayer.Mainnet,
)
signedTx, err:=c.EncodeSignedTransaction(tx, witness)

See examples/send-coins/ for a complete end-to-end transaction flow.


Top-level client

sdk.New constructs only the sub-clients whose URL is non-empty.

// Node + WASM only — no wallet or indexer client is created.client:=sdk.New(sdk.Config{
NodeURL: "http://127.0.0.1:3030",
Username: "user",
Password: "pass",
})
// Call InitWASM before using client.WASM.iferr:=client.InitWASM(ctx); err!=nil {
log.Fatal(err)
}
deferclient.Close()

Convenience type aliases (sdk.Amount, sdk.Network, sdk.Mainnet, …) are re-exported so callers that only import the top-level package do not need to also import github.com/mintlayer/go-sdk/wasm.


Examples

ExampleDescription
examples/send-coins/Derive key → fetch UTXOs → build, sign, and submit a transaction
examples/issue-token/Issue a fungible token and mint an initial supply via the wallet daemon

Amounts

All coin and token amounts use the Amount type, which stores the value as a decimal string of atoms — the smallest indivisible unit. 1 ML = 100,000,000,000 atoms (11 decimal places).

one:=mintlayer.NewAmount("100000000000") // 1 MLzero:=mintlayer.NewAmountZero()
fmt.Println(one.Atoms()) // "100000000000"

The indexer and wallet clients use their own Amount struct with both Atoms and Decimal fields populated by the server.


Networks

ConstantValueUse
Mainnet0Production network
Testnet1Public test network
Regtest2Local regression testing
Signet3Signet

Pass the network constant to any function that derives addresses or encodes transactions.


Error handling

  • node.RPCError — JSON-RPC error from the node daemon (Code, Message)
  • wallet.RPCError — JSON-RPC error from the wallet daemon
  • indexer.HTTPError — non-2xx HTTP response from the indexer (StatusCode, Body)
  • WASM errors are plain error values with a descriptive message prefixed by mintlayer:.

About

Official Go SDK for interacting with the Mintlayer blockchain. Provides idiomatic Go clients for the node daemon, indexer API, and wallet RPC, plus an embedded WASM cryptography runtime for building, signing, and broadcasting transactions, all from a single top-level client.

Topics

Resources

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages