From 4dabbcd23a3d44a69145961f29852ec36efc961e Mon Sep 17 00:00:00 2001 From: Andrew Miller Date: Tue, 17 Feb 2026 13:24:35 -0500 Subject: [PATCH] Document fire-and-forget transaction mode Add godoc to Create and CreateBulk explaining they return immediately without waiting for block inclusion. Update package-level example to show both fire-and-forget and wait-for-block patterns. Add Transaction Modes section to README with code examples. --- README.md | 51 ++++++++++++++++++++++++++++++ dragonchain.go | 65 ++++++++++++++++++++------------------ transaction/transaction.go | 8 +++++ 3 files changed, 93 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 7f6bf2c..926663e 100755 --- a/README.md +++ b/README.md @@ -65,6 +65,57 @@ func main() { } ``` +## Transaction Modes + +`Create` and `CreateBulk` return **immediately** with the assigned transaction ID(s). They do **not** wait for block inclusion. Blocks are assembled asynchronously on a ~5-second cycle. + +### Fire and Forget + +Most use cases only need the transaction ID. No polling required. + +```go +ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) +defer cancel() + +resp, err := client.Transaction.Create(ctx, &models.TransactionCreateRequest{ + TxnType: "my-transaction-type", + Payload: `{"message": "Hello Dragonchain"}`, +}) +if err != nil { + log.Fatal(err) +} +fmt.Printf("Transaction ID: %s\n", resp.TransactionID) +// Done — no need to wait for a block. +``` + +### Wait for Block + +If you need the block ID (e.g. for interchain verification or Daria), poll `Get` until `Header.BlockId` is populated. + +```go +resp, err := client.Transaction.Create(ctx, &models.TransactionCreateRequest{ + TxnType: "my-transaction-type", + Payload: `{"message": "Hello Dragonchain"}`, +}) +if err != nil { + log.Fatal(err) +} + +// Poll until the transaction is included in a block. +ticker := time.NewTicker(2 * time.Second) +defer ticker.Stop() +for range ticker.C { + txn, err := client.Transaction.Get(ctx, resp.TransactionID) + if err != nil { + log.Fatal(err) + } + if txn.Header.BlockId != "" { + fmt.Printf("Block ID: %s\n", txn.Header.BlockId) + break + } +} +``` + ## Available Endpoints All API methods accept a `context.Context` as their first parameter for timeout and cancellation control. diff --git a/dragonchain.go b/dragonchain.go index daf0bfc..56f58c8 100755 --- a/dragonchain.go +++ b/dragonchain.go @@ -2,47 +2,50 @@ // // All API methods require a context.Context parameter for timeout and cancellation control. // -// Example usage: +// Example — fire and forget (most use cases): // -// package main -// -// import ( -// "context" -// "fmt" -// "log" -// "time" -// -// "git.dragonchain.com/dragonchain/prime-sdk-go" -// "git.dragonchain.com/dragonchain/prime-sdk-go/models" +// client := sdk.NewDragonchainSDK( +// "your-public-id", +// "your-auth-key-id", +// "your-auth-key", +// "https://your-dragonchain-endpoint.com", // ) // -// func main() { -// client := sdk.NewDragonchainSDK( -// "your-public-id", -// "your-auth-key-id", -// "your-auth-key", -// "https://your-dragonchain-endpoint.com", -// ) +// ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) +// defer cancel() // -// ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) -// defer cancel() +// resp, err := client.Transaction.Create(ctx, &models.TransactionCreateRequest{ +// TxnType: "my-transaction-type", +// Payload: `{"message": "Hello Dragonchain"}`, +// }) +// if err != nil { +// log.Fatal(err) +// } +// fmt.Printf("Transaction ID: %s\n", resp.TransactionID) +// // Done — no need to wait for a block. // -// // Check system health -// if err := client.System.Health(ctx); err != nil { -// log.Fatal(err) -// } +// Example — wait for block inclusion (interchain / Daria): // -// // Create a transaction -// txn := &models.TransactionCreateRequest{ -// TxnType: "my-transaction-type", -// Payload: map[string]interface{}{"message": "Hello Dragonchain"}, -// } +// resp, err := client.Transaction.Create(ctx, &models.TransactionCreateRequest{ +// TxnType: "my-transaction-type", +// Payload: `{"message": "Hello Dragonchain"}`, +// }) +// if err != nil { +// log.Fatal(err) +// } // -// resp, err := client.Transaction.Create(ctx, txn) +// // Poll until the transaction is included in a block. +// ticker := time.NewTicker(2 * time.Second) +// defer ticker.Stop() +// for range ticker.C { +// txn, err := client.Transaction.Get(ctx, resp.TransactionID) // if err != nil { // log.Fatal(err) // } -// fmt.Printf("Created transaction: %s\n", resp.TransactionID) +// if txn.Header.BlockId != "" { +// fmt.Printf("Block ID: %s\n", txn.Header.BlockId) +// break +// } // } package sdk diff --git a/transaction/transaction.go b/transaction/transaction.go index 7a27101..fe8d241 100755 --- a/transaction/transaction.go +++ b/transaction/transaction.go @@ -16,6 +16,10 @@ func NewTransactionClient(c *client.Client) *TransactionClient { return &TransactionClient{client: c} } +// Create submits a new transaction and returns immediately with the assigned transaction ID. +// It does NOT wait for the transaction to be included in a block. Block processing happens +// asynchronously on a ~5-second cycle. If you need the block ID (e.g. for interchain +// verification), poll Get until Header.BlockId is populated. func (tc *TransactionClient) Create(ctx context.Context, req *models.TransactionCreateRequest) (*models.TransactionCreateResponse, error) { var resp models.TransactionCreateResponse err := tc.client.Post(ctx, "/api/v1/transaction", models.ContentTypeJSON, req, &resp) @@ -25,6 +29,10 @@ func (tc *TransactionClient) Create(ctx context.Context, req *models.Transaction return &resp, nil } +// CreateBulk submits multiple transactions and returns immediately with the assigned transaction IDs. +// It does NOT wait for the transactions to be included in a block. Block processing happens +// asynchronously on a ~5-second cycle. If you need block IDs, poll Get for each transaction +// until Header.BlockId is populated. func (tc *TransactionClient) CreateBulk(ctx context.Context, req *models.TransactionBulkRequest) (*models.TransactionBulkResponse, error) { var resp models.TransactionBulkResponse err := tc.client.Post(ctx, "/api/v1/transaction/bulk", models.ContentTypeJSON, req, &resp)