Created
April 20, 2026 18:41
-
-
Save losh11/972ad8360c57fb0d1900a9e96ea7726a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package psbt | |
| import ( | |
| "bytes" | |
| "encoding/base64" | |
| "fmt" | |
| "testing" | |
| ) | |
| // TestVerifyHandCheck decodes the post-fix Jade-signed PSBT and checks | |
| // both the byte-level KV presence of the presign proprietary fields and | |
| // the ltcsuite-level post-sign invariants. | |
| func TestVerifyHandCheck(t *testing.T) { | |
| signed := "cHNidP8BAgQCAAAAAQQBAQEFAQEBkCBLF0jEaHhpqh6JUMpjM6ud+roPbN9CqN25RL4iMiJBYAGRIAnNF9/kI2c859EI63vSBn1xQuPMHv/X/EYXmISqDYZUAZIBAQH7BAIAAAAAAQFL5JEHAAAAAABCAhU/BX4I2AYbLM/YwFF/GjXc2pj2a/nKmbOrEdHudOFjAwQyTjlm1D4JqzAKcLoHXrxZ0dlwNmMZgtV+2kNxxUk3ARAEAAAAAAGQILLmjAKHXqav0f1C6mnjBcONBzC5j8jvK8YW3EF5393PAZEhCBTuzVrmckhzLMdwZCmIcc+f5LRRxRptfHMPG50mehARAZIhAguA9mLqgbMeD36JX+7nCC6jGAIffIFcjuP7AfRNBU00AZMhAlv+KkQ3JXy/E+//YgjhNxGfhl2FOGGOjWQox9j9tykSAZQBAQGVQMP+b+vKz4P1YTtPo8+STz1bYrJl2NRck58qYTXLfis0dizkQs39ejJDpxXLl3Sva0IXlntE2ff5Gwp1qV+e19YAIgIDvMOu+Ez5hLrtn+fgLoezj/grQaXtiMoAzW1X+HwQR7QUAAAAAAAAAIBkAACAAQAAAAAAAAABAwitbgEAAAAAAAEEQgMyp/+M0e5BV1Gi5XG2x0i2lmZ0CsfVTNDUggDmXjxcvwO8w674TPmEuu2f5+Auh7OP+CtBpe2IygDNbVf4fBBHtAGQQgMyp/+M0e5BV1Gi5XG2x0i2lmZ0CsfVTNDUggDmXjxcvwO8w674TPmEuu2f5+Auh7OP+CtBpe2IygDNbVf4fBBHtAGRIQjyaRwCbjMsJz8JN5kbY5g980I6dOk6HCe5vj5R9lB93AGSAQEBkyECm/z/77YA5TnhiKya6I9N+yXthtwpBhP/QzkfluQ/AKwBlCEDrTqtHv5GOm4B076DJSTn+vFOlvDsnMnI9fKPJN5QeWgBlToDecNjx2rzbA2m223pBjF5cFN57SFVxxTK5blD5igxOHLzfX6/RQFFAYF2STQPPUa3ZrO+fWT11sUnAZb9owIXX0aULeR4MIdebBqK4Pay41cW1+n0Cgp7Qqd50fPTnyg5Iqa0Z20XMizFss9la4oUAwviD92j5DKFfZ8DD+FyBfJqOJUohNJKHEYDqv7kHYGCkJjYsVvNs5we+1fwxuqsq/Y4DclPBbyGmjySAegoZ5C35b/Aw3yH0L3PO6AfkgGnT2mo7TUpr/Y6LFcT/z97zGNCBeE//i/3QahfWJpSUo+KWI3wsI2+LjpgESv2uoAOAcuyLUxLEhrSgC0ufAlPeBbKAJTWsEOTo58YB7Z0fa0DrJ1pL0uoKRR8sU4ybc6UXkpr0RC96WSE5U1V/vG0SQli39Ta2OwUtqPZQ8JHVNQTwxB770dZgmWJAWMJJ6MUIdFK0bAeFGIxXgJvvPmmBCvOeZExgqMpgjTP0IjX33VlPMW5cVFcr5rsPSNX8sgEbIIDQyn6vbNMvaOx3jEcx9bLje0COG1zZCh6LonLhU4CNJuhZH1ik1T7QI9htE/XdIQJPDhhwibWU6iIBTATpVrOPCnQxBL2lpriwBtzLENQ/1RVBaGD5B15lc0ashNK3zoh1s34lnxeO3ZPm5JqJIvUbpRdCxNiDgq2CoTd2ys8/T3LzjY4cc6eiDN/QH36vrLHr46hYhCxXDJjyOfQA3U6AvxkS08s0xJ3YZmbT6X4aj1PCz4TIPSH1zPHTVgPZBSLG+oVMzuw7rfqcNK5WXPGqGYftwA583/yekrml1JDm1Op7pj5uUIyFPnCUtl2UTPN/Kvw+X0+91oQbC4MqxYq8A5rvbpbMy09jPHpDoYGD7FKdEiYE7V+pHM+SerrDcxUdA2bkXqkJdj5sGW8+TbTXoQMqvMM4OrEwtAx7PkolJuIq1+WVaUWiQKzMCbsES5qNaJz0o3PoE9hoYeZZ9EBl0AapK17MrnjVqkQ+3RhlcXp0gtGh4HIfvb3FR1q/gHdhO7ZVwOo4kvdYyQPeUwYPEvj6zJT/yqKjaiFEoJ+24CBAAEAIQmSrR1NuKRfQYM3p9zs8miNCVgg2OMdML4KOAkXcC4vlAEBIQO3m8mcdtWoEGH8dPdBr33Ip6OPSPP0gYKivyGWXoLjWgECCLcIAAAAAAAAAgQAH4AaBgAAAAAAFgAUHy0M8xJnq9O6KFm1bj3pSGiMSo8BBgEVAQhAaToke/rQ5q83wQ8XAqOUA8k0TQxK9/7Z6EtR9zE8tDCIjvt8+8TtEAVefhDu0CoFufGjJ8yXw/eLRvLpxz4C6wA=" | |
| raw, err := base64.StdEncoding.DecodeString(signed) | |
| if err != nil { | |
| t.Fatalf("decode: %v", err) | |
| } | |
| // Byte-level search for the proprietary key prefixes. | |
| jadeOut := []byte{0xfc, 0x04, 'J', 'A', 'D', 'E', 0x01} | |
| jadeKrn := []byte{0xfc, 0x04, 'J', 'A', 'D', 'E', 0x02} | |
| fmt.Printf("byte-level 0xFC \"JADE\" 0x01 present in PSBT: %v\n", | |
| bytes.Contains(raw, jadeOut)) | |
| fmt.Printf("byte-level 0xFC \"JADE\" 0x02 present in PSBT: %v\n", | |
| bytes.Contains(raw, jadeKrn)) | |
| p, err := NewFromRawBytes(bytes.NewReader(raw), false) | |
| if err != nil { | |
| t.Fatalf("parse: %v", err) | |
| } | |
| fmt.Printf("\nversion=%d inputs=%d outputs=%d kernels=%d\n", | |
| p.PsbtVersion, len(p.Inputs), len(p.Outputs), len(p.Kernels)) | |
| if p.MwebTxOffset != nil { | |
| fmt.Printf("MwebTxOffset: %x\n", (*p.MwebTxOffset)[:]) | |
| } | |
| if p.MwebStealthOffset != nil { | |
| fmt.Printf("MwebStealthOffset: %x\n", (*p.MwebStealthOffset)[:]) | |
| } | |
| for i := range p.Inputs { | |
| in := &p.Inputs[i] | |
| fmt.Printf("input[%d] sig=%v pubkey=%v commit=%v amount=%v outId=%v outPk=%v kexPk=%v\n", | |
| i, in.MwebInputSig != nil, in.MwebInputPubkey != nil, | |
| in.MwebCommit != nil, in.MwebAmount != nil, | |
| in.MwebOutputId != nil, in.MwebOutputPubkey != nil, | |
| in.MwebKeyExchangePubkey != nil) | |
| } | |
| for i := range p.Outputs { | |
| o := &p.Outputs[i] | |
| sk, skErr := o.GetMwebPresignSenderKey() | |
| if o.isMWEB() { | |
| fmt.Printf("output[%d] sig=%v commit=%v sender=%v outPk=%v stdFields=%v rp=%v presign_sender_key_len=%d err=%v\n", | |
| i, o.MwebSignature != nil, o.OutputCommit != nil, | |
| o.SenderPubkey != nil, o.OutputPubkey != nil, | |
| o.MwebStandardFields != nil, o.RangeProof != nil, | |
| len(sk), skErr) | |
| } else { | |
| fmt.Printf("output[%d] non-mweb amount=%d\n", i, o.Amount) | |
| } | |
| } | |
| for i := range p.Kernels { | |
| k := &p.Kernels[i] | |
| stealthKey, stErr := k.GetMwebPresignStealthKey() | |
| feat := uint8(0) | |
| if k.Features != nil { | |
| feat = uint8(*k.Features) | |
| } | |
| fmt.Printf("kernel[%d] features=0x%02x sig=%v excess=%v stealthExcess=%v fee=%v pegouts=%d presign_stealth_key_len=%d err=%v\n", | |
| i, feat, | |
| k.Signature != nil, k.ExcessCommitment != nil, | |
| k.StealthExcess != nil, k.Fee != nil, | |
| len(k.PegOuts), len(stealthKey), stErr) | |
| if k.ExcessCommitment != nil { | |
| fmt.Printf(" excess=%x\n", k.ExcessCommitment[:]) | |
| } | |
| if k.StealthExcess != nil { | |
| fmt.Printf(" stealth_excess=%x\n", k.StealthExcess[:]) | |
| } | |
| if k.Signature != nil { | |
| fmt.Printf(" signature=%x\n", k.Signature[:]) | |
| } | |
| fmt.Printf(" unknowns count=%d\n", len(k.Unknowns)) | |
| for ui, u := range k.Unknowns { | |
| fmt.Printf(" unknown[%d] key=%x value_len=%d\n", ui, u.Key, len(u.Value)) | |
| } | |
| } | |
| fmt.Printf("\noutput[0] unknowns count=%d\n", len(p.Outputs[0].Unknowns)) | |
| for ui, u := range p.Outputs[0].Unknowns { | |
| fmt.Printf(" unknown[%d] key=%x value_len=%d\n", ui, u.Key, len(u.Value)) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment