We use necessary cookies for site function. For analytics and marketing, we need your consent. You can change your mind anytime. Privacy Policy
Olvis Gil · September 27, 2026 · 9 min readIf you write Go services and need to move money on-chain, Stellar is the friendliest integration you will find this side of a REST API. There is an official SDK maintained by the Stellar Development Foundation — go-stellar-sdk — and a community CLI that wraps it for humans and scripts — stellar-go-cli. This guide goes from zero to a signed payment on testnet, then to a deployed Soroban smart contract, all without leaving the Go ecosystem.
Ledgers close every ~5 seconds and confirmed transactions are final — no reorgs, no "wait N confirmations" logic in your service code.
A 100-stroop base fee (0.00001 XLM) makes micropayments, streaming payments, and machine-to-machine settlement actually viable.
Native USDC, a built-in decentralized exchange, and anchor fiat rails mean a payment API is already half-built before you write a line.
go-stellar-sdk is maintained by the Stellar Development Foundation — txnbuild, Horizon and RPC clients, XDR primitives, plus ingestion and processor libraries for data pipelines.
Services, CLIs, daemons, ETL jobs — the places Go dominates are exactly the places blockchain integration code runs.
One bit of history worth knowing: the SDK repo used to be the SDF Go monorepo (github.com/stellar/go). In October 2025 it was refactored into a focused SDK — services like Horizon, Galexie, and Friendbot moved to their own repositories. If you find old imports using github.com/stellar/go/..., they resolve to the same codebase; new projects should use the go-stellar-sdk path.
mkdir stellar-pay && cd stellar-pay
go mod init stellar-pay
# Official SDF SDK — the building blocks
go get github.com/stellar/go-stellar-sdk@latest
# Community CLI that wraps it — for terminal + scripting work
go install github.com/stellar-go-cli/stellar-go-cli/cmd/stellar-go-cli@latestNext you need an account and test funds. Generate a keypair with keypair.Random() (or let the CLI create a wallet for you), then hit Friendbot — the testnet faucet:
# Generate a testnet keypair in code:
# kp, _ := keypair.Random()
# fmt.Println(kp.Address()) // G...
# fmt.Println(kp.Seed()) // S...
# Then fund it with Friendbot (10,000 test XLM):
curl "https://friendbot.stellar.org/?addr=GABC...YOUR_ADDRESS"Every Stellar transaction follows the same pipeline: load the source account (for its sequence number), describe operations, assemble the envelope, sign against the network passphrase, submit. Here is a complete payment in about 40 lines:
package main
import (
"fmt"
"log"
"github.com/stellar/go-stellar-sdk/clients/horizonclient"
"github.com/stellar/go-stellar-sdk/keypair"
"github.com/stellar/go-stellar-sdk/network"
"github.com/stellar/go-stellar-sdk/txnbuild"
)
func main() {
// Testnet secret — never hardcode a real secret key
kp := keypair.MustParseFull("SXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
client := horizonclient.DefaultTestNetClient
// 1. Load the source account (gets the current sequence number)
sourceAccount, err := client.AccountDetail(horizonclient.AccountRequest{
AccountID: kp.Address(),
})
if err != nil {
log.Fatal(err)
}
// 2. The operation: send 10 XLM
payment := txnbuild.Payment{
Destination: "GYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
Amount: "10",
Asset: txnbuild.NativeAsset{},
}
// 3. Assemble the transaction envelope
tx, err := txnbuild.NewTransaction(txnbuild.TransactionParams{
SourceAccount: &sourceAccount,
IncrementSequenceNum: true,
BaseFee: txnbuild.MinBaseFee,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewTimeout(300),
},
Operations: []txnbuild.Operation{&payment},
})
if err != nil {
log.Fatal(err)
}
// 4. Sign for the testnet passphrase and submit
tx, err = tx.Sign(network.TestNetworkPassphrase, kp)
if err != nil {
log.Fatal(err)
}
resp, err := client.SubmitTransaction(tx)
if err != nil {
log.Fatal(err)
}
fmt.Println("Paid! Hash:", resp.Hash)
}Run it and you get back a transaction hash — the payment is already final, roughly five seconds after submission. Swap txnbuild.NativeAsset{} for txnbuild.CreditAsset{Code: "USDC", Issuer: "..."} and the same code sends stablecoins. Batch operations into one transaction and you get atomic settlement of up to 100 payments for one base fee — the trick payroll and disbursement services are built on.
Writing forty lines to test a payment idea is fine in a service; in a shell it is friction. stellar-go-cli wraps the SDK so the same operation is one command — and because it is a real binary, it composes with bash, cron, and CI:
# One-time setup
stellar-go-cli init
stellar-go-cli wallet connect --provider stellar --network stellar-testnet
stellar-go-cli wallet fund --network stellar-testnet # Friendbot under the hood
# The same payment — one line, no boilerplate
stellar-go-cli pay send --to GYYYY... --amount 10 --asset XLM
stellar-go-cli wallet balanceUnder the hood it is doing exactly what the Go program did — account lookup, txnbuild, signing, submission — plus the operational extras you end up wanting:swap quote/execute for DEX path payments, asset trust for trustlines, claimable balances for async payouts, and report iso20022 to export payments as banking-standard XML.
Stellar's contract platform is Soroban — contracts compile to WebAssembly and the canonical toolchain is Rust. Go's role is everything around the contract: deploying the WASM, invoking methods, simulating reads, and orchestrating workflows. From the terminal:
# Deploy a compiled Soroban WASM contract — pure Go, no stellar CLI needed
stellar-go-cli contract deploy --wasm hello_contract.wasm --network stellar-testnet
# → prints Contract ID (C...) and saves it to your config
# Call a method on it
stellar-go-cli contract invoke --fn increment
# Read-only call — simulated, nothing submitted on-chain
stellar-go-cli contract invoke --fn get_count --simulateThe same functionality lives in the CLI's public pkg/soroban package — a pure-Go RPC client you can import when you want contract calls inside a service rather than a script:
// The CLI's Soroban client is a public Go package you can import:
import (
"context"
"github.com/stellar-go-cli/stellar-go-cli/pkg/soroban"
"github.com/stellar/go-stellar-sdk/keypair"
)
client := soroban.NewClientForNetwork("stellar-testnet")
defer client.Close()
kp := keypair.MustParseFull("S...")
// Submit a real invocation — simulate, assemble, sign, send, poll: done for you
res, err := client.Invoke(ctx, kp, "CDEF...CONTRACT_ID", "increment", nil)
// res.TxHash is your on-chain receipt
// Read-only path — simulation only, no fees, no signature needed
ret, err := client.SimulateOnly(ctx, "CDEF...CONTRACT_ID", "get_count", nil)If you need full control, the official SDK exposes the same primitives directly: build a txnbuild.InvokeHostFunction operation, simulate it with clients/rpcclient to get the Soroban transaction data and auth entries, rebuild, sign, send, and poll GetTransaction until it lands. That is literally the loop the CLI runs for you — worth knowing, worth not typing by hand.
If you run disbursements or payroll on the Stellar Disbursement Platform, you already know the hard part is rarely the blockchain hop — it is the paperwork after it. NGOs and payroll providers routinely need to hand a pain.001 (batch disbursement initiation) or a camt.054 (settlement notification) to a bank, donor, or auditor — and today that usually means a hand-built spreadsheet. The CLI ships pkg/iso20022, a Go package that turns Stellar payments into ISO 20022 XML validated against the official XSDs:
pain.001 — one disbursement batch, N receivers (name, phone/email, or wallet handle as a proxy), with NbOfTxs/CtrlSum computed automaticallycamt.054 — settlement notifications back to the org or donorpacs.008/.002/.004/.009 — per-transaction and batch interbank messagesCcy="XXX" with the asset code and issuer preserved in SplmtryData, so USDC from different issuers stays distinguishable — a detail that matters to compliance teamsimport (
"github.com/stellar-go-cli/stellar-go-cli/pkg/iso20022"
"github.com/stellar-go-cli/stellar-go-cli/pkg/models"
)
// One batch disbursement, N receivers — NbOfTxs / CtrlSum computed for you
xmlDoc, err := iso20022.BuildPain001(
[]*iso20022.CreditTransferInstruction{
{
Payment: &models.Payment{
ID: "pay-001", To: "GRCVR1...", Amount: "10", Asset: "USDC",
},
Creditor: &iso20022.Party{
Name: "Receiver One", Phone: "+221-77XXXXXXX",
},
},
},
&iso20022.Pain001Options{
InitiatingParty: &iso20022.Party{Name: "Relief Org"},
Debtor: &iso20022.Party{AcctID: "GORG...", AgentBIC: "DEUTDEFF"},
},
)From the shell, stellar-go-cli report iso20022 --type pacs.008 does the same job over your payment history — which means it can slot into an SDP deployment two ways: as an integration inside the disbursement pipeline, or as a standalone CLI step run over the SDP API after a batch settles. If your org moves aid or payroll on Stellar and someone downstream is asking for ISO 20022 files, this is the shortest path from ledger entry to bank-grade XML.
Data pipelines. The SDK ships ingest and processors — libraries for parsing raw ledger data from Captive Core or a Galexie data lake. If you are building analytics, compliance reporting, or indexers, start there instead of scraping Horizon.
AI-assisted workflows. stellar-go-cli can run as an MCP server, exposing wallet, payment, and swap operations as tools that AI assistants can call:
# Expose wallet/pay/swap as tools for AI assistants
stellar-go-cli mcp # stdio — Claude Desktop, etc.
stellar-go-cli mcp --transport sse --port 3000 # SSE over HTTP for remote agentsPoint your agent at it and "check my testnet balance and send 5 XLM to this address" becomes a real tool call — an early taste of agents that can hold and move money. Combined with our AI × blockchain article, that is a fun rabbit hole.
Keep learning. The Soroban course goes deeper on contract development, the stablecoin guide covers the assets your payments will probably carry, and the developer roadmap maps the rest of the journey.
Yes. github.com/stellar/go-stellar-sdk is maintained by the Stellar Development Foundation. It used to be the SDF Go monorepo (github.com/stellar/go); in October 2025 it was refactored into a focused SDK, while services like Horizon, Galexie, and Friendbot moved to their own repositories.
Soroban contracts compile to WebAssembly and the canonical toolchain is Rust — Go is not a supported contract language today. What Go does excel at is everything around the contract: deploying the WASM, invoking methods, simulating calls, and building services that orchestrate contract workflows.
Horizon is the REST API for the "classic" layer: accounts, payments, offers, history, and transaction submission. Stellar RPC is the leaner API used for Soroban: contract simulation, invocation, ledger entries, and events. Most payment apps talk to Horizon; contract-heavy apps talk to RPC; many use both.
No — it is a community project (Apache 2.0) built on top of the official SDK. It was extracted from a commercial codebase and covers wallets, payments, swaps, Soroban deployment, ISO 20022 reporting, DIDs/VCs, and an MCP server for AI assistants.
Yes — the CLI ships pkg/iso20022, a Go package that turns Stellar payments into XSD-valid ISO 20022 XML: pain.001 batch disbursement initiations, camt.054 settlement notifications, and pacs.008/002/004/009 interbank messages. It is aimed squarely at Stellar Disbursement Platform-style flows where an NGO or payroll provider must hand structured XML to a bank, donor, or auditor.
Everything in this guide runs on testnet. Friendbot funds any testnet address with 10,000 test XLM for free. When you are ready for mainnet, the same code works — you just swap the client, network passphrase, and RPC endpoint to the public network.
[1] stellar/go-stellar-sdk — official SDF Go SDK
[2] stellar-go-cli/stellar-go-cli — community Go CLI for Stellar