Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation: Update go-sequencer-client README #152

Merged
merged 5 commits into from
Aug 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 117 additions & 27 deletions modules/go-sequencer-client/README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,142 @@
# go-sequencer-client

The `go-sequencer-client` is a Go package that enables interacting with an
Astria sequencer.

## Table of Contents

- [Installation](#installation)
- [Usage](#usage)
- [Example](#example)

## Installation

To use the `go-sequencer-client`, install the following packages:

1. Sequencer Client:

```bash
go get github.com/astriaorg/astria-cli-go/modules/go-sequencer-client
```

2. Protobuf Types:
The Astria sequencer uses ProtoBuf for message passing. A full list of the
APIs and Primitives can be found [here](https://buf.build/astria).

```bash
go get buf.build/gen/go/astria/primitives/protocolbuffers/go
go get buf.build/gen/go/astria/protocol-apis/protocolbuffers/go
```

3. Bech32m Package:
The Astria sequencer uses "astria" prefixed `bech32m` addresses.

```bash
go get github.com/astriaorg/astria-cli-go/modules/bech32m
```

## Usage

All sequencer client methods can be found in the [client.go](./client/client.go)
file.

## Example

The following example demonstrates how to create a sequencer client, then build
and send a transaction to a sequencer:

```go
package main

import (
"context"
"crypto/sha256"
"crypto/ed25519"
"encoding/hex"
"fmt"

sqproto "buf.build/gen/go/astria/astria/protocolbuffers/go/astria/sequencer/v1alpha1"
client "github.com/astriaorg/astria-cli-go/modules/go-sequencer-client/client"
"github.com/astriaorg/astria-cli-go/modules/bech32m"
"github.com/astriaorg/astria-cli-go/modules/go-sequencer-client/client"
txproto "buf.build/gen/go/astria/protocol-apis/protocolbuffers/go/astria/protocol/transactions/v1alpha1"
primproto "buf.build/gen/go/astria/primitives/protocolbuffers/go/astria/primitive/v1"
)

// create a sequencer client and send a transfer
func main() {
signer, err := client.GenerateSigner()
if err != nil {
panic(err)
}

// default tendermint RPC endpoint
// create a new sequencer client pointing to the default CometBFT RPC endpoint
c, err := client.NewClient("http://localhost:26657")
if err != nil {
panic(err)
}
if err != nil {
log.WithError(err).Error("Error creating sequencer client")
panic(err)
}

// parse a private key into an ed25519.PrivateKey
privKeyBytes, err := hex.DecodeString("hex private key string")
if err != nil {
panic(err)
}
from := ed25519.NewKeyFromSeed(privKeyBytes)

// create a FROM address from the private key
signer := client.NewSigner(from)
fromAddr := signer.Address()
addr, err := bech32m.EncodeFromBytes("astria", fromAddr)
if err != nil {
log.WithError(err).Error("Failed to encode address")
panic(err)
}

rollupId := sha256.Sum256([]byte("test-chain"))
tx := &sqproto.UnsignedTransaction{
Nonce: 1,
Actions: []*sqproto.Action{
{
Value: &sqproto.Action_SequenceAction{
SequenceAction: &sqproto.SequenceAction{
RollupId: rollupId[:],
Data: []byte("test-data"),
},
},
},
// automatically get the nonce for the FROM account
nonce, err := c.GetNonce(ctx, addr.String())
if err != nil {
log.WithError(err).Error("Error getting nonce")
panic(err)
}

// convert the transfer amount to a uint128
bigInt := new(big.Int)
_, ok := bigInt.SetString("1000", 10) // the transfer amount is 1000
if !ok {
return nil, fmt.Errorf("failed to convert string to big.Int")
}
if bigInt.Sign() < 0 {
panic(fmt.Errorf("negative number not allowed"))
} else if bigInt.BitLen() > 128 {
panic(fmt.Errorf("value overflows Uint128"))
}
lo := bigInt.Uint64()
hi := bigInt.Rsh(bigInt, 64).Uint64()
transferAmount := &primproto.Uint128{
Lo: lo,
Hi: hi,
}

// build the transaction
unsignedTx := &txproto.UnsignedTransaction{
Params: &txproto.TransactionParams{
ChainId: "test-sequencer",
Nonce: nonce,
},
Actions: []*txproto.Action{
{
Value: &txproto.Action_TransferAction{
TransferAction: &txproto.TransferAction{
To: "astria prefixed bech32m TO address",
Amount: transferAmount,
Asset: "asset",
FeeAsset: "feeAsset",
},
},
}
},
},
}

signed, err := signer.SignTransaction(tx)
signedTx, err := signer.SignTransaction(unsignedTx)
if err != nil {
panic(err)
}

resp, err := c.BroadcastTxSync(context.Background(), signed)
sendAsync := false
resp, err := c.BroadcastTx(context.Background(), signedTx, sendAsync)
if err != nil {
panic(err)
}
Expand Down
Loading