@ironwallet/mcp-server 1.0.0-preprod.0

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 (110) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -0
  3. package/assets/knight.png +0 -0
  4. package/assets/wordmark.svg +20 -0
  5. package/dist/api/auth.d.ts +20 -0
  6. package/dist/api/auth.js +92 -0
  7. package/dist/api/auth.js.map +1 -0
  8. package/dist/api/balances.d.ts +25 -0
  9. package/dist/api/balances.js +565 -0
  10. package/dist/api/balances.js.map +1 -0
  11. package/dist/api/http.d.ts +34 -0
  12. package/dist/api/http.js +277 -0
  13. package/dist/api/http.js.map +1 -0
  14. package/dist/api/relay.d.ts +49 -0
  15. package/dist/api/relay.js +194 -0
  16. package/dist/api/relay.js.map +1 -0
  17. package/dist/api/rpc.d.ts +10 -0
  18. package/dist/api/rpc.js +26 -0
  19. package/dist/api/rpc.js.map +1 -0
  20. package/dist/api/swap.d.ts +134 -0
  21. package/dist/api/swap.js +554 -0
  22. package/dist/api/swap.js.map +1 -0
  23. package/dist/cli.d.ts +6 -0
  24. package/dist/cli.js +20 -0
  25. package/dist/cli.js.map +1 -0
  26. package/dist/config.d.ts +91 -0
  27. package/dist/config.js +175 -0
  28. package/dist/config.js.map +1 -0
  29. package/dist/generated/env-config.d.ts +5 -0
  30. package/dist/generated/env-config.js +23 -0
  31. package/dist/generated/env-config.js.map +1 -0
  32. package/dist/generated/env-profile.d.ts +15 -0
  33. package/dist/generated/env-profile.js +2 -0
  34. package/dist/generated/env-profile.js.map +1 -0
  35. package/dist/keystore/crypto.d.ts +17 -0
  36. package/dist/keystore/crypto.js +57 -0
  37. package/dist/keystore/crypto.js.map +1 -0
  38. package/dist/keystore/store.d.ts +45 -0
  39. package/dist/keystore/store.js +224 -0
  40. package/dist/keystore/store.js.map +1 -0
  41. package/dist/keystore/types.d.ts +31 -0
  42. package/dist/keystore/types.js +2 -0
  43. package/dist/keystore/types.js.map +1 -0
  44. package/dist/local-secrets.d.ts +16 -0
  45. package/dist/local-secrets.js +73 -0
  46. package/dist/local-secrets.js.map +1 -0
  47. package/dist/log.d.ts +30 -0
  48. package/dist/log.js +323 -0
  49. package/dist/log.js.map +1 -0
  50. package/dist/passphrase.d.ts +6 -0
  51. package/dist/passphrase.js +10 -0
  52. package/dist/passphrase.js.map +1 -0
  53. package/dist/policy.d.ts +22 -0
  54. package/dist/policy.js +108 -0
  55. package/dist/policy.js.map +1 -0
  56. package/dist/server.d.ts +6 -0
  57. package/dist/server.js +38 -0
  58. package/dist/server.js.map +1 -0
  59. package/dist/signing/bitcoin.d.ts +18 -0
  60. package/dist/signing/bitcoin.js +84 -0
  61. package/dist/signing/bitcoin.js.map +1 -0
  62. package/dist/signing/dispatch.d.ts +7 -0
  63. package/dist/signing/dispatch.js +35 -0
  64. package/dist/signing/dispatch.js.map +1 -0
  65. package/dist/signing/evm.d.ts +16 -0
  66. package/dist/signing/evm.js +59 -0
  67. package/dist/signing/evm.js.map +1 -0
  68. package/dist/signing/index.d.ts +10 -0
  69. package/dist/signing/index.js +57 -0
  70. package/dist/signing/index.js.map +1 -0
  71. package/dist/signing/solana.d.ts +18 -0
  72. package/dist/signing/solana.js +106 -0
  73. package/dist/signing/solana.js.map +1 -0
  74. package/dist/signing/swap.d.ts +10 -0
  75. package/dist/signing/swap.js +114 -0
  76. package/dist/signing/swap.js.map +1 -0
  77. package/dist/signing/ton.d.ts +33 -0
  78. package/dist/signing/ton.js +166 -0
  79. package/dist/signing/ton.js.map +1 -0
  80. package/dist/signing/tron.d.ts +11 -0
  81. package/dist/signing/tron.js +39 -0
  82. package/dist/signing/tron.js.map +1 -0
  83. package/dist/signing/types.d.ts +23 -0
  84. package/dist/signing/types.js +2 -0
  85. package/dist/signing/types.js.map +1 -0
  86. package/dist/signing/xrp.d.ts +11 -0
  87. package/dist/signing/xrp.js +122 -0
  88. package/dist/signing/xrp.js.map +1 -0
  89. package/dist/tools/helpers.d.ts +42 -0
  90. package/dist/tools/helpers.js +80 -0
  91. package/dist/tools/helpers.js.map +1 -0
  92. package/dist/tools/index.d.ts +7 -0
  93. package/dist/tools/index.js +16 -0
  94. package/dist/tools/index.js.map +1 -0
  95. package/dist/tools/swap.d.ts +6 -0
  96. package/dist/tools/swap.js +343 -0
  97. package/dist/tools/swap.js.map +1 -0
  98. package/dist/tools/transfer.d.ts +6 -0
  99. package/dist/tools/transfer.js +284 -0
  100. package/dist/tools/transfer.js.map +1 -0
  101. package/dist/tools/wallets.d.ts +6 -0
  102. package/dist/tools/wallets.js +79 -0
  103. package/dist/tools/wallets.js.map +1 -0
  104. package/dist/wallet/derive.d.ts +53 -0
  105. package/dist/wallet/derive.js +233 -0
  106. package/dist/wallet/derive.js.map +1 -0
  107. package/dist/web/manager.d.ts +15 -0
  108. package/dist/web/manager.js +444 -0
  109. package/dist/web/manager.js.map +1 -0
  110. package/package.json +54 -0
