diff --git a/pkg/cascadekit/signatures.go b/pkg/cascadekit/signatures.go index 8375f023..74f90032 100644 --- a/pkg/cascadekit/signatures.go +++ b/pkg/cascadekit/signatures.go @@ -7,9 +7,6 @@ import ( "github.com/LumeraProtocol/supernode/v2/pkg/codec" "github.com/LumeraProtocol/supernode/v2/pkg/errors" - - actionkeeper "github.com/LumeraProtocol/lumera/x/action/v1/keeper" - keyringpkg "github.com/LumeraProtocol/supernode/v2/pkg/keyring" sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -42,28 +39,26 @@ func SignLayoutB64(layout codec.Layout, signer Signer) (layoutB64 string, layout } // SignIndexB64 marshals the index to JSON, base64-encodes it, and signs the -// JSON string (not the base64), returning both the index base64 and creator-signature base64. +// base64 payload, returning both the index base64 and creator-signature base64. // // IMPORTANT: -// - Message signed = index JSON string (same as JS signArbitrary(indexFileString)) -// - indexB64 is still base64(JSON(index)), used in metadata and RQID generation. +// - Message signed = indexB64 string (chain-compatible) +// - indexB64 is base64(JSON(index)), used in metadata and RQID generation. func SignIndexB64(idx IndexFile, signer Signer) (indexB64 string, creatorSigB64 string, err error) { raw, err := json.Marshal(idx) if err != nil { return "", "", errors.Errorf("marshal index file: %w", err) } - indexJSON := string(raw) + indexB64 = base64.StdEncoding.EncodeToString(raw) - // Sign the JSON string (JS-style) - sig, err := signer([]byte(indexJSON)) + // Sign the base64 payload (chain-compatible) + sig, err := signer([]byte(indexB64)) if err != nil { return "", "", errors.Errorf("sign index: %w", err) } creatorSigB64 = base64.StdEncoding.EncodeToString(sig) - // Base64(JSON(index)) used as the first segment of indexSignatureFormat - indexB64 = base64.StdEncoding.EncodeToString(raw) return indexB64, creatorSigB64, nil } @@ -73,9 +68,7 @@ func SignIndexB64(idx IndexFile, signer Signer) (indexB64 string, creatorSigB64 // // It validates the layout has exactly one block. // -// The "signer" can be: -// - raw: directly sign msg bytes (legacy Go path) -// - ADR-36: wrap msg into an ADR-36 sign doc, then sign (JS-compatible path) +// The signer directly signs the message bytes (raw signing). func CreateSignatures(layout codec.Layout, signer Signer, ic, max uint32) (indexSignatureFormat string, indexIDs []string, err error) { layoutB64, layoutSigB64, err := SignLayoutB64(layout, signer) if err != nil { @@ -89,7 +82,7 @@ func CreateSignatures(layout codec.Layout, signer Signer, ic, max uint32) (index return "", nil, err } - // Build and sign the index file (JS-style: message = index JSON string) + // Build and sign the index file (message = indexB64 string) idx := BuildIndex(layoutIDs, layoutSigB64) indexB64, creatorSigB64, err := SignIndexB64(idx, signer) if err != nil { @@ -105,12 +98,10 @@ func CreateSignatures(layout codec.Layout, signer Signer, ic, max uint32) (index return indexSignatureFormat, indexIDs, nil } -// CreateSignaturesWithKeyring signs layout and index using a Cosmos keyring (legacy path). +// CreateSignaturesWithKeyring signs layout and index using a Cosmos keyring. // Message signed = raw bytes passed by SignLayoutB64 / SignIndexB64: // - layout: layoutB64 string // - index: index JSON string -// -// The verification pipeline already handles both raw and ADR-36, so this remains valid. func CreateSignaturesWithKeyring( layout codec.Layout, kr sdkkeyring.Keyring, @@ -122,97 +113,3 @@ func CreateSignaturesWithKeyring( } return CreateSignatures(layout, signer, ic, max) } - -// adr36SignerForKeyring creates a signer that signs ADR-36 doc bytes -// for the given signer address. The "msg" we pass in is the *message* -// (layoutB64, index JSON, etc.), and this helper wraps it into ADR-36. -func adr36SignerForKeyring( - kr sdkkeyring.Keyring, - keyName string, - signerAddr string, -) Signer { - return func(msg []byte) ([]byte, error) { - // msg is the cleartext message we want to sign (e.g., layoutB64 or index JSON string) - dataB64 := base64.StdEncoding.EncodeToString(msg) - - // Build ADR-36 sign bytes: signerAddr + base64(message) - doc, err := actionkeeper.MakeADR36AminoSignBytes(signerAddr, dataB64) - if err != nil { - return nil, err - } - - // Now sign the ADR-36 doc bytes with the keyring (direct secp256k1) - return keyringpkg.SignBytes(kr, keyName, doc) - } -} - -// CreateSignaturesWithKeyringADR36WithSigner creates signatures in the SAME way as the JS SDK, -// allowing an explicit bech32 signer address override for ADR-36 sign bytes. -func CreateSignaturesWithKeyringADR36WithSigner( - layout codec.Layout, - kr sdkkeyring.Keyring, - keyName string, - signerAddr string, - ic, max uint32, -) (string, []string, error) { - if signerAddr == "" { - addr, err := keyringpkg.GetAddress(kr, keyName) - if err != nil { - return "", nil, fmt.Errorf("resolve signer address: %w", err) - } - signerAddr = addr.String() - } - - signer := adr36SignerForKeyring(kr, keyName, signerAddr) - - return CreateSignatures(layout, signer, ic, max) -} - -// CreateSignaturesWithKeyringADR36 creates signatures in the SAME way as the JS SDK: -// -// - layout: Keplr-like ADR-36 signature over layoutB64 string -// - index: Keplr-like ADR-36 signature over index JSON string -// -// The resulting indexSignatureFormat string will match what JS produces for the same -// layout, signer, ic, and max. -func CreateSignaturesWithKeyringADR36( - layout codec.Layout, - kr sdkkeyring.Keyring, - keyName string, - ic, max uint32, -) (string, []string, error) { - return CreateSignaturesWithKeyringADR36WithSigner(layout, kr, keyName, "", ic, max) -} - -// SignADR36String signs a message string using the ADR-36 scheme that Keplr uses. -// "message" must be the same string you'd pass to Keplr's signArbitrary, e.g.: -// - layoutB64 -// - index JSON -// - dataHash (base64 blake3) -func SignADR36String( - kr sdkkeyring.Keyring, - keyName string, - signerAddr string, - message string, -) (string, error) { - // 1) message -> []byte - msgBytes := []byte(message) - - // 2) base64(UTF-8(message)) - dataB64 := base64.StdEncoding.EncodeToString(msgBytes) - - // 3) Build ADR-36 sign bytes (Keplr-accurate) - docBytes, err := actionkeeper.MakeADR36AminoSignBytes(signerAddr, dataB64) - if err != nil { - return "", fmt.Errorf("build adr36 sign bytes: %w", err) - } - - // 4) Sign with Cosmos keyring - sig, err := keyringpkg.SignBytes(kr, keyName, docBytes) - if err != nil { - return "", fmt.Errorf("sign adr36 doc: %w", err) - } - - // 5) Wire format: base64(rsSignature) - return base64.StdEncoding.EncodeToString(sig), nil -} diff --git a/sdk/action/client.go b/sdk/action/client.go index ec7c45c1..d286d25c 100644 --- a/sdk/action/client.go +++ b/sdk/action/client.go @@ -48,7 +48,7 @@ type Client interface { // and returns CascadeMetadata (with signatures) along with price and expiration time. // Internally derives ic (random in [1..100]), max (from chain params), price (GetActionFee), // and expiration (params duration + 1h buffer). signerAddr overrides the bech32 signer - // used in ADR-36 sign bytes; pass empty string to use the keyring address. + // used for key selection (e.g. ICA owner key); pass empty string to use the client signer. BuildCascadeMetadataFromFile(ctx context.Context, filePath string, public bool, signerAddr string) (actiontypes.CascadeMetadata, string, string, error) // GenerateStartCascadeSignatureFromFile computes blake3(file) and signs it with the configured key; returns base64 signature. GenerateStartCascadeSignatureFromFile(ctx context.Context, filePath string) (string, error) @@ -292,7 +292,7 @@ func (c *ClientImpl) BuildCascadeMetadataFromFile(ctx context.Context, filePath rnd, _ := crand.Int(crand.Reader, big.NewInt(100)) ic := uint32(rnd.Int64() + 1) // 1..100 - // Create signatures from the layout struct using ADR-36 scheme (JS compatible). + // Create signatures from the layout struct using raw signing. if signerAddr == "" { signerAddr = c.signerAddr } @@ -309,11 +309,10 @@ func (c *ClientImpl) BuildCascadeMetadataFromFile(ctx context.Context, filePath event.KeyMessage: "metadata signed with ICA signer address", })) } - indexSignatureFormat, _, err := cascadekit.CreateSignaturesWithKeyringADR36WithSigner( + indexSignatureFormat, _, err := cascadekit.CreateSignaturesWithKeyring( layout, c.keyring, keyName, - signerAddr, ic, max, ) @@ -370,15 +369,14 @@ func (c *ClientImpl) GenerateStartCascadeSignatureFromFileDeprecated(ctx context return base64.StdEncoding.EncodeToString(sig), nil } -// GenerateStartCascadeSignatureFromFile computes blake3(file) and signs it with the configured key -// using the ADR-36 scheme, matching Keplr's signArbitrary(dataHash) behavior. -// Returns base64-encoded signature suitable for StartCascade. +// GenerateStartCascadeSignatureFromFile computes blake3(file) and signs the base64 hash string +// using raw signing (pure Go internal format). Returns base64-encoded signature suitable for StartCascade. func (c *ClientImpl) GenerateStartCascadeSignatureFromFile(ctx context.Context, filePath string) (string, error) { return c.GenerateStartCascadeSignatureFromFileWithSigner(ctx, filePath, "") } // GenerateStartCascadeSignatureFromFileWithSigner computes blake3(file) and signs it with the configured key, -// using the provided bech32 signer address for ADR-36 sign bytes. +// using signerAddr for key selection (e.g. ICA owner key). func (c *ClientImpl) GenerateStartCascadeSignatureFromFileWithSigner(ctx context.Context, filePath string, signerAddr string) (string, error) { // Compute blake3(file), encode as base64 string h, err := utils.Blake3HashFile(filePath) @@ -387,7 +385,6 @@ func (c *ClientImpl) GenerateStartCascadeSignatureFromFileWithSigner(ctx context } dataHashB64 := base64.StdEncoding.EncodeToString(h) - // Sign the dataHashB64 string using ADR-36 (same as JS / Keplr). if signerAddr == "" { signerAddr = c.signerAddr } @@ -400,17 +397,12 @@ func (c *ClientImpl) GenerateStartCascadeSignatureFromFileWithSigner(ctx context logtrace.Info(ctx, "auth: ICA start signature", logFields) c.logger.Info(ctx, "Signing cascade start with ICA signer", "signer", signerAddr, "key_name", keyName) } - sigB64, err := cascadekit.SignADR36String( - c.keyring, - keyName, - signerAddr, // bech32 address for ADR-36 sign bytes - dataHashB64, - ) + sig, err := snkeyring.SignBytes(c.keyring, keyName, []byte(dataHashB64)) if err != nil { - return "", fmt.Errorf("sign adr36 hash string: %w", err) + return "", fmt.Errorf("sign hash string: %w", err) } - return sigB64, nil + return base64.StdEncoding.EncodeToString(sig), nil } func (c *ClientImpl) resolveSigningKeyName(signerAddr string) (string, bool) {