mirror of
https://github.com/luxfi/bridge.git
synced 2026-10-30 14:45:52 +00:00
Brings the SDK-v1.0.3 layered cosigner pattern from app/server/src/domain/cosigners.ts
across to Go. Adds:
internal/secrets/ URI-scheme secret resolver (literal:/env:/file:/kms:)
with pluggable KMS providers (init-time Register).
Single source of truth for mpcd bearer tokens,
cosigner PEMs, and any future secret material.
internal/cosigners/ Layered cosigner SDK — per-swap external custodian
attestation on TOP of the native MPC threshold sig.
Wire shape mirrors the TS reference exactly (snake-
case, `kind` discriminator). Families:
- fireblocks.go Real REST integration; RAW
transaction approval flow,
per-tenant JWT (RSA), polls
/v1/transactions/{id} to
terminal status.
- utila.go Connect-RPC scaffold; mirrors
FireblocksRESTFamily shape so
the future port is one
contained method swap.
- stub_family.go Catch-all for unknown kinds.
Security invariant baked in: SECRET MATERIAL NEVER CROSSES THE WIRE. The
SDK sends only public identifiers (org_id, client_id, api_key, vault ids).
ValidateIntents rejects SECRET_FIELD_NAMES (api_secret, private_key, jwt,
token, …) as a defensive layer. Secrets are fetched at dispatch time via
secrets.Resolver, which is also where KMS plugs in.
Tests: cosigners (2.0s) + secrets (0.3s) all green. Self-contained — no
out-of-tree imports beyond stdlib and within-repo packages.
Extracted from origin/whispers/bridgev2 as the first of a series of focused
slices integrating that branch onto main without dragging in the noise
(export.txt transcript dump, bridge binary diff). Per "x.x.x+1" rule the
next bridge release tag is v1.2.0 — this is the first additive feature
that warrants the minor bump (new internal packages, no consumer break).
42 lines
1.8 KiB
Go
42 lines
1.8 KiB
Go
package cosigners
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
// StubFamilyDispatcher fails every cosign step with a clear "not
|
|
// implemented in Go bridge" reason. Used as the default during Phase 1.4
|
|
// so that institutional users hitting cmd/bridge see a LOUD failure
|
|
// pointing them at app/server, instead of the current silent-drop
|
|
// regression where the swap completes without cosigning at all.
|
|
//
|
|
// Drop-in replacements:
|
|
// - For Fireblocks: a real RESTful Fireblocks client (Task #39).
|
|
// - For Utila: pending implementation of the @luxfi/utila Connect-RPC
|
|
// transaction-approval flow (TS module currently also a stub).
|
|
//
|
|
// Tests should swap in MockFamilyDispatcher instead of using this — the
|
|
// stub's whole purpose is to produce a known failure shape, not to be
|
|
// mockable.
|
|
type StubFamilyDispatcher struct{}
|
|
|
|
// RunUtila returns StatusFailed with a clear "not implemented" reason.
|
|
func (StubFamilyDispatcher) RunUtila(_ context.Context, intent *UtilaIntent, _ string, opts DispatchOptions) Result {
|
|
return Result{
|
|
Intent: Intent{Kind: KindUtila, Utila: intent},
|
|
Status: StatusFailed,
|
|
Reason: fmt.Sprintf("utila cosign not yet implemented in cmd/bridge (Go); use app/server (Express) for swap=%s, or wait for §3.5 e2e soak", opts.SwapID),
|
|
}
|
|
}
|
|
|
|
// RunFireblocks returns StatusFailed with a clear "not implemented" reason
|
|
// that points at Task #39 (the real REST client work).
|
|
func (StubFamilyDispatcher) RunFireblocks(_ context.Context, intent *FireblocksIntent, _ string, opts DispatchOptions) Result {
|
|
return Result{
|
|
Intent: Intent{Kind: KindFireblocks, Fireblocks: intent},
|
|
Status: StatusFailed,
|
|
Reason: fmt.Sprintf("fireblocks cosign not yet implemented in cmd/bridge (Go); REST client + JWT signing pending — see Task #39 for swap=%s", opts.SwapID),
|
|
}
|
|
}
|