@@ -0,0 +1,166 @@
1
+ /**
2
+ * TON signing — matches mobile `ton_net_api_client` (IR-673 RelayV2 path):
3
+ *
4
+ * Relay estimate returns unsigned wallet-transfer bodies as BoC in `txData`
5
+ * (hex or base64). The client ed25519-signs each cell hash, wraps the signed
6
+ * body in an external message (with wallet init when seqno == 0), and puts the
7
+ * external-message BoC hex into both `signature` and `txData` of the forward
8
+ * payload.
9
+ *
10
+ * Estimate must include `fromPublicKey` (32-byte ed25519 pubkey hex) — same as
11
+ * mobile `RelayV2EstimateRequest.fromPublicKey` for NetType.ton.
12
+ *
13
+ * `sendTon` remains as a direct TonCenter broadcast fallback (pre-relay path).
14
+ */
15
+ import { Address, WalletContractV4, beginCell, Cell, external, storeMessage, internal, toNano, SendMode, TonClient, } from "@ton/ton";
16
+ import { sign } from "@ton/crypto";
17
+ import { ed25519 } from "@noble/curves/ed25519.js";
18
+ import { getConfig } from "../config.js";
19
+ import { deriveTon } from "../wallet/derive.js";
20
+ import { logError, logInfo } from "../log.js";
21
+ function hexToBytes(h) {
22
+ return Buffer.from(h.replace(/^0x/, ""), "hex");
23
+ }
24
+ function isHexString(value) {
25
+ return value.length > 0 && value.length % 2 === 0 && /^[0-9a-fA-F]+$/.test(value);
26
+ }
27
+ function decodeRelayPayload(txData) {
28
+ let normalized = txData.trim();
29
+ if (normalized.startsWith("0x") || normalized.startsWith("0X")) {
30
+ normalized = normalized.slice(2);
31
+ }
32
+ if (isHexString(normalized)) {
33
+ return Buffer.from(normalized, "hex");
34
+ }
35
+ return Buffer.from(normalized, "base64");
36
+ }
37
+ function parseRelayTxDataCell(txData) {
38
+ const bytes = decodeRelayPayload(txData);
39
+ const cells = Cell.fromBoc(bytes);
40
+ if (cells.length === 0) {
41
+ throw new Error("Invalid TON relay txData: empty BoC");
42
+ }
43
+ return cells[0];
44
+ }
45
+ /** 32-byte ed25519 public key hex (no 0x), for relay estimate `fromPublicKey`. */
46
+ export function tonPublicKeyHex(mnemonic) {
47
+ const derived = deriveTon(mnemonic);
48
+ const seed = hexToBytes(derived.privateKey);
49
+ return Buffer.from(ed25519.getPublicKey(seed)).toString("hex");
50
+ }
51
+ function secretKeyFromSeed(seed) {
52
+ const pub = Buffer.from(ed25519.getPublicKey(seed));
53
+ return Buffer.concat([seed, pub]);
54
+ }
55
+ /**
56
+ * Sign relay `transactionsToSign` the same way as mobile
57
+ * `_signRelayWalletTransfer`: signature || unsigned body → external message BoC.
58
+ */
59
+ export function signTon(ctx, txs) {
60
+ const seed = hexToBytes(ctx.privateKey);
61
+ const secretKey = secretKeyFromSeed(seed);
62
+ const publicKey = Buffer.from(ed25519.getPublicKey(seed));
63
+ const wallet = WalletContractV4.create({ workchain: 0, publicKey });
64
+ const destination = Address.parse(ctx.address);
65
+ const signed = [];
66
+ for (const tx of txs) {
67
+ if (!tx.txData)
68
+ continue;
69
+ const unsignedCell = parseRelayTxDataCell(tx.txData);
70
+ const signature = sign(unsignedCell.hash(), secretKey);
71
+ const signedBody = beginCell()
72
+ .storeBuffer(signature)
73
+ .storeSlice(unsignedCell.beginParse())
74
+ .endCell();
75
+ const unsignedSlice = unsignedCell.beginParse();
76
+ unsignedSlice.loadUint(32); // wallet id
77
+ unsignedSlice.loadUint(32); // valid until
78
+ const seqno = unsignedSlice.loadUint(32);
79
+ const externalMessage = seqno === 0
80
+ ? external({
81
+ to: destination,
82
+ init: wallet.init,
83
+ body: signedBody,
84
+ })
85
+ : external({
86
+ to: destination,
87
+ body: signedBody,
88
+ });
89
+ const externalBocHex = beginCell()
90
+ .store(storeMessage(externalMessage))
91
+ .endCell()
92
+ .toBoc()
93
+ .toString("hex");
94
+ signed.push({
95
+ txID: tx.txId ?? "",
96
+ signature: externalBocHex,
97
+ txData: externalBocHex,
98
+ transactionId: tx.transactionId,
99
+ });
100
+ }
101
+ return signed;
102
+ }
103
+ /** Direct TonCenter broadcast (legacy / fallback; mobile still keeps this path). */
104
+ export async function sendTon(mnemonic, params) {
105
+ const started = Date.now();
106
+ const derived = deriveTon(mnemonic);
107
+ const seed = hexToBytes(derived.privateKey);
108
+ const secretKey = secretKeyFromSeed(seed);
109
+ const pub = Buffer.from(ed25519.getPublicKey(seed));
110
+ const wallet = WalletContractV4.create({ workchain: 0, publicKey: pub });
111
+ const cfg = getConfig();
112
+ const apiKey = process.env.IW_TON_API_KEY?.trim();
113
+ const endpoint = `${cfg.tonApiUrl}/jsonRPC`;
114
+ logInfo("ton.send.start", {
115
+ from: derived.address,
116
+ to: params.to,
117
+ amount: params.amount,
118
+ hasMemo: Boolean(params.memo),
119
+ endpoint,
120
+ hasApiKey: Boolean(apiKey),
121
+ });
122
+ try {
123
+ const client = new TonClient({
124
+ endpoint,
125
+ ...(apiKey ? { apiKey } : {}),
126
+ });
127
+ const opened = client.open(wallet);
128
+ const seqno = await opened.getSeqno();
129
+ logInfo("ton.send.seqno", { from: derived.address, seqno });
130
+ const transfer = wallet.createTransfer({
131
+ seqno,
132
+ secretKey,
133
+ sendMode: SendMode.PAY_GAS_SEPARATELY + SendMode.IGNORE_ERRORS,
134
+ messages: [
135
+ internal({
136
+ to: Address.parse(params.to),
137
+ value: toNano(params.amount),
138
+ bounce: false,
139
+ body: params.memo && params.memo.length > 0 ? params.memo : undefined,
140
+ }),
141
+ ],
142
+ });
143
+ await opened.send(transfer);
144
+ const txHash = Buffer.from(transfer.hash()).toString("base64");
145
+ logInfo("ton.send.ok", {
146
+ from: derived.address,
147
+ to: params.to,
148
+ amount: params.amount,
149
+ seqno,
150
+ txHash,
151
+ elapsedMs: Date.now() - started,
152
+ });
153
+ return { txHash };
154
+ }
155
+ catch (e) {
156
+ logError("ton.send.fail", e, {
157
+ from: derived.address,
158
+ to: params.to,
159
+ amount: params.amount,
160
+ endpoint,
161
+ elapsedMs: Date.now() - started,
162
+ });
163
+ throw e;
164
+ }
165
+ }
166
+ //# sourceMappingURL=ton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ton.js","sourceRoot":"","sources":["../../src/signing/ton.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Tron forward signing, matching the mobile app's tron_client signer:
3
+ *
4
+ * - The estimate returns `txId` = the transaction hash (hex).
5
+ * - Sign the raw 32-byte txId bytes directly with secp256k1 (no extra hashing).
6
+ * - Signature bytes = r(32) || s(32) || v(1), where v is 27/28 (web3dart's
7
+ * recovery id + 27). Encoded as a 130-char hex string.
8
+ * - `txData` and `txID` are returned unchanged from the estimate.
9
+ */
10
+ import type { SignContext, SignedTransaction, TransactionToSign } from "./types.js";
11
+ export declare function signTron(ctx: SignContext, txs: TransactionToSign[]): SignedTransaction[];
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Tron forward signing, matching the mobile app's tron_client signer:
3
+ *
4
+ * - The estimate returns `txId` = the transaction hash (hex).
5
+ * - Sign the raw 32-byte txId bytes directly with secp256k1 (no extra hashing).
6
+ * - Signature bytes = r(32) || s(32) || v(1), where v is 27/28 (web3dart's
7
+ * recovery id + 27). Encoded as a 130-char hex string.
8
+ * - `txData` and `txID` are returned unchanged from the estimate.
9
+ */
10
+ import { SigningKey, getBytes, hexlify, zeroPadValue } from "ethers";
11
+ import { logInfo } from "../log.js";
12
+ export function signTron(ctx, txs) {
13
+ const key = new SigningKey(ctx.privateKey);
14
+ const signed = [];
15
+ logInfo("sign.tron.start", { address: ctx.address, txCount: txs.length });
16
+ for (const item of txs) {
17
+ if (!item.txId)
18
+ throw new Error("Tron transactionToSign has no txId.");
19
+ if (!item.txData)
20
+ throw new Error("Tron transactionToSign has no txData.");
21
+ const digest = getBytes("0x" + item.txId.replace(/^0x/, ""));
22
+ const sig = key.sign(digest);
23
+ const r = getBytes(zeroPadValue(sig.r, 32)); // 32 bytes
24
+ const s = getBytes(zeroPadValue(sig.s, 32)); // 32 bytes
25
+ const v = sig.v; // 27 or 28
26
+ const raw = new Uint8Array(65);
27
+ raw.set(r, 0);
28
+ raw.set(s, 32);
29
+ raw[64] = v;
30
+ signed.push({
31
+ signature: hexlify(raw).replace(/^0x/, ""), // 130 hex chars, no 0x prefix
32
+ txData: item.txData,
33
+ txID: item.txId,
34
+ transactionId: item.transactionId,
35
+ });
36
+ }
37
+ return signed;
38
+ }
39
+ //# sourceMappingURL=tron.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tron.js","sourceRoot":"","sources":["../../src/signing/tron.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAErE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,UAAU,QAAQ,CACtB,GAAgB,EAChB,GAAwB;IAExB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAwB,EAAE,CAAC;IACvC,OAAO,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAE1E,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACvE,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAE3E,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE7B,MAAM,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW;QACxD,MAAM,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW;QACxD,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW;QAE5B,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACd,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACf,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;QAEZ,MAAM,CAAC,IAAI,CAAC;YACV,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,8BAA8B;YAC1E,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** A transaction the backend estimate returned for the client to sign. */
2
+ export interface TransactionToSign {
3
+ transactionId?: string;
4
+ txId?: string;
5
+ txData?: string;
6
+ extraData?: string;
7
+ type?: string;
8
+ value?: string;
9
+ valueEx?: string;
10
+ }
11
+ /** The signed transaction shape sent back in the forward request. */
12
+ export interface SignedTransaction {
13
+ txID: string;
14
+ signature: string;
15
+ txData: string;
16
+ transactionId?: string;
17
+ }
18
+ export interface SignContext {
19
+ /** 0x-prefixed private key for the network. */
20
+ privateKey: string;
21
+ /** Sender address (network formatted). */
22
+ address: string;
23
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/signing/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * XRP forward / swap signing, matching the mobile app's xrp_net_client:
3
+ *
4
+ * - `txData` = an XRPL transaction blob (hex).
5
+ * - Decode → set SigningPubKey → autofill Sequence/Fee/LastLedgerSequence →
6
+ * secp256k1 sign → re-encode signed blob.
7
+ * - Forward/SWP payload: `signature` = TxnSignature hex, `txData` = signed
8
+ * blob hex, `txID` = transaction hash.
9
+ */
10
+ import type { SignContext, SignedTransaction, TransactionToSign } from "./types.js";
11
+ export declare function signXrp(ctx: SignContext, txs: TransactionToSign[]): Promise<SignedTransaction[]>;
@@ -0,0 +1,122 @@
1
+ /**
2
+ * XRP forward / swap signing, matching the mobile app's xrp_net_client:
3
+ *
4
+ * - `txData` = an XRPL transaction blob (hex).
5
+ * - Decode → set SigningPubKey → autofill Sequence/Fee/LastLedgerSequence →
6
+ * secp256k1 sign → re-encode signed blob.
7
+ * - Forward/SWP payload: `signature` = TxnSignature hex, `txData` = signed
8
+ * blob hex, `txID` = transaction hash.
9
+ */
10
+ import { encode, decode, encodeForSigning } from "ripple-binary-codec";
11
+ import { sign as rippleSign } from "ripple-keypairs";
12
+ import { SigningKey } from "ethers";
13
+ import { sha512 } from "@noble/hashes/sha2.js";
14
+ import { getConfig } from "../config.js";
15
+ import { httpJson } from "../api/http.js";
16
+ import { logInfo } from "../log.js";
17
+ const TX_HASH_PREFIX = Uint8Array.from([0x54, 0x58, 0x4e, 0x00]); // "TXN\0"
18
+ /** XRPL JSON-RPC ({ method, params: [ {...} ] } envelope). */
19
+ async function xrpRpc(method, params) {
20
+ const cfg = getConfig();
21
+ const res = await httpJson(cfg.xrpRpcUrl, {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/json" },
24
+ body: JSON.stringify({ method, params: [params] }),
25
+ }, { retry: true });
26
+ const result = res.result;
27
+ if (!result)
28
+ throw new Error(`XRPL ${method} returned no result.`);
29
+ if (result.error)
30
+ throw new Error(`XRPL ${method} failed: ${result.error}`);
31
+ return result;
32
+ }
33
+ async function accountSequence(account) {
34
+ const r = await xrpRpc("account_info", {
35
+ account,
36
+ ledger_index: "current",
37
+ });
38
+ const seq = r.account_data?.Sequence;
39
+ if (seq == null)
40
+ throw new Error("Could not read XRP account Sequence.");
41
+ return seq;
42
+ }
43
+ async function openLedgerFee() {
44
+ try {
45
+ const r = await xrpRpc("fee", {});
46
+ return r.drops?.open_ledger_fee ?? r.drops?.base_fee ?? "12";
47
+ }
48
+ catch {
49
+ return "12";
50
+ }
51
+ }
52
+ async function currentLedgerIndex() {
53
+ const r = await xrpRpc("ledger_current", {});
54
+ return r.ledger_current_index ?? 0;
55
+ }
56
+ function txHash(signedBlobHex) {
57
+ const blob = Uint8Array.from(Buffer.from(signedBlobHex, "hex"));
58
+ const buf = new Uint8Array(TX_HASH_PREFIX.length + blob.length);
59
+ buf.set(TX_HASH_PREFIX, 0);
60
+ buf.set(blob, TX_HASH_PREFIX.length);
61
+ return Buffer.from(sha512(buf).slice(0, 32)).toString("hex").toUpperCase();
62
+ }
63
+ export async function signXrp(ctx, txs) {
64
+ if (txs.length === 0)
65
+ throw new Error("XRP transactionToSign list is empty.");
66
+ logInfo("sign.xrp.start", {
67
+ address: ctx.address,
68
+ txCount: txs.length,
69
+ });
70
+ const pubKey = SigningKey.computePublicKey(ctx.privateKey, true)
71
+ .replace(/^0x/, "")
72
+ .toUpperCase();
73
+ const ripplePriv = ("00" + ctx.privateKey.replace(/^0x/, "")).toUpperCase();
74
+ let nextSequence;
75
+ const fee = await openLedgerFee();
76
+ const ledger = await currentLedgerIndex();
77
+ const signed = [];
78
+ for (const item of txs) {
79
+ if (!item.txData)
80
+ throw new Error("XRP transactionToSign has no txData.");
81
+ const tx = decode(item.txData.replace(/^0x/, "").toUpperCase());
82
+ tx.SigningPubKey = pubKey;
83
+ if (tx.Account == null)
84
+ tx.Account = ctx.address;
85
+ if (tx.Sequence == null) {
86
+ if (nextSequence === undefined) {
87
+ nextSequence = await accountSequence(ctx.address);
88
+ }
89
+ tx.Sequence = nextSequence;
90
+ nextSequence += 1;
91
+ }
92
+ else if (typeof tx.Sequence === "number") {
93
+ nextSequence = tx.Sequence + 1;
94
+ }
95
+ if (tx.Fee == null)
96
+ tx.Fee = fee;
97
+ if (tx.LastLedgerSequence == null) {
98
+ tx.LastLedgerSequence = ledger + 20;
99
+ }
100
+ const signingData = encodeForSigning(tx);
101
+ tx.TxnSignature = rippleSign(signingData, ripplePriv);
102
+ const signedBlob = encode(tx);
103
+ const hash = txHash(signedBlob);
104
+ logInfo("sign.xrp.tx", {
105
+ address: ctx.address,
106
+ transactionId: item.transactionId,
107
+ txID: hash,
108
+ sequence: tx.Sequence,
109
+ fee: tx.Fee,
110
+ lastLedgerSequence: tx.LastLedgerSequence,
111
+ signedBlobLen: signedBlob.length,
112
+ });
113
+ signed.push({
114
+ signature: tx.TxnSignature,
115
+ txData: signedBlob,
116
+ txID: hash,
117
+ transactionId: item.transactionId,
118
+ });
119
+ }
120
+ return signed;
121
+ }
122
+ //# sourceMappingURL=xrp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xrp.js","sourceRoot":"","sources":["../../src/signing/xrp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Shared MCP tool helpers: response shaping, logging wrapper, wallet session.
3
+ */
4
+ import { z } from "zod";
5
+ import { type NetworkId } from "../config.js";
6
+ import type { WalletEntry } from "../keystore/types.js";
7
+ export declare const networkEnum: z.ZodEnum<[NetworkId, ...NetworkId[]]>;
8
+ export declare function ok(payload: unknown): {
9
+ content: {
10
+ type: "text";
11
+ text: string;
12
+ }[];
13
+ };
14
+ export declare function fail(err: unknown): {
15
+ isError: true;
16
+ content: {
17
+ type: "text";
18
+ text: string;
19
+ }[];
20
+ };
21
+ export type ToolOk = ReturnType<typeof ok>;
22
+ export type ToolFail = ReturnType<typeof fail>;
23
+ /**
24
+ * Wrap every MCP tool handler with start/ok/fail JSONL logging and a
25
+ * correlation id. Nested modules (http/relay/auth/…) reuse the same id when
26
+ * callers pass it through.
27
+ */
28
+ export declare function withToolLog<TArgs extends Record<string, unknown> | undefined>(tool: string, args: TArgs, fn: (ctx: {
29
+ correlationId: string;
30
+ started: number;
31
+ }) => Promise<ToolOk>): Promise<ToolOk | ToolFail>;
32
+ /** Resolve wallet + decrypt mnemonic + obtain a Bearer token. */
33
+ export declare function session(walletName: string | undefined, correlationId?: string): Promise<{
34
+ entry: WalletEntry;
35
+ mnemonic: string;
36
+ token: string;
37
+ }>;
38
+ export type ToolHelpers = {
39
+ ok: typeof ok;
40
+ withToolLog: typeof withToolLog;
41
+ session: typeof session;
42
+ };
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Shared MCP tool helpers: response shaping, logging wrapper, wallet session.
3
+ */
4
+ import { z } from "zod";
5
+ import { ALL_NETWORKS } from "../config.js";
6
+ import { resolveEntry, syncAddresses, unlockMnemonic, } from "../keystore/store.js";
7
+ import { requirePassphrase } from "../passphrase.js";
8
+ import { getAccessToken } from "../api/auth.js";
9
+ import { logError, logInfo, newCorrelationId, } from "../log.js";
10
+ export const networkEnum = z.enum(ALL_NETWORKS);
11
+ export function ok(payload) {
12
+ return {
13
+ content: [
14
+ { type: "text", text: JSON.stringify(payload, null, 2) },
15
+ ],
16
+ };
17
+ }
18
+ export function fail(err) {
19
+ const message = err instanceof Error ? err.message : String(err);
20
+ return {
21
+ isError: true,
22
+ content: [{ type: "text", text: `Error: ${message}` }],
23
+ };
24
+ }
25
+ /**
26
+ * Wrap every MCP tool handler with start/ok/fail JSONL logging and a
27
+ * correlation id. Nested modules (http/relay/auth/…) reuse the same id when
28
+ * callers pass it through.
29
+ */
30
+ export async function withToolLog(tool, args, fn) {
31
+ const correlationId = newCorrelationId(tool.replace(/[^a-z0-9]+/gi, "").slice(0, 12) || "tool");
32
+ const started = Date.now();
33
+ logInfo("tool.start", { correlationId, tool, args: args ?? {} });
34
+ try {
35
+ const result = await fn({ correlationId, started });
36
+ logInfo("tool.ok", {
37
+ correlationId,
38
+ tool,
39
+ elapsedMs: Date.now() - started,
40
+ isError: false,
41
+ });
42
+ return result;
43
+ }
44
+ catch (e) {
45
+ logError("tool.fail", e, {
46
+ correlationId,
47
+ tool,
48
+ elapsedMs: Date.now() - started,
49
+ args: args ?? {},
50
+ });
51
+ return fail(e);
52
+ }
53
+ }
54
+ /** Resolve wallet + decrypt mnemonic + obtain a Bearer token. */
55
+ export async function session(walletName, correlationId) {
56
+ const started = Date.now();
57
+ logInfo("session.start", { correlationId, wallet: walletName ?? "<default>" });
58
+ try {
59
+ const resolved = resolveEntry(walletName);
60
+ const mnemonic = unlockMnemonic(resolved, requirePassphrase());
61
+ const entry = syncAddresses(resolved, mnemonic);
62
+ const token = await getAccessToken(mnemonic, { correlationId });
63
+ logInfo("session.ok", {
64
+ correlationId,
65
+ wallet: entry.name,
66
+ elapsedMs: Date.now() - started,
67
+ addressCount: Object.keys(entry.addresses).length,
68
+ });
69
+ return { entry, mnemonic, token };
70
+ }
71
+ catch (e) {
72
+ logError("session.fail", e, {
73
+ correlationId,
74
+ wallet: walletName ?? "<default>",
75
+ elapsedMs: Date.now() - started,
76
+ });
77
+ throw e;
78
+ }
79
+ }
80
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/tools/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP tool registrations. Design rule: the mnemonic never crosses the agent
3
+ * boundary. Tools return addresses, balances, estimates, and tx hashes — never
4
+ * seed words. There is intentionally no export_seed / import_wallet tool.
5
+ */
6
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
+ export declare function registerTools(server: McpServer): void;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * MCP tool registrations. Design rule: the mnemonic never crosses the agent
3
+ * boundary. Tools return addresses, balances, estimates, and tx hashes — never
4
+ * seed words. There is intentionally no export_seed / import_wallet tool.
5
+ */
6
+ import { ok, session, withToolLog } from "./helpers.js";
7
+ import { registerWalletTools } from "./wallets.js";
8
+ import { registerTransferTools } from "./transfer.js";
9
+ import { registerSwapTools } from "./swap.js";
10
+ export function registerTools(server) {
11
+ const helpers = { ok, withToolLog, session };
12
+ registerWalletTools(server, helpers);
13
+ registerTransferTools(server, helpers);
14
+ registerSwapTools(server, helpers);
15
+ }
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,UAAU,aAAa,CAAC,MAAiB;IAC7C,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;IAC7C,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP tools for Swap Proxy (SWP): discovery, estimate, execute, status.
3
+ */
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import type { ToolHelpers } from "./helpers.js";
6
+ export declare function registerSwapTools(server: McpServer, helpers: ToolHelpers): void;