@chainberry/berry-signer 1.0.0 → 1.0.2

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.
Files changed (49) hide show
  1. package/README.md +76 -0
  2. package/dist/btc/btc-sign.d.ts +8 -0
  3. package/dist/btc/btc-sign.d.ts.map +1 -0
  4. package/dist/btc/btc-sign.js +24 -0
  5. package/dist/btc/btc-sign.js.map +1 -0
  6. package/dist/evm/evm-sign.d.ts +19 -0
  7. package/dist/evm/evm-sign.d.ts.map +1 -0
  8. package/dist/evm/evm-sign.js +34 -0
  9. package/dist/evm/evm-sign.js.map +1 -0
  10. package/{src/index.ts → dist/index.d.ts} +1 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +11 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/ltc/ltc-sign.d.ts +14 -0
  15. package/dist/ltc/ltc-sign.d.ts.map +1 -0
  16. package/dist/ltc/ltc-sign.js +55 -0
  17. package/dist/ltc/ltc-sign.js.map +1 -0
  18. package/dist/sol/sol-sign.d.ts +7 -0
  19. package/dist/sol/sol-sign.d.ts.map +1 -0
  20. package/dist/sol/sol-sign.js +37 -0
  21. package/dist/sol/sol-sign.js.map +1 -0
  22. package/dist/ton/ton-sign.d.ts +15 -0
  23. package/dist/ton/ton-sign.d.ts.map +1 -0
  24. package/dist/ton/ton-sign.js +33 -0
  25. package/dist/ton/ton-sign.js.map +1 -0
  26. package/dist/trx/trx-sign.d.ts +8 -0
  27. package/dist/trx/trx-sign.d.ts.map +1 -0
  28. package/dist/trx/trx-sign.js +22 -0
  29. package/dist/trx/trx-sign.js.map +1 -0
  30. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  31. package/dist/utxo/parse-private-key.d.ts +6 -0
  32. package/dist/utxo/parse-private-key.d.ts.map +1 -0
  33. package/dist/utxo/parse-private-key.js +19 -0
  34. package/dist/utxo/parse-private-key.js.map +1 -0
  35. package/dist/xrp/xrp-sign.d.ts +8 -0
  36. package/dist/xrp/xrp-sign.d.ts.map +1 -0
  37. package/dist/xrp/xrp-sign.js +24 -0
  38. package/dist/xrp/xrp-sign.js.map +1 -0
  39. package/package.json +2 -1
  40. package/src/btc/btc-sign.ts +0 -22
  41. package/src/evm/evm-sign.ts +0 -43
  42. package/src/ltc/ltc-sign.ts +0 -53
  43. package/src/sol/sol-sign.ts +0 -31
  44. package/src/ton/ton-sign.ts +0 -38
  45. package/src/trx/trx-sign.ts +0 -17
  46. package/src/utxo/parse-private-key.ts +0 -14
  47. package/src/xrp/xrp-sign.ts +0 -21
  48. package/tsconfig.json +0 -11
  49. package/tsconfig.lib.json +0 -15
package/README.md CHANGED
@@ -92,6 +92,82 @@ const { bocBase64, txHash } = signTonTransaction(privateKeyHex, {
92
92
  // txHash is the pre-computed transaction hash (needed for TON broadcast fallback)
93
93
  ```
94
94
 
95
+ ## Full Example — EVM
96
+
97
+ This example shows the complete flow: backend prepares the unsigned transaction, frontend signs it, backend broadcasts it.
98
+
99
+ **Backend (Node.js) — prepare unsigned tx:**
100
+ ```ts
101
+ import { ethers } from "ethers";
102
+
103
+ const provider = new ethers.JsonRpcProvider("https://arb1.arbitrum.io/rpc");
104
+ const feeData = await provider.getFeeData();
105
+ const nonce = await provider.getTransactionCount(fromAddress, "latest");
106
+
107
+ const unsignedTx = {
108
+ to: toAddress,
109
+ chainId: 42161, // Arbitrum
110
+ nonce,
111
+ gasLimit: "21000",
112
+ maxFeePerGas: feeData.maxFeePerGas.toString(),
113
+ maxPriorityFeePerGas: feeData.maxPriorityFeePerGas.toString(),
114
+ value: ethers.parseEther("0.01").toString(),
115
+ };
116
+
117
+ // Send unsignedTx to frontend
118
+ ```
119
+
120
+ **Frontend — sign with BerrySigner:**
121
+ ```ts
122
+ import { signEvmTransaction } from "@chainberry/berry-signer";
123
+
124
+ const signedTx = await signEvmTransaction(privateKeyHex, unsignedTx);
125
+ // Send signedTx back to backend
126
+ ```
127
+
128
+ **Backend — broadcast:**
129
+ ```ts
130
+ const tx = await provider.broadcastTransaction(signedTx);
131
+ console.log("txHash:", tx.hash);
132
+ ```
133
+
134
+ ## Full Example — TON
135
+
136
+ **Backend — fetch seqno:**
137
+ ```ts
138
+ const response = await fetch(
139
+ "https://toncenter.com/api/v2/runGetMethod",
140
+ { method: "POST", body: JSON.stringify({ address: walletAddress, method: "seqno", stack: [] }) }
141
+ );
142
+ const data = await response.json();
143
+ const seqno = data.result?.exit_code === 0
144
+ ? parseInt(data.result.stack[0][1], 16)
145
+ : 0; // 0 = wallet not yet deployed
146
+
147
+ // Send seqno to frontend
148
+ ```
149
+
150
+ **Frontend — sign:**
151
+ ```ts
152
+ import { signTonTransaction } from "@chainberry/berry-signer";
153
+
154
+ const { bocBase64, txHash } = signTonTransaction(privateKeyHex, {
155
+ toAddress: "UQA...",
156
+ amount: "1.5",
157
+ seqno,
158
+ });
159
+ // Send bocBase64 and txHash back to backend
160
+ ```
161
+
162
+ **Backend — broadcast:**
163
+ ```ts
164
+ await fetch("https://toncenter.com/api/v2/sendBoc", {
165
+ method: "POST",
166
+ body: JSON.stringify({ boc: bocBase64 }),
167
+ });
168
+ console.log("txHash:", txHash);
169
+ ```
170
+
95
171
  ## Design
96
172
 
97
173
  The split between signing and broadcasting allows the private key to stay on the client:
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Pure signing — no network calls. `unsignedPsbtBase64` comes from
3
+ * wallet-broadcast's prepareBtcTransaction (a read-only call that fetches
4
+ * UTXOs/fee rate). Signs every input, finalizes, and returns the raw tx hex
5
+ * ready for broadcast.
6
+ */
7
+ export declare function signBtcTransaction(privateKeyHex: string, unsignedPsbtBase64: string, isMainnet: boolean): string;
8
+ //# sourceMappingURL=btc-sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"btc-sign.d.ts","sourceRoot":"","sources":["../../src/btc/btc-sign.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAUhH"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signBtcTransaction = signBtcTransaction;
4
+ const bitcoin = require("bitcoinjs-lib");
5
+ const ecpair_1 = require("ecpair");
6
+ const ecc = require("tiny-secp256k1");
7
+ const parse_private_key_1 = require("../utxo/parse-private-key");
8
+ /**
9
+ * Pure signing — no network calls. `unsignedPsbtBase64` comes from
10
+ * wallet-broadcast's prepareBtcTransaction (a read-only call that fetches
11
+ * UTXOs/fee rate). Signs every input, finalizes, and returns the raw tx hex
12
+ * ready for broadcast.
13
+ */
14
+ function signBtcTransaction(privateKeyHex, unsignedPsbtBase64, isMainnet) {
15
+ const network = isMainnet ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;
16
+ const ECPair = (0, ecpair_1.default)(ecc);
17
+ const keyPair = ECPair.fromPrivateKey((0, parse_private_key_1.parsePrivateKey)(privateKeyHex), { network });
18
+ const psbt = bitcoin.Psbt.fromBase64(unsignedPsbtBase64, { network });
19
+ for (let i = 0; i < psbt.inputCount; i++)
20
+ psbt.signInput(i, keyPair);
21
+ psbt.finalizeAllInputs();
22
+ return psbt.extractTransaction().toHex();
23
+ }
24
+ //# sourceMappingURL=btc-sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"btc-sign.js","sourceRoot":"","sources":["../../src/btc/btc-sign.ts"],"names":[],"mappings":";;AAWA,gDAUC;AArBD,yCAAyC;AACzC,mCAAmC;AACnC,sCAAsC;AACtC,iEAA4D;AAE5D;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,aAAqB,EAAE,kBAA0B,EAAE,SAAkB;IACtG,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAChF,MAAM,MAAM,GAAG,IAAA,gBAAa,EAAC,GAAG,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,IAAA,mCAAe,EAAC,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAEnF,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrE,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAEzB,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,CAAC;AAC3C,CAAC","sourcesContent":["import * as bitcoin from \"bitcoinjs-lib\";\nimport ECPairFactory from \"ecpair\";\nimport * as ecc from \"tiny-secp256k1\";\nimport { parsePrivateKey } from \"../utxo/parse-private-key\";\n\n/**\n * Pure signing — no network calls. `unsignedPsbtBase64` comes from\n * wallet-broadcast's prepareBtcTransaction (a read-only call that fetches\n * UTXOs/fee rate). Signs every input, finalizes, and returns the raw tx hex\n * ready for broadcast.\n */\nexport function signBtcTransaction(privateKeyHex: string, unsignedPsbtBase64: string, isMainnet: boolean): string {\n const network = isMainnet ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;\n const ECPair = ECPairFactory(ecc);\n const keyPair = ECPair.fromPrivateKey(parsePrivateKey(privateKeyHex), { network });\n\n const psbt = bitcoin.Psbt.fromBase64(unsignedPsbtBase64, { network });\n for (let i = 0; i < psbt.inputCount; i++) psbt.signInput(i, keyPair);\n psbt.finalizeAllInputs();\n\n return psbt.extractTransaction().toHex();\n}\n"]}
@@ -0,0 +1,19 @@
1
+ export type EvmUnsignedTx = {
2
+ to: string;
3
+ chainId: number;
4
+ nonce: number;
5
+ gasLimit: string;
6
+ value?: string;
7
+ data?: string;
8
+ gasPrice?: string;
9
+ maxFeePerGas?: string;
10
+ maxPriorityFeePerGas?: string;
11
+ };
12
+ /**
13
+ * Pure signing — no network calls, no key storage/decryption.
14
+ * Caller (frontend or backend) supplies the raw private key directly.
15
+ * `unsignedTx` must already carry nonce/gas/chainId, since those require
16
+ * a prior read-only RPC call (see wallet-broadcast's prepare helpers).
17
+ */
18
+ export declare function signEvmTransaction(privateKeyHex: string, unsignedTx: EvmUnsignedTx): Promise<string>;
19
+ //# sourceMappingURL=evm-sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evm-sign.d.ts","sourceRoot":"","sources":["../../src/evm/evm-sign.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAMF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBpG"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signEvmTransaction = signEvmTransaction;
4
+ const ethers_1 = require("ethers");
5
+ function formatPrivateKey(key) {
6
+ return key.startsWith("0x") ? key : `0x${key}`;
7
+ }
8
+ /**
9
+ * Pure signing — no network calls, no key storage/decryption.
10
+ * Caller (frontend or backend) supplies the raw private key directly.
11
+ * `unsignedTx` must already carry nonce/gas/chainId, since those require
12
+ * a prior read-only RPC call (see wallet-broadcast's prepare helpers).
13
+ */
14
+ function signEvmTransaction(privateKeyHex, unsignedTx) {
15
+ const wallet = new ethers_1.ethers.Wallet(formatPrivateKey(privateKeyHex));
16
+ const txRequest = {
17
+ to: unsignedTx.to,
18
+ chainId: unsignedTx.chainId,
19
+ nonce: unsignedTx.nonce,
20
+ gasLimit: BigInt(unsignedTx.gasLimit),
21
+ value: unsignedTx.value !== undefined ? BigInt(unsignedTx.value) : undefined,
22
+ data: unsignedTx.data,
23
+ };
24
+ if (unsignedTx.maxFeePerGas !== undefined) {
25
+ txRequest.maxFeePerGas = BigInt(unsignedTx.maxFeePerGas);
26
+ txRequest.maxPriorityFeePerGas =
27
+ unsignedTx.maxPriorityFeePerGas !== undefined ? BigInt(unsignedTx.maxPriorityFeePerGas) : undefined;
28
+ }
29
+ else if (unsignedTx.gasPrice !== undefined) {
30
+ txRequest.gasPrice = BigInt(unsignedTx.gasPrice);
31
+ }
32
+ return wallet.signTransaction(txRequest);
33
+ }
34
+ //# sourceMappingURL=evm-sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evm-sign.js","sourceRoot":"","sources":["../../src/evm/evm-sign.ts"],"names":[],"mappings":";;AAwBA,gDAkBC;AA1CD,mCAAgC;AAchC,SAAS,gBAAgB,CAAC,GAAW;IACnC,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,aAAqB,EAAE,UAAyB;IACjF,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;IAClE,MAAM,SAAS,GAA8B;QAC3C,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;QACrC,KAAK,EAAE,UAAU,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;QAC5E,IAAI,EAAE,UAAU,CAAC,IAAI;KACtB,CAAC;IACF,IAAI,UAAU,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QAC1C,SAAS,CAAC,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACzD,SAAS,CAAC,oBAAoB;YAC5B,UAAU,CAAC,oBAAoB,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxG,CAAC;SAAM,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC7C,SAAS,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["import { ethers } from \"ethers\";\n\nexport type EvmUnsignedTx = {\n to: string;\n chainId: number;\n nonce: number;\n gasLimit: string;\n value?: string;\n data?: string;\n gasPrice?: string;\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n};\n\nfunction formatPrivateKey(key: string): string {\n return key.startsWith(\"0x\") ? key : `0x${key}`;\n}\n\n/**\n * Pure signing — no network calls, no key storage/decryption.\n * Caller (frontend or backend) supplies the raw private key directly.\n * `unsignedTx` must already carry nonce/gas/chainId, since those require\n * a prior read-only RPC call (see wallet-broadcast's prepare helpers).\n */\nexport function signEvmTransaction(privateKeyHex: string, unsignedTx: EvmUnsignedTx): Promise<string> {\n const wallet = new ethers.Wallet(formatPrivateKey(privateKeyHex));\n const txRequest: ethers.TransactionRequest = {\n to: unsignedTx.to,\n chainId: unsignedTx.chainId,\n nonce: unsignedTx.nonce,\n gasLimit: BigInt(unsignedTx.gasLimit),\n value: unsignedTx.value !== undefined ? BigInt(unsignedTx.value) : undefined,\n data: unsignedTx.data,\n };\n if (unsignedTx.maxFeePerGas !== undefined) {\n txRequest.maxFeePerGas = BigInt(unsignedTx.maxFeePerGas);\n txRequest.maxPriorityFeePerGas =\n unsignedTx.maxPriorityFeePerGas !== undefined ? BigInt(unsignedTx.maxPriorityFeePerGas) : undefined;\n } else if (unsignedTx.gasPrice !== undefined) {\n txRequest.gasPrice = BigInt(unsignedTx.gasPrice);\n }\n return wallet.signTransaction(txRequest);\n}\n"]}
@@ -5,3 +5,4 @@ export * from "./trx/trx-sign";
5
5
  export * from "./btc/btc-sign";
6
6
  export * from "./ltc/ltc-sign";
7
7
  export * from "./ton/ton-sign";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./evm/evm-sign"), exports);
5
+ tslib_1.__exportStar(require("./xrp/xrp-sign"), exports);
6
+ tslib_1.__exportStar(require("./sol/sol-sign"), exports);
7
+ tslib_1.__exportStar(require("./trx/trx-sign"), exports);
8
+ tslib_1.__exportStar(require("./btc/btc-sign"), exports);
9
+ tslib_1.__exportStar(require("./ltc/ltc-sign"), exports);
10
+ tslib_1.__exportStar(require("./ton/ton-sign"), exports);
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yDAA+B;AAC/B,yDAA+B;AAC/B,yDAA+B;AAC/B,yDAA+B;AAC/B,yDAA+B;AAC/B,yDAA+B;AAC/B,yDAA+B","sourcesContent":["export * from \"./evm/evm-sign\";\nexport * from \"./xrp/xrp-sign\";\nexport * from \"./sol/sol-sign\";\nexport * from \"./trx/trx-sign\";\nexport * from \"./btc/btc-sign\";\nexport * from \"./ltc/ltc-sign\";\nexport * from \"./ton/ton-sign\";\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Pure signing — no network calls. `unsignedPsbtBase64` comes from
3
+ * wallet-broadcast's prepareLtcTransaction (a read-only call that fetches
4
+ * UTXOs/fee rate). Signs every input, finalizes, and returns the raw tx hex
5
+ * ready for broadcast.
6
+ */
7
+ export declare function signLtcTransaction(privateKeyHex: string, unsignedPsbtBase64: string, isMainnet: boolean): string;
8
+ /**
9
+ * Derives the P2WPKH address for a raw private key. WalletCore (TrustWallet) has no
10
+ * native Litecoin testnet support, so this is the one place that still needs bitcoinjs-lib
11
+ * for address derivation — kept here instead of duplicated at call sites.
12
+ */
13
+ export declare function getLtcAddressFromPrivateKey(privateKeyHex: string, isMainnet: boolean): string;
14
+ //# sourceMappingURL=ltc-sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ltc-sign.d.ts","sourceRoot":"","sources":["../../src/ltc/ltc-sign.ts"],"names":[],"mappings":"AAsBA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAUhH;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAO7F"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signLtcTransaction = signLtcTransaction;
4
+ exports.getLtcAddressFromPrivateKey = getLtcAddressFromPrivateKey;
5
+ const bitcoin = require("bitcoinjs-lib");
6
+ const ecpair_1 = require("ecpair");
7
+ const ecc = require("tiny-secp256k1");
8
+ const parse_private_key_1 = require("../utxo/parse-private-key");
9
+ const LITECOIN_MAINNET = {
10
+ messagePrefix: "\x19Litecoin Signed Message:\n",
11
+ bech32: "ltc",
12
+ bip32: { public: 0x019da462, private: 0x019d9cfe },
13
+ pubKeyHash: 0x30,
14
+ scriptHash: 0x32,
15
+ wif: 0xb0,
16
+ };
17
+ const LITECOIN_TESTNET = {
18
+ messagePrefix: "\x19Litecoin Signed Message:\n",
19
+ bech32: "tltc",
20
+ bip32: { public: 0x0436f6e1, private: 0x0436ef7d },
21
+ pubKeyHash: 0x6f,
22
+ scriptHash: 0xc4,
23
+ wif: 0xef,
24
+ };
25
+ /**
26
+ * Pure signing — no network calls. `unsignedPsbtBase64` comes from
27
+ * wallet-broadcast's prepareLtcTransaction (a read-only call that fetches
28
+ * UTXOs/fee rate). Signs every input, finalizes, and returns the raw tx hex
29
+ * ready for broadcast.
30
+ */
31
+ function signLtcTransaction(privateKeyHex, unsignedPsbtBase64, isMainnet) {
32
+ const network = isMainnet ? LITECOIN_MAINNET : LITECOIN_TESTNET;
33
+ const ECPair = (0, ecpair_1.default)(ecc);
34
+ const keyPair = ECPair.fromPrivateKey((0, parse_private_key_1.parsePrivateKey)(privateKeyHex), { network });
35
+ const psbt = bitcoin.Psbt.fromBase64(unsignedPsbtBase64, { network });
36
+ for (let i = 0; i < psbt.inputCount; i++)
37
+ psbt.signInput(i, keyPair);
38
+ psbt.finalizeAllInputs();
39
+ return psbt.extractTransaction().toHex();
40
+ }
41
+ /**
42
+ * Derives the P2WPKH address for a raw private key. WalletCore (TrustWallet) has no
43
+ * native Litecoin testnet support, so this is the one place that still needs bitcoinjs-lib
44
+ * for address derivation — kept here instead of duplicated at call sites.
45
+ */
46
+ function getLtcAddressFromPrivateKey(privateKeyHex, isMainnet) {
47
+ const network = isMainnet ? LITECOIN_MAINNET : LITECOIN_TESTNET;
48
+ const ECPair = (0, ecpair_1.default)(ecc);
49
+ const keyPair = ECPair.fromPrivateKey((0, parse_private_key_1.parsePrivateKey)(privateKeyHex), { network });
50
+ const address = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network }).address;
51
+ if (!address)
52
+ throw new Error("Failed to derive LTC address");
53
+ return address;
54
+ }
55
+ //# sourceMappingURL=ltc-sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ltc-sign.js","sourceRoot":"","sources":["../../src/ltc/ltc-sign.ts"],"names":[],"mappings":";;AA4BA,gDAUC;AAOD,kEAOC;AApDD,yCAAyC;AACzC,mCAAmC;AACnC,sCAAsC;AACtC,iEAA4D;AAE5D,MAAM,gBAAgB,GAAoB;IACxC,aAAa,EAAE,gCAAgC;IAC/C,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE;IAClD,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,IAAI;IAChB,GAAG,EAAE,IAAI;CACV,CAAC;AACF,MAAM,gBAAgB,GAAoB;IACxC,aAAa,EAAE,gCAAgC;IAC/C,MAAM,EAAE,MAAM;IACd,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE;IAClD,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,IAAI;IAChB,GAAG,EAAE,IAAI;CACV,CAAC;AAEF;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,aAAqB,EAAE,kBAA0B,EAAE,SAAkB;IACtG,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAChE,MAAM,MAAM,GAAG,IAAA,gBAAa,EAAC,GAAG,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,IAAA,mCAAe,EAAC,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAEnF,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrE,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAEzB,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,SAAgB,2BAA2B,CAAC,aAAqB,EAAE,SAAkB;IACnF,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAChE,MAAM,MAAM,GAAG,IAAA,gBAAa,EAAC,GAAG,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,IAAA,mCAAe,EAAC,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACnF,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC;IACxF,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC9D,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import * as bitcoin from \"bitcoinjs-lib\";\nimport ECPairFactory from \"ecpair\";\nimport * as ecc from \"tiny-secp256k1\";\nimport { parsePrivateKey } from \"../utxo/parse-private-key\";\n\nconst LITECOIN_MAINNET: bitcoin.Network = {\n messagePrefix: \"\\x19Litecoin Signed Message:\\n\",\n bech32: \"ltc\",\n bip32: { public: 0x019da462, private: 0x019d9cfe },\n pubKeyHash: 0x30,\n scriptHash: 0x32,\n wif: 0xb0,\n};\nconst LITECOIN_TESTNET: bitcoin.Network = {\n messagePrefix: \"\\x19Litecoin Signed Message:\\n\",\n bech32: \"tltc\",\n bip32: { public: 0x0436f6e1, private: 0x0436ef7d },\n pubKeyHash: 0x6f,\n scriptHash: 0xc4,\n wif: 0xef,\n};\n\n/**\n * Pure signing — no network calls. `unsignedPsbtBase64` comes from\n * wallet-broadcast's prepareLtcTransaction (a read-only call that fetches\n * UTXOs/fee rate). Signs every input, finalizes, and returns the raw tx hex\n * ready for broadcast.\n */\nexport function signLtcTransaction(privateKeyHex: string, unsignedPsbtBase64: string, isMainnet: boolean): string {\n const network = isMainnet ? LITECOIN_MAINNET : LITECOIN_TESTNET;\n const ECPair = ECPairFactory(ecc);\n const keyPair = ECPair.fromPrivateKey(parsePrivateKey(privateKeyHex), { network });\n\n const psbt = bitcoin.Psbt.fromBase64(unsignedPsbtBase64, { network });\n for (let i = 0; i < psbt.inputCount; i++) psbt.signInput(i, keyPair);\n psbt.finalizeAllInputs();\n\n return psbt.extractTransaction().toHex();\n}\n\n/**\n * Derives the P2WPKH address for a raw private key. WalletCore (TrustWallet) has no\n * native Litecoin testnet support, so this is the one place that still needs bitcoinjs-lib\n * for address derivation — kept here instead of duplicated at call sites.\n */\nexport function getLtcAddressFromPrivateKey(privateKeyHex: string, isMainnet: boolean): string {\n const network = isMainnet ? LITECOIN_MAINNET : LITECOIN_TESTNET;\n const ECPair = ECPairFactory(ecc);\n const keyPair = ECPair.fromPrivateKey(parsePrivateKey(privateKeyHex), { network });\n const address = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network }).address;\n if (!address) throw new Error(\"Failed to derive LTC address\");\n return address;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Pure signing — no network calls. `unsignedTxBase64` must already carry
3
+ * recentBlockhash/feePayer/instructions (see wallet-broadcast's
4
+ * prepareSolTransaction, a read-only RPC call).
5
+ */
6
+ export declare function signSolTransaction(privateKey: string, unsignedTxBase64: string): string;
7
+ //# sourceMappingURL=sol-sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sol-sign.d.ts","sourceRoot":"","sources":["../../src/sol/sol-sign.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAKvF"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signSolTransaction = signSolTransaction;
4
+ const bs58_1 = require("bs58");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ function getSolKeypairFromPrivateKey(privateKey) {
7
+ const cleanedKey = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
8
+ let secretKey;
9
+ if (/^[0-9a-fA-F]+$/.test(cleanedKey)) {
10
+ secretKey = Uint8Array.from(Buffer.from(cleanedKey, "hex"));
11
+ }
12
+ else {
13
+ try {
14
+ secretKey = bs58_1.default.decode(cleanedKey);
15
+ }
16
+ catch (error) {
17
+ throw new Error(`Invalid private key encoding: not valid hex or base58 (${error.message})`);
18
+ }
19
+ }
20
+ if (secretKey.length === 64)
21
+ return web3_js_1.Keypair.fromSecretKey(secretKey);
22
+ if (secretKey.length === 32)
23
+ return web3_js_1.Keypair.fromSeed(secretKey);
24
+ throw new Error(`Invalid private key length: ${secretKey.length} bytes. Expected 32 or 64 bytes.`);
25
+ }
26
+ /**
27
+ * Pure signing — no network calls. `unsignedTxBase64` must already carry
28
+ * recentBlockhash/feePayer/instructions (see wallet-broadcast's
29
+ * prepareSolTransaction, a read-only RPC call).
30
+ */
31
+ function signSolTransaction(privateKey, unsignedTxBase64) {
32
+ const keypair = getSolKeypairFromPrivateKey(privateKey);
33
+ const transaction = web3_js_1.Transaction.from(Buffer.from(unsignedTxBase64, "base64"));
34
+ transaction.sign(keypair);
35
+ return transaction.serialize().toString("base64");
36
+ }
37
+ //# sourceMappingURL=sol-sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sol-sign.js","sourceRoot":"","sources":["../../src/sol/sol-sign.ts"],"names":[],"mappings":";;AAyBA,gDAKC;AA9BD,+BAAwB;AACxB,6CAAuD;AAEvD,SAAS,2BAA2B,CAAC,UAAkB;IACrD,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAClF,IAAI,SAAqB,CAAC;IAC1B,IAAI,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9D,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,SAAS,GAAG,cAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,0DAA2D,KAAe,CAAC,OAAO,GAAG,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,iBAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IACrE,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,iBAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChE,MAAM,IAAI,KAAK,CAAC,+BAA+B,SAAS,CAAC,MAAM,kCAAkC,CAAC,CAAC;AACrG,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,UAAkB,EAAE,gBAAwB;IAC7E,MAAM,OAAO,GAAG,2BAA2B,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,qBAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9E,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,OAAO,WAAW,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACpD,CAAC","sourcesContent":["import bs58 from \"bs58\";\nimport { Keypair, Transaction } from \"@solana/web3.js\";\n\nfunction getSolKeypairFromPrivateKey(privateKey: string): Keypair {\n const cleanedKey = privateKey.startsWith(\"0x\") ? privateKey.slice(2) : privateKey;\n let secretKey: Uint8Array;\n if (/^[0-9a-fA-F]+$/.test(cleanedKey)) {\n secretKey = Uint8Array.from(Buffer.from(cleanedKey, \"hex\"));\n } else {\n try {\n secretKey = bs58.decode(cleanedKey);\n } catch (error) {\n throw new Error(`Invalid private key encoding: not valid hex or base58 (${(error as Error).message})`);\n }\n }\n if (secretKey.length === 64) return Keypair.fromSecretKey(secretKey);\n if (secretKey.length === 32) return Keypair.fromSeed(secretKey);\n throw new Error(`Invalid private key length: ${secretKey.length} bytes. Expected 32 or 64 bytes.`);\n}\n\n/**\n * Pure signing — no network calls. `unsignedTxBase64` must already carry\n * recentBlockhash/feePayer/instructions (see wallet-broadcast's\n * prepareSolTransaction, a read-only RPC call).\n */\nexport function signSolTransaction(privateKey: string, unsignedTxBase64: string): string {\n const keypair = getSolKeypairFromPrivateKey(privateKey);\n const transaction = Transaction.from(Buffer.from(unsignedTxBase64, \"base64\"));\n transaction.sign(keypair);\n return transaction.serialize().toString(\"base64\");\n}\n"]}
@@ -0,0 +1,15 @@
1
+ export type SignedTonTx = {
2
+ bocBase64: string;
3
+ txHash: string;
4
+ };
5
+ /**
6
+ * Pure signing — no network calls. `seqno` comes from wallet-broadcast's
7
+ * fetchTonSeqno (a read-only RPC call).
8
+ */
9
+ export declare function signTonTransaction(privateKeyHex: string, params: {
10
+ toAddress: string;
11
+ amount: string;
12
+ seqno: number;
13
+ memoId?: string;
14
+ }): SignedTonTx;
15
+ //# sourceMappingURL=ton-sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ton-sign.d.ts","sourceRoot":"","sources":["../../src/ton/ton-sign.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,WAAW,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5E,WAAW,CAkBb"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signTonTransaction = signTonTransaction;
4
+ const core_1 = require("@ton/core");
5
+ const crypto_1 = require("@ton/crypto");
6
+ const ton_1 = require("@ton/ton");
7
+ function getKeyPairFromPrivateKey(privateKeyHex) {
8
+ const raw = privateKeyHex.replace(/^0x/i, "");
9
+ if (raw.length !== 64)
10
+ throw new Error(`Invalid TON private key length: ${raw.length} hex chars. Expected 64 (32 bytes).`);
11
+ return (0, crypto_1.keyPairFromSeed)(Buffer.from(raw, "hex"));
12
+ }
13
+ /**
14
+ * Pure signing — no network calls. `seqno` comes from wallet-broadcast's
15
+ * fetchTonSeqno (a read-only RPC call).
16
+ */
17
+ function signTonTransaction(privateKeyHex, params) {
18
+ const keyPair = getKeyPairFromPrivateKey(privateKeyHex);
19
+ const wallet = ton_1.WalletContractV4.create({ workchain: 0, publicKey: keyPair.publicKey });
20
+ const walletAddress = wallet.address;
21
+ const recipientAddress = ton_1.Address.parse(params.toAddress.trim());
22
+ const amountInNano = (0, ton_1.toNano)(params.amount);
23
+ let body;
24
+ if (params.memoId) {
25
+ body = (0, ton_1.beginCell)().storeUint(0, 32).storeStringTail(params.memoId).endCell();
26
+ }
27
+ const internalMessage = (0, ton_1.internal)({ to: recipientAddress, value: amountInNano, body, bounce: false });
28
+ const transferBody = wallet.createTransfer({ secretKey: keyPair.secretKey, messages: [internalMessage], seqno: params.seqno });
29
+ const extMessage = (0, core_1.external)({ to: walletAddress, init: params.seqno === 0 ? wallet.init : undefined, body: transferBody });
30
+ const bocBytes = (0, ton_1.beginCell)().store((0, core_1.storeMessage)(extMessage)).endCell().toBoc();
31
+ return { bocBase64: Buffer.from(bocBytes).toString("base64"), txHash: transferBody.hash().toString("hex") };
32
+ }
33
+ //# sourceMappingURL=ton-sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ton-sign.js","sourceRoot":"","sources":["../../src/ton/ton-sign.ts"],"names":[],"mappings":";;AAgBA,gDAqBC;AArCD,oCAAmD;AACnD,wCAA8C;AAC9C,kCAAwF;AAExF,SAAS,wBAAwB,CAAC,aAAqB;IACrD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,CAAC,MAAM,qCAAqC,CAAC,CAAC;IAC3H,OAAO,IAAA,wBAAe,EAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAClD,CAAC;AAID;;;GAGG;AACH,SAAgB,kBAAkB,CAChC,aAAqB,EACrB,MAA6E;IAE7E,MAAM,OAAO,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,sBAAgB,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACvF,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC;IAErC,MAAM,gBAAgB,GAAG,aAAO,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,IAAA,YAAM,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,IAAsB,CAAC;IAC3B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,IAAI,GAAG,IAAA,eAAS,GAAE,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/E,CAAC;IAED,MAAM,eAAe,GAAG,IAAA,cAAQ,EAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACrG,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/H,MAAM,UAAU,GAAG,IAAA,eAAQ,EAAC,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3H,MAAM,QAAQ,GAAG,IAAA,eAAS,GAAE,CAAC,KAAK,CAAC,IAAA,mBAAY,EAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC;IAE/E,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9G,CAAC","sourcesContent":["import { external, storeMessage } from \"@ton/core\";\nimport { keyPairFromSeed } from \"@ton/crypto\";\nimport { Address, beginCell, Cell, internal, toNano, WalletContractV4 } from \"@ton/ton\";\n\nfunction getKeyPairFromPrivateKey(privateKeyHex: string): { publicKey: Buffer; secretKey: Buffer } {\n const raw = privateKeyHex.replace(/^0x/i, \"\");\n if (raw.length !== 64) throw new Error(`Invalid TON private key length: ${raw.length} hex chars. Expected 64 (32 bytes).`);\n return keyPairFromSeed(Buffer.from(raw, \"hex\"));\n}\n\nexport type SignedTonTx = { bocBase64: string; txHash: string };\n\n/**\n * Pure signing — no network calls. `seqno` comes from wallet-broadcast's\n * fetchTonSeqno (a read-only RPC call).\n */\nexport function signTonTransaction(\n privateKeyHex: string,\n params: { toAddress: string; amount: string; seqno: number; memoId?: string }\n): SignedTonTx {\n const keyPair = getKeyPairFromPrivateKey(privateKeyHex);\n const wallet = WalletContractV4.create({ workchain: 0, publicKey: keyPair.publicKey });\n const walletAddress = wallet.address;\n\n const recipientAddress = Address.parse(params.toAddress.trim());\n const amountInNano = toNano(params.amount);\n let body: Cell | undefined;\n if (params.memoId) {\n body = beginCell().storeUint(0, 32).storeStringTail(params.memoId).endCell();\n }\n\n const internalMessage = internal({ to: recipientAddress, value: amountInNano, body, bounce: false });\n const transferBody = wallet.createTransfer({ secretKey: keyPair.secretKey, messages: [internalMessage], seqno: params.seqno });\n const extMessage = external({ to: walletAddress, init: params.seqno === 0 ? wallet.init : undefined, body: transferBody });\n const bocBytes = beginCell().store(storeMessage(extMessage)).endCell().toBoc();\n\n return { bocBase64: Buffer.from(bocBytes).toString(\"base64\"), txHash: transferBody.hash().toString(\"hex\") };\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Pure signing — TronWeb's signing call itself makes no network request, but its
3
+ * constructor still requires node URLs (an SDK quirk, not an actual dependency for
4
+ * signing). `rpcUrl` can be any reachable TRON node; it is never called during sign.
5
+ * `unsignedTx` comes from wallet-broadcast's prepareTrxTransaction (a read-only call).
6
+ */
7
+ export declare function signTrxTransaction(privateKey: string, unsignedTx: unknown, rpcUrl: string): Promise<string>;
8
+ //# sourceMappingURL=trx-sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trx-sign.d.ts","sourceRoot":"","sources":["../../src/trx/trx-sign.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKjH"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signTrxTransaction = signTrxTransaction;
4
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
5
+ let TronWeb = require("tronweb");
6
+ if (TronWeb.TronWeb)
7
+ TronWeb = TronWeb.TronWeb;
8
+ else if (TronWeb.default)
9
+ TronWeb = TronWeb.default;
10
+ /**
11
+ * Pure signing — TronWeb's signing call itself makes no network request, but its
12
+ * constructor still requires node URLs (an SDK quirk, not an actual dependency for
13
+ * signing). `rpcUrl` can be any reachable TRON node; it is never called during sign.
14
+ * `unsignedTx` comes from wallet-broadcast's prepareTrxTransaction (a read-only call).
15
+ */
16
+ async function signTrxTransaction(privateKey, unsignedTx, rpcUrl) {
17
+ const cleanPrivateKey = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
18
+ const tronWeb = new TronWeb({ fullNode: rpcUrl, solidityNode: rpcUrl, eventServer: rpcUrl, privateKey: cleanPrivateKey });
19
+ const signedTx = await tronWeb.trx.sign(unsignedTx, cleanPrivateKey);
20
+ return JSON.stringify(signedTx);
21
+ }
22
+ //# sourceMappingURL=trx-sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trx-sign.js","sourceRoot":"","sources":["../../src/trx/trx-sign.ts"],"names":[],"mappings":";;AAWA,gDAKC;AAhBD,iEAAiE;AACjE,IAAI,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AACjC,IAAI,OAAO,CAAC,OAAO;IAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;KAC1C,IAAI,OAAO,CAAC,OAAO;IAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;AAEpD;;;;;GAKG;AACI,KAAK,UAAU,kBAAkB,CAAC,UAAkB,EAAE,UAAmB,EAAE,MAAc;IAC9F,MAAM,eAAe,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACvF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC,CAAC;IAC1H,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC","sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-require-imports\nlet TronWeb = require(\"tronweb\");\nif (TronWeb.TronWeb) TronWeb = TronWeb.TronWeb;\nelse if (TronWeb.default) TronWeb = TronWeb.default;\n\n/**\n * Pure signing — TronWeb's signing call itself makes no network request, but its\n * constructor still requires node URLs (an SDK quirk, not an actual dependency for\n * signing). `rpcUrl` can be any reachable TRON node; it is never called during sign.\n * `unsignedTx` comes from wallet-broadcast's prepareTrxTransaction (a read-only call).\n */\nexport async function signTrxTransaction(privateKey: string, unsignedTx: unknown, rpcUrl: string): Promise<string> {\n const cleanPrivateKey = privateKey.startsWith(\"0x\") ? privateKey.slice(2) : privateKey;\n const tronWeb = new TronWeb({ fullNode: rpcUrl, solidityNode: rpcUrl, eventServer: rpcUrl, privateKey: cleanPrivateKey });\n const signedTx = await tronWeb.trx.sign(unsignedTx, cleanPrivateKey);\n return JSON.stringify(signedTx);\n}\n"]}