GetInterchain: perChain + chains options (default first anchor per chain)
Transaction.GetInterchain and Block.GetInterchain take variadic options (client.WithPerChain / client.WithChains, re-exported as sdk.WithPerChain / sdk.WithChains) that map to the new prime-node ?perChain=&chains= query params. Backward compatible: existing no-option calls get the default (one anchor per chain). client.InterchainQuery builds the suffix; unit-tested.
This commit is contained in:
57
client/interchain.go
Normal file
57
client/interchain.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// InterchainOption configures an interchain-trace request (Transaction.GetInterchain
|
||||
// / Block.GetInterchain). Anchor proofs are chained, so by default the trace
|
||||
// returns the first anchor per public chain; these options change how many and
|
||||
// which chains are returned.
|
||||
type InterchainOption func(*interchainConfig)
|
||||
|
||||
type interchainConfig struct {
|
||||
perChain *int
|
||||
chains []string
|
||||
}
|
||||
|
||||
// WithPerChain caps how many interchain anchors are returned per public chain,
|
||||
// earliest-first: 1 is the first anchor per chain (the service default), 0
|
||||
// returns all anchors for each chain.
|
||||
func WithPerChain(n int) InterchainOption {
|
||||
return func(c *interchainConfig) { c.perChain = &n }
|
||||
}
|
||||
|
||||
// WithChains restricts the trace to these interchain chain ids ("1" = ETH
|
||||
// mainnet, "0" = BTC; testnet ids differ).
|
||||
func WithChains(chains ...string) InterchainOption {
|
||||
return func(c *interchainConfig) { c.chains = chains }
|
||||
}
|
||||
|
||||
// InterchainQuery builds the "?perChain=...&chains=..." suffix for the interchain
|
||||
// trace endpoints. Returns "" when no options are set (the server then applies
|
||||
// its defaults: one anchor per chain, all chains).
|
||||
func InterchainQuery(opts ...InterchainOption) string {
|
||||
cfg := &interchainConfig{}
|
||||
for _, o := range opts {
|
||||
o(cfg)
|
||||
}
|
||||
|
||||
var parts []string
|
||||
if cfg.perChain != nil {
|
||||
parts = append(parts, "perChain="+strconv.Itoa(*cfg.perChain))
|
||||
}
|
||||
if len(cfg.chains) > 0 {
|
||||
escaped := make([]string, len(cfg.chains))
|
||||
for i, c := range cfg.chains {
|
||||
escaped[i] = url.QueryEscape(c)
|
||||
}
|
||||
parts = append(parts, "chains="+strings.Join(escaped, ","))
|
||||
}
|
||||
if len(parts) == 0 {
|
||||
return ""
|
||||
}
|
||||
return "?" + strings.Join(parts, "&")
|
||||
}
|
||||
22
client/interchain_test.go
Normal file
22
client/interchain_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package client
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestInterchainQuery(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
opts []InterchainOption
|
||||
want string
|
||||
}{
|
||||
{"none", nil, ""},
|
||||
{"perChain1", []InterchainOption{WithPerChain(1)}, "?perChain=1"},
|
||||
{"perChain0 (all)", []InterchainOption{WithPerChain(0)}, "?perChain=0"},
|
||||
{"chains", []InterchainOption{WithChains("1", "0")}, "?chains=1,0"},
|
||||
{"both", []InterchainOption{WithPerChain(2), WithChains("1", "0")}, "?perChain=2&chains=1,0"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := InterchainQuery(c.opts...); got != c.want {
|
||||
t.Errorf("%s: InterchainQuery = %q, want %q", c.name, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user