@ercworldio/blockchain-shared 1.0.22 → 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.
- package/build/services/solana/escrow/services/TreasuryWithdrawalSignature.d.ts +18 -1
- package/build/services/solana/escrow/services/TreasuryWithdrawalSignature.d.ts.map +1 -1
- package/build/services/solana/escrow/services/TreasuryWithdrawalSignature.js +38 -1
- package/build/services/tron/services/TronHotWallet.d.ts.map +1 -1
- package/build/services/tron/services/TronHotWallet.js +4 -2
- package/package.json +1 -1
|
@@ -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(
|
|
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;
|
|
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(
|
|
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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TronHotWallet.d.ts","sourceRoot":"","sources":["../../../../src/services/tron/services/TronHotWallet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAoB,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEnH,cAAM,aAAa;IACf;;OAEG;WACU,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAYhF;;OAEG;WACU,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAe1G;;OAEG;WACU,aAAa,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;WAsB3H,oBAAoB,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;IA+B/I,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAe9C;IAEF,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;WAM9B,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"TronHotWallet.d.ts","sourceRoot":"","sources":["../../../../src/services/tron/services/TronHotWallet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAoB,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEnH,cAAM,aAAa;IACf;;OAEG;WACU,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAYhF;;OAEG;WACU,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAe1G;;OAEG;WACU,aAAa,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;WAsB3H,oBAAoB,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;IA+B/I,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAe9C;IAEF,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;WAM9B,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC;WA4BzG,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;CAelE;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -112,8 +112,10 @@ class TronHotWallet {
|
|
|
112
112
|
try {
|
|
113
113
|
if (tokenAddress === ethers_1.ethers.ZeroAddress.slice(2) || tokenAddress === ethers_1.ethers.ZeroAddress || tokenAddress.toUpperCase() === "TRX") {
|
|
114
114
|
const tx = yield tronWeb.trx.sendTransaction(to, Number(amount));
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
// A rejected broadcast usually comes back as { code, txid, message } with no `result`,
|
|
116
|
+
// so anything other than result === true is a failure (the txid alone proves nothing)
|
|
117
|
+
if (tx.result !== true) {
|
|
118
|
+
const code = tx.code || 'BROADCAST_REJECTED';
|
|
117
119
|
const msg = tx.message
|
|
118
120
|
? Buffer.from(tx.message, 'hex').toString('utf8')
|
|
119
121
|
: code;
|