@ercworldio/blockchain-shared 1.0.23 → 1.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -50,6 +50,23 @@ export interface Ed25519Entry {
50
50
  signature: Uint8Array;
51
51
  message: Uint8Array;
52
52
  }
53
+ /**
54
+ * Wraps `message` in the Solana off-chain message envelope (legacy version 0 header). MUST match
55
+ * the program's `offchain_envelope` byte for byte:
56
+ *
57
+ * 0xff "solana offchain" | version (0) | format | length (u16 LE) | message
58
+ *
59
+ * Ledger-backed wallets can't sign arbitrary bytes, so `signMessage` on them signs this envelope
60
+ * instead of the raw approval text. Format is 0 for printable ASCII only, otherwise 1.
61
+ */
62
+ export declare function offchainEnvelope(message: Uint8Array): Buffer;
63
+ /**
64
+ * Returns the bytes `signature` actually covers: the raw message (regular wallets) or its
65
+ * off-chain envelope (Ledger-backed wallets). The precompile verifies whatever bytes the Ed25519
66
+ * instruction carries, and the program accepts either form, so the entry must carry the one that
67
+ * verifies. Falls back to the raw message when neither does; the precompile then rejects it.
68
+ */
69
+ export declare function resolveSignedMessage(publicKey: Uint8Array, signature: Uint8Array, message: Uint8Array): Uint8Array;
53
70
  /**
54
71
  * Builds a single Ed25519SigVerify instruction carrying `entries` self-contained signatures
55
72
  * (each entry's pubkey, signature and message live in this instruction's own data). This is the
@@ -61,5 +78,5 @@ export interface Ed25519Entry {
61
78
  * approve one withdrawal all sign the same ~194-byte payload, so without sharing, a 2-of-N
62
79
  * approval would spend an extra ~194 bytes and overflow Solana's 1232-byte transaction limit.
63
80
  */
64
- export declare function buildTreasuryEd25519Instruction(entries: Ed25519Entry[]): TransactionInstruction;
81
+ export declare function buildTreasuryEd25519Instruction(input: Ed25519Entry[]): TransactionInstruction;
65
82
  //# sourceMappingURL=TreasuryWithdrawalSignature.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TreasuryWithdrawalSignature.d.ts","sourceRoot":"","sources":["../../../../../src/services/solana/escrow/services/TreasuryWithdrawalSignature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAGpF;;;;;GAKG;AAEH,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACnC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACnD,eAAe,EAAE,SAAS,CAAC;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAWT;AAED,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAU5D;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,sBAAsB,CAoD/F"}
1
+ {"version":3,"file":"TreasuryWithdrawalSignature.d.ts","sourceRoot":"","sources":["../../../../../src/services/solana/escrow/services/TreasuryWithdrawalSignature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAIpF;;;;;GAKG;AAEH,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACnC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACnD,eAAe,EAAE,SAAS,CAAC;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAWT;AAED,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAU5D;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;CACvB;AAID;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAM5D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU,CAKlH;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,sBAAsB,CAsD7F"}
@@ -5,9 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.buildWithdrawalApprovalMessage = buildWithdrawalApprovalMessage;
7
7
  exports.decodeEd25519Signature = decodeEd25519Signature;
8
+ exports.offchainEnvelope = offchainEnvelope;
9
+ exports.resolveSignedMessage = resolveSignedMessage;
8
10
  exports.buildTreasuryEd25519Instruction = buildTreasuryEd25519Instruction;
9
11
  const web3_js_1 = require("@solana/web3.js");
10
12
  const bs58_1 = __importDefault(require("bs58"));
13
+ const tweetnacl_1 = __importDefault(require("tweetnacl"));
11
14
  /**
12
15
  * Builds the UTF-8 approval message a treasury signer approves. MUST match the program's
13
16
  * `build_withdrawal_message` byte for byte, or verification fails.
@@ -57,6 +60,38 @@ function decodeEd25519Signature(s) {
57
60
  catch ( /* fallthrough */_a) { /* fallthrough */ }
58
61
  throw new Error("Invalid Ed25519 signature encoding (expected 64 bytes as base64/hex/base58)");
59
62
  }
63
+ const OFFCHAIN_SIGNING_DOMAIN = Buffer.concat([Buffer.from([0xff]), Buffer.from("solana offchain", "ascii")]);
64
+ /**
65
+ * Wraps `message` in the Solana off-chain message envelope (legacy version 0 header). MUST match
66
+ * the program's `offchain_envelope` byte for byte:
67
+ *
68
+ * 0xff "solana offchain" | version (0) | format | length (u16 LE) | message
69
+ *
70
+ * Ledger-backed wallets can't sign arbitrary bytes, so `signMessage` on them signs this envelope
71
+ * instead of the raw approval text. Format is 0 for printable ASCII only, otherwise 1.
72
+ */
73
+ function offchainEnvelope(message) {
74
+ if (message.length > 0xffff)
75
+ throw new Error("Message too long for the off-chain message header");
76
+ const format = message.every(b => b >= 0x20 && b <= 0x7e) ? 0 : 1;
77
+ const len = Buffer.alloc(2);
78
+ len.writeUInt16LE(message.length);
79
+ return Buffer.concat([OFFCHAIN_SIGNING_DOMAIN, Buffer.from([0, format]), len, Buffer.from(message)]);
80
+ }
81
+ /**
82
+ * Returns the bytes `signature` actually covers: the raw message (regular wallets) or its
83
+ * off-chain envelope (Ledger-backed wallets). The precompile verifies whatever bytes the Ed25519
84
+ * instruction carries, and the program accepts either form, so the entry must carry the one that
85
+ * verifies. Falls back to the raw message when neither does; the precompile then rejects it.
86
+ */
87
+ function resolveSignedMessage(publicKey, signature, message) {
88
+ if (tweetnacl_1.default.sign.detached.verify(message, signature, publicKey))
89
+ return message;
90
+ const envelope = offchainEnvelope(message);
91
+ if (tweetnacl_1.default.sign.detached.verify(envelope, signature, publicKey))
92
+ return envelope;
93
+ return message;
94
+ }
60
95
  /**
61
96
  * Builds a single Ed25519SigVerify instruction carrying `entries` self-contained signatures
62
97
  * (each entry's pubkey, signature and message live in this instruction's own data). This is the
@@ -68,7 +103,9 @@ function decodeEd25519Signature(s) {
68
103
  * approve one withdrawal all sign the same ~194-byte payload, so without sharing, a 2-of-N
69
104
  * approval would spend an extra ~194 bytes and overflow Solana's 1232-byte transaction limit.
70
105
  */
71
- function buildTreasuryEd25519Instruction(entries) {
106
+ function buildTreasuryEd25519Instruction(input) {
107
+ // Carry the bytes each signature actually covers (raw, or the Ledger off-chain envelope)
108
+ const entries = input.map(e => (Object.assign(Object.assign({}, e), { message: resolveSignedMessage(e.publicKey, e.signature, e.message) })));
72
109
  const N = entries.length;
73
110
  const OFFSETS_SIZE = 14;
74
111
  const ENTRY_SIZE = 32 + 64; // pubkey + signature
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ercworldio/blockchain-shared",
3
- "version": "1.0.23",
3
+ "version": "1.0.24",
4
4
  "description": "Shared library for blockchain projects",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",