Documentation Index Fetch the complete documentation index at: https://mintlify.com/tempoxyz/tempo/llms.txt
Use this file to discover all available pages before exploring further.
The Go SDK provides Go bindings for building payment applications, backend services, and integrations with Tempo. It offers full support for TIP-20 tokens, batch payments, and Tempo’s account abstraction features.
The Go SDK is currently under development. Check the Tempo repository for the latest updates.
Installation
Install the Go SDK:
go get github.com/tempoxyz/tempo/sdk/go
Quick Start
Connect to Tempo testnet:
package main
import (
" context "
" log "
" github.com/tempoxyz/tempo/sdk/go "
)
func main () {
client , err := tempo . Dial ( "https://rpc.moderato.tempo.xyz" )
if err != nil {
log . Fatal ( err )
}
defer client . Close ()
blockNumber , err := client . BlockNumber ( context . Background ())
if err != nil {
log . Fatal ( err )
}
log . Printf ( "Current block: %d " , blockNumber )
}
Get Token Balance
Query TIP-20 token balances:
import (
" context "
" math/big "
" github.com/ethereum/go-ethereum/common "
" github.com/tempoxyz/tempo/sdk/go/contracts "
)
tokenAddress := common . HexToAddress ( "0x20c0000000000000000000000000000000000001" )
token , err := contracts . NewTIP20 ( tokenAddress , client )
if err != nil {
log . Fatal ( err )
}
balance , err := token . BalanceOf (
nil , // call options
common . HexToAddress ( "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb" ),
)
if err != nil {
log . Fatal ( err )
}
log . Printf ( "Balance: %s " , balance . String ())
Send Transfer
Send a TIP-20 token transfer:
import (
" crypto/ecdsa "
" github.com/ethereum/go-ethereum/accounts/abi/bind "
" github.com/ethereum/go-ethereum/crypto "
)
// Load private key
privateKey , err := crypto . HexToECDSA ( "your-private-key" )
if err != nil {
log . Fatal ( err )
}
// Create transactor
auth , err := bind . NewKeyedTransactorWithChainID ( privateKey , big . NewInt ( 42431 ))
if err != nil {
log . Fatal ( err )
}
// Send transfer
tx , err := token . Transfer (
auth ,
common . HexToAddress ( "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb" ),
big . NewInt ( 100000000 ), // 100 tokens (6 decimals)
)
if err != nil {
log . Fatal ( err )
}
log . Printf ( "Transaction sent: %s " , tx . Hash (). Hex ())
// Wait for receipt
receipt , err := bind . WaitMined ( context . Background (), client , tx )
if err != nil {
log . Fatal ( err )
}
log . Printf ( "Transaction mined in block %d " , receipt . BlockNumber )
TIP-20 Tokens
Transfer with Memo
Include reconciliation data:
memo := [ 32 ] byte {}
copy ( memo [:], [] byte ( "INV-12345" ))
tx , err := token . TransferWithMemo (
auth ,
recipient ,
amount ,
memo ,
)
Watch Transfer Events
Listen for incoming transfers:
import (
" github.com/ethereum/go-ethereum/accounts/abi/bind "
" github.com/ethereum/go-ethereum/core/types "
)
// Create watch options
watchOpts := & bind . WatchOpts {
Context : context . Background (),
}
// Watch for transfers
events := make ( chan * contracts . TIP20Transfer )
sub , err := token . WatchTransfer ( watchOpts , events , nil , nil )
if err != nil {
log . Fatal ( err )
}
defer sub . Unsubscribe ()
for {
select {
case err := <- sub . Err ():
log . Fatal ( err )
case transfer := <- events :
log . Printf ( "Transfer: %s -> %s : %s " ,
transfer . From . Hex (),
transfer . To . Hex (),
transfer . Value . String (),
)
}
}
Filter Historical Transfers
Query past transfer events:
// Create filter options
filterOpts := & bind . FilterOpts {
Start : 0 ,
End : nil , // latest block
}
// Filter transfers to a specific address
recipient := common . HexToAddress ( "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb" )
iter , err := token . FilterTransfer (
filterOpts ,
nil , // any sender
[] common . Address { recipient }, // specific recipient
)
if err != nil {
log . Fatal ( err )
}
defer iter . Close ()
for iter . Next () {
log . Printf ( "Block %d : %s tokens" ,
iter . Event . Raw . BlockNumber ,
iter . Event . Value . String (),
)
}
Batch Payments
Send multiple transfers atomically using Tempo Transactions:
import (
" github.com/tempoxyz/tempo/sdk/go/types "
)
// Create batch of calls
calls := [] types . Call {
{
To : tokenAddress ,
Data : encodeTransfer ( recipient1 , amount1 ),
Value : big . NewInt ( 0 ),
},
{
To : tokenAddress ,
Data : encodeTransfer ( recipient2 , amount2 ),
Value : big . NewInt ( 0 ),
},
}
// Create Tempo Transaction
tx := types . NewTempoTransaction (
auth . From ,
calls ,
auth . Nonce ,
auth . GasLimit ,
auth . GasFeeCap ,
auth . GasTipCap ,
)
// Sign and send
signedTx , err := auth . Signer ( auth . From , tx )
if err != nil {
log . Fatal ( err )
}
err = client . SendTransaction ( context . Background (), signedTx )
if err != nil {
log . Fatal ( err )
}
log . Printf ( "Batch transaction sent: %s " , signedTx . Hash (). Hex ())
Account Abstraction
Pay gas fees for users:
tx := types . NewTempoTransaction (
userAddress ,
calls ,
nonce ,
gasLimit ,
maxFeePerGas ,
maxPriorityFeePerGas ,
)
// Set fee token for sponsor
tx . SetFeeToken ( tokenAddress )
// Sponsor signs the transaction
signedTx , err := sponsorAuth . Signer ( sponsorAuth . From , tx )
if err != nil {
log . Fatal ( err )
}
err = client . SendTransaction ( context . Background (), signedTx )
Scheduled Payments
Set validity windows:
import " time "
now := uint64 ( time . Now (). Unix ())
oneHourLater := now + 3600
tx := types . NewTempoTransaction (
auth . From ,
calls ,
nonce ,
gasLimit ,
maxFeePerGas ,
maxPriorityFeePerGas ,
)
tx . SetValidAfter ( now )
tx . SetValidBefore ( oneHourLater )
Network Configuration
Configure for Tempo testnet:
import (
" github.com/ethereum/go-ethereum/ethclient "
" github.com/ethereum/go-ethereum/rpc "
)
const (
TempoTestnetChainID = 42431
TempoTestnetRPC = "https://rpc.moderato.tempo.xyz"
TempoTestnetWSS = "wss://rpc.moderato.tempo.xyz"
)
// HTTP connection
client , err := ethclient . Dial ( TempoTestnetRPC )
// WebSocket connection for subscriptions
clientWS , err := ethclient . Dial ( TempoTestnetWSS )
Error Handling
Handle common errors:
import (
" errors "
" github.com/ethereum/go-ethereum/accounts/abi "
" github.com/ethereum/go-ethereum/core/types "
)
tx , err := token . Transfer ( auth , recipient , amount )
if err != nil {
// Check for specific errors
if errors . Is ( err , abi . ErrInvalidData ) {
log . Printf ( "Invalid transaction data: %v " , err )
} else {
log . Printf ( "Transfer failed: %v " , err )
}
return
}
receipt , err := bind . WaitMined ( ctx , client , tx )
if err != nil {
log . Fatal ( err )
}
if receipt . Status == types . ReceiptStatusFailed {
log . Printf ( "Transaction failed on-chain: %s " , tx . Hash (). Hex ())
}
Testing with Localnet
Connect to a local Tempo node:
// Connect to localnet
client , err := tempo . Dial ( "http://localhost:8545" )
if err != nil {
log . Fatal ( err )
}
// Use test accounts
testKey , _ := crypto . HexToECDSA ( "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" )
auth , _ := bind . NewKeyedTransactorWithChainID ( testKey , big . NewInt ( 42431 ))
Contract Bindings
Generate Go bindings for custom contracts:
abigen --abi MyContract.abi --pkg contracts --type MyContract --out my_contract.go
For Tempo precompiles, use the built-in bindings:
import " github.com/tempoxyz/tempo/sdk/go/contracts "
// TIP-20 token
token , err := contracts . NewTIP20 ( address , client )
// TIP-403 policy registry
policy , err := contracts . NewTIP403 ( address , client )
// Fee AMM
feeAmm , err := contracts . NewFeeAMM ( address , client )
Production Considerations
Connection Pooling
Reuse clients across requests:
var globalClient * ethclient . Client
func init () {
var err error
globalClient , err = ethclient . Dial ( TempoTestnetRPC )
if err != nil {
panic ( err )
}
}
Transaction Management
Manage nonces for concurrent transactions:
import " sync "
type NonceManager struct {
mu sync . Mutex
nonce uint64
}
func ( nm * NonceManager ) NextNonce () uint64 {
nm . mu . Lock ()
defer nm . mu . Unlock ()
nonce := nm . nonce
nm . nonce ++
return nonce
}
Monitoring
Track transaction status:
import " time "
func waitForConfirmations ( ctx context . Context , client * ethclient . Client , txHash common . Hash , confirmations uint64 ) error {
ticker := time . NewTicker ( time . Second )
defer ticker . Stop ()
for {
select {
case <- ctx . Done ():
return ctx . Err ()
case <- ticker . C :
receipt , err := client . TransactionReceipt ( ctx , txHash )
if err != nil {
continue
}
currentBlock , err := client . BlockNumber ( ctx )
if err != nil {
continue
}
if currentBlock - receipt . BlockNumber . Uint64 () >= confirmations {
return nil
}
}
}
}
Next Steps
Go Ethereum Docs Learn go-ethereum basics
TIP-20 Reference Complete TIP-20 specification
Tempo Transactions Account abstraction features
Repository View source code on GitHub