Files
zeekay fa49881b9c A signed warp message is an Envelope, and says so in the type
warp split content from signatures: a Message is content, an Envelope is that
content plus the beam, corona and ML-DSA signatures over it. Every function
here was still named Get...Message and typed *warp.Message regardless of which
it produced, so one word did two jobs and the compiler could not tell them
apart.

Each signature is now set from what the function actually returns, not from
its name. SignMessage parses what the aggregator hands back — a message plus
the signatures gathered over it — so it returns an Envelope. The three
functions that aggregate return Envelope; the ones that construct or extract
content return Message; and where a caller wants the content out of a signed
result it takes .Message rather than the wrapper.

Two functions in registration.go look like they should follow but do not: they
aggregate and then convert the result back to a node warp message, so a
Message is genuinely what they yield.

go build ./... exits 0 and go test ./... is 23 ok. The three packages that
still fail to build their tests -- profiles, wallet/keychain, wallet/primary --
fail identically before this change; Consensus, VerifyHybridSecp256k1MLDSA and
isXChainNotEnabled are referenced by tests and defined nowhere.
2026-08-28 22:55:54 -07:00
..
2026-08-21 09:33:15 -07:00

Signature-aggregator SDK

Usage example

// Copyright (C) 2025, Lux Industries, Inc. All rights reserved
// See the file LICENSE for licensing terms.

package main

import (
	"fmt"
	"os"

	"github.com/luxfi/lux-cli/sdk/network"
	"github.com/luxfi/lux-cli/sdk/warp"
	"github.com/luxfi/luxd/ids"
	"github.com/luxfi/luxd/utils/logging"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func main() {
	network := network.TestnetNetwork()
	aggregator, err := warp.NewSignatureAggregator(
		network,
		logging.NewLogger(
			"aggregator_test",
			logging.NewWrappedCore(
				logging.Error,
				os.Stdout,
				zapcore.NewConsoleEncoder(
					zap.NewProductionEncoderConfig(),
				),
			),
		),
		logging.Error,
		ids.Empty,
		warp.DefaultQuorumPercentage,
	)
	if err != nil {
		panic(err)
	}

	msgHexString := "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002cc0000000000057fc93d85c6d62c5b2ac0b519c87010ea5294012d1e407030d6acd0021cac10d5000002a200000000000100000014253b2784c75e510dd0ff1da844684a1ac0aa5fcf000002800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000049d0000000000000000000000009297e09b81db7ae921fb69dc745dc0d37ec4ab6ddd30039ae180ccb3b132f5c67f299b83749f1f0a12f7d69878c6b696598fd0c50000000000000000000000006839ebb9c7b7df12a2147790f6aaa19ac1bf76eb000000000000000000000000000000000000000000000000000000000001117000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000600000000000000000000000014c3ae49cb46c965e6c9aca4a121c8f8481d44b900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000f7571ae49399c8a1b4c8c8eb8cc328bc5f817590000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000"
	justificationHexString := hex.EncodeToString([]byte("test"))
	reply, err := aggregator.AggregateSignatures(msgHexString, justificationHexString)
	if err != nil {
		panic(err)
	}
	fmt.Println(reply)
}
❯ go run example.go
0000000000057fc93d85c6d62c5b2ac0b519c87010ea5294012d1e407030d6acd0021cac10d5000002a200000000000100000014253b2784c75e510dd0ff1da844684a1ac0aa5fcf000002800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000049d0000000000000000000000009297e09b81db7ae921fb69dc745dc0d37ec4ab6ddd30039ae180ccb3b132f5c67f299b83749f1f0a12f7d69878c6b696598fd0c50000000000000000000000006839ebb9c7b7df12a2147790f6aaa19ac1bf76eb000000000000000000000000000000000000000000000000000000000001117000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000600000000000000000000000014c3ae49cb46c965e6c9aca4a121c8f8481d44b900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000f7571ae49399c8a1b4c8c8eb8cc328bc5f817590000000000000000000000000000000000000000000000000016345785d8a00000000000000000036210300000084000102000a10100100000402000000001204000020000000000000000030100040000400130444001000084011042040aa495650029c5a7106a75623ab55ab9e895795f79d12a5f5b62ce1f55c71989f3bc70a7ddbfdf520953c0d9cfe1329b60e6e931a9f548da3101d435773bdb5756cbdb1a8cc25c08f7dba367642a6c35cfbb3d817d93fb7948e8038d0cb06414f