Go
Tempo distributes a Go SDK for building application clients. The SDK provides packages for RPC communication, transaction signing, and key management.
The Tempo Go SDK can be used to perform common operations with the chain, such as: sending Tempo transactions, batching multiple calls, fee sponsorship, and more.
Create an RPC Client
To interact with Tempo, first create an RPC client connected to a Tempo node:
package main
import (
"context"
"fmt"
"github.com/tempoxyz/tempo-go/pkg/client"
)
func main() {
c := client.New("https://rpc.testnet.tempo.xyz")
ctx := context.Background()
blockNum, _ := c.GetBlockNumber(ctx)
fmt.Printf("Connected to Tempo at block %d\n", blockNum)
}For authenticated RPC endpoints:
c := client.New("https://rpc.testnet.tempo.xyz",
client.WithAuth("username", "password"),
)Create a Signer
Create a signer to sign transactions. The signer manages your private key and generates signatures:
package main
import (
"fmt"
"github.com/tempoxyz/tempo-go/pkg/signer"
)
func main() {
s, err := signer.NewSigner("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
if err != nil {
panic(err)
}
fmt.Printf("Address: %s\n", s.Address().Hex())
}Send a Transaction
Build and send a transaction using the builder pattern:
package main
import (
"context"
"log"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/tempoxyz/tempo-go/pkg/client"
"github.com/tempoxyz/tempo-go/pkg/signer"
"github.com/tempoxyz/tempo-go/pkg/transaction"
)
func main() {
c := client.New("https://rpc.testnet.tempo.xyz")
s, _ := signer.NewSigner("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
ctx := context.Background()
nonce, _ := c.GetTransactionCount(ctx, s.Address().Hex())
recipient := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8")
tx := transaction.NewBuilder(big.NewInt(42431)). // Tempo testnet
SetNonce(nonce).
SetGas(100000).
SetMaxFeePerGas(big.NewInt(20000000000)). // 20 gwei base fee
SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
AddCall(recipient, big.NewInt(0), []byte{}).
Build()
transaction.SignTransaction(tx, s)
serialized, _ := transaction.Serialize(tx, nil)
hash, _ := c.SendRawTransaction(ctx, serialized)
log.Printf("Transaction hash: %s", hash)
}Examples
Read Chain Data
Query the blockchain for basic information:
ctx := context.Background()
blockNum, _ := c.GetBlockNumber(ctx)
chainID, _ := c.GetChainID(ctx)
nonce, _ := c.GetTransactionCount(ctx, "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb")
fmt.Printf("Block: %d, Chain: %d, Nonce: %d\n", blockNum, chainID, nonce)Token Transfer
Send a TIP-20 token transfer using go-ethereum's ABI encoding:
import "github.com/ethereum/go-ethereum/accounts/abi"
erc20ABI, _ := abi.JSON(strings.NewReader(`[{"name":"transfer","type":"function","inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}]}]`))
recipient := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8")
amount := big.NewInt(100_000_000) // 100 tokens (6 decimals)
transferData, _ := erc20ABI.Pack("transfer", recipient, amount)
tx := transaction.NewBuilder(big.NewInt(42429)).
SetNonce(nonce).
SetGas(100000).
SetMaxFeePerGas(big.NewInt(10000000000)).
SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
AddCall(transaction.AlphaUSDAddress, big.NewInt(0), transferData).
Build()Transfer with Memo
Include a memo for payment reconciliation:
tip20ABI, _ := abi.JSON(strings.NewReader(`[{"name":"transferWithMemo","type":"function","inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"},{"name":"memo","type":"bytes32"}]}]`))
recipient := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8")
amount := big.NewInt(100_000_000)
memo := [32]byte{}
copy(memo[:], "INV-12345")
memoData, _ := tip20ABI.Pack("transferWithMemo", recipient, amount, memo)
tx := transaction.NewBuilder(big.NewInt(42429)).
SetNonce(nonce).
SetGas(100000).
SetMaxFeePerGas(big.NewInt(10000000000)).
SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
AddCall(transaction.AlphaUSDAddress, big.NewInt(0), memoData).
Build()Batch Multiple Calls
Execute multiple operations atomically in a single transaction:
tx := transaction.NewBuilder(big.NewInt(42429)).
SetNonce(nonce).
SetGas(200000).
SetMaxFeePerGas(big.NewInt(10000000000)).
SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
AddCall(addr1, big.NewInt(0), transfer1Data).
AddCall(addr2, big.NewInt(0), transfer2Data).
AddCall(addr3, big.NewInt(0), contractCallData).
Build()
transaction.SignTransaction(tx, s)Parallel Transactions (2D Nonces)
Send multiple transactions concurrently using different nonce keys:
tx1 := transaction.NewBuilder(big.NewInt(42429)).
SetNonceKey(big.NewInt(1)). // Sequence A
SetNonce(0).
SetGas(100000).
SetMaxFeePerGas(big.NewInt(10000000000)).
SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
AddCall(recipient1, big.NewInt(0), data1).
Build()
tx2 := transaction.NewBuilder(big.NewInt(42429)).
SetNonceKey(big.NewInt(2)). // Sequence B (parallel)
SetNonce(0).
SetGas(100000).
SetMaxFeePerGas(big.NewInt(10000000000)).
SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
AddCall(recipient2, big.NewInt(0), data2).
Build()
transaction.SignTransaction(tx1, s)
transaction.SignTransaction(tx2, s)
// Send both in parallel
go func() { c.SendRawTransaction(ctx, serialize(tx1)) }()
go func() { c.SendRawTransaction(ctx, serialize(tx2)) }()Fee Sponsorship
Have another account pay for transaction fees:
tx := transaction.NewBuilder(big.NewInt(42429)).
SetNonce(nonce).
SetGas(100000).
SetMaxFeePerGas(big.NewInt(10000000000)).
SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
SetSponsored(true). // Mark as awaiting fee payer
AddCall(recipient, big.NewInt(0), data).
Build()
transaction.SignTransaction(tx, userSigner)
transaction.AddFeePayerSignature(tx, feePayerSigner)Transaction Validity Window
Set a time window during which the transaction is valid:
now := time.Now()
tx := transaction.NewBuilder(big.NewInt(42429)).
SetNonce(nonce).
SetGas(100000).
SetMaxFeePerGas(big.NewInt(10000000000)).
SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
SetValidAfter(uint64(now.Unix())).
SetValidBefore(uint64(now.Add(1 * time.Hour).Unix())).
AddCall(recipient, big.NewInt(0), data).
Build()Batch RPC Requests
Send multiple RPC calls efficiently in a single HTTP request:
batch := client.NewBatchRequest()
batch.Add("eth_blockNumber").
Add("eth_chainId").
Add("eth_getBalance", "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb", "latest")
responses, _ := c.SendBatch(ctx, batch)
for _, resp := range responses {
fmt.Printf("Result: %v\n", resp.Result)
}Packages
| Package | Description |
|---|---|
transaction | TempoTransaction encoding, signing, and validation |
client | RPC client for interacting with Tempo nodes |
signer | Key management and signature generation |
Next Steps
After setting up the Go SDK, you can:
- Follow a guide on how to use accounts, make payments, issue stablecoins, exchange stablecoins, and more.
- View the examples on GitHub