Skip to content
LogoLogo

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.

Install

To install the Tempo Go SDK:

go
go get github.com/tempoxyz/tempo-go@v0.1.0

Create an RPC Client

To interact with Tempo, first create an RPC client connected to a Tempo node:

main.go
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:

main.go
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:

main.go
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:

main.go
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:

read.go
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:

transfer.go
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:

memo.go
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:

batch.go
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:

parallel.go
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:

feepayer.go
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:

validity.go
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_rpc.go
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

PackageDescription
transactionTempoTransaction encoding, signing, and validation
clientRPC client for interacting with Tempo nodes
signerKey management and signature generation

Next Steps

After setting up the Go SDK, you can: