@execra/core 1.0.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 (52) hide show
  1. package/dist/cli/commands.d.ts +21 -0
  2. package/dist/cli/commands.js +686 -0
  3. package/dist/cli/commands.js.map +1 -0
  4. package/dist/cli/index.d.ts +8 -0
  5. package/dist/cli/index.js +1162 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/cli/prompts.d.ts +12 -0
  8. package/dist/cli/prompts.js +98 -0
  9. package/dist/cli/prompts.js.map +1 -0
  10. package/dist/cli/ui.d.ts +38 -0
  11. package/dist/cli/ui.js +990 -0
  12. package/dist/cli/ui.js.map +1 -0
  13. package/dist/handler/index.d.ts +93 -0
  14. package/dist/handler/index.js +628 -0
  15. package/dist/handler/index.js.map +1 -0
  16. package/dist/handler/walletConnect.d.ts +6 -0
  17. package/dist/handler/walletConnect.js +623 -0
  18. package/dist/handler/walletConnect.js.map +1 -0
  19. package/dist/index.d.ts +14 -0
  20. package/dist/index.js +2046 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/session/index.d.ts +20 -0
  23. package/dist/session/index.js +79 -0
  24. package/dist/session/index.js.map +1 -0
  25. package/dist/solana/index.d.ts +5 -0
  26. package/dist/solana/index.js +302 -0
  27. package/dist/solana/index.js.map +1 -0
  28. package/dist/solana/rpc.d.ts +45 -0
  29. package/dist/solana/rpc.js +120 -0
  30. package/dist/solana/rpc.js.map +1 -0
  31. package/dist/solana/simulate.d.ts +41 -0
  32. package/dist/solana/simulate.js +173 -0
  33. package/dist/solana/simulate.js.map +1 -0
  34. package/dist/solana/tx.d.ts +54 -0
  35. package/dist/solana/tx.js +141 -0
  36. package/dist/solana/tx.js.map +1 -0
  37. package/dist/vault/accounts.d.ts +88 -0
  38. package/dist/vault/accounts.js +126 -0
  39. package/dist/vault/accounts.js.map +1 -0
  40. package/dist/vault/config.d.ts +40 -0
  41. package/dist/vault/config.js +131 -0
  42. package/dist/vault/config.js.map +1 -0
  43. package/dist/vault/index.d.ts +122 -0
  44. package/dist/vault/index.js +580 -0
  45. package/dist/vault/index.js.map +1 -0
  46. package/dist/vault/keystore.d.ts +44 -0
  47. package/dist/vault/keystore.js +118 -0
  48. package/dist/vault/keystore.js.map +1 -0
  49. package/dist/vault/mnemonic.d.ts +43 -0
  50. package/dist/vault/mnemonic.js +37 -0
  51. package/dist/vault/mnemonic.js.map +1 -0
  52. package/package.json +49 -0
@@ -0,0 +1,623 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/handler/walletConnect.ts
4
+ import SignClientPkg from "@walletconnect/sign-client";
5
+ import { getSdkError } from "@walletconnect/utils";
6
+ import chalk from "chalk";
7
+
8
+ // src/solana/simulate.ts
9
+ import {
10
+ Transaction,
11
+ VersionedTransaction,
12
+ LAMPORTS_PER_SOL as LAMPORTS_PER_SOL2
13
+ } from "@solana/web3.js";
14
+
15
+ // src/solana/rpc.ts
16
+ import { Connection, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js";
17
+
18
+ // src/vault/config.ts
19
+ import fs2 from "fs";
20
+
21
+ // src/vault/keystore.ts
22
+ import fs from "fs";
23
+ import os from "os";
24
+ import path from "path";
25
+ function getWalletDir() {
26
+ return path.join(os.homedir(), ".wallet");
27
+ }
28
+ function getConfigPath() {
29
+ return path.join(getWalletDir(), "config.json");
30
+ }
31
+ function getSessionsPath() {
32
+ return path.join(getWalletDir(), "sessions.json");
33
+ }
34
+ var SESSIONS_FILE = getSessionsPath();
35
+ function ensureWalletDir() {
36
+ const dir = getWalletDir();
37
+ if (!fs.existsSync(dir)) {
38
+ fs.mkdirSync(dir, { recursive: true, mode: 448 });
39
+ }
40
+ }
41
+
42
+ // src/vault/accounts.ts
43
+ import { derivePath } from "ed25519-hd-key";
44
+ import nacl from "tweetnacl";
45
+ import bs58 from "bs58";
46
+
47
+ // src/vault/mnemonic.ts
48
+ import * as bip39 from "bip39";
49
+
50
+ // src/vault/config.ts
51
+ var HELIUS_API_KEY = process.env.HELIUS_API_KEY;
52
+ var RPC_URLS = {
53
+ "mainnet-beta": HELIUS_API_KEY ? `https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}` : "https://api.mainnet-beta.solana.com",
54
+ devnet: HELIUS_API_KEY ? `https://devnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}` : "https://api.devnet.solana.com",
55
+ testnet: "https://api.testnet.solana.com",
56
+ localnet: "http://localhost:8899"
57
+ };
58
+ function configExists() {
59
+ return fs2.existsSync(getConfigPath());
60
+ }
61
+ function loadConfig() {
62
+ if (!configExists()) {
63
+ throw new Error("No config found. Run `wallet init` first.");
64
+ }
65
+ const raw = fs2.readFileSync(getConfigPath(), "utf8");
66
+ return JSON.parse(raw);
67
+ }
68
+ function getRpcUrl() {
69
+ return loadConfig().rpcUrl;
70
+ }
71
+
72
+ // src/solana/rpc.ts
73
+ var _connection = null;
74
+ function getConnection(forceNew = false) {
75
+ if (!_connection || forceNew) {
76
+ const rpcUrl = getRpcUrl();
77
+ _connection = new Connection(rpcUrl, "confirmed");
78
+ }
79
+ return _connection;
80
+ }
81
+
82
+ // src/solana/simulate.ts
83
+ async function simulateTransaction(serializedTx, signerPublicKey, conn) {
84
+ const connection = conn ?? getConnection();
85
+ try {
86
+ const txBuffer = Buffer.from(serializedTx, "base64");
87
+ let simulation;
88
+ try {
89
+ const versionedTx = VersionedTransaction.deserialize(txBuffer);
90
+ simulation = await connection.simulateTransaction(versionedTx, {
91
+ sigVerify: false,
92
+ // skip sig verification — wallet hasn't signed yet
93
+ replaceRecentBlockhash: true
94
+ });
95
+ } catch {
96
+ const legacyTx = Transaction.from(txBuffer);
97
+ simulation = await connection.simulateTransaction(legacyTx, []);
98
+ }
99
+ const { value } = simulation;
100
+ return parseSimulationResult(value, signerPublicKey, txBuffer);
101
+ } catch (err) {
102
+ return {
103
+ success: false,
104
+ error: err instanceof Error ? err.message : "Simulation failed",
105
+ logs: [],
106
+ accountChanges: [],
107
+ tokenChanges: [],
108
+ computeUnitsConsumed: 0,
109
+ programIds: [],
110
+ fee: 0,
111
+ rawLogs: []
112
+ };
113
+ }
114
+ }
115
+ function parseSimulationResult(value, signerPublicKey, txBuffer) {
116
+ const success = !value.err;
117
+ const logs = value.logs ?? [];
118
+ const accountChanges = (value.accounts ?? []).map((account, i) => {
119
+ if (!account) return null;
120
+ const preBalance = account.lamports ?? 0;
121
+ const postBalance = account.lamports ?? 0;
122
+ return {
123
+ address: signerPublicKey,
124
+ // simplified — full impl maps account indices
125
+ preBalance,
126
+ postBalance,
127
+ solDelta: (postBalance - preBalance) / LAMPORTS_PER_SOL2,
128
+ isWritable: true,
129
+ isSigner: i === 0
130
+ };
131
+ }).filter(Boolean);
132
+ const programIds = extractProgramIds(logs);
133
+ const computeUnitsConsumed = extractComputeUnits(logs);
134
+ const fee = 5e3;
135
+ return {
136
+ success,
137
+ error: value.err ? JSON.stringify(value.err) : null,
138
+ logs: formatLogs(logs),
139
+ accountChanges,
140
+ tokenChanges: [],
141
+ // full SPL parsing requires additional RPC calls
142
+ computeUnitsConsumed,
143
+ programIds,
144
+ fee,
145
+ rawLogs: logs
146
+ };
147
+ }
148
+ function extractProgramIds(logs) {
149
+ const ids = /* @__PURE__ */ new Set();
150
+ const invokePattern = /Program (\w+) invoke/;
151
+ for (const log of logs) {
152
+ const match = log.match(invokePattern);
153
+ if (match) ids.add(match[1]);
154
+ }
155
+ return Array.from(ids);
156
+ }
157
+ function extractComputeUnits(logs) {
158
+ for (const log of logs) {
159
+ const match = log.match(/consumed (\d+) of/);
160
+ if (match) return parseInt(match[1], 10);
161
+ }
162
+ return 0;
163
+ }
164
+ function formatLogs(logs) {
165
+ return logs.map((log) => {
166
+ return log.replace(/\b([1-9A-HJ-NP-Za-km-z]{32,44})\b/g, (addr) => {
167
+ const known = KNOWN_PROGRAMS[addr];
168
+ return known ? known : `${addr.slice(0, 4)}..${addr.slice(-4)}`;
169
+ });
170
+ });
171
+ }
172
+ var KNOWN_PROGRAMS = {
173
+ "11111111111111111111111111111111": "System Program",
174
+ TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA: "SPL Token",
175
+ JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4: "Jupiter V6",
176
+ "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin": "Serum DEX",
177
+ ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJe1bv: "Associated Token",
178
+ SysvarRent111111111111111111111111111111111: "Sysvar Rent",
179
+ SysvarC1ock11111111111111111111111111111111: "Sysvar Clock"
180
+ };
181
+
182
+ // src/solana/tx.ts
183
+ import {
184
+ Transaction as Transaction2,
185
+ VersionedTransaction as VersionedTransaction2,
186
+ Keypair
187
+ } from "@solana/web3.js";
188
+ import nacl2 from "tweetnacl";
189
+ import bs582 from "bs58";
190
+ async function signTransaction(serializedTx, keypair) {
191
+ const txBuffer = Buffer.from(serializedTx, "base64");
192
+ const solanaKeypair = toSolanaKeypair(keypair);
193
+ try {
194
+ const versionedTx = VersionedTransaction2.deserialize(txBuffer);
195
+ versionedTx.sign([solanaKeypair]);
196
+ const serialized = Buffer.from(versionedTx.serialize()).toString("base64");
197
+ const signature = bs582.encode(versionedTx.signatures[0]);
198
+ return { serialized, signature };
199
+ } catch {
200
+ const legacyTx = Transaction2.from(txBuffer);
201
+ legacyTx.partialSign(solanaKeypair);
202
+ const serialized = legacyTx.serialize({ requireAllSignatures: false }).toString("base64");
203
+ const signature = bs582.encode(legacyTx.signature);
204
+ return { serialized, signature };
205
+ }
206
+ }
207
+ async function signAllTransactions(serializedTxs, keypair) {
208
+ return Promise.all(serializedTxs.map((tx) => signTransaction(tx, keypair)));
209
+ }
210
+ async function signAndSendTransaction(serializedTx, keypair, options = {}, conn) {
211
+ const { serialized } = await signTransaction(serializedTx, keypair);
212
+ return sendSignedTransaction(serialized, options, conn);
213
+ }
214
+ async function sendSignedTransaction(serializedSignedTx, options = {}, conn) {
215
+ const connection = conn ?? getConnection();
216
+ const txBuffer = Buffer.from(serializedSignedTx, "base64");
217
+ const sendOptions = {
218
+ skipPreflight: false,
219
+ // run preflight checks
220
+ preflightCommitment: "confirmed",
221
+ ...options
222
+ };
223
+ let txHash;
224
+ try {
225
+ const versionedTx = VersionedTransaction2.deserialize(txBuffer);
226
+ txHash = await connection.sendTransaction(versionedTx, sendOptions);
227
+ } catch {
228
+ const legacyTx = Transaction2.from(txBuffer);
229
+ txHash = await connection.sendRawTransaction(
230
+ legacyTx.serialize(),
231
+ sendOptions
232
+ );
233
+ }
234
+ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
235
+ const confirmResult = await connection.confirmTransaction(
236
+ { signature: txHash, blockhash, lastValidBlockHeight },
237
+ "confirmed"
238
+ );
239
+ return {
240
+ txHash,
241
+ confirmed: !confirmResult.value.err
242
+ };
243
+ }
244
+ function signOffchainMessage(message, keypair) {
245
+ const signature = nacl2.sign.detached(message, keypair.secretKey);
246
+ return bs582.encode(Buffer.from(signature));
247
+ }
248
+ function toSolanaKeypair(keypair) {
249
+ return Keypair.fromSecretKey(keypair.secretKey);
250
+ }
251
+
252
+ // src/handler/index.ts
253
+ import bs583 from "bs58";
254
+ var ERROR_CODES = {
255
+ USER_REJECTED: 4001,
256
+ UNAUTHORIZED: 4100,
257
+ UNSUPPORTED_METHOD: 4200,
258
+ DISCONNECTED: 4900,
259
+ CHAIN_DISCONNECTED: 4901
260
+ };
261
+ var WalletRequestHandler = class {
262
+ vault;
263
+ constructor(vault) {
264
+ this.vault = vault;
265
+ }
266
+ /**
267
+ * Handle any incoming wallet request.
268
+ * This is the single entry point — all bridges call this.
269
+ */
270
+ async handle(request) {
271
+ try {
272
+ switch (request.method) {
273
+ case "solana_connect":
274
+ return this.handleConnect(request);
275
+ case "solana_disconnect":
276
+ return this.handleDisconnect(request);
277
+ case "solana_signTransaction":
278
+ return this.handleSignTransaction(request);
279
+ case "solana_signAndSendTransaction":
280
+ return this.handleSignAndSend(request);
281
+ case "solana_signAllTransactions":
282
+ return this.handleSignAll(request);
283
+ case "solana_signMessage":
284
+ return this.handleSignMessage(request);
285
+ default:
286
+ return this.errorResponse(
287
+ request.id,
288
+ ERROR_CODES.UNSUPPORTED_METHOD,
289
+ `Method not supported: ${request.method}`
290
+ );
291
+ }
292
+ } catch (err) {
293
+ return this.errorResponse(
294
+ request.id,
295
+ 4e3,
296
+ err instanceof Error ? err.message : "Unknown error"
297
+ );
298
+ }
299
+ }
300
+ // ── Connect / Disconnect ───────────────────────────────────────────────────
301
+ async handleConnect(request) {
302
+ const keypair = this.vault.getActiveKeypair();
303
+ return {
304
+ id: request.id,
305
+ result: {
306
+ publicKey: keypair.publicKey
307
+ }
308
+ };
309
+ }
310
+ async handleDisconnect(request) {
311
+ return { id: request.id, result: { disconnected: true } };
312
+ }
313
+ // ── Sign Transaction ───────────────────────────────────────────────────────
314
+ async handleSignTransaction(request) {
315
+ const tx = request.params.transaction;
316
+ if (!tx) return this.errorResponse(request.id, 4e3, "Missing transaction");
317
+ const keypair = this.vault.getActiveKeypair();
318
+ const simulation = await simulateTransaction(tx, keypair.publicKey);
319
+ this.log(request, `simulate \u2192 ${simulation.success ? "ok" : "fail"}`);
320
+ if (!simulation.success) {
321
+ return this.errorResponse(
322
+ request.id,
323
+ 4e3,
324
+ `Simulation failed: ${simulation.error}`
325
+ );
326
+ }
327
+ const signed = await signTransaction(tx, keypair);
328
+ this.log(request, `signed \u2192 ${signed.signature.slice(0, 8)}...`);
329
+ return {
330
+ id: request.id,
331
+ result: { signedTransaction: signed.serialized }
332
+ };
333
+ }
334
+ // ── Sign and Send ──────────────────────────────────────────────────────────
335
+ async handleSignAndSend(request) {
336
+ const tx = request.params.transaction;
337
+ if (!tx) return this.errorResponse(request.id, 4e3, "Missing transaction");
338
+ const keypair = this.vault.getActiveKeypair();
339
+ const simulation = await simulateTransaction(tx, keypair.publicKey);
340
+ this.log(request, `simulate \u2192 ${simulation.success ? "ok" : "fail"}`);
341
+ if (!simulation.success) {
342
+ return this.errorResponse(
343
+ request.id,
344
+ 4e3,
345
+ `Simulation failed: ${simulation.error}`
346
+ );
347
+ }
348
+ const result = await signAndSendTransaction(tx, keypair);
349
+ this.log(request, `sent \u2192 ${result.txHash.slice(0, 8)}...`);
350
+ return {
351
+ id: request.id,
352
+ result: {
353
+ signature: result.txHash,
354
+ confirmed: result.confirmed
355
+ }
356
+ };
357
+ }
358
+ // ── Sign All Transactions ──────────────────────────────────────────────────
359
+ async handleSignAll(request) {
360
+ const txs = request.params.transactions;
361
+ if (!txs?.length)
362
+ return this.errorResponse(request.id, 4e3, "Missing transactions");
363
+ const keypair = this.vault.getActiveKeypair();
364
+ for (const tx of txs) {
365
+ const simulation = await simulateTransaction(tx, keypair.publicKey);
366
+ if (!simulation.success) {
367
+ return this.errorResponse(
368
+ request.id,
369
+ 4e3,
370
+ `Simulation failed for tx in batch: ${simulation.error}`
371
+ );
372
+ }
373
+ }
374
+ const signed = await signAllTransactions(txs, keypair);
375
+ this.log(request, `signed ${signed.length} transactions`);
376
+ return {
377
+ id: request.id,
378
+ result: { signedTransactions: signed.map((s) => s.serialized) }
379
+ };
380
+ }
381
+ // ── Sign Message ───────────────────────────────────────────────────────────
382
+ async handleSignMessage(request) {
383
+ const message = request.params.message;
384
+ if (!message)
385
+ return this.errorResponse(request.id, 4e3, "Missing message");
386
+ const keypair = this.vault.getActiveKeypair();
387
+ let messageBytes;
388
+ try {
389
+ messageBytes = decodeMessage(message);
390
+ } catch {
391
+ return this.errorResponse(
392
+ request.id,
393
+ 4e3,
394
+ "Could not decode message bytes"
395
+ );
396
+ }
397
+ const signature = signOffchainMessage(messageBytes, keypair);
398
+ this.log(request, "message signed");
399
+ return {
400
+ id: request.id,
401
+ result: {
402
+ signature,
403
+ publicKey: keypair.publicKey
404
+ }
405
+ };
406
+ }
407
+ // ── Helpers ────────────────────────────────────────────────────────────────
408
+ errorResponse(id, code, message) {
409
+ return { id, error: { code, message } };
410
+ }
411
+ // TODO: handle logging
412
+ log(request, note) {
413
+ }
414
+ };
415
+ function decodeMessage(message) {
416
+ try {
417
+ const decoded = bs583.decode(message);
418
+ if (decoded.length > 0) return decoded;
419
+ } catch {
420
+ }
421
+ try {
422
+ const decoded = Buffer.from(message, "base64");
423
+ if (decoded.length > 0) return decoded;
424
+ } catch {
425
+ }
426
+ return new TextEncoder().encode(message);
427
+ }
428
+ async function handleRequest(request, options) {
429
+ const handler = new WalletRequestHandler(options.vault);
430
+ return handler.handle(request);
431
+ }
432
+
433
+ // src/session/index.ts
434
+ import * as fs3 from "fs";
435
+ function read() {
436
+ ensureWalletDir();
437
+ if (!fs3.existsSync(SESSIONS_FILE)) return { sessions: [] };
438
+ return JSON.parse(fs3.readFileSync(SESSIONS_FILE, "utf8"));
439
+ }
440
+ function write(store) {
441
+ ensureWalletDir();
442
+ fs3.writeFileSync(SESSIONS_FILE, JSON.stringify(store, null, 2));
443
+ }
444
+ function saveSession(session) {
445
+ const store = read();
446
+ const idx = store.sessions.findIndex((s) => s.topic === session.topic);
447
+ if (idx >= 0) {
448
+ store.sessions[idx] = session;
449
+ } else {
450
+ store.sessions.push(session);
451
+ }
452
+ write(store);
453
+ }
454
+ function removeSession(topic) {
455
+ const store = read();
456
+ store.sessions = store.sessions.filter((s) => s.topic !== topic);
457
+ write(store);
458
+ }
459
+ function markInactive(topic) {
460
+ const store = read();
461
+ const sess = store.sessions.find((s) => s.topic === topic);
462
+ if (sess) {
463
+ sess.active = false;
464
+ write(store);
465
+ }
466
+ }
467
+
468
+ // src/handler/walletConnect.ts
469
+ var SignClient = SignClientPkg.default ?? SignClientPkg;
470
+ var CHAIN_ID = "solana:devnet";
471
+ var signClient = null;
472
+ async function initWalletConnect(opts) {
473
+ signClient = await SignClient.init({
474
+ projectId: opts.projectId,
475
+ metadata: {
476
+ name: "Agentic Wallet",
477
+ description: "Autonomous AI agent wallet for Solana",
478
+ url: "https://github.com/your-repo/agentic-wallet",
479
+ icons: []
480
+ }
481
+ });
482
+ console.log(chalk.green("[WC] WalletConnect initialized"));
483
+ signClient.on("session_proposal", async ({ id, params }) => {
484
+ const meta = params.proposer.metadata;
485
+ console.log(
486
+ chalk.cyan(`
487
+ [WC] Session proposal from: ${meta.name} (${meta.url})`)
488
+ );
489
+ let approved = true;
490
+ if (opts.onSessionProposal) {
491
+ approved = await opts.onSessionProposal(meta);
492
+ }
493
+ if (!approved) {
494
+ await signClient.reject({ id, reason: getSdkError("USER_REJECTED") });
495
+ console.log(chalk.red("[WC] Session rejected"));
496
+ return;
497
+ }
498
+ const account = opts.handlerOptions.vault.getActiveKeypair();
499
+ const { topic, acknowledged } = await signClient.approve({
500
+ id,
501
+ namespaces: {
502
+ solana: {
503
+ accounts: [`${CHAIN_ID}:${account.publicKey}`],
504
+ methods: [
505
+ "solana_signTransaction",
506
+ "solana_signAndSendTransaction",
507
+ "solana_signAllTransactions",
508
+ "solana_signMessage"
509
+ ],
510
+ events: []
511
+ }
512
+ }
513
+ });
514
+ await acknowledged();
515
+ saveSession({
516
+ topic,
517
+ dappName: meta.name,
518
+ dappUrl: meta.url,
519
+ dappIcon: meta.icons?.[0],
520
+ connectedAccount: account.publicKey,
521
+ connectedAt: (/* @__PURE__ */ new Date()).toISOString(),
522
+ lastActivity: (/* @__PURE__ */ new Date()).toISOString(),
523
+ permissions: [
524
+ "solana_signTransaction",
525
+ "solana_signAndSendTransaction",
526
+ "solana_signAllTransactions",
527
+ "solana_signMessage"
528
+ ],
529
+ chainId: CHAIN_ID,
530
+ active: true
531
+ });
532
+ console.log(chalk.green(`[WC] Connected to ${meta.name}`));
533
+ console.log(chalk.dim(` Address: ${account.publicKey}`));
534
+ });
535
+ signClient.on("session_request", async ({ id, topic, params }) => {
536
+ const session = signClient.session.get(topic);
537
+ const dapp = {
538
+ name: session.peer.metadata.name,
539
+ url: session.peer.metadata.url
540
+ };
541
+ console.log(
542
+ chalk.yellow(
543
+ `
544
+ [WC] Request: ${params.request.method} from ${dapp.name}`
545
+ )
546
+ );
547
+ const request = {
548
+ id,
549
+ method: params.request.method,
550
+ params: params.request.params,
551
+ dapp,
552
+ topic
553
+ };
554
+ const response = await handleRequest(request, opts.handlerOptions);
555
+ const jsonRpcResponse = response.error ? {
556
+ id,
557
+ jsonrpc: "2.0",
558
+ error: { code: response.error.code, message: response.error.message }
559
+ } : { id, jsonrpc: "2.0", result: response.result ?? null };
560
+ await signClient.respond({ topic, response: jsonRpcResponse });
561
+ if (response.error) {
562
+ console.log(chalk.red(`[WC] Rejected: ${response.error.message}`));
563
+ } else {
564
+ console.log(chalk.green(`[WC] Request fulfilled`));
565
+ }
566
+ });
567
+ signClient.on("session_delete", ({ topic }) => {
568
+ markInactive(topic);
569
+ console.log(
570
+ chalk.dim(`[WC] dApp disconnected (topic: ${topic.slice(0, 8)}...)`)
571
+ );
572
+ });
573
+ return signClient;
574
+ }
575
+ async function pairWithDapp(uri) {
576
+ if (!signClient) throw new Error("WalletConnect not initialised");
577
+ console.log(chalk.dim("[WC] Connecting to dApp..."));
578
+ await new Promise((resolve, reject) => {
579
+ const timeout = setTimeout(() => {
580
+ signClient.off("session_proposal", onProposal);
581
+ reject(new Error("WalletConnect pairing timed out after 30s"));
582
+ }, 3e4);
583
+ const onProposal = ({ params }) => {
584
+ clearTimeout(timeout);
585
+ signClient.off("session_proposal", onProposal);
586
+ const meta = params.proposer.metadata;
587
+ console.log(
588
+ chalk.cyan(
589
+ `[WC] Request from: ${chalk.bold(meta.name)} (${meta.url})`,
590
+ params
591
+ )
592
+ );
593
+ resolve();
594
+ };
595
+ signClient.on("session_proposal", onProposal);
596
+ signClient.core.pairing.pair({ uri }).catch((err) => {
597
+ clearTimeout(timeout);
598
+ signClient.off("session_proposal", onProposal);
599
+ reject(err);
600
+ });
601
+ });
602
+ }
603
+ async function disconnectDapp(topic) {
604
+ if (!signClient) throw new Error("WalletConnect not initialised");
605
+ await signClient.disconnect({
606
+ topic,
607
+ reason: getSdkError("USER_DISCONNECTED")
608
+ });
609
+ removeSession(topic);
610
+ console.log(
611
+ chalk.dim(`[WC] Disconnected from topic ${topic.slice(0, 8)}...`)
612
+ );
613
+ }
614
+ function getSignClient() {
615
+ return signClient;
616
+ }
617
+ export {
618
+ disconnectDapp,
619
+ getSignClient,
620
+ initWalletConnect,
621
+ pairWithDapp
622
+ };
623
+ //# sourceMappingURL=walletConnect.js.map