Skip to content
Merged
Show file tree
Hide file tree
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
93 changes: 0 additions & 93 deletions integration/codegen.mdx

This file was deleted.

201 changes: 142 additions & 59 deletions integration/go.md
Original file line number Diff line number Diff line change
@@ -1,91 +1,174 @@
---
title: Go
title: Go SDK
sidebar:
label: Go
order: 2
---

To integrate with Go you need to make sure that your _trix_ project has the `go` bindings generation enabled in the config:
The official Go SDK for Tx3 is published as the [`github.com/tx3-lang/go-sdk/sdk`](https://pkg.go.dev/github.com/tx3-lang/go-sdk/sdk) module. It loads a compiled `.tii` protocol, binds parties and signers, and drives the full transaction lifecycle (resolve, sign, submit, confirm) via the Transaction Resolve Protocol (TRP).

```toml
[[bindings]]
plugin = "go"
output_dir = "./gen/go"
```
The source lives at [tx3-lang/go-sdk](https://github.com/tx3-lang/go-sdk).

With the binding generation enabled, run the following command from your CLI to trigger the code generator:
## Installation

```
trix bindgen
```bash
go get github.com/tx3-lang/go-sdk/sdk
```

If things went well, you should see the following new files:
## Quick start

```
my-protocol/
└── gen/
└── go/
├── protocol.go
└── go.mod
```go
package main

import (
"context"
"fmt"
"log"

tx3 "github.com/tx3-lang/go-sdk/sdk"
"github.com/tx3-lang/go-sdk/sdk/signer"
"github.com/tx3-lang/go-sdk/sdk/trp"
)

func main() {
// Load a compiled .tii protocol
protocol, err := tx3.ProtocolFromFile("transfer.tii")
if err != nil {
log.Fatal(err)
}

// Connect to a TRP server
trpClient := tx3.NewTRPClient(trp.ClientOptions{
Endpoint: "http://localhost:3000",
})

// Create a Cardano signer from a mnemonic
mySigner, err := signer.CardanoSignerFromMnemonic(
"addr_test1qz...",
"word1 word2 ... word24",
)
if err != nil {
log.Fatal(err)
}

// Configure client with profile and parties
client := tx3.NewClient(protocol, trpClient).
WithProfile("preprod").
WithParty("sender", tx3.SignerParty(mySigner)).
WithParty("receiver", tx3.AddressParty("addr_test1qz..."))

ctx := context.Background()

// Build, resolve, sign, submit, and wait for confirmation
status, err := client.Tx("transfer").
Arg("quantity", 10_000_000).
Resolve(ctx) // -> ResolvedTx
.Sign() // -> SignedTx
.Submit(ctx) // -> SubmittedTx
.WaitForConfirmed(ctx, tx3.DefaultPollConfig())
if err != nil {
log.Fatal(err)
}

fmt.Printf("Confirmed at stage %s\n", status.Stage)
}
```

That new `protocol.go` file has the required types and functions to call your protocol from a Go code.
> **Note:** The quick-start example above shows the conceptual flow. In real code, check errors at each step since Go doesn't chain errors across method calls.

The `go.mod` file is a standard file for Go projects.
## Concepts

Now, we can use the generated bindings to build a transaction using our protocol.
| SDK Type | Glossary Term | Description |
|---|---|---|
| `Protocol` | TII / Protocol | Loaded `.tii` file exposing transactions, parties, and profiles |
| `Tx3Client` | Facade | Entry point holding protocol, TRP client, and party bindings |
| `TxBuilder` | Invocation builder | Collects args, resolves via TRP |
| `Party` | Party | Named participant — `AddressParty` (read-only) or `SignerParty` (signing) |
| `Signer` | Signer | Interface producing a `TxWitness` for a `SignRequest` |
| `SignRequest` | SignRequest | Input passed to `Signer.Sign`: `TxHashHex` + `TxCborHex` |
| `CardanoSigner` | Cardano Signer | BIP32-Ed25519 signer at `m/1852'/1815'/0'/0/0` |
| `Ed25519Signer` | Ed25519 Signer | Generic raw-key Ed25519 signer |
| `ResolvedTx` | Resolved transaction | Output of `Resolve()`, ready for signing |
| `SignedTx` | Signed transaction | Output of `Sign()`, ready for submission |
| `SubmittedTx` | Submitted transaction | Output of `Submit()`, pollable for status |
| `PollConfig` | Poll configuration | Controls `WaitForConfirmed` / `WaitForFinalized` polling |

First access to the `gen/go` folder and install the required dependencies:
```bash
cd gen/go && go mod tidy
```
## Low-level TRP client

We need to open `protocol.go` and update the TRP endpoint to point to the correct URL (unless you have it configured on trix.toml). The default value is `http://localhost:3000/trp`, but if you're using different port or endpoint, make sure to update it.
```go
import "github.com/tx3-lang/go-sdk/sdk/trp"

client := trp.NewClient(trp.ClientOptions{
Endpoint: "http://localhost:3000",
Headers: map[string]string{"Authorization": "Bearer token"},
})

envelope, err := client.Resolve(ctx, trp.ResolveParams{...})
resp, err := client.Submit(ctx, trp.SubmitParams{...})
status, err := client.CheckStatus(ctx, []string{txHash})
```

For the following example, we will use the main.tx3 file generated by trix.
## Custom Signer

Now, we can create a new file called `test.go` with the following code on the same folder as `main.tx3`:
Implement the `Signer` interface. `Sign` receives a `SignRequest` carrying both
the tx hash and the full tx CBOR; hash-based signers read `TxHashHex`, tx-based
signers (e.g. wallet bridges) read `TxCborHex`.

```go
package main
import "github.com/tx3-lang/go-sdk/sdk/signer"

import (
"fmt"
"log"
type MySigner struct { /* ... */ }

"protocol"
)
func (s *MySigner) Address() string { return "addr_test1..." }

func main() {
// Create parameters for the transfer
params := protocol.TransferParams{
Sender: "addr_test1vpgcjapuwl7gfnzhzg6svtj0ph3gxu8kyuadudmf0kzsksqrfugfc",
Receiver: "addr_test1vpry6n9s987fpnmjqcqt9un35t2rx5t66v4x06k9awdm5hqpma4pp",
Quantity: 100000000,
}

// Execute the transfer transaction
cbor, err := protocol.DefaultClient.TransferTx(params)
if err != nil {
log.Fatalf("Error: %v", err)
}

// Print the result
fmt.Printf("%+v\n", cbor)
func (s *MySigner) Sign(request signer.SignRequest) (*signer.TxWitness, error) {
// sign request.TxHashHex with your key
return signer.NewVKeyWitness(pubKeyHex, signatureHex), nil
}

client.WithParty("sender", tx3.SignerParty(&MySigner{}))
```

For this, add the protocol as a dependency in your `go.mod` file:
## Manual witness attachment

When a witness is produced outside any registered signer — for example by an
external wallet app or a remote signing service — resolve the transaction
first, hand the resolved hash (or full tx CBOR) to the wallet, then attach
the returned witness before `Sign()`:

```go
require protocol v0.0.0
import "github.com/tx3-lang/go-sdk/sdk/trp"

resolved, err := client.Tx("transfer").Arg("quantity", 10_000_000).Resolve(ctx)
if err != nil { /* ... */ }

// Hand resolved.Hash (or resolved.TxHex) to the external wallet and get
// back a witness. The wallet needs the resolved tx to sign.
var witness trp.TxWitness // sign resolved.Hash with external wallet

signed, err := resolved.AddWitness(witness).Sign()
if err != nil { /* ... */ }

replace protocol => ./gen/go
submitted, err := signed.Submit(ctx)
```

Finally, we can run the test file to build a transaction using our protocol:
```bash
go run test.go
`AddWitness` may be called any number of times; manual witnesses are appended after registered-signer witnesses in attach order.

## Error handling

All errors are discriminable via `errors.As()` — no string matching needed:

```go
import "github.com/tx3-lang/go-sdk/sdk/facade"

_, err := client.Tx("transfer").Resolve(ctx)
var unknownParty *facade.UnknownPartyError
if errors.As(err, &unknownParty) {
fmt.Printf("Party %q not found in protocol\n", unknownParty.Name)
}
```
If everything went well, you should see a message like this:

```bash
&{Tx:84a400d9010281825820705e5d956d318 264043baf8031e250c14b8703b69947ab2d3212d67210c4b240010182a200581d60464d4cb029fc90cf720600b2f271a2d433517ad32a67eac5eb9bba5c011a05f5e100a200581d605189743c77fc84cc571235062e4f0de28370f6273ade37697d850b40011b0000000248151b86021a0005833d0f00a0f5f6 Bytes: Encoding:}
```
## Tx3 protocol compatibility

- **TRP protocol version:** v1beta0
- **TII schema version:** v1beta0
18 changes: 18 additions & 0 deletions integration/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Integration
sidebar:
label: Introduction
order: 0
pagefind: false
---

import { LinkCard, CardGrid } from '@astrojs/starlight/components';

Tx3 ships official runtime SDKs in four languages. Each SDK loads a compiled `.tii` protocol, binds parties and signers, and drives the `resolve → sign → submit → wait` lifecycle through a TRP server.

<CardGrid>
<LinkCard title="TypeScript / JavaScript" href="/tx3/integration/typescript" description="The tx3-sdk npm package — runs in Node.js, browsers, Bun, and Deno." />
<LinkCard title="Go" href="/tx3/integration/go" description="The github.com/tx3-lang/go-sdk module." />
<LinkCard title="Rust" href="/tx3/integration/rust" description="The tx3-sdk crate, published on crates.io." />
<LinkCard title="Python" href="/tx3/integration/python" description="The tx3-sdk package, published on PyPI." />
</CardGrid>
Loading