Skip to content

Client library #29

@louisinger

Description

@louisinger

Summary

Provide a high-level Go client library (importable package) that abstracts the complexity of integrating with the introspector service. Developers building Arkade Script-enabled wallets, SDKs, or tools should be able to do so without understanding the low-level details of key tweaking, script encoding, or co-signing protocol mechanics.

Current State

The repo already has foundational primitives:

  • pkg/arkade/tweak.goArkadeScriptHash, ComputeArkadeScriptPublicKey, ComputeArkadeScriptPrivateKey (key tweaking via tagged hash + point addition)
  • pkg/arkade/opcode.go — Arkade extension opcodes (0xc4–0xf2)
  • pkg/arkade/script.go + tokenizer.go — script encoding/decoding
  • pkg/arkade/introspector_packet.go — OP_RETURN packet construction
  • pkg/client/transport_client.go — low-level TransportClient interface + NewGRPCClient(conn) implementation covering all four RPC methods: GetInfo, SubmitTx, SubmitIntent, SubmitFinalization

What's missing is a high-level, ergonomic public API on top of these primitives — something an external Go developer can go get and use without reading the internals.

Motivation

Currently, integrating introspector support requires:

  • Manually constructing a *grpc.ClientConn before you can call anything
  • Directly working with ComputeArkadeScriptPublicKey / ArkadeScriptHash with no obvious entry point
  • Hand-assembling Arkade scripts using raw opcodes
  • Orchestrating the two-step co-signing flow (SubmitIntentSubmitFinalization) with no helper to guide sequencing
  • Understanding which transport to use (gRPC, or the HTTP gateway)

This is a high adoption barrier. A clean wrapper makes Arkade Script support accessible to go-sdk, arkd, and third-party integrators.

Reference Implementation

See ts-sdk#319 for the TypeScript reference. It includes:

  • Script codec — encode/decode Arkade extension opcodes with ASM helpers
  • Key tweakingtweakKey(pubkey, script)
  • ArkadeVtxoScript — extends VtxoScript with auto-tweaking
  • Provider — REST client wrapping /info, /intent, /finalize
  • Batch handler — full boarding + settlement flow with co-signing

The Go client should offer equivalent coverage, adapted to Go idioms and the existing TransportClient abstraction.

Proposed API (Go)

// --- Connection ---

// NewClient creates a ready-to-use client from a server URL.
// Handles gRPC dial internally (TLS if https://, plaintext otherwise).
client, err := introspector.NewClient(ctx, "https://introspector.example.com")
defer client.Close()

// --- Service info ---

info, err := client.GetInfo(ctx)
// info.SignerPublicKey — hex-encoded compressed pubkey
// info.Version

// --- Key tweaking ---

// TweakKey computes an introspector-bound pubkey: pubkey + G*hash(ArkScriptHash || script)
tweakedPubKey := introspector.TweakKey(signerPubKey, arkadeScript)
tweakedPrivKey := introspector.TweakPrivKey(signerPrivKey, arkadeScript)

// --- Script building ---

script, err := introspector.NewScriptBuilder().
    PushData(someData).
    Op(introspector.OP_INSPECTINPUTVALUE).
    Op(introspector.OP_LESSTHAN).
    Build()

// Encode/decode to ASM for debugging
asm := script.ToASM()
script, err = introspector.ParseASM(asm)

// --- Transaction co-signing ---

// Step 1: submit an Ark tx (settlement/boarding) for introspector co-signature.
// Used outside of a round, e.g. for contract-based boarding.
signedArkTx, signedCheckpoints, err := client.SubmitTx(ctx, psbt, checkpointPsbts)

// Step 2a: submit intent proof before round registration
signedProof, err := client.SubmitIntent(ctx, introspector.Intent{
    Proof:   intentProof,
    Message: intentMessage,
})

// Step 2b: finalize during batch settlement — gets introspector to sign forfeits + commitment tx
result, err := client.SubmitFinalization(ctx, introspector.FinalizationRequest{
    SignedIntent:   signedIntent,
    Forfeits:       forfeitPsbts,
    ConnectorTree:  connectorTree,
    CommitmentTx:   commitmentPsbt,
})
// result.SignedForfeits, result.SignedCommitmentTx

Scope

  • introspector.NewClient(ctx, url string) (*Client, error) — dials gRPC, respects TLS from URL scheme
  • Client.GetInfo, SubmitTx, SubmitIntent, SubmitFinalization — thin wrappers over TransportClient with ergonomic Go types (no protobuf types leaking to callers)
  • TweakKey(pubkey, script) / TweakPrivKey(privkey, script) — public helpers (thin wrappers over existing pkg/arkade/tweak.go)
  • ScriptBuilder — fluent builder for Arkade scripts, wrapping existing opcode/script primitives
  • ParseASM / Script.ToASM — encode/decode for debugging and logging
  • Proper Go module: either expose via the root module or a dedicated client/ module with a clean import path
  • Usage examples in docs/ or README
  • Unit tests for key tweaking, script builder, ASM roundtrip
  • Integration/e2e test showing the full intent → finalization flow (can mirror the ts-sdk e2e pattern)

Out of Scope

  • HTTP/REST client (the existing gRPC + HTTP gateway covers both; gRPC is preferred for Go)
  • Higher-level VtxoScript integration (belongs in go-sdk, not here)
  • Batch/round coordination helpers (orchestration belongs in arkd / go-sdk)

Notes

  • The pkg/client/transport_client.go interface is the right internal abstraction — the public Client type should compose it, not replace it.
  • Protobuf types should not appear in the public API surface; map them to plain Go structs internally.
  • The pkg/arkade primitives (ComputeArkadeScriptPublicKey, etc.) are already correct — the public helpers just need to wrap them with friendlier names and signatures.
  • go-sdk will likely be the primary consumer; coordinate with @altafan on the import path.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions