fiber-go
Go client package for interacting with Fiber Network.
Installation
go get github.com/chainbound/fiber-go
Usage
Connecting
import (
"context"
"log"
"time"
fiber "github.com/chainbound/fiber-go"
)
func main() {
endpoint := "fiber.example.io"
apiKey := "YOUR_API_KEY"
client := fiber.NewClient(endpoint, apiKey)
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
}
Subscriptions
You can find some examples on how to subscribe below. fiber-go
uses the familiar go-ethereum
core types where possible,
making it easy to integrate with existing applications.
Transactions
Transactions are returned as *fiber.TransactionWithSender
which is a wrapper around go-ethereum
*types.Transaction
plus the sender's address.
The sender address is included in the message to avoid having to recompute it from ECDSA signature recovery in the client, which can be slow.
import (
"context"
"log"
"time"
fiber "github.com/chainbound/fiber-go"
"github.com/chainbound/fiber-go/filter"
"github.com/chainbound/fiber-go/protobuf/api"
)
func main() {
endpoint := "fiber.example.io"
apiKey := "YOUR_API_KEY"
client := fiber.NewClient(endpoint, apiKey)
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
ch := make(chan *fiber.TransactionWithSender)
go func() {
if err := client.SubscribeNewTxs(nil, ch); err != nil {
log.Fatal(err)
}
}()
for message := range ch {
handleTransaction(message.Transaction)
}
}
Filtering
The first argument to SubscribeNewTxs
is a filter, which can be nil
if you want to get all transactions.
A filter can be built with the filter
package:
import (
...
"github.com/chainbound/fiber-go/filter"
)
func main() {
...
f := filter.New(filter.Or(
filter.To("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
filter.To("0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"),
))
f := filter.New(filter.ValueGte(big.NewInt(1) * big.NewInt(1e18)))
f := filter.New(filter.ValueEq(big.NewInt(1) * big.NewInt(1e18)))
f := filter.New(filter.ValueLte(big.NewInt(1) * big.NewInt(1e18)))
f := filter.New(filter.And(
filter.MethodID("0xa9059cbb"),
filter.Or(
filter.To("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
filter.To("0xdAC17F958D2ee523a2206206994597C13D831ec7"),
),
))
ch := make(chan *fiber.TransactionWithSender)
go func() {
if err := client.SubscribeNewTxs(f, ch); err != nil {
log.Fatal(err)
}
}()
...
}
You can currently filter the following properties
- To
- From
- MethodID
- Value (greater than, less than, equal to)
Execution Payloads (new blocks with transactions)
Execution payloads are returned as *fiber.Block
which is a wrapper around go-ethereum
native types such as Header
, Transaction
and Withdrawal
.
import (
...
fiber "github.com/chainbound/fiber-go"
)
func main() {
...
ch := make(chan *fiber.Block)
go func() {
if err := client.SubscribeNewExecutionPayloads(ch); err != nil {
log.Fatal(err)
}
}()
for block := range ch {
handlePayload(block)
}
}
Beacon Blocks
Beacon blocks follow the Consensus specs.
The returned items are *fiber.BeaconBlock
which is a wrapper around go-eth-2
SignedBeaconBlock
depending on the hardfork version:
Each *fiber.BeaconBlock
contains the DataVersion
field which indicates the hardfork version of the beacon block.
The returned type will contain either a Bellatrix (3), Capella (4) or Deneb (5) hardfork block depending on the specified DataVersion.
import (
...
fiber "github.com/chainbound/fiber-go"
)
func main() {
...
ch := make(chan *fiber.BeaconBlock)
go func() {
if err := client.SubscribeNewBeaconBlocks(ch); err != nil {
log.Fatal(err)
}
}()
for block := range ch {
handleBeaconBlock(block)
}
}
Raw Beacon Blocks
Raw beacon blocks are raw, SSZ-encoded bytes that you can manually decode into SignedBeaconBlocks in your application.
import (
...
fiber "github.com/chainbound/fiber-go"
)
func main() {
...
ch := make(chan []byte)
go func() {
if err := client.SubscribeNewRawBeaconBlocks(ch); err != nil {
log.Fatal(err)
}
}()
for block := range ch {
handleRawBeaconBlock(block)
}
}
Sending Transactions
SendTransaction
This method supports sending a single go-ethereum
*types.Transaction
object to the Fiber Network.
import (
"context"
"log"
"math/big"
"time"
fiber "github.com/chainbound/fiber-go"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func main() {
endpoint := "fiber.example.io"
apiKey := "YOUR_API_KEY"
client := fiber.NewClient(endpoint, apiKey)
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
tx := types.NewTx(&types.DynamicFeeTx{
Nonce: nonce,
To: common.HexToAddress("0x...."),
Value: big.NewInt(100),
Gas: 21000,
GasFeeCap: big.NewInt(x),
GasTipCap: big.NewInt(y),
Data: nil,
})
pk, _ := crypto.HexToECDSA("PRIVATE_KEY")
signer := types.NewLondonSigner(common.Big1)
signed, err := types.SignTx(tx, signer, pk)
if err != nil {
log.Fatal(err)
}
hash, timestamp, err := client.SendTransaction(ctx, signed)
if err != nil {
log.Fatal(err)
}
doSomething(hash, timestamp)
}
SendTransactionSequence
This method supports sending a sequence of transactions to the Fiber Network.
import (
"context"
"log"
"math/big"
"time"
fiber "github.com/chainbound/fiber-go"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func main() {
endpoint := "fiber.example.io"
apiKey := "YOUR_API_KEY"
client := fiber.NewClient(endpoint, apiKey)
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
tx := types.NewTx(&types.DynamicFeeTx{
Nonce: nonce,
To: common.HexToAddress("0x...."),
Value: big.NewInt(100),
Gas: 21000,
GasFeeCap: big.NewInt(x),
GasTipCap: big.NewInt(y),
Data: nil,
})
pk, _ := crypto.HexToECDSA("PRIVATE_KEY")
signer := types.NewLondonSigner(common.Big1)
signed, err := types.SignTx(tx, signer, pk)
if err != nil {
log.Fatal(err)
}
target := someTargetTransaction
hashes, timestamp, err := client.SendTransactionSequence(ctx, target, signed)
if err != nil {
log.Fatal(err)
}
doSomething(hashes, timestamp)
}
SendRawTransaction
This method supports sending a single raw, RLP-encoded transaction to the Fiber Network.
import (
"context"
"log"
"math/big"
"time"
fiber "github.com/chainbound/fiber-go"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func main() {
endpoint := "fiber.example.io"
apiKey := "YOUR_API_KEY"
client := fiber.NewClient(endpoint, apiKey)
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
tx := types.NewTx(&types.DynamicFeeTx{
Nonce: nonce,
To: common.HexToAddress("0x...."),
Value: big.NewInt(100),
Gas: 21000,
GasFeeCap: big.NewInt(x),
GasTipCap: big.NewInt(y),
Data: nil,
})
pk, _ := crypto.HexToECDSA("PRIVATE_KEY")
signer := types.NewLondonSigner(common.Big1)
signed, err := types.SignTx(tx, signer, pk)
if err != nil {
log.Fatal(err)
}
bytes, err := signed.MarshalBinary()
if err != nil {
log.Fatal(err)
}
hash, timestamp, err := client.SendRawTransaction(ctx, bytes)
if err != nil {
log.Fatal(err)
}
doSomething(hash, timestamp)
}
SendRawTransactionSequence
This method supports sending a sequence of raw, RLP-encoded transactions to the Fiber Network.
import (
"context"
"log"
"math/big"
"time"
fiber "github.com/chainbound/fiber-go"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func main() {
endpoint := "fiber.example.io"
apiKey := "YOUR_API_KEY"
client := fiber.NewClient(endpoint, apiKey)
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
tx := types.NewTx(&types.DynamicFeeTx{
Nonce: nonce,
To: common.HexToAddress("0x...."),
Value: big.NewInt(100),
Gas: 21000,
GasFeeCap: big.NewInt(x),
GasTipCap: big.NewInt(y),
Data: nil,
})
pk, _ := crypto.HexToECDSA("PRIVATE_KEY")
signer := types.NewLondonSigner(common.Big1)
signed, err := types.SignTx(tx, signer, pk)
if err != nil {
log.Fatal(err)
}
bytes, err := signed.MarshalBinary()
if err != nil {
log.Fatal(err)
}
targetTransaction := someTargetTransaction
hashes, timestamp, err := client.SendRawTransactionSequence(ctx, targetTransaction, bytes)
if err != nil {
log.Fatal(err)
}
doSomething(hashes, timestamp)
}