@naculus/connect-appkit-vue 0.2.4 → 0.2.6
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/README.md +38 -4
- package/dist/index.cjs +2748 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +955 -4
- package/dist/index.d.ts +955 -4
- package/dist/index.js +2773 -42
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -209,40 +209,2536 @@ function useAccounts(accounts) {
|
|
|
209
209
|
};
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
// src/useNotification.ts
|
|
213
|
+
import {
|
|
214
|
+
addInAppNotification,
|
|
215
|
+
channelsUpdate,
|
|
216
|
+
clearOneInAppNotification,
|
|
217
|
+
createNotificationSettingsStorage,
|
|
218
|
+
DEFAULT_NOTIFICATION_SETTINGS,
|
|
219
|
+
loadNotificationSettings,
|
|
220
|
+
mutedChainSettings,
|
|
221
|
+
saveNotificationSettings,
|
|
222
|
+
updateNotificationSettings
|
|
223
|
+
} from "@naculus/connect-appkit-core";
|
|
224
|
+
import {
|
|
225
|
+
InAppChannel
|
|
226
|
+
} from "@naculus/connect-core";
|
|
227
|
+
import { computed as computed2, onScopeDispose, shallowRef, unref } from "vue";
|
|
228
|
+
function useNotification(options = {}) {
|
|
229
|
+
const channel = unref(options.channel) ?? new InAppChannel();
|
|
230
|
+
const storage = unref(options.storage) ?? createNotificationSettingsStorage();
|
|
231
|
+
const notifications = shallowRef(channel.getHistory());
|
|
232
|
+
const settings = shallowRef(
|
|
233
|
+
DEFAULT_NOTIFICATION_SETTINGS
|
|
234
|
+
);
|
|
235
|
+
const unreadCount = computed2(
|
|
236
|
+
() => notifications.value.filter((item) => !item.read).length
|
|
237
|
+
);
|
|
238
|
+
let disposed = false;
|
|
239
|
+
void loadNotificationSettings(storage).then((saved) => {
|
|
240
|
+
if (!disposed && saved) settings.value = saved;
|
|
241
|
+
});
|
|
242
|
+
channel.onNotification = (item) => {
|
|
243
|
+
if (!disposed) notifications.value = [...notifications.value, item];
|
|
244
|
+
};
|
|
245
|
+
void channel.restore().then(() => {
|
|
246
|
+
if (!disposed) notifications.value = channel.getHistory();
|
|
247
|
+
});
|
|
248
|
+
onScopeDispose(() => {
|
|
249
|
+
disposed = true;
|
|
250
|
+
channel.onNotification = void 0;
|
|
251
|
+
});
|
|
252
|
+
const updateSettings = (update) => {
|
|
253
|
+
settings.value = updateNotificationSettings(settings.value, update);
|
|
254
|
+
saveNotificationSettings(storage, settings.value);
|
|
255
|
+
};
|
|
256
|
+
return {
|
|
257
|
+
notifications,
|
|
258
|
+
unreadCount,
|
|
259
|
+
settings,
|
|
260
|
+
addNotification: (item) => addInAppNotification(channel, item),
|
|
261
|
+
clear: () => {
|
|
262
|
+
channel.clear();
|
|
263
|
+
notifications.value = [];
|
|
264
|
+
},
|
|
265
|
+
clearOne: (id) => {
|
|
266
|
+
void clearOneInAppNotification(channel, id).then(() => {
|
|
267
|
+
if (!disposed) notifications.value = channel.getHistory();
|
|
268
|
+
});
|
|
269
|
+
},
|
|
270
|
+
markAsRead: (id) => {
|
|
271
|
+
channel.markAsRead(id);
|
|
272
|
+
notifications.value = notifications.value.map(
|
|
273
|
+
(item) => item.id === id ? { ...item, read: true } : item
|
|
274
|
+
);
|
|
275
|
+
},
|
|
276
|
+
markAllAsRead: () => {
|
|
277
|
+
channel.markAllAsRead();
|
|
278
|
+
notifications.value = notifications.value.map((item) => ({
|
|
279
|
+
...item,
|
|
280
|
+
read: true
|
|
281
|
+
}));
|
|
282
|
+
},
|
|
283
|
+
updateSettings,
|
|
284
|
+
setChannels: (channels) => updateSettings(channelsUpdate(channels)),
|
|
285
|
+
muteChain: (chainId) => updateSettings(mutedChainSettings(settings.value, chainId, true)),
|
|
286
|
+
unmuteChain: (chainId) => updateSettings(mutedChainSettings(settings.value, chainId, false))
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/useSimulateTransfer.ts
|
|
291
|
+
import { resolveSimulationEndpoint } from "@naculus/connect-appkit-core";
|
|
292
|
+
import {
|
|
293
|
+
SimulationManager
|
|
294
|
+
} from "@naculus/connect-core";
|
|
295
|
+
import { onScopeDispose as onScopeDispose2, shallowRef as shallowRef2, unref as unref2 } from "vue";
|
|
296
|
+
function useSimulateTransfer(options = {}) {
|
|
297
|
+
const result = shallowRef2(null);
|
|
298
|
+
const loading = shallowRef2(false);
|
|
299
|
+
const error = shallowRef2(null);
|
|
300
|
+
let manager;
|
|
301
|
+
let generation = 0;
|
|
302
|
+
let disposed = false;
|
|
303
|
+
const simulate = async (tokenAddress, from, to, amount, callOptions) => {
|
|
304
|
+
const own = ++generation;
|
|
305
|
+
loading.value = true;
|
|
306
|
+
error.value = null;
|
|
307
|
+
try {
|
|
308
|
+
const fallbackRpcUrl = unref2(options.rpcUrl);
|
|
309
|
+
const endpoint = resolveSimulationEndpoint(
|
|
310
|
+
callOptions?.chainId,
|
|
311
|
+
unref2(options.chainId),
|
|
312
|
+
callOptions?.rpcUrl,
|
|
313
|
+
fallbackRpcUrl
|
|
314
|
+
);
|
|
315
|
+
manager ??= new SimulationManager({
|
|
316
|
+
enabled: true,
|
|
317
|
+
rpcUrl: fallbackRpcUrl,
|
|
318
|
+
autoSimulate: false
|
|
319
|
+
});
|
|
320
|
+
const value = await manager.simulateERC20Transfer(
|
|
321
|
+
tokenAddress,
|
|
322
|
+
from,
|
|
323
|
+
to,
|
|
324
|
+
amount,
|
|
325
|
+
endpoint.chainId,
|
|
326
|
+
callOptions?.decimals,
|
|
327
|
+
endpoint.rpcUrl
|
|
328
|
+
);
|
|
329
|
+
if (!disposed && own === generation) result.value = value;
|
|
330
|
+
return value;
|
|
331
|
+
} catch (cause) {
|
|
332
|
+
const normalized = cause instanceof Error ? cause : new Error(String(cause));
|
|
333
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
334
|
+
throw normalized;
|
|
335
|
+
} finally {
|
|
336
|
+
if (!disposed && own === generation) loading.value = false;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
const reset = () => {
|
|
340
|
+
generation++;
|
|
341
|
+
result.value = null;
|
|
342
|
+
error.value = null;
|
|
343
|
+
loading.value = false;
|
|
344
|
+
};
|
|
345
|
+
onScopeDispose2(() => {
|
|
346
|
+
disposed = true;
|
|
347
|
+
generation++;
|
|
348
|
+
});
|
|
349
|
+
return { result, loading, error, simulate, reset };
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// src/useTransactionSimulation.ts
|
|
353
|
+
import {
|
|
354
|
+
simulateTransactionPreview
|
|
355
|
+
} from "@naculus/connect-appkit-core";
|
|
356
|
+
import { onScopeDispose as onScopeDispose3, shallowRef as shallowRef3, toValue as toValue2, unref as unref3, watch } from "vue";
|
|
357
|
+
function useTransactionSimulation(tx, options = {}) {
|
|
358
|
+
const result = shallowRef3(void 0);
|
|
359
|
+
const isSimulating = shallowRef3(false);
|
|
360
|
+
const error = shallowRef3(null);
|
|
361
|
+
let timer;
|
|
362
|
+
let generation = 0;
|
|
363
|
+
let disposed = false;
|
|
364
|
+
const simulate = async () => {
|
|
365
|
+
const own = ++generation;
|
|
366
|
+
const transaction = toValue2(tx);
|
|
367
|
+
if (transaction) {
|
|
368
|
+
isSimulating.value = true;
|
|
369
|
+
error.value = null;
|
|
370
|
+
}
|
|
371
|
+
try {
|
|
372
|
+
const value = await simulateTransactionPreview(transaction, {
|
|
373
|
+
chainId: unref3(options.chainId),
|
|
374
|
+
currentChain: unref3(options.currentChain),
|
|
375
|
+
publicClient: unref3(options.publicClient),
|
|
376
|
+
evmAccount: unref3(options.evmAccount)
|
|
377
|
+
});
|
|
378
|
+
if (!disposed && own === generation) result.value = value;
|
|
379
|
+
return value;
|
|
380
|
+
} catch (cause) {
|
|
381
|
+
const normalized = cause instanceof Error ? cause : new Error("Simulation failed");
|
|
382
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
383
|
+
throw normalized;
|
|
384
|
+
} finally {
|
|
385
|
+
if (transaction && !disposed && own === generation)
|
|
386
|
+
isSimulating.value = false;
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
watch(
|
|
390
|
+
[
|
|
391
|
+
() => toValue2(tx),
|
|
392
|
+
() => unref3(options.chainId),
|
|
393
|
+
() => unref3(options.currentChain),
|
|
394
|
+
() => unref3(options.publicClient),
|
|
395
|
+
() => unref3(options.evmAccount)
|
|
396
|
+
],
|
|
397
|
+
([transaction]) => {
|
|
398
|
+
generation++;
|
|
399
|
+
if (timer) clearTimeout(timer);
|
|
400
|
+
if (!transaction) return;
|
|
401
|
+
timer = setTimeout(() => {
|
|
402
|
+
timer = void 0;
|
|
403
|
+
void simulate().catch(() => {
|
|
404
|
+
});
|
|
405
|
+
}, 300);
|
|
406
|
+
},
|
|
407
|
+
{ immediate: true }
|
|
408
|
+
);
|
|
409
|
+
const reset = () => {
|
|
410
|
+
generation++;
|
|
411
|
+
result.value = void 0;
|
|
412
|
+
error.value = null;
|
|
413
|
+
isSimulating.value = false;
|
|
414
|
+
};
|
|
415
|
+
onScopeDispose3(() => {
|
|
416
|
+
disposed = true;
|
|
417
|
+
generation++;
|
|
418
|
+
if (timer) clearTimeout(timer);
|
|
419
|
+
});
|
|
420
|
+
return { result, isSimulating, error, simulate, reset };
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// src/useERC20Transfer.ts
|
|
424
|
+
import {
|
|
425
|
+
createDecimalsCache,
|
|
426
|
+
encodeErc20Transfer,
|
|
427
|
+
readDecimals,
|
|
428
|
+
writeDecimals
|
|
429
|
+
} from "@naculus/connect-appkit-core";
|
|
430
|
+
import {
|
|
431
|
+
ERC20_MIN_ABI,
|
|
432
|
+
parseUnits,
|
|
433
|
+
WalletError as WalletError2
|
|
434
|
+
} from "@naculus/connect-core";
|
|
435
|
+
import { onScopeDispose as onScopeDispose4, shallowRef as shallowRef4, toValue as toValue3, unref as unref4, watch as watch2 } from "vue";
|
|
436
|
+
|
|
437
|
+
// src/erc20.ts
|
|
438
|
+
import {
|
|
439
|
+
bareEvmAddress,
|
|
440
|
+
tokenChainMismatch
|
|
441
|
+
} from "@naculus/connect-appkit-core";
|
|
442
|
+
import { WalletError } from "@naculus/connect-core";
|
|
443
|
+
function assertErc20Context(token, chainId, account, connected) {
|
|
444
|
+
if (!connected || !account) {
|
|
445
|
+
throw new WalletError("wallet_unavailable", "No connected account");
|
|
446
|
+
}
|
|
447
|
+
const mismatch = tokenChainMismatch(token, chainId);
|
|
448
|
+
if (mismatch) throw mismatch;
|
|
449
|
+
const bare = bareEvmAddress(account);
|
|
450
|
+
if (!bare) {
|
|
451
|
+
throw new WalletError("wallet_unavailable", "No valid EVM account");
|
|
452
|
+
}
|
|
453
|
+
return bare;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// src/useERC20Transfer.ts
|
|
457
|
+
function useERC20Transfer(options) {
|
|
458
|
+
const initialToken = toValue3(options.token);
|
|
459
|
+
const decimals = createDecimalsCache(initialToken, initialToken.decimals);
|
|
460
|
+
const isSending = shallowRef4(false);
|
|
461
|
+
const error = shallowRef4(null);
|
|
462
|
+
let generation = 0;
|
|
463
|
+
let disposed = false;
|
|
464
|
+
watch2(
|
|
465
|
+
[
|
|
466
|
+
() => toValue3(options.token).address,
|
|
467
|
+
() => toValue3(options.token).chainId,
|
|
468
|
+
() => toValue3(options.token).decimals,
|
|
469
|
+
() => toValue3(options.account),
|
|
470
|
+
() => toValue3(options.chainId),
|
|
471
|
+
() => toValue3(options.connected),
|
|
472
|
+
() => toValue3(options.publicClient),
|
|
473
|
+
() => unref4(options.sendTransaction)
|
|
474
|
+
],
|
|
475
|
+
() => {
|
|
476
|
+
generation++;
|
|
477
|
+
isSending.value = false;
|
|
478
|
+
error.value = null;
|
|
479
|
+
},
|
|
480
|
+
{ flush: "sync" }
|
|
481
|
+
);
|
|
482
|
+
const sendTransfer = async (to, amount) => {
|
|
483
|
+
const own = ++generation;
|
|
484
|
+
const token = toValue3(options.token);
|
|
485
|
+
const reader = toValue3(options.publicClient);
|
|
486
|
+
const stillCurrent = () => !disposed && own === generation;
|
|
487
|
+
error.value = null;
|
|
488
|
+
isSending.value = true;
|
|
489
|
+
try {
|
|
490
|
+
assertErc20Context(
|
|
491
|
+
token,
|
|
492
|
+
toValue3(options.chainId),
|
|
493
|
+
toValue3(options.account),
|
|
494
|
+
toValue3(options.connected)
|
|
495
|
+
);
|
|
496
|
+
if (!reader) {
|
|
497
|
+
throw new WalletError2(
|
|
498
|
+
"wallet_unavailable",
|
|
499
|
+
"No public client available"
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
let precision = readDecimals(decimals, token, token.decimals);
|
|
503
|
+
if (precision === void 0) {
|
|
504
|
+
precision = Number(
|
|
505
|
+
await reader.readContract({
|
|
506
|
+
address: token.address,
|
|
507
|
+
abi: ERC20_MIN_ABI,
|
|
508
|
+
functionName: "decimals"
|
|
509
|
+
})
|
|
510
|
+
);
|
|
511
|
+
if (!stillCurrent()) {
|
|
512
|
+
throw new WalletError2(
|
|
513
|
+
"session_inactive",
|
|
514
|
+
"Wallet or token context changed. Retry the transfer."
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
writeDecimals(decimals, token, precision);
|
|
518
|
+
}
|
|
519
|
+
const data = encodeErc20Transfer(to, parseUnits(amount, precision));
|
|
520
|
+
return await unref4(options.sendTransaction)({
|
|
521
|
+
to: token.address,
|
|
522
|
+
data,
|
|
523
|
+
value: "0"
|
|
524
|
+
});
|
|
525
|
+
} catch (cause) {
|
|
526
|
+
const normalized = cause instanceof Error ? cause : new Error("Transfer failed");
|
|
527
|
+
if (stillCurrent()) error.value = normalized;
|
|
528
|
+
throw normalized;
|
|
529
|
+
} finally {
|
|
530
|
+
if (stillCurrent()) isSending.value = false;
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
onScopeDispose4(() => {
|
|
534
|
+
disposed = true;
|
|
535
|
+
generation++;
|
|
536
|
+
});
|
|
537
|
+
return { sendTransfer, isSending, error };
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// src/useERC20Approve.ts
|
|
541
|
+
import {
|
|
542
|
+
createDecimalsCache as createDecimalsCache2,
|
|
543
|
+
encodeErc20Approve,
|
|
544
|
+
readDecimals as readDecimals2,
|
|
545
|
+
writeDecimals as writeDecimals2
|
|
546
|
+
} from "@naculus/connect-appkit-core";
|
|
547
|
+
import {
|
|
548
|
+
ERC20_MIN_ABI as ERC20_MIN_ABI2,
|
|
549
|
+
formatUnits,
|
|
550
|
+
parseUnits as parseUnits2,
|
|
551
|
+
WalletError as WalletError3
|
|
552
|
+
} from "@naculus/connect-core";
|
|
553
|
+
import {
|
|
554
|
+
computed as computed3,
|
|
555
|
+
onScopeDispose as onScopeDispose5,
|
|
556
|
+
shallowRef as shallowRef5,
|
|
557
|
+
toValue as toValue4,
|
|
558
|
+
unref as unref5,
|
|
559
|
+
watch as watch3
|
|
560
|
+
} from "vue";
|
|
561
|
+
var MAX_UINT256 = (1n << 256n) - 1n;
|
|
562
|
+
function useERC20Approve(options) {
|
|
563
|
+
const initialToken = toValue4(options.token);
|
|
564
|
+
const decimals = createDecimalsCache2(initialToken, initialToken.decimals);
|
|
565
|
+
const allowanceRaw = shallowRef5(null);
|
|
566
|
+
const isApproving = shallowRef5(false);
|
|
567
|
+
const isFetchingAllowance = shallowRef5(false);
|
|
568
|
+
const error = shallowRef5(null);
|
|
569
|
+
let generation = 0;
|
|
570
|
+
let allowanceGeneration = 0;
|
|
571
|
+
let disposed = false;
|
|
572
|
+
watch3(
|
|
573
|
+
[
|
|
574
|
+
() => toValue4(options.token).address,
|
|
575
|
+
() => toValue4(options.token).chainId,
|
|
576
|
+
() => toValue4(options.token).decimals,
|
|
577
|
+
() => toValue4(options.spender),
|
|
578
|
+
() => toValue4(options.account),
|
|
579
|
+
() => toValue4(options.chainId),
|
|
580
|
+
() => toValue4(options.connected),
|
|
581
|
+
() => toValue4(options.publicClient),
|
|
582
|
+
() => unref5(options.sendTransaction)
|
|
583
|
+
],
|
|
584
|
+
() => {
|
|
585
|
+
generation++;
|
|
586
|
+
allowanceGeneration++;
|
|
587
|
+
allowanceRaw.value = null;
|
|
588
|
+
isApproving.value = false;
|
|
589
|
+
isFetchingAllowance.value = false;
|
|
590
|
+
error.value = null;
|
|
591
|
+
},
|
|
592
|
+
{ flush: "sync" }
|
|
593
|
+
);
|
|
594
|
+
const context = () => {
|
|
595
|
+
const token = toValue4(options.token);
|
|
596
|
+
const account = assertErc20Context(
|
|
597
|
+
token,
|
|
598
|
+
toValue4(options.chainId),
|
|
599
|
+
toValue4(options.account),
|
|
600
|
+
toValue4(options.connected)
|
|
601
|
+
);
|
|
602
|
+
const reader = toValue4(options.publicClient);
|
|
603
|
+
if (!reader)
|
|
604
|
+
throw new WalletError3("wallet_unavailable", "No public client");
|
|
605
|
+
return { token, account, reader, spender: toValue4(options.spender) };
|
|
606
|
+
};
|
|
607
|
+
const readPrecision = async () => {
|
|
608
|
+
const { token, reader } = context();
|
|
609
|
+
let precision = readDecimals2(decimals, token, token.decimals);
|
|
610
|
+
if (precision === void 0) {
|
|
611
|
+
precision = Number(
|
|
612
|
+
await reader.readContract({
|
|
613
|
+
address: token.address,
|
|
614
|
+
abi: ERC20_MIN_ABI2,
|
|
615
|
+
functionName: "decimals"
|
|
616
|
+
})
|
|
617
|
+
);
|
|
618
|
+
writeDecimals2(decimals, token, precision);
|
|
619
|
+
}
|
|
620
|
+
return precision;
|
|
621
|
+
};
|
|
622
|
+
const refetchAllowance = async () => {
|
|
623
|
+
const own = ++allowanceGeneration;
|
|
624
|
+
allowanceRaw.value = null;
|
|
625
|
+
error.value = null;
|
|
626
|
+
isFetchingAllowance.value = true;
|
|
627
|
+
try {
|
|
628
|
+
const { token, account, reader, spender } = context();
|
|
629
|
+
const raw = BigInt(
|
|
630
|
+
await reader.readContract({
|
|
631
|
+
address: token.address,
|
|
632
|
+
abi: ERC20_MIN_ABI2,
|
|
633
|
+
functionName: "allowance",
|
|
634
|
+
args: [account, spender]
|
|
635
|
+
})
|
|
636
|
+
);
|
|
637
|
+
if (disposed || own !== allowanceGeneration) return null;
|
|
638
|
+
allowanceRaw.value = raw;
|
|
639
|
+
return raw;
|
|
640
|
+
} catch (cause) {
|
|
641
|
+
if (!disposed && own === allowanceGeneration) {
|
|
642
|
+
error.value = cause instanceof Error ? cause : new Error("Failed to fetch allowance");
|
|
643
|
+
}
|
|
644
|
+
return null;
|
|
645
|
+
} finally {
|
|
646
|
+
if (!disposed && own === allowanceGeneration)
|
|
647
|
+
isFetchingAllowance.value = false;
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
const doApprove = async (rawAmount) => {
|
|
651
|
+
const own = ++generation;
|
|
652
|
+
error.value = null;
|
|
653
|
+
isApproving.value = true;
|
|
654
|
+
try {
|
|
655
|
+
const { token, spender } = context();
|
|
656
|
+
const hash = await unref5(options.sendTransaction)({
|
|
657
|
+
to: token.address,
|
|
658
|
+
data: encodeErc20Approve(spender, rawAmount),
|
|
659
|
+
value: "0"
|
|
660
|
+
});
|
|
661
|
+
if (!disposed && own === generation) void refetchAllowance();
|
|
662
|
+
return hash;
|
|
663
|
+
} catch (cause) {
|
|
664
|
+
const normalized = cause instanceof Error ? cause : new Error("Approve failed");
|
|
665
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
666
|
+
throw normalized;
|
|
667
|
+
} finally {
|
|
668
|
+
if (!disposed && own === generation) isApproving.value = false;
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
const approve = async (amount) => {
|
|
672
|
+
const contextGeneration = generation;
|
|
673
|
+
let rawAmount;
|
|
674
|
+
try {
|
|
675
|
+
const precision = await readPrecision();
|
|
676
|
+
if (contextGeneration !== generation || disposed) {
|
|
677
|
+
throw new WalletError3(
|
|
678
|
+
"session_inactive",
|
|
679
|
+
"Wallet or token context changed. Retry the approval."
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
rawAmount = parseUnits2(amount, precision);
|
|
683
|
+
} catch (cause) {
|
|
684
|
+
const normalized = cause instanceof Error ? cause : new Error("Approve failed");
|
|
685
|
+
if (!disposed && contextGeneration === generation)
|
|
686
|
+
error.value = normalized;
|
|
687
|
+
throw normalized;
|
|
688
|
+
}
|
|
689
|
+
return doApprove(rawAmount);
|
|
690
|
+
};
|
|
691
|
+
const approveMax = () => doApprove(MAX_UINT256);
|
|
692
|
+
const hasAllowance = async (required) => {
|
|
693
|
+
const raw = allowanceRaw.value ?? await refetchAllowance();
|
|
694
|
+
if (raw === null) return false;
|
|
695
|
+
return raw >= parseUnits2(required, await readPrecision());
|
|
696
|
+
};
|
|
697
|
+
const allowance = computed3(() => {
|
|
698
|
+
if (allowanceRaw.value === null) return null;
|
|
699
|
+
const token = toValue4(options.token);
|
|
700
|
+
const precision = readDecimals2(decimals, token, token.decimals);
|
|
701
|
+
return precision === void 0 ? null : formatUnits(allowanceRaw.value, precision);
|
|
702
|
+
});
|
|
703
|
+
onScopeDispose5(() => {
|
|
704
|
+
disposed = true;
|
|
705
|
+
generation++;
|
|
706
|
+
allowanceGeneration++;
|
|
707
|
+
});
|
|
708
|
+
return {
|
|
709
|
+
approve,
|
|
710
|
+
approveMax,
|
|
711
|
+
allowanceRaw,
|
|
712
|
+
allowance,
|
|
713
|
+
hasAllowance,
|
|
714
|
+
isApproving,
|
|
715
|
+
isFetchingAllowance,
|
|
716
|
+
error,
|
|
717
|
+
refetchAllowance
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// src/useERC20TransferSimulation.ts
|
|
722
|
+
import { chainNumber, encodeErc20Transfer as encodeErc20Transfer2 } from "@naculus/connect-appkit-core";
|
|
723
|
+
import { parseUnits as parseUnits3 } from "@naculus/connect-core";
|
|
724
|
+
import { computed as computed4, toValue as toValue5 } from "vue";
|
|
725
|
+
function useERC20TransferSimulation(options) {
|
|
726
|
+
const transaction = computed4(() => {
|
|
727
|
+
const token = toValue5(options.token);
|
|
728
|
+
if (!toValue5(options.connected) || !toValue5(options.evmAccount))
|
|
729
|
+
return void 0;
|
|
730
|
+
try {
|
|
731
|
+
if (token.decimals === void 0) return void 0;
|
|
732
|
+
return {
|
|
733
|
+
to: token.address,
|
|
734
|
+
data: encodeErc20Transfer2(
|
|
735
|
+
toValue5(options.to),
|
|
736
|
+
parseUnits3(toValue5(options.amount), token.decimals)
|
|
737
|
+
),
|
|
738
|
+
value: "0"
|
|
739
|
+
};
|
|
740
|
+
} catch {
|
|
741
|
+
return void 0;
|
|
742
|
+
}
|
|
743
|
+
});
|
|
744
|
+
const chainId = computed4(() => {
|
|
745
|
+
const token = toValue5(options.token);
|
|
746
|
+
if (token.chainId !== void 0) return token.chainId;
|
|
747
|
+
const currentChain = toValue5(options.currentChain);
|
|
748
|
+
return currentChain ? chainNumber(currentChain) ?? void 0 : void 0;
|
|
749
|
+
});
|
|
750
|
+
const simulation = useTransactionSimulation(transaction, {
|
|
751
|
+
chainId,
|
|
752
|
+
currentChain: options.currentChain,
|
|
753
|
+
publicClient: options.publicClient,
|
|
754
|
+
evmAccount: options.evmAccount
|
|
755
|
+
});
|
|
756
|
+
return {
|
|
757
|
+
result: computed4(
|
|
758
|
+
() => transaction.value ? simulation.result.value : void 0
|
|
759
|
+
),
|
|
760
|
+
isSimulating: computed4(
|
|
761
|
+
() => !!transaction.value && simulation.isSimulating.value
|
|
762
|
+
),
|
|
763
|
+
error: computed4(() => transaction.value ? simulation.error.value : null),
|
|
764
|
+
reSimulate: simulation.simulate,
|
|
765
|
+
reset: simulation.reset
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// src/useAccount.ts
|
|
770
|
+
import { computed as computed5, toValue as toValue6 } from "vue";
|
|
771
|
+
function useAccount(accounts, connected) {
|
|
772
|
+
const parsed = useAccounts(accounts);
|
|
773
|
+
const isConnected = computed5(() => toValue6(connected));
|
|
774
|
+
const accountList = computed5(() => toValue6(accounts) ?? []);
|
|
775
|
+
return {
|
|
776
|
+
accounts: computed5(
|
|
777
|
+
() => isConnected.value && accountList.value.length > 0 ? parsed.accounts.value : null
|
|
778
|
+
),
|
|
779
|
+
evmAccount: computed5(
|
|
780
|
+
() => isConnected.value ? parsed.evmAccount.value : null
|
|
781
|
+
),
|
|
782
|
+
primaryAccount: computed5(() => accountList.value[0] ?? null),
|
|
783
|
+
isConnected,
|
|
784
|
+
count: computed5(() => accountList.value.length)
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// src/useSession.ts
|
|
789
|
+
import { computed as computed6, shallowRef as shallowRef6, toValue as toValue7, watch as watch4 } from "vue";
|
|
790
|
+
function readSession(manager) {
|
|
791
|
+
const bundle = manager?.getActiveBundle();
|
|
792
|
+
if (!bundle) {
|
|
793
|
+
return {
|
|
794
|
+
session: null,
|
|
795
|
+
chainSessions: [],
|
|
796
|
+
activeChainId: null,
|
|
797
|
+
connectorId: null
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
return {
|
|
801
|
+
session: bundle.walletSession,
|
|
802
|
+
chainSessions: Array.from(bundle.chainSessions.values()),
|
|
803
|
+
activeChainId: bundle.activeChainId,
|
|
804
|
+
connectorId: bundle.walletSession.walletType
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
function useSession(manager) {
|
|
808
|
+
const snapshot = shallowRef6(readSession(toValue7(manager)));
|
|
809
|
+
watch4(
|
|
810
|
+
() => toValue7(manager),
|
|
811
|
+
(current, _previous, onCleanup) => {
|
|
812
|
+
const update = () => {
|
|
813
|
+
snapshot.value = readSession(current);
|
|
814
|
+
};
|
|
815
|
+
update();
|
|
816
|
+
if (!current) return;
|
|
817
|
+
current.on("sessionConnected", update);
|
|
818
|
+
current.on("sessionDisconnected", update);
|
|
819
|
+
current.on("chainChanged", update);
|
|
820
|
+
onCleanup(() => {
|
|
821
|
+
current.off("sessionConnected", update);
|
|
822
|
+
current.off("sessionDisconnected", update);
|
|
823
|
+
current.off("chainChanged", update);
|
|
824
|
+
});
|
|
825
|
+
},
|
|
826
|
+
{ immediate: true }
|
|
827
|
+
);
|
|
828
|
+
return {
|
|
829
|
+
session: computed6(() => snapshot.value.session),
|
|
830
|
+
chainSessions: computed6(() => snapshot.value.chainSessions),
|
|
831
|
+
activeChainId: computed6(() => snapshot.value.activeChainId),
|
|
832
|
+
isConnected: computed6(() => snapshot.value.session !== null),
|
|
833
|
+
connectorId: computed6(() => snapshot.value.connectorId)
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// src/useConnect.ts
|
|
838
|
+
import { WalletError as WalletError4 } from "@naculus/connect-core";
|
|
839
|
+
import { computed as computed7, onScopeDispose as onScopeDispose6, shallowRef as shallowRef7, toValue as toValue8, unref as unref6 } from "vue";
|
|
840
|
+
function useConnect(action, status) {
|
|
841
|
+
const isLoading = shallowRef7(false);
|
|
842
|
+
const error = shallowRef7(null);
|
|
843
|
+
let disposed = false;
|
|
844
|
+
let inFlight = null;
|
|
845
|
+
const connect = () => {
|
|
846
|
+
if (inFlight) return inFlight;
|
|
847
|
+
const invoke = unref6(action);
|
|
848
|
+
isLoading.value = true;
|
|
849
|
+
error.value = null;
|
|
850
|
+
const pending = Promise.resolve().then(() => invoke()).catch((cause) => {
|
|
851
|
+
if (disposed) return;
|
|
852
|
+
const message = cause instanceof Error ? cause.message : "Connection failed";
|
|
853
|
+
error.value = cause instanceof WalletError4 ? cause : new Error(message);
|
|
854
|
+
}).finally(() => {
|
|
855
|
+
if (inFlight === pending) inFlight = null;
|
|
856
|
+
if (!disposed) isLoading.value = false;
|
|
857
|
+
});
|
|
858
|
+
inFlight = pending;
|
|
859
|
+
return pending;
|
|
860
|
+
};
|
|
861
|
+
onScopeDispose6(() => {
|
|
862
|
+
disposed = true;
|
|
863
|
+
});
|
|
864
|
+
return {
|
|
865
|
+
connect,
|
|
866
|
+
isConnecting: computed7(
|
|
867
|
+
() => isLoading.value || toValue8(status) === "connecting"
|
|
868
|
+
),
|
|
869
|
+
error
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// src/useDisconnect.ts
|
|
874
|
+
import { onScopeDispose as onScopeDispose7, shallowRef as shallowRef8, toValue as toValue9, unref as unref7 } from "vue";
|
|
875
|
+
function useDisconnect(action, status) {
|
|
876
|
+
const isDisconnecting = shallowRef8(false);
|
|
877
|
+
const error = shallowRef8(null);
|
|
878
|
+
let disposed = false;
|
|
879
|
+
let inFlight = null;
|
|
880
|
+
const disconnect = () => {
|
|
881
|
+
if (inFlight) return inFlight;
|
|
882
|
+
if (toValue9(status) === "disconnected") return Promise.resolve();
|
|
883
|
+
const invoke = unref7(action);
|
|
884
|
+
isDisconnecting.value = true;
|
|
885
|
+
error.value = null;
|
|
886
|
+
const pending = Promise.resolve().then(() => invoke()).catch((cause) => {
|
|
887
|
+
if (!disposed) {
|
|
888
|
+
error.value = cause instanceof Error ? cause : new Error("Disconnect failed");
|
|
889
|
+
}
|
|
890
|
+
}).finally(() => {
|
|
891
|
+
if (inFlight === pending) inFlight = null;
|
|
892
|
+
if (!disposed) isDisconnecting.value = false;
|
|
893
|
+
});
|
|
894
|
+
inFlight = pending;
|
|
895
|
+
return pending;
|
|
896
|
+
};
|
|
897
|
+
const cleanup = () => {
|
|
898
|
+
disposed = true;
|
|
899
|
+
};
|
|
900
|
+
onScopeDispose7(cleanup);
|
|
901
|
+
return { disconnect, isDisconnecting, error, cleanup };
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// src/useSwitchChain.ts
|
|
905
|
+
import { toChainSwitchError } from "@naculus/connect-appkit-core";
|
|
906
|
+
import { computed as computed8, onScopeDispose as onScopeDispose8, shallowRef as shallowRef9, toValue as toValue10, unref as unref8 } from "vue";
|
|
907
|
+
function useSwitchChain(action, chainId) {
|
|
908
|
+
const isSwitching = shallowRef9(false);
|
|
909
|
+
const error = shallowRef9(null);
|
|
910
|
+
let generation = 0;
|
|
911
|
+
let active = 0;
|
|
912
|
+
let disposed = false;
|
|
913
|
+
const switchChain = async (targetChainId) => {
|
|
914
|
+
const invoke = unref8(action);
|
|
915
|
+
const mine = ++generation;
|
|
916
|
+
active++;
|
|
917
|
+
isSwitching.value = true;
|
|
918
|
+
error.value = null;
|
|
919
|
+
try {
|
|
920
|
+
await invoke(targetChainId);
|
|
921
|
+
} catch (cause) {
|
|
922
|
+
const walletError = toChainSwitchError(cause);
|
|
923
|
+
if (!disposed && mine === generation) error.value = walletError;
|
|
924
|
+
throw walletError;
|
|
925
|
+
} finally {
|
|
926
|
+
active--;
|
|
927
|
+
if (!disposed) isSwitching.value = active > 0;
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
onScopeDispose8(() => {
|
|
931
|
+
disposed = true;
|
|
932
|
+
generation++;
|
|
933
|
+
});
|
|
934
|
+
return {
|
|
935
|
+
switchChain,
|
|
936
|
+
isSwitching,
|
|
937
|
+
currentChainId: computed8(() => toValue10(chainId) ?? null),
|
|
938
|
+
error,
|
|
939
|
+
clearError: () => {
|
|
940
|
+
error.value = null;
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// src/useSignMessage.ts
|
|
946
|
+
import { onScopeDispose as onScopeDispose9, shallowRef as shallowRef10, unref as unref9 } from "vue";
|
|
947
|
+
function useSignMessage(action) {
|
|
948
|
+
const isSigning = shallowRef10(false);
|
|
949
|
+
const error = shallowRef10(null);
|
|
950
|
+
let active = 0;
|
|
951
|
+
let generation = 0;
|
|
952
|
+
let disposed = false;
|
|
953
|
+
const signMessage = async (message) => {
|
|
954
|
+
const invoke = unref9(action);
|
|
955
|
+
const own = ++generation;
|
|
956
|
+
active++;
|
|
957
|
+
isSigning.value = true;
|
|
958
|
+
error.value = null;
|
|
959
|
+
try {
|
|
960
|
+
return await invoke(message);
|
|
961
|
+
} catch (cause) {
|
|
962
|
+
const normalized = cause instanceof Error ? cause : new Error("Signing failed");
|
|
963
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
964
|
+
throw normalized;
|
|
965
|
+
} finally {
|
|
966
|
+
active--;
|
|
967
|
+
if (!disposed) isSigning.value = active > 0;
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
const reset = () => {
|
|
971
|
+
generation++;
|
|
972
|
+
error.value = null;
|
|
973
|
+
};
|
|
974
|
+
onScopeDispose9(() => {
|
|
975
|
+
disposed = true;
|
|
976
|
+
generation++;
|
|
977
|
+
});
|
|
978
|
+
return { signMessage, isSigning, error, reset };
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// src/useSendTransaction.ts
|
|
982
|
+
import { computed as computed9, onScopeDispose as onScopeDispose10, shallowRef as shallowRef11, unref as unref10 } from "vue";
|
|
983
|
+
function useSendTransaction(action) {
|
|
984
|
+
const status = shallowRef11("idle");
|
|
985
|
+
const error = shallowRef11(null);
|
|
986
|
+
let generation = 0;
|
|
987
|
+
let disposed = false;
|
|
988
|
+
const sendTransaction = async (transaction) => {
|
|
989
|
+
const invoke = unref10(action);
|
|
990
|
+
const own = ++generation;
|
|
991
|
+
status.value = "awaiting_approval";
|
|
992
|
+
error.value = null;
|
|
993
|
+
try {
|
|
994
|
+
const hash = await invoke(transaction);
|
|
995
|
+
if (!disposed && own === generation) status.value = "submitted";
|
|
996
|
+
return hash;
|
|
997
|
+
} catch (cause) {
|
|
998
|
+
const normalized = cause instanceof Error ? cause : new Error("Transaction failed");
|
|
999
|
+
if (!disposed && own === generation) {
|
|
1000
|
+
status.value = "failed";
|
|
1001
|
+
error.value = normalized;
|
|
1002
|
+
}
|
|
1003
|
+
throw normalized;
|
|
1004
|
+
}
|
|
1005
|
+
};
|
|
1006
|
+
const reset = () => {
|
|
1007
|
+
generation++;
|
|
1008
|
+
status.value = "idle";
|
|
1009
|
+
error.value = null;
|
|
1010
|
+
};
|
|
1011
|
+
onScopeDispose10(() => {
|
|
1012
|
+
disposed = true;
|
|
1013
|
+
generation++;
|
|
1014
|
+
});
|
|
1015
|
+
return {
|
|
1016
|
+
sendTransaction,
|
|
1017
|
+
status,
|
|
1018
|
+
error,
|
|
1019
|
+
reset,
|
|
1020
|
+
isSending: computed9(() => status.value === "awaiting_approval")
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
// src/useSolanaTransaction.ts
|
|
1025
|
+
import { onScopeDispose as onScopeDispose11, shallowRef as shallowRef12, unref as unref11 } from "vue";
|
|
1026
|
+
function useSolanaTransaction(options) {
|
|
1027
|
+
const isSigning = shallowRef12(false);
|
|
1028
|
+
const isSending = shallowRef12(false);
|
|
1029
|
+
const error = shallowRef12(null);
|
|
1030
|
+
let signing = 0;
|
|
1031
|
+
let sending = 0;
|
|
1032
|
+
let generation = 0;
|
|
1033
|
+
let disposed = false;
|
|
1034
|
+
const signTransaction = async (transaction) => {
|
|
1035
|
+
const invoke = unref11(options.signTransaction);
|
|
1036
|
+
const own = ++generation;
|
|
1037
|
+
signing++;
|
|
1038
|
+
isSigning.value = true;
|
|
1039
|
+
error.value = null;
|
|
1040
|
+
try {
|
|
1041
|
+
return await invoke(transaction);
|
|
1042
|
+
} catch (cause) {
|
|
1043
|
+
const normalized = cause instanceof Error ? cause : new Error("Signing failed");
|
|
1044
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
1045
|
+
throw normalized;
|
|
1046
|
+
} finally {
|
|
1047
|
+
signing--;
|
|
1048
|
+
if (!disposed) isSigning.value = signing > 0;
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
const sendTransaction = async (transaction) => {
|
|
1052
|
+
const invoke = unref11(options.sendTransaction);
|
|
1053
|
+
const own = ++generation;
|
|
1054
|
+
sending++;
|
|
1055
|
+
isSending.value = true;
|
|
1056
|
+
error.value = null;
|
|
1057
|
+
try {
|
|
1058
|
+
return await invoke(transaction);
|
|
1059
|
+
} catch (cause) {
|
|
1060
|
+
const normalized = cause instanceof Error ? cause : new Error("Send failed");
|
|
1061
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
1062
|
+
throw normalized;
|
|
1063
|
+
} finally {
|
|
1064
|
+
sending--;
|
|
1065
|
+
if (!disposed) isSending.value = sending > 0;
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
const getStatus = (signature) => unref11(options.getStatus)(signature);
|
|
1069
|
+
const reset = () => {
|
|
1070
|
+
generation++;
|
|
1071
|
+
error.value = null;
|
|
1072
|
+
};
|
|
1073
|
+
onScopeDispose11(() => {
|
|
1074
|
+
disposed = true;
|
|
1075
|
+
generation++;
|
|
1076
|
+
});
|
|
1077
|
+
return {
|
|
1078
|
+
signTransaction,
|
|
1079
|
+
sendTransaction,
|
|
1080
|
+
getStatus,
|
|
1081
|
+
isSigning,
|
|
1082
|
+
isSending,
|
|
1083
|
+
error,
|
|
1084
|
+
reset
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// src/useSignInWithX.ts
|
|
1089
|
+
import { onScopeDispose as onScopeDispose12, shallowRef as shallowRef13, unref as unref12 } from "vue";
|
|
1090
|
+
function useSignInWithX(action) {
|
|
1091
|
+
const isSigningIn = shallowRef13(false);
|
|
1092
|
+
const result = shallowRef13(null);
|
|
1093
|
+
const error = shallowRef13(null);
|
|
1094
|
+
let generation = 0;
|
|
1095
|
+
let active = 0;
|
|
1096
|
+
let disposed = false;
|
|
1097
|
+
const signIn = async (options) => {
|
|
1098
|
+
const invoke = unref12(action);
|
|
1099
|
+
const own = ++generation;
|
|
1100
|
+
active++;
|
|
1101
|
+
isSigningIn.value = true;
|
|
1102
|
+
error.value = null;
|
|
1103
|
+
try {
|
|
1104
|
+
const next = await invoke(options);
|
|
1105
|
+
if (!disposed && own === generation) result.value = next;
|
|
1106
|
+
return next;
|
|
1107
|
+
} catch (cause) {
|
|
1108
|
+
const normalized = cause instanceof Error ? cause : new Error("SIWX sign-in failed");
|
|
1109
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
1110
|
+
throw normalized;
|
|
1111
|
+
} finally {
|
|
1112
|
+
active--;
|
|
1113
|
+
if (!disposed) isSigningIn.value = active > 0;
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
const clearError = () => {
|
|
1117
|
+
error.value = null;
|
|
1118
|
+
};
|
|
1119
|
+
const reset = () => {
|
|
1120
|
+
generation++;
|
|
1121
|
+
result.value = null;
|
|
1122
|
+
error.value = null;
|
|
1123
|
+
};
|
|
1124
|
+
onScopeDispose12(() => {
|
|
1125
|
+
disposed = true;
|
|
1126
|
+
generation++;
|
|
1127
|
+
});
|
|
1128
|
+
return { signIn, isSigningIn, result, error, clearError, reset };
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
// src/useSignInWithEthereum.ts
|
|
1132
|
+
function useSignInWithEthereum(action) {
|
|
1133
|
+
return useSignInWithX(action);
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
// src/useExecuteCalls.ts
|
|
1137
|
+
import { computed as computed10, onScopeDispose as onScopeDispose13, shallowRef as shallowRef14, toValue as toValue11, unref as unref13 } from "vue";
|
|
1138
|
+
function useExecuteCalls(options) {
|
|
1139
|
+
const isExecuting = shallowRef14(false);
|
|
1140
|
+
const error = shallowRef14(null);
|
|
1141
|
+
let generation = 0;
|
|
1142
|
+
let active = 0;
|
|
1143
|
+
let disposed = false;
|
|
1144
|
+
const preview = (callCount, atomicity) => unref13(options.preview)(callCount, atomicity);
|
|
1145
|
+
const execute = async (calls, atomicity) => {
|
|
1146
|
+
const invoke = unref13(options.execute);
|
|
1147
|
+
const own = ++generation;
|
|
1148
|
+
active++;
|
|
1149
|
+
isExecuting.value = true;
|
|
1150
|
+
error.value = null;
|
|
1151
|
+
try {
|
|
1152
|
+
return await invoke(calls, atomicity);
|
|
1153
|
+
} catch (cause) {
|
|
1154
|
+
const normalized = cause instanceof Error ? cause : new Error("Execution failed");
|
|
1155
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
1156
|
+
throw normalized;
|
|
1157
|
+
} finally {
|
|
1158
|
+
active--;
|
|
1159
|
+
if (!disposed) isExecuting.value = active > 0;
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
const reset = () => {
|
|
1163
|
+
generation++;
|
|
1164
|
+
error.value = null;
|
|
1165
|
+
unref13(options.reset)();
|
|
1166
|
+
};
|
|
1167
|
+
onScopeDispose13(() => {
|
|
1168
|
+
disposed = true;
|
|
1169
|
+
generation++;
|
|
1170
|
+
});
|
|
1171
|
+
return {
|
|
1172
|
+
preview,
|
|
1173
|
+
execute,
|
|
1174
|
+
isExecuting,
|
|
1175
|
+
error,
|
|
1176
|
+
lastRoute: computed10(() => toValue11(options.lastRoute)),
|
|
1177
|
+
reset
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// src/useDelegationPolicy.ts
|
|
1182
|
+
import {
|
|
1183
|
+
bareEvmAddress as bareEvmAddress2,
|
|
1184
|
+
createDelegationPolicyFlow,
|
|
1185
|
+
getSharedSessionKeyManager as getSharedSessionKeyManager2,
|
|
1186
|
+
isVerifiablePolicy
|
|
1187
|
+
} from "@naculus/connect-appkit-core";
|
|
1188
|
+
import {
|
|
1189
|
+
computed as computed12,
|
|
1190
|
+
onScopeDispose as onScopeDispose16,
|
|
1191
|
+
shallowRef as shallowRef17,
|
|
1192
|
+
toValue as toValue13,
|
|
1193
|
+
unref as unref14,
|
|
1194
|
+
watch as watch6
|
|
1195
|
+
} from "vue";
|
|
1196
|
+
|
|
1197
|
+
// src/internal/action-guard.ts
|
|
1198
|
+
import { onScopeDispose as onScopeDispose14, shallowRef as shallowRef15 } from "vue";
|
|
1199
|
+
function useActionGuard() {
|
|
1200
|
+
const busy = shallowRef15(false);
|
|
1201
|
+
const error = shallowRef15(null);
|
|
1202
|
+
let active = 0;
|
|
1203
|
+
let generation = 0;
|
|
1204
|
+
let disposed = false;
|
|
1205
|
+
const run = async (action, fallbackMessage) => {
|
|
1206
|
+
const own = ++generation;
|
|
1207
|
+
active++;
|
|
1208
|
+
busy.value = true;
|
|
1209
|
+
error.value = null;
|
|
1210
|
+
try {
|
|
1211
|
+
return await action();
|
|
1212
|
+
} catch (cause) {
|
|
1213
|
+
const normalized = cause instanceof Error ? cause : new Error(fallbackMessage);
|
|
1214
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
1215
|
+
throw normalized;
|
|
1216
|
+
} finally {
|
|
1217
|
+
active--;
|
|
1218
|
+
if (!disposed) busy.value = active > 0;
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
const reset = () => {
|
|
1222
|
+
generation++;
|
|
1223
|
+
error.value = null;
|
|
1224
|
+
};
|
|
1225
|
+
onScopeDispose14(() => {
|
|
1226
|
+
disposed = true;
|
|
1227
|
+
generation++;
|
|
1228
|
+
});
|
|
1229
|
+
return { busy, error, run, reset };
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// src/useSessionKeys.ts
|
|
1233
|
+
import { getSharedSessionKeyManager } from "@naculus/connect-appkit-core";
|
|
1234
|
+
import { computed as computed11, onScopeDispose as onScopeDispose15, shallowRef as shallowRef16, toValue as toValue12, watch as watch5 } from "vue";
|
|
1235
|
+
function resolveManager(config, options) {
|
|
1236
|
+
return options.manager ?? getSharedSessionKeyManager(config);
|
|
1237
|
+
}
|
|
1238
|
+
function useSessionKeys(connected, config, options = {}) {
|
|
1239
|
+
const manager = resolveManager(config, options);
|
|
1240
|
+
const sessions = shallowRef16([]);
|
|
1241
|
+
const loading = shallowRef16(false);
|
|
1242
|
+
const error = shallowRef16(null);
|
|
1243
|
+
let generation = 0;
|
|
1244
|
+
let disposed = false;
|
|
1245
|
+
const refresh = async () => {
|
|
1246
|
+
const own = ++generation;
|
|
1247
|
+
if (!toValue12(connected)) {
|
|
1248
|
+
sessions.value = [];
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
loading.value = true;
|
|
1252
|
+
error.value = null;
|
|
1253
|
+
try {
|
|
1254
|
+
const keys = await manager.listSessions();
|
|
1255
|
+
if (!disposed && own === generation) sessions.value = keys;
|
|
1256
|
+
} catch (cause) {
|
|
1257
|
+
if (!disposed && own === generation) {
|
|
1258
|
+
error.value = cause instanceof Error ? cause : new Error("Failed to load session keys");
|
|
1259
|
+
}
|
|
1260
|
+
} finally {
|
|
1261
|
+
if (!disposed && own === generation) loading.value = false;
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
watch5(
|
|
1265
|
+
() => toValue12(connected),
|
|
1266
|
+
() => {
|
|
1267
|
+
void refresh();
|
|
1268
|
+
},
|
|
1269
|
+
{ immediate: true }
|
|
1270
|
+
);
|
|
1271
|
+
onScopeDispose15(() => {
|
|
1272
|
+
disposed = true;
|
|
1273
|
+
generation++;
|
|
1274
|
+
});
|
|
1275
|
+
return {
|
|
1276
|
+
sessions,
|
|
1277
|
+
activeSessions: computed11(
|
|
1278
|
+
() => sessions.value.filter((s) => s.status === "active")
|
|
1279
|
+
),
|
|
1280
|
+
loading,
|
|
1281
|
+
error,
|
|
1282
|
+
refresh,
|
|
1283
|
+
clearError: () => {
|
|
1284
|
+
error.value = null;
|
|
1285
|
+
},
|
|
1286
|
+
storageAvailable: manager.isStorageAvailable()
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
function useCreateSessionKey(config, options = {}) {
|
|
1290
|
+
const manager = resolveManager(config, options);
|
|
1291
|
+
const guard = useActionGuard();
|
|
1292
|
+
const lastCreated = shallowRef16(null);
|
|
1293
|
+
return {
|
|
1294
|
+
createSessionKey: (scope, signerAddress) => guard.run(async () => {
|
|
1295
|
+
const info = await manager.createSessionKey(scope, signerAddress);
|
|
1296
|
+
lastCreated.value = info;
|
|
1297
|
+
return info;
|
|
1298
|
+
}, "Failed to create session key"),
|
|
1299
|
+
lastCreated,
|
|
1300
|
+
isCreating: guard.busy,
|
|
1301
|
+
error: guard.error,
|
|
1302
|
+
clearError: guard.reset
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
function useRevokeSession(config, options = {}) {
|
|
1306
|
+
const manager = resolveManager(config, options);
|
|
1307
|
+
const guard = useActionGuard();
|
|
1308
|
+
return {
|
|
1309
|
+
revokeSession: (sessionId) => guard.run(
|
|
1310
|
+
() => manager.revokeSession(sessionId),
|
|
1311
|
+
"Failed to revoke session key"
|
|
1312
|
+
),
|
|
1313
|
+
isRevoking: guard.busy,
|
|
1314
|
+
error: guard.error,
|
|
1315
|
+
clearError: guard.reset
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
function useSendWithSession(config, options = {}) {
|
|
1319
|
+
const manager = resolveManager(config, options);
|
|
1320
|
+
const guard = useActionGuard();
|
|
1321
|
+
return {
|
|
1322
|
+
signWithSession: (sessionId, messageHash, tx) => guard.run(
|
|
1323
|
+
() => manager.signWithSessionKey(sessionId, messageHash, tx),
|
|
1324
|
+
"Failed to sign with session key"
|
|
1325
|
+
),
|
|
1326
|
+
checkScope: (sessionId, tx) => guard.run(
|
|
1327
|
+
() => manager.checkSessionScope(sessionId, tx),
|
|
1328
|
+
"Failed to check session scope"
|
|
1329
|
+
),
|
|
1330
|
+
isBusy: guard.busy,
|
|
1331
|
+
error: guard.error,
|
|
1332
|
+
clearError: guard.reset
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
// src/useDelegationPolicy.ts
|
|
1337
|
+
function useDelegationPolicy(options) {
|
|
1338
|
+
const manager = options.manager ?? getSharedSessionKeyManager2(options.managerConfig);
|
|
1339
|
+
const sessionKeys = useSessionKeys(options.connected, options.managerConfig, {
|
|
1340
|
+
manager
|
|
1341
|
+
});
|
|
1342
|
+
const guard = useActionGuard();
|
|
1343
|
+
const verifiedIds = shallowRef17(/* @__PURE__ */ new Set());
|
|
1344
|
+
const isVerifying = shallowRef17(false);
|
|
1345
|
+
const verifyError = shallowRef17(null);
|
|
1346
|
+
let verifyGeneration = 0;
|
|
1347
|
+
let disposed = false;
|
|
1348
|
+
const origin = options.origin ?? (typeof window !== "undefined" ? window.location.origin : "unknown");
|
|
1349
|
+
const flow = createDelegationPolicyFlow({
|
|
1350
|
+
manager,
|
|
1351
|
+
origin,
|
|
1352
|
+
signer: () => bareEvmAddress2(toValue13(options.account)),
|
|
1353
|
+
signMessage: (message) => unref14(options.signMessage)(message),
|
|
1354
|
+
verifySignature: (input) => unref14(options.verifySignature)(input),
|
|
1355
|
+
previewExecution: (callCount, atomicity) => unref14(options.previewExecution)(callCount, atomicity),
|
|
1356
|
+
sponsorship: options.sponsorship,
|
|
1357
|
+
adapter: options.adapter,
|
|
1358
|
+
delegation: () => toValue13(options.delegation),
|
|
1359
|
+
encryptionKeyConfigured: Boolean(options.managerConfig?.encryptionKey),
|
|
1360
|
+
storageAvailable: () => sessionKeys.storageAvailable,
|
|
1361
|
+
refresh: sessionKeys.refresh
|
|
1362
|
+
});
|
|
1363
|
+
watch6(
|
|
1364
|
+
() => sessionKeys.sessions.value,
|
|
1365
|
+
(sessions) => {
|
|
1366
|
+
const own = ++verifyGeneration;
|
|
1367
|
+
const candidates = sessions.filter(isVerifiablePolicy);
|
|
1368
|
+
if (candidates.length === 0) {
|
|
1369
|
+
verifiedIds.value = /* @__PURE__ */ new Set();
|
|
1370
|
+
isVerifying.value = false;
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
isVerifying.value = true;
|
|
1374
|
+
void Promise.all(
|
|
1375
|
+
candidates.map(
|
|
1376
|
+
async (policy) => [policy.id, await flow.verifyStoredPolicy(policy)]
|
|
1377
|
+
)
|
|
1378
|
+
).then((results) => {
|
|
1379
|
+
if (disposed || own !== verifyGeneration) return;
|
|
1380
|
+
verifiedIds.value = new Set(
|
|
1381
|
+
results.filter(([, ok]) => ok).map(([id]) => id)
|
|
1382
|
+
);
|
|
1383
|
+
}).catch((cause) => {
|
|
1384
|
+
if (disposed || own !== verifyGeneration) return;
|
|
1385
|
+
verifiedIds.value = /* @__PURE__ */ new Set();
|
|
1386
|
+
verifyError.value = cause instanceof Error ? cause : new Error("Policy verification failed");
|
|
1387
|
+
}).finally(() => {
|
|
1388
|
+
if (!disposed && own === verifyGeneration) isVerifying.value = false;
|
|
1389
|
+
});
|
|
1390
|
+
},
|
|
1391
|
+
{ immediate: true }
|
|
1392
|
+
);
|
|
1393
|
+
onScopeDispose16(() => {
|
|
1394
|
+
disposed = true;
|
|
1395
|
+
verifyGeneration++;
|
|
1396
|
+
});
|
|
1397
|
+
return {
|
|
1398
|
+
policies: sessionKeys.sessions,
|
|
1399
|
+
activePolicies: computed12(
|
|
1400
|
+
() => sessionKeys.activeSessions.value.filter(
|
|
1401
|
+
(p) => verifiedIds.value.has(p.id)
|
|
1402
|
+
)
|
|
1403
|
+
),
|
|
1404
|
+
storageAvailable: sessionKeys.storageAvailable,
|
|
1405
|
+
loading: computed12(() => sessionKeys.loading.value || isVerifying.value),
|
|
1406
|
+
isBusy: guard.busy,
|
|
1407
|
+
error: computed12(
|
|
1408
|
+
() => guard.error.value ?? verifyError.value ?? sessionKeys.error.value
|
|
1409
|
+
),
|
|
1410
|
+
createPolicy: (scope) => guard.run(() => flow.createPolicy(scope), "Policy creation failed"),
|
|
1411
|
+
revokePolicy: (policyId) => guard.run(() => flow.revokePolicy(policyId), "Policy revocation failed"),
|
|
1412
|
+
previewPolicyExecution: flow.previewPolicyExecution,
|
|
1413
|
+
signPolicyDigest: flow.signPolicyDigest,
|
|
1414
|
+
executePolicy: (policyId, tx) => guard.run(
|
|
1415
|
+
() => flow.executePolicy(policyId, tx),
|
|
1416
|
+
"Policy execution failed"
|
|
1417
|
+
),
|
|
1418
|
+
refresh: sessionKeys.refresh,
|
|
1419
|
+
clearError: () => {
|
|
1420
|
+
guard.reset();
|
|
1421
|
+
verifyError.value = null;
|
|
1422
|
+
sessionKeys.clearError();
|
|
1423
|
+
}
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
// src/useSmartAccount.ts
|
|
1428
|
+
import {
|
|
1429
|
+
bareEvmAddress as bareEvmAddress3,
|
|
1430
|
+
buildSmartAccountConfig,
|
|
1431
|
+
resolveEvmChainId
|
|
1432
|
+
} from "@naculus/connect-appkit-core";
|
|
1433
|
+
import { WalletError as WalletError5 } from "@naculus/connect-core";
|
|
1434
|
+
import {
|
|
1435
|
+
computed as computed13,
|
|
1436
|
+
onScopeDispose as onScopeDispose17,
|
|
1437
|
+
shallowRef as shallowRef18,
|
|
1438
|
+
toValue as toValue14,
|
|
1439
|
+
unref as unref15,
|
|
1440
|
+
watch as watch7
|
|
1441
|
+
} from "vue";
|
|
1442
|
+
function useSmartAccount(options) {
|
|
1443
|
+
const address = shallowRef18(null);
|
|
1444
|
+
const isDeployed = shallowRef18(false);
|
|
1445
|
+
const accountInfo = shallowRef18(null);
|
|
1446
|
+
const guard = useActionGuard();
|
|
1447
|
+
const managerRef = shallowRef18(null);
|
|
1448
|
+
let generation = 0;
|
|
1449
|
+
let inFlight = false;
|
|
1450
|
+
let disposed = false;
|
|
1451
|
+
const chainId = computed13(
|
|
1452
|
+
() => resolveEvmChainId(
|
|
1453
|
+
toValue14(options.chainId),
|
|
1454
|
+
toValue14(options.connectedChainId)
|
|
1455
|
+
)
|
|
1456
|
+
);
|
|
1457
|
+
watch7(
|
|
1458
|
+
[
|
|
1459
|
+
() => toValue14(options.manager),
|
|
1460
|
+
() => toValue14(options.rpcUrl),
|
|
1461
|
+
() => toValue14(options.bundlerUrl),
|
|
1462
|
+
() => chainId.value
|
|
1463
|
+
],
|
|
1464
|
+
([supplied, rpcUrl, bundlerUrl, chain]) => {
|
|
1465
|
+
const own = ++generation;
|
|
1466
|
+
managerRef.value = null;
|
|
1467
|
+
if (supplied) {
|
|
1468
|
+
managerRef.value = supplied;
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
if (!rpcUrl || !chain) return;
|
|
1472
|
+
import("@naculus/connect-core").then(({ SmartAccountManager }) => {
|
|
1473
|
+
if (disposed || own !== generation) return;
|
|
1474
|
+
managerRef.value = new SmartAccountManager({
|
|
1475
|
+
rpcUrl,
|
|
1476
|
+
chainId: chain,
|
|
1477
|
+
bundlerClient: { url: bundlerUrl ?? "" }
|
|
1478
|
+
});
|
|
1479
|
+
}).catch((cause) => {
|
|
1480
|
+
if (disposed || own !== generation) return;
|
|
1481
|
+
guard.error.value = cause instanceof Error ? cause : new Error("Failed to load account-abstraction module");
|
|
1482
|
+
});
|
|
1483
|
+
},
|
|
1484
|
+
{ immediate: true }
|
|
1485
|
+
);
|
|
1486
|
+
const config = computed13(() => {
|
|
1487
|
+
const owner = bareEvmAddress3(toValue14(options.account));
|
|
1488
|
+
const chain = chainId.value;
|
|
1489
|
+
if (!owner || !chain || !managerRef.value) return null;
|
|
1490
|
+
return buildSmartAccountConfig(owner, chain, {
|
|
1491
|
+
accountType: options.accountType,
|
|
1492
|
+
entryPoint: options.entryPoint,
|
|
1493
|
+
salt: options.salt
|
|
1494
|
+
});
|
|
1495
|
+
});
|
|
1496
|
+
const apply = (info) => {
|
|
1497
|
+
address.value = info.address;
|
|
1498
|
+
isDeployed.value = info.isDeployed;
|
|
1499
|
+
accountInfo.value = info;
|
|
1500
|
+
};
|
|
1501
|
+
const operate = async (action, fallback) => {
|
|
1502
|
+
const cfg = config.value;
|
|
1503
|
+
const manager = managerRef.value;
|
|
1504
|
+
if (!cfg || !manager) {
|
|
1505
|
+
guard.error.value = new Error("Smart account not configured");
|
|
1506
|
+
return null;
|
|
1507
|
+
}
|
|
1508
|
+
if (inFlight) {
|
|
1509
|
+
guard.error.value = new Error(
|
|
1510
|
+
"Smart account operation already in progress"
|
|
1511
|
+
);
|
|
1512
|
+
return null;
|
|
1513
|
+
}
|
|
1514
|
+
inFlight = true;
|
|
1515
|
+
const own = generation;
|
|
1516
|
+
const current = () => !disposed && own === generation;
|
|
1517
|
+
const commit = (write) => {
|
|
1518
|
+
if (current()) write();
|
|
1519
|
+
};
|
|
1520
|
+
try {
|
|
1521
|
+
return await guard.run(async () => {
|
|
1522
|
+
const result = await action(manager, cfg, commit);
|
|
1523
|
+
return current() ? result : null;
|
|
1524
|
+
}, fallback);
|
|
1525
|
+
} catch {
|
|
1526
|
+
return null;
|
|
1527
|
+
} finally {
|
|
1528
|
+
inFlight = false;
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
const createWallet = () => operate(async (manager, cfg, commit) => {
|
|
1532
|
+
const info = await manager.createAccount(cfg);
|
|
1533
|
+
commit(() => apply(info));
|
|
1534
|
+
return info;
|
|
1535
|
+
}, "Failed to create smart account");
|
|
1536
|
+
const deployWallet = () => operate(async (manager, cfg, commit) => {
|
|
1537
|
+
const send = unref15(options.sendTransaction);
|
|
1538
|
+
if (!send) {
|
|
1539
|
+
throw new WalletError5(
|
|
1540
|
+
"wallet_unavailable",
|
|
1541
|
+
"deployWallet needs the connected wallet's sendTransaction"
|
|
1542
|
+
);
|
|
1543
|
+
}
|
|
1544
|
+
const before = await manager.createAccount(cfg);
|
|
1545
|
+
if (before.isDeployed) {
|
|
1546
|
+
commit(() => apply(before));
|
|
1547
|
+
return before.address;
|
|
1548
|
+
}
|
|
1549
|
+
const deployTx = await manager.getDeployCallData(cfg);
|
|
1550
|
+
const hash = await send({
|
|
1551
|
+
to: deployTx.to,
|
|
1552
|
+
data: deployTx.data,
|
|
1553
|
+
value: deployTx.value.toString(),
|
|
1554
|
+
chainId: cfg.chainId
|
|
1555
|
+
});
|
|
1556
|
+
const after = await manager.createAccount(cfg);
|
|
1557
|
+
commit(() => apply(after));
|
|
1558
|
+
return hash;
|
|
1559
|
+
}, "Failed to deploy smart account");
|
|
1560
|
+
const getAddress = () => operate(async (manager, cfg, commit) => {
|
|
1561
|
+
const addr = await manager.getAccountAddress(cfg);
|
|
1562
|
+
commit(() => {
|
|
1563
|
+
address.value = addr;
|
|
1564
|
+
});
|
|
1565
|
+
return addr;
|
|
1566
|
+
}, "Failed to get smart account address");
|
|
1567
|
+
onScopeDispose17(() => {
|
|
1568
|
+
disposed = true;
|
|
1569
|
+
generation++;
|
|
1570
|
+
});
|
|
1571
|
+
return {
|
|
1572
|
+
address,
|
|
1573
|
+
isDeployed,
|
|
1574
|
+
accountInfo,
|
|
1575
|
+
isLoading: guard.busy,
|
|
1576
|
+
error: guard.error,
|
|
1577
|
+
config,
|
|
1578
|
+
createWallet,
|
|
1579
|
+
deployWallet,
|
|
1580
|
+
getAddress
|
|
1581
|
+
};
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
// src/useSendUserOperation.ts
|
|
1585
|
+
import {
|
|
1586
|
+
bareEvmAddress as bareEvmAddress4,
|
|
1587
|
+
buildSmartAccountConfig as buildSmartAccountConfig2,
|
|
1588
|
+
resolveUserOpChain
|
|
1589
|
+
} from "@naculus/connect-appkit-core";
|
|
1590
|
+
import { WalletError as WalletError6 } from "@naculus/connect-core";
|
|
1591
|
+
import { onScopeDispose as onScopeDispose18, shallowRef as shallowRef19, toValue as toValue15, unref as unref16 } from "vue";
|
|
1592
|
+
function useSendUserOperation(options) {
|
|
1593
|
+
const userOpHash = shallowRef19(null);
|
|
1594
|
+
const receipt = shallowRef19(null);
|
|
1595
|
+
const isPending = shallowRef19(false);
|
|
1596
|
+
const isEstimating = shallowRef19(false);
|
|
1597
|
+
const error = shallowRef19(null);
|
|
1598
|
+
let requestId = 0;
|
|
1599
|
+
let inFlight = false;
|
|
1600
|
+
let disposed = false;
|
|
1601
|
+
const fail = (cause) => {
|
|
1602
|
+
error.value = cause;
|
|
1603
|
+
return null;
|
|
1604
|
+
};
|
|
1605
|
+
const sendUserOp = async (calls, opts) => {
|
|
1606
|
+
const rpcUrl = toValue15(options.rpcUrl);
|
|
1607
|
+
const bundlerUrl = toValue15(options.bundlerUrl);
|
|
1608
|
+
if (!rpcUrl) return fail(new Error("RPC URL not configured"));
|
|
1609
|
+
if (!bundlerUrl) return fail(new Error("Bundler URL not configured"));
|
|
1610
|
+
if (!calls.length) return fail(new Error("At least one call is required"));
|
|
1611
|
+
if (inFlight) {
|
|
1612
|
+
return fail(new Error("A UserOperation is already in progress"));
|
|
1613
|
+
}
|
|
1614
|
+
const owner = bareEvmAddress4(
|
|
1615
|
+
toValue15(options.owner) ?? toValue15(options.account)
|
|
1616
|
+
);
|
|
1617
|
+
if (!owner) {
|
|
1618
|
+
return fail(
|
|
1619
|
+
new WalletError6("wallet_unavailable", "No EVM account found")
|
|
1620
|
+
);
|
|
1621
|
+
}
|
|
1622
|
+
let targetChainId;
|
|
1623
|
+
try {
|
|
1624
|
+
targetChainId = resolveUserOpChain(
|
|
1625
|
+
toValue15(options.chainId),
|
|
1626
|
+
toValue15(options.connectedChainId)
|
|
1627
|
+
);
|
|
1628
|
+
} catch (chainError) {
|
|
1629
|
+
return fail(chainError);
|
|
1630
|
+
}
|
|
1631
|
+
const signer = unref16(options.signer);
|
|
1632
|
+
const own = ++requestId;
|
|
1633
|
+
inFlight = true;
|
|
1634
|
+
isPending.value = true;
|
|
1635
|
+
isEstimating.value = true;
|
|
1636
|
+
error.value = null;
|
|
1637
|
+
userOpHash.value = null;
|
|
1638
|
+
receipt.value = null;
|
|
1639
|
+
try {
|
|
1640
|
+
const { SmartAccountManager } = await import("@naculus/connect-core");
|
|
1641
|
+
const manager = new SmartAccountManager({
|
|
1642
|
+
rpcUrl,
|
|
1643
|
+
bundlerClient: { url: bundlerUrl },
|
|
1644
|
+
chainId: targetChainId,
|
|
1645
|
+
signer,
|
|
1646
|
+
signerMode: options.signerMode ?? "eip191"
|
|
1647
|
+
});
|
|
1648
|
+
const config = buildSmartAccountConfig2(owner, targetChainId, {
|
|
1649
|
+
accountType: options.accountType,
|
|
1650
|
+
entryPoint: options.entryPoint,
|
|
1651
|
+
salt: options.salt
|
|
1652
|
+
});
|
|
1653
|
+
const response = await manager.sendUserOperation(config, calls, opts);
|
|
1654
|
+
if (disposed || own !== requestId) return null;
|
|
1655
|
+
isEstimating.value = false;
|
|
1656
|
+
userOpHash.value = response.userOpHash;
|
|
1657
|
+
void manager.getUserOperationReceipt(response.userOpHash).then((next) => {
|
|
1658
|
+
if (!disposed && own === requestId) receipt.value = next;
|
|
1659
|
+
}).catch(() => void 0);
|
|
1660
|
+
return response;
|
|
1661
|
+
} catch (cause) {
|
|
1662
|
+
if (disposed || own !== requestId) return null;
|
|
1663
|
+
return fail(
|
|
1664
|
+
cause instanceof Error ? cause : new Error("Failed to send UserOperation")
|
|
1665
|
+
);
|
|
1666
|
+
} finally {
|
|
1667
|
+
inFlight = false;
|
|
1668
|
+
if (!disposed && own === requestId) {
|
|
1669
|
+
isPending.value = false;
|
|
1670
|
+
isEstimating.value = false;
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
};
|
|
1674
|
+
const reset = () => {
|
|
1675
|
+
requestId++;
|
|
1676
|
+
userOpHash.value = null;
|
|
1677
|
+
receipt.value = null;
|
|
1678
|
+
isPending.value = false;
|
|
1679
|
+
isEstimating.value = false;
|
|
1680
|
+
error.value = null;
|
|
1681
|
+
};
|
|
1682
|
+
onScopeDispose18(() => {
|
|
1683
|
+
disposed = true;
|
|
1684
|
+
requestId++;
|
|
1685
|
+
});
|
|
1686
|
+
return {
|
|
1687
|
+
sendUserOp,
|
|
1688
|
+
userOpHash,
|
|
1689
|
+
receipt,
|
|
1690
|
+
isPending,
|
|
1691
|
+
isEstimating,
|
|
1692
|
+
error,
|
|
1693
|
+
reset
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
// src/useUserOpStatus.ts
|
|
1698
|
+
import {
|
|
1699
|
+
fetchUserOperationReceipt,
|
|
1700
|
+
InvalidUserOperationReceiptError
|
|
1701
|
+
} from "@naculus/connect-appkit-core";
|
|
1702
|
+
import { onScopeDispose as onScopeDispose19, shallowRef as shallowRef20, toValue as toValue16 } from "vue";
|
|
1703
|
+
function useUserOpStatus(options) {
|
|
1704
|
+
const status = shallowRef20("idle");
|
|
1705
|
+
const receipt = shallowRef20(null);
|
|
1706
|
+
const userOpHash = shallowRef20(null);
|
|
1707
|
+
const error = shallowRef20(null);
|
|
1708
|
+
const isPolling = shallowRef20(false);
|
|
1709
|
+
const elapsedMs = shallowRef20(0);
|
|
1710
|
+
const attempts = shallowRef20(0);
|
|
1711
|
+
const pollInterval = options.pollInterval ?? 2e3;
|
|
1712
|
+
const maxRetries = options.maxRetries ?? 30;
|
|
1713
|
+
let generation = 0;
|
|
1714
|
+
let startedAt = 0;
|
|
1715
|
+
let ticker = null;
|
|
1716
|
+
let timer = null;
|
|
1717
|
+
let controller = null;
|
|
1718
|
+
const clearTimers = () => {
|
|
1719
|
+
if (ticker) clearInterval(ticker);
|
|
1720
|
+
if (timer) clearTimeout(timer);
|
|
1721
|
+
ticker = null;
|
|
1722
|
+
timer = null;
|
|
1723
|
+
};
|
|
1724
|
+
const finish = (next, cause) => {
|
|
1725
|
+
status.value = next;
|
|
1726
|
+
error.value = cause;
|
|
1727
|
+
isPolling.value = false;
|
|
1728
|
+
clearTimers();
|
|
1729
|
+
};
|
|
1730
|
+
const poll = async (hash, own) => {
|
|
1731
|
+
const bundlerUrl = toValue16(options.bundlerUrl);
|
|
1732
|
+
if (!bundlerUrl || own !== generation) return;
|
|
1733
|
+
const attempt = ++attempts.value;
|
|
1734
|
+
const abort = new AbortController();
|
|
1735
|
+
controller = abort;
|
|
1736
|
+
try {
|
|
1737
|
+
const next = await fetchUserOperationReceipt(
|
|
1738
|
+
bundlerUrl,
|
|
1739
|
+
hash,
|
|
1740
|
+
abort.signal
|
|
1741
|
+
);
|
|
1742
|
+
if (own !== generation) return;
|
|
1743
|
+
if (next) {
|
|
1744
|
+
receipt.value = next;
|
|
1745
|
+
finish(next.success ? "confirmed" : "failed", null);
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1748
|
+
status.value = "pending";
|
|
1749
|
+
if (attempt <= maxRetries) {
|
|
1750
|
+
timer = setTimeout(() => void poll(hash, own), pollInterval);
|
|
1751
|
+
} else {
|
|
1752
|
+
finish(
|
|
1753
|
+
"not_found",
|
|
1754
|
+
new Error("UserOperation not included after maximum retries")
|
|
1755
|
+
);
|
|
1756
|
+
}
|
|
1757
|
+
} catch (cause) {
|
|
1758
|
+
if (own !== generation || abort.signal.aborted) return;
|
|
1759
|
+
const next = cause instanceof Error ? cause : new Error("Unknown bundler response failure");
|
|
1760
|
+
if (next instanceof InvalidUserOperationReceiptError) {
|
|
1761
|
+
finish("not_found", next);
|
|
1762
|
+
return;
|
|
1763
|
+
}
|
|
1764
|
+
if (attempt <= maxRetries) {
|
|
1765
|
+
timer = setTimeout(() => void poll(hash, own), pollInterval);
|
|
1766
|
+
} else {
|
|
1767
|
+
finish(
|
|
1768
|
+
"not_found",
|
|
1769
|
+
new Error(
|
|
1770
|
+
`UserOperation status unavailable after ${attempt} attempt${attempt === 1 ? "" : "s"}: ${next.message}`
|
|
1771
|
+
)
|
|
1772
|
+
);
|
|
1773
|
+
}
|
|
1774
|
+
} finally {
|
|
1775
|
+
if (controller === abort) controller = null;
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
const start = (hash) => {
|
|
1779
|
+
const own = ++generation;
|
|
1780
|
+
controller?.abort();
|
|
1781
|
+
controller = null;
|
|
1782
|
+
clearTimers();
|
|
1783
|
+
userOpHash.value = hash;
|
|
1784
|
+
receipt.value = null;
|
|
1785
|
+
error.value = null;
|
|
1786
|
+
attempts.value = 0;
|
|
1787
|
+
elapsedMs.value = 0;
|
|
1788
|
+
if (!toValue16(options.bundlerUrl)) {
|
|
1789
|
+
finish("not_found", new Error("Bundler URL not configured"));
|
|
1790
|
+
return;
|
|
1791
|
+
}
|
|
1792
|
+
status.value = "pending";
|
|
1793
|
+
isPolling.value = true;
|
|
1794
|
+
startedAt = Date.now();
|
|
1795
|
+
ticker = setInterval(() => {
|
|
1796
|
+
elapsedMs.value = Date.now() - startedAt;
|
|
1797
|
+
}, 1e3);
|
|
1798
|
+
void poll(hash, own);
|
|
1799
|
+
};
|
|
1800
|
+
const stop = () => {
|
|
1801
|
+
generation++;
|
|
1802
|
+
controller?.abort();
|
|
1803
|
+
controller = null;
|
|
1804
|
+
clearTimers();
|
|
1805
|
+
isPolling.value = false;
|
|
1806
|
+
};
|
|
1807
|
+
const reset = () => {
|
|
1808
|
+
stop();
|
|
1809
|
+
status.value = "idle";
|
|
1810
|
+
receipt.value = null;
|
|
1811
|
+
userOpHash.value = null;
|
|
1812
|
+
error.value = null;
|
|
1813
|
+
attempts.value = 0;
|
|
1814
|
+
elapsedMs.value = 0;
|
|
1815
|
+
};
|
|
1816
|
+
onScopeDispose19(stop);
|
|
1817
|
+
return {
|
|
1818
|
+
status,
|
|
1819
|
+
receipt,
|
|
1820
|
+
userOpHash,
|
|
1821
|
+
error,
|
|
1822
|
+
isPolling,
|
|
1823
|
+
elapsedMs,
|
|
1824
|
+
attempts,
|
|
1825
|
+
start,
|
|
1826
|
+
stop,
|
|
1827
|
+
reset
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
// src/useSendCalls.ts
|
|
1832
|
+
import { computed as computed14, onScopeDispose as onScopeDispose20, shallowRef as shallowRef21, toValue as toValue17, unref as unref17 } from "vue";
|
|
1833
|
+
function useSendCalls(options) {
|
|
1834
|
+
const status = shallowRef21("idle");
|
|
1835
|
+
const error = shallowRef21(null);
|
|
1836
|
+
const batchHash = shallowRef21(null);
|
|
1837
|
+
const callsStatus = shallowRef21(null);
|
|
1838
|
+
let sendGeneration = 0;
|
|
1839
|
+
let statusGeneration = 0;
|
|
1840
|
+
let disposed = false;
|
|
1841
|
+
const sendCalls = async (calls, input) => {
|
|
1842
|
+
const invoke = unref17(options.sendCalls);
|
|
1843
|
+
const own = ++sendGeneration;
|
|
1844
|
+
status.value = "awaiting_approval";
|
|
1845
|
+
error.value = null;
|
|
1846
|
+
batchHash.value = null;
|
|
1847
|
+
try {
|
|
1848
|
+
const hash = await invoke(calls, input);
|
|
1849
|
+
if (!disposed && own === sendGeneration) {
|
|
1850
|
+
status.value = "submitted";
|
|
1851
|
+
batchHash.value = hash;
|
|
1852
|
+
}
|
|
1853
|
+
return hash;
|
|
1854
|
+
} catch (cause) {
|
|
1855
|
+
const normalized = cause instanceof Error ? cause : new Error("sendCalls failed");
|
|
1856
|
+
if (!disposed && own === sendGeneration) {
|
|
1857
|
+
status.value = "failed";
|
|
1858
|
+
error.value = normalized;
|
|
1859
|
+
}
|
|
1860
|
+
throw normalized;
|
|
1861
|
+
}
|
|
1862
|
+
};
|
|
1863
|
+
const getCallsStatus = async (hash) => {
|
|
1864
|
+
const invoke = unref17(options.getCallsStatus);
|
|
1865
|
+
const own = ++statusGeneration;
|
|
1866
|
+
const result = await invoke(hash);
|
|
1867
|
+
if (!disposed && own === statusGeneration) callsStatus.value = result;
|
|
1868
|
+
return result;
|
|
1869
|
+
};
|
|
1870
|
+
const showCallsStatus = (hash) => unref17(options.showCallsStatus)(hash);
|
|
1871
|
+
const reset = () => {
|
|
1872
|
+
sendGeneration++;
|
|
1873
|
+
statusGeneration++;
|
|
1874
|
+
status.value = "idle";
|
|
1875
|
+
error.value = null;
|
|
1876
|
+
batchHash.value = null;
|
|
1877
|
+
callsStatus.value = null;
|
|
1878
|
+
};
|
|
1879
|
+
onScopeDispose20(() => {
|
|
1880
|
+
disposed = true;
|
|
1881
|
+
sendGeneration++;
|
|
1882
|
+
statusGeneration++;
|
|
1883
|
+
});
|
|
1884
|
+
return {
|
|
1885
|
+
sendCalls,
|
|
1886
|
+
getCallsStatus,
|
|
1887
|
+
showCallsStatus,
|
|
1888
|
+
status,
|
|
1889
|
+
error,
|
|
1890
|
+
batchHash,
|
|
1891
|
+
callsStatus,
|
|
1892
|
+
execution: computed14(() => toValue17(options.execution) ?? null),
|
|
1893
|
+
isSending: computed14(() => status.value === "awaiting_approval"),
|
|
1894
|
+
reset
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
// src/useEmbeddedWallet.ts
|
|
1899
|
+
import { computed as computed15, onScopeDispose as onScopeDispose21, shallowRef as shallowRef22, toValue as toValue18, unref as unref18 } from "vue";
|
|
1900
|
+
function useEmbeddedWallet(options) {
|
|
1901
|
+
const isBusy = shallowRef22(false);
|
|
1902
|
+
const error = shallowRef22(null);
|
|
1903
|
+
let active = 0;
|
|
1904
|
+
let generation = 0;
|
|
1905
|
+
let disposed = false;
|
|
1906
|
+
const run = async (action) => {
|
|
1907
|
+
const own = ++generation;
|
|
1908
|
+
active++;
|
|
1909
|
+
isBusy.value = true;
|
|
1910
|
+
error.value = null;
|
|
1911
|
+
try {
|
|
1912
|
+
return await action();
|
|
1913
|
+
} catch (cause) {
|
|
1914
|
+
const normalized = cause instanceof Error ? cause : new Error("Embedded wallet action failed");
|
|
1915
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
1916
|
+
throw normalized;
|
|
1917
|
+
} finally {
|
|
1918
|
+
active--;
|
|
1919
|
+
if (!disposed) isBusy.value = active > 0;
|
|
1920
|
+
}
|
|
1921
|
+
};
|
|
1922
|
+
const wallet = computed15(() => toValue18(options.wallet));
|
|
1923
|
+
onScopeDispose21(() => {
|
|
1924
|
+
disposed = true;
|
|
1925
|
+
generation++;
|
|
1926
|
+
});
|
|
1927
|
+
return {
|
|
1928
|
+
wallet,
|
|
1929
|
+
hasWallet: computed15(() => wallet.value !== null),
|
|
1930
|
+
address: computed15(() => wallet.value?.address ?? null),
|
|
1931
|
+
accounts: computed15(() => wallet.value?.accounts ?? []),
|
|
1932
|
+
activeNamespace: computed15(() => wallet.value?.activeNamespace ?? null),
|
|
1933
|
+
backupPending: computed15(() => toValue18(options.backupPending)),
|
|
1934
|
+
storageSecurityLevel: computed15(() => toValue18(options.storageSecurityLevel)),
|
|
1935
|
+
securityReport: computed15(() => toValue18(options.securityReport)),
|
|
1936
|
+
connectEmbedded: () => run(() => unref18(options.connectEmbedded)()),
|
|
1937
|
+
restoreWallet: () => run(() => unref18(options.restoreWallet)()),
|
|
1938
|
+
generateWallet: () => run(() => unref18(options.generateWallet)()),
|
|
1939
|
+
importFromMnemonic: (value) => run(() => unref18(options.importFromMnemonic)(value)),
|
|
1940
|
+
importFromPrivateKey: (value) => run(() => unref18(options.importFromPrivateKey)(value)),
|
|
1941
|
+
wipe: () => run(() => unref18(options.wipe)()),
|
|
1942
|
+
setActiveNamespace: (value) => unref18(options.setActiveNamespace)(value),
|
|
1943
|
+
backfillAccounts: () => run(() => unref18(options.backfillAccounts)()),
|
|
1944
|
+
getSeedPhrase: () => unref18(options.getSeedPhrase)(),
|
|
1945
|
+
getPrivateKey: () => unref18(options.getPrivateKey)(),
|
|
1946
|
+
confirmBackup: () => unref18(options.confirmBackup)(),
|
|
1947
|
+
isBusy,
|
|
1948
|
+
error,
|
|
1949
|
+
clearError: () => {
|
|
1950
|
+
error.value = null;
|
|
1951
|
+
}
|
|
1952
|
+
};
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
// src/useSIWxLogin.ts
|
|
1956
|
+
function useSIWxLogin(action) {
|
|
1957
|
+
const state = useSignInWithX(action);
|
|
1958
|
+
return {
|
|
1959
|
+
signIn: state.signIn,
|
|
1960
|
+
isSigningIn: state.isSigningIn,
|
|
1961
|
+
error: state.error,
|
|
1962
|
+
clearError: state.clearError
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
// src/useSIWxSession.ts
|
|
1967
|
+
import { computed as computed16, onScopeDispose as onScopeDispose22, shallowRef as shallowRef23, toValue as toValue19, unref as unref19 } from "vue";
|
|
1968
|
+
function useSIWxSession(options) {
|
|
1969
|
+
const isSigningIn = shallowRef23(false);
|
|
1970
|
+
const error = shallowRef23(null);
|
|
1971
|
+
let generation = 0;
|
|
1972
|
+
let active = 0;
|
|
1973
|
+
let disposed = false;
|
|
1974
|
+
const run = async (action, message) => {
|
|
1975
|
+
const own = ++generation;
|
|
1976
|
+
active++;
|
|
1977
|
+
isSigningIn.value = true;
|
|
1978
|
+
error.value = null;
|
|
1979
|
+
try {
|
|
1980
|
+
return await action();
|
|
1981
|
+
} catch (cause) {
|
|
1982
|
+
const normalized = cause instanceof Error ? cause : new Error(message);
|
|
1983
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
1984
|
+
throw normalized;
|
|
1985
|
+
} finally {
|
|
1986
|
+
active--;
|
|
1987
|
+
if (!disposed) isSigningIn.value = active > 0;
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1990
|
+
onScopeDispose22(() => {
|
|
1991
|
+
disposed = true;
|
|
1992
|
+
generation++;
|
|
1993
|
+
});
|
|
1994
|
+
return {
|
|
1995
|
+
session: computed16(() => toValue19(options.session)),
|
|
1996
|
+
isAuthenticated: computed16(
|
|
1997
|
+
() => toValue19(options.session) !== null && !toValue19(options.isExpired)
|
|
1998
|
+
),
|
|
1999
|
+
isRestoring: computed16(() => toValue19(options.isRestoring)),
|
|
2000
|
+
isSigningIn,
|
|
2001
|
+
isExpired: computed16(() => toValue19(options.isExpired)),
|
|
2002
|
+
timeUntilExpiry: computed16(() => toValue19(options.timeUntilExpiry)),
|
|
2003
|
+
signIn: (input) => run(() => unref19(options.signIn)(input), "SIWX sign-in failed"),
|
|
2004
|
+
signOut: async () => {
|
|
2005
|
+
await unref19(options.signOut)();
|
|
2006
|
+
error.value = null;
|
|
2007
|
+
},
|
|
2008
|
+
refresh: () => run(() => unref19(options.refresh)(), "Session refresh failed"),
|
|
2009
|
+
error,
|
|
2010
|
+
clearError: () => {
|
|
2011
|
+
error.value = null;
|
|
2012
|
+
}
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// src/useSiwxAuthSession.ts
|
|
2017
|
+
import { computed as computed17, onScopeDispose as onScopeDispose23, shallowRef as shallowRef24, toValue as toValue20, unref as unref20 } from "vue";
|
|
2018
|
+
function useSiwxAuthSession(options) {
|
|
2019
|
+
const isSigningIn = shallowRef24(false);
|
|
2020
|
+
const error = shallowRef24(null);
|
|
2021
|
+
let generation = 0;
|
|
2022
|
+
let disposed = false;
|
|
2023
|
+
const signIn = async (input) => {
|
|
2024
|
+
const own = ++generation;
|
|
2025
|
+
isSigningIn.value = true;
|
|
2026
|
+
error.value = null;
|
|
2027
|
+
try {
|
|
2028
|
+
return await unref20(options.signIn)(input);
|
|
2029
|
+
} catch (cause) {
|
|
2030
|
+
const normalized = cause instanceof Error ? cause : new Error("SIWX sign-in failed");
|
|
2031
|
+
if (!disposed && own === generation) error.value = normalized;
|
|
2032
|
+
throw normalized;
|
|
2033
|
+
} finally {
|
|
2034
|
+
if (!disposed && own === generation) isSigningIn.value = false;
|
|
2035
|
+
}
|
|
2036
|
+
};
|
|
2037
|
+
const signOut = async () => {
|
|
2038
|
+
generation++;
|
|
2039
|
+
await unref20(options.signOut)();
|
|
2040
|
+
if (!disposed) {
|
|
2041
|
+
isSigningIn.value = false;
|
|
2042
|
+
error.value = null;
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
2045
|
+
onScopeDispose23(() => {
|
|
2046
|
+
disposed = true;
|
|
2047
|
+
generation++;
|
|
2048
|
+
});
|
|
2049
|
+
const siwxResult = computed17(() => toValue20(options.result));
|
|
2050
|
+
return {
|
|
2051
|
+
isSignedIn: computed17(() => siwxResult.value !== null),
|
|
2052
|
+
isRestoring: computed17(() => toValue20(options.isRestoring)),
|
|
2053
|
+
siwxResult,
|
|
2054
|
+
isSigningIn,
|
|
2055
|
+
error,
|
|
2056
|
+
signIn,
|
|
2057
|
+
signOut,
|
|
2058
|
+
clearError: () => {
|
|
2059
|
+
error.value = null;
|
|
2060
|
+
}
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
// src/useBalance.ts
|
|
2065
|
+
import { bareEvmAddress as bareEvmAddress5 } from "@naculus/connect-appkit-core";
|
|
2066
|
+
import { formatUnits as formatUnits2 } from "@naculus/connect-core";
|
|
2067
|
+
import { computed as computed18, onScopeDispose as onScopeDispose24, shallowRef as shallowRef25, toValue as toValue21, watch as watch8 } from "vue";
|
|
2068
|
+
function useBalance(account, client, options = {}) {
|
|
2069
|
+
const balance = shallowRef25(null);
|
|
2070
|
+
const isFetching = shallowRef25(false);
|
|
2071
|
+
const error = shallowRef25(null);
|
|
2072
|
+
let generation = 0;
|
|
2073
|
+
let disposed = false;
|
|
2074
|
+
let timer = null;
|
|
2075
|
+
const refetch = async () => {
|
|
2076
|
+
const reader = toValue21(client);
|
|
2077
|
+
const address = bareEvmAddress5(toValue21(account));
|
|
2078
|
+
const own = ++generation;
|
|
2079
|
+
if (!reader || !address) {
|
|
2080
|
+
balance.value = null;
|
|
2081
|
+
error.value = null;
|
|
2082
|
+
isFetching.value = false;
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
isFetching.value = true;
|
|
2086
|
+
error.value = null;
|
|
2087
|
+
try {
|
|
2088
|
+
const next = await reader.getBalance({ address });
|
|
2089
|
+
if (disposed || own !== generation) return;
|
|
2090
|
+
balance.value = next.toString();
|
|
2091
|
+
} catch (cause) {
|
|
2092
|
+
if (disposed || own !== generation) return;
|
|
2093
|
+
balance.value = null;
|
|
2094
|
+
error.value = cause instanceof Error ? cause : new Error("Balance read failed");
|
|
2095
|
+
} finally {
|
|
2096
|
+
if (!disposed && own === generation) isFetching.value = false;
|
|
2097
|
+
}
|
|
2098
|
+
};
|
|
2099
|
+
const stopTimer = () => {
|
|
2100
|
+
if (timer) clearInterval(timer);
|
|
2101
|
+
timer = null;
|
|
2102
|
+
};
|
|
2103
|
+
watch8(
|
|
2104
|
+
[
|
|
2105
|
+
() => toValue21(account),
|
|
2106
|
+
() => toValue21(client),
|
|
2107
|
+
() => toValue21(options.refreshInterval) ?? 0
|
|
2108
|
+
],
|
|
2109
|
+
([, , interval]) => {
|
|
2110
|
+
stopTimer();
|
|
2111
|
+
void refetch();
|
|
2112
|
+
if (interval > 0) timer = setInterval(() => void refetch(), interval);
|
|
2113
|
+
},
|
|
2114
|
+
{ immediate: true }
|
|
2115
|
+
);
|
|
2116
|
+
onScopeDispose24(() => {
|
|
2117
|
+
disposed = true;
|
|
2118
|
+
generation++;
|
|
2119
|
+
stopTimer();
|
|
2120
|
+
});
|
|
2121
|
+
return {
|
|
2122
|
+
balance,
|
|
2123
|
+
formatted: computed18(
|
|
2124
|
+
() => balance.value === null ? null : formatUnits2(BigInt(balance.value), toValue21(options.decimals) ?? 18)
|
|
2125
|
+
),
|
|
2126
|
+
symbol: computed18(() => toValue21(options.symbol) ?? null),
|
|
2127
|
+
isFetching,
|
|
2128
|
+
error,
|
|
2129
|
+
refetch
|
|
2130
|
+
};
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
// src/useRouteQuote.ts
|
|
2134
|
+
import {
|
|
2135
|
+
isQuotableInput
|
|
2136
|
+
} from "@naculus/connect-appkit-core";
|
|
2137
|
+
import { onScopeDispose as onScopeDispose25, shallowRef as shallowRef26, toValue as toValue22, unref as unref21, watch as watch9 } from "vue";
|
|
2138
|
+
function useRouteQuote(input, getQuotes, options = {}) {
|
|
2139
|
+
const quotes = shallowRef26([]);
|
|
2140
|
+
const loading = shallowRef26(false);
|
|
2141
|
+
const error = shallowRef26(null);
|
|
2142
|
+
let generation = 0;
|
|
2143
|
+
let disposed = false;
|
|
2144
|
+
let timer = null;
|
|
2145
|
+
const clearTimer = () => {
|
|
2146
|
+
if (timer) clearTimeout(timer);
|
|
2147
|
+
timer = null;
|
|
2148
|
+
};
|
|
2149
|
+
const fetchQuotes = async () => {
|
|
2150
|
+
const current = toValue22(input);
|
|
2151
|
+
const fn = unref21(getQuotes);
|
|
2152
|
+
const own = ++generation;
|
|
2153
|
+
if (!isQuotableInput(current)) {
|
|
2154
|
+
quotes.value = [];
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2157
|
+
if (!fn) return;
|
|
2158
|
+
loading.value = true;
|
|
2159
|
+
error.value = null;
|
|
2160
|
+
try {
|
|
2161
|
+
const result = await fn(
|
|
2162
|
+
current.fromChain,
|
|
2163
|
+
current.toChain,
|
|
2164
|
+
current.fromToken,
|
|
2165
|
+
current.amount,
|
|
2166
|
+
current.options,
|
|
2167
|
+
current.toToken
|
|
2168
|
+
);
|
|
2169
|
+
if (disposed || own !== generation) return;
|
|
2170
|
+
quotes.value = result;
|
|
2171
|
+
} catch (cause) {
|
|
2172
|
+
if (disposed || own !== generation) return;
|
|
2173
|
+
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
2174
|
+
quotes.value = [];
|
|
2175
|
+
} finally {
|
|
2176
|
+
if (!disposed && own === generation) loading.value = false;
|
|
2177
|
+
}
|
|
2178
|
+
};
|
|
2179
|
+
watch9(
|
|
2180
|
+
[
|
|
2181
|
+
() => toValue22(input).fromChain,
|
|
2182
|
+
() => toValue22(input).toChain,
|
|
2183
|
+
() => toValue22(input).fromToken,
|
|
2184
|
+
() => toValue22(input).toToken,
|
|
2185
|
+
() => toValue22(input).amount,
|
|
2186
|
+
() => unref21(getQuotes)
|
|
2187
|
+
],
|
|
2188
|
+
([fromChain, toChain, fromToken, , amount]) => {
|
|
2189
|
+
clearTimer();
|
|
2190
|
+
if (!fromChain || !toChain || !fromToken || !amount) {
|
|
2191
|
+
quotes.value = [];
|
|
2192
|
+
return;
|
|
2193
|
+
}
|
|
2194
|
+
timer = setTimeout(() => {
|
|
2195
|
+
timer = null;
|
|
2196
|
+
void fetchQuotes();
|
|
2197
|
+
}, options.debounceMs ?? 300);
|
|
2198
|
+
},
|
|
2199
|
+
{ immediate: true }
|
|
2200
|
+
);
|
|
2201
|
+
onScopeDispose25(() => {
|
|
2202
|
+
disposed = true;
|
|
2203
|
+
generation++;
|
|
2204
|
+
clearTimer();
|
|
2205
|
+
});
|
|
2206
|
+
return {
|
|
2207
|
+
quotes,
|
|
2208
|
+
loading,
|
|
2209
|
+
error,
|
|
2210
|
+
refresh: fetchQuotes,
|
|
2211
|
+
clear: () => {
|
|
2212
|
+
clearTimer();
|
|
2213
|
+
generation++;
|
|
2214
|
+
quotes.value = [];
|
|
2215
|
+
error.value = null;
|
|
2216
|
+
loading.value = false;
|
|
2217
|
+
}
|
|
2218
|
+
};
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
// src/useCompareCosts.ts
|
|
2222
|
+
import {
|
|
2223
|
+
compareCostsKey
|
|
2224
|
+
} from "@naculus/connect-appkit-core";
|
|
2225
|
+
import { onScopeDispose as onScopeDispose26, shallowRef as shallowRef27, toValue as toValue23, unref as unref22, watch as watch10 } from "vue";
|
|
2226
|
+
function useCompareCosts(input, compareCosts) {
|
|
2227
|
+
const comparisons = shallowRef27([]);
|
|
2228
|
+
const loading = shallowRef27(false);
|
|
2229
|
+
const error = shallowRef27(null);
|
|
2230
|
+
let generation = 0;
|
|
2231
|
+
let disposed = false;
|
|
2232
|
+
const fetchComparisons = async () => {
|
|
2233
|
+
const { operation, chains, options } = toValue23(input);
|
|
2234
|
+
const fn = unref22(compareCosts);
|
|
2235
|
+
const own = ++generation;
|
|
2236
|
+
if (!chains || chains.length === 0) {
|
|
2237
|
+
comparisons.value = [];
|
|
2238
|
+
return;
|
|
2239
|
+
}
|
|
2240
|
+
if (!fn) return;
|
|
2241
|
+
loading.value = true;
|
|
2242
|
+
error.value = null;
|
|
2243
|
+
try {
|
|
2244
|
+
const result = await fn(operation, chains, options);
|
|
2245
|
+
if (disposed || own !== generation) return;
|
|
2246
|
+
comparisons.value = result;
|
|
2247
|
+
} catch (cause) {
|
|
2248
|
+
if (disposed || own !== generation) return;
|
|
2249
|
+
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
2250
|
+
comparisons.value = [];
|
|
2251
|
+
} finally {
|
|
2252
|
+
if (!disposed && own === generation) loading.value = false;
|
|
2253
|
+
}
|
|
2254
|
+
};
|
|
2255
|
+
watch10(
|
|
2256
|
+
[() => compareCostsKey(toValue23(input)), () => unref22(compareCosts)],
|
|
2257
|
+
() => {
|
|
2258
|
+
void fetchComparisons();
|
|
2259
|
+
},
|
|
2260
|
+
{ immediate: true }
|
|
2261
|
+
);
|
|
2262
|
+
onScopeDispose26(() => {
|
|
2263
|
+
disposed = true;
|
|
2264
|
+
generation++;
|
|
2265
|
+
});
|
|
2266
|
+
return { comparisons, loading, error, refresh: fetchComparisons };
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
// src/useExecuteRoute.ts
|
|
2270
|
+
import {
|
|
2271
|
+
toExecuteRouteError,
|
|
2272
|
+
validateRouteRecipient
|
|
2273
|
+
} from "@naculus/connect-appkit-core";
|
|
2274
|
+
import { onScopeDispose as onScopeDispose27, shallowRef as shallowRef28, unref as unref23 } from "vue";
|
|
2275
|
+
function useExecuteRoute(executeRoute) {
|
|
2276
|
+
const executing = shallowRef28(false);
|
|
2277
|
+
const result = shallowRef28(null);
|
|
2278
|
+
const error = shallowRef28(null);
|
|
2279
|
+
let inFlight = false;
|
|
2280
|
+
let disposed = false;
|
|
2281
|
+
const execute = async (quote, recipient, options) => {
|
|
2282
|
+
const fn = unref23(executeRoute);
|
|
2283
|
+
if (!fn) {
|
|
2284
|
+
error.value = {
|
|
2285
|
+
code: "no_executor",
|
|
2286
|
+
message: "No executeRoute function provided"
|
|
2287
|
+
};
|
|
2288
|
+
result.value = null;
|
|
2289
|
+
return null;
|
|
2290
|
+
}
|
|
2291
|
+
const recipientError = validateRouteRecipient(quote, recipient);
|
|
2292
|
+
if (recipientError) {
|
|
2293
|
+
error.value = recipientError;
|
|
2294
|
+
result.value = null;
|
|
2295
|
+
return null;
|
|
2296
|
+
}
|
|
2297
|
+
if (inFlight) {
|
|
2298
|
+
error.value = {
|
|
2299
|
+
code: "execution_in_progress",
|
|
2300
|
+
message: "A route execution is already in progress"
|
|
2301
|
+
};
|
|
2302
|
+
return null;
|
|
2303
|
+
}
|
|
2304
|
+
inFlight = true;
|
|
2305
|
+
executing.value = true;
|
|
2306
|
+
error.value = null;
|
|
2307
|
+
result.value = null;
|
|
2308
|
+
try {
|
|
2309
|
+
const execResult = await fn(quote, recipient, options);
|
|
2310
|
+
if (!disposed) result.value = execResult;
|
|
2311
|
+
return execResult;
|
|
2312
|
+
} catch (cause) {
|
|
2313
|
+
if (!disposed) error.value = toExecuteRouteError(cause);
|
|
2314
|
+
return null;
|
|
2315
|
+
} finally {
|
|
2316
|
+
inFlight = false;
|
|
2317
|
+
if (!disposed) executing.value = false;
|
|
2318
|
+
}
|
|
2319
|
+
};
|
|
2320
|
+
onScopeDispose27(() => {
|
|
2321
|
+
disposed = true;
|
|
2322
|
+
});
|
|
2323
|
+
return {
|
|
2324
|
+
execute,
|
|
2325
|
+
executing,
|
|
2326
|
+
result,
|
|
2327
|
+
error,
|
|
2328
|
+
reset: () => {
|
|
2329
|
+
result.value = null;
|
|
2330
|
+
error.value = null;
|
|
2331
|
+
executing.value = false;
|
|
2332
|
+
}
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
// src/useTokenList.ts
|
|
2337
|
+
import { eip155ChainIdToNumber } from "@naculus/connect-appkit-core";
|
|
2338
|
+
import {
|
|
2339
|
+
TokenListManager
|
|
2340
|
+
} from "@naculus/connect-core";
|
|
2341
|
+
import { onScopeDispose as onScopeDispose28, shallowRef as shallowRef29, toValue as toValue24, watch as watch11 } from "vue";
|
|
2342
|
+
function useTokenList(chainId, options = {}) {
|
|
2343
|
+
const config = {};
|
|
2344
|
+
if (options.sources) config.sources = options.sources;
|
|
2345
|
+
const manager = options.manager ?? new TokenListManager(config);
|
|
2346
|
+
const tokens = shallowRef29([]);
|
|
2347
|
+
const isLoading = shallowRef29(options.autoLoad !== false);
|
|
2348
|
+
const isLoaded = shallowRef29(false);
|
|
2349
|
+
const error = shallowRef29(null);
|
|
2350
|
+
let generation = 0;
|
|
2351
|
+
let disposed = false;
|
|
2352
|
+
const select = () => {
|
|
2353
|
+
const id = toValue24(chainId);
|
|
2354
|
+
const numeric = id ? eip155ChainIdToNumber(id) : void 0;
|
|
2355
|
+
return manager.getTokens(
|
|
2356
|
+
numeric !== void 0 ? { chainId: numeric } : void 0
|
|
2357
|
+
);
|
|
2358
|
+
};
|
|
2359
|
+
const run = async (op) => {
|
|
2360
|
+
const own = ++generation;
|
|
2361
|
+
isLoading.value = true;
|
|
2362
|
+
error.value = null;
|
|
2363
|
+
try {
|
|
2364
|
+
await op();
|
|
2365
|
+
if (disposed || own !== generation) return;
|
|
2366
|
+
tokens.value = select();
|
|
2367
|
+
isLoaded.value = true;
|
|
2368
|
+
} catch (cause) {
|
|
2369
|
+
if (disposed || own !== generation) return;
|
|
2370
|
+
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
2371
|
+
} finally {
|
|
2372
|
+
if (!disposed && own === generation) isLoading.value = false;
|
|
2373
|
+
}
|
|
2374
|
+
};
|
|
2375
|
+
watch11(
|
|
2376
|
+
() => toValue24(chainId),
|
|
2377
|
+
() => {
|
|
2378
|
+
if (options.autoLoad !== false) void run(() => manager.load());
|
|
2379
|
+
},
|
|
2380
|
+
{ immediate: true }
|
|
2381
|
+
);
|
|
2382
|
+
onScopeDispose28(() => {
|
|
2383
|
+
disposed = true;
|
|
2384
|
+
generation++;
|
|
2385
|
+
});
|
|
2386
|
+
return {
|
|
2387
|
+
tokens,
|
|
2388
|
+
isLoading,
|
|
2389
|
+
isLoaded,
|
|
2390
|
+
error,
|
|
2391
|
+
refetch: () => run(() => manager.refresh())
|
|
2392
|
+
};
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
// src/useTokenSearch.ts
|
|
2396
|
+
import { eip155ChainIdToNumber as eip155ChainIdToNumber2 } from "@naculus/connect-appkit-core";
|
|
2397
|
+
import {
|
|
2398
|
+
TokenListManager as TokenListManager2
|
|
2399
|
+
} from "@naculus/connect-core";
|
|
2400
|
+
import { onScopeDispose as onScopeDispose29, shallowRef as shallowRef30, toValue as toValue25, watch as watch12 } from "vue";
|
|
2401
|
+
var DEBOUNCE_MS = 300;
|
|
2402
|
+
var EMPTY = { exact: [], fuzzy: [], hasMore: false };
|
|
2403
|
+
var sharedManager = null;
|
|
2404
|
+
function getSharedManager() {
|
|
2405
|
+
if (!sharedManager) {
|
|
2406
|
+
sharedManager = new TokenListManager2();
|
|
2407
|
+
sharedManager.load().catch(() => {
|
|
2408
|
+
});
|
|
2409
|
+
}
|
|
2410
|
+
return sharedManager;
|
|
2411
|
+
}
|
|
2412
|
+
function useTokenSearch(query, chainId, options = {}) {
|
|
2413
|
+
const results = shallowRef30(EMPTY);
|
|
2414
|
+
const isSearching = shallowRef30(false);
|
|
2415
|
+
let timer = null;
|
|
2416
|
+
const clear = () => {
|
|
2417
|
+
if (timer) clearTimeout(timer);
|
|
2418
|
+
timer = null;
|
|
2419
|
+
};
|
|
2420
|
+
watch12(
|
|
2421
|
+
[() => (toValue25(query) ?? "").trim(), () => toValue25(chainId)],
|
|
2422
|
+
([q, id]) => {
|
|
2423
|
+
clear();
|
|
2424
|
+
if (!q) {
|
|
2425
|
+
results.value = EMPTY;
|
|
2426
|
+
isSearching.value = false;
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
isSearching.value = true;
|
|
2430
|
+
timer = setTimeout(() => {
|
|
2431
|
+
timer = null;
|
|
2432
|
+
const manager = options.manager ?? getSharedManager();
|
|
2433
|
+
const numeric = id ? eip155ChainIdToNumber2(id) : void 0;
|
|
2434
|
+
results.value = manager.search(q, {
|
|
2435
|
+
chainId: numeric,
|
|
2436
|
+
limit: options.limit ?? 20
|
|
2437
|
+
});
|
|
2438
|
+
isSearching.value = false;
|
|
2439
|
+
}, options.debounceMs ?? DEBOUNCE_MS);
|
|
2440
|
+
},
|
|
2441
|
+
{ immediate: true }
|
|
2442
|
+
);
|
|
2443
|
+
onScopeDispose29(clear);
|
|
2444
|
+
return { results, isSearching };
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
// src/useValidateDestination.ts
|
|
2448
|
+
import {
|
|
2449
|
+
validateDestination
|
|
2450
|
+
} from "@naculus/connect-appkit-core";
|
|
2451
|
+
import { computed as computed19, toValue as toValue26 } from "vue";
|
|
2452
|
+
function useValidateDestination(address) {
|
|
2453
|
+
return {
|
|
2454
|
+
validation: computed19(() => validateDestination(toValue26(address) ?? ""))
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
|
|
2458
|
+
// src/useTokenBalance.ts
|
|
2459
|
+
import { bareEvmAddress as bareEvmAddress6 } from "@naculus/connect-appkit-core";
|
|
2460
|
+
import { ERC20_MIN_ABI as ERC20_MIN_ABI3, formatUnits as formatUnits3 } from "@naculus/connect-core";
|
|
2461
|
+
import { onScopeDispose as onScopeDispose30, shallowRef as shallowRef31, toValue as toValue27, watch as watch13 } from "vue";
|
|
2462
|
+
function tokensKey(tokens) {
|
|
2463
|
+
return tokens.map((t) => `${t.address.toLowerCase()}|${t.decimals}|${t.symbol}`).join(",");
|
|
2464
|
+
}
|
|
2465
|
+
function useTokenBalance(account, client, tokens, options = {}) {
|
|
2466
|
+
const tokenBalances = shallowRef31([]);
|
|
2467
|
+
const isFetching = shallowRef31(false);
|
|
2468
|
+
const error = shallowRef31(null);
|
|
2469
|
+
let generation = 0;
|
|
2470
|
+
let disposed = false;
|
|
2471
|
+
let timer = null;
|
|
2472
|
+
const refetch = async () => {
|
|
2473
|
+
const reader = toValue27(client);
|
|
2474
|
+
const address = bareEvmAddress6(toValue27(account));
|
|
2475
|
+
const list = toValue27(tokens) ?? [];
|
|
2476
|
+
const own = ++generation;
|
|
2477
|
+
if (!reader || !address || list.length === 0) {
|
|
2478
|
+
tokenBalances.value = [];
|
|
2479
|
+
error.value = null;
|
|
2480
|
+
isFetching.value = false;
|
|
2481
|
+
return;
|
|
2482
|
+
}
|
|
2483
|
+
isFetching.value = true;
|
|
2484
|
+
error.value = null;
|
|
2485
|
+
try {
|
|
2486
|
+
const results = await Promise.all(
|
|
2487
|
+
list.map(async (token) => {
|
|
2488
|
+
try {
|
|
2489
|
+
const raw = await reader.readContract({
|
|
2490
|
+
address: token.address,
|
|
2491
|
+
abi: ERC20_MIN_ABI3,
|
|
2492
|
+
functionName: "balanceOf",
|
|
2493
|
+
args: [address]
|
|
2494
|
+
});
|
|
2495
|
+
const value = BigInt(raw);
|
|
2496
|
+
return {
|
|
2497
|
+
...token,
|
|
2498
|
+
balance: value.toString(),
|
|
2499
|
+
formatted: formatUnits3(value, token.decimals)
|
|
2500
|
+
};
|
|
2501
|
+
} catch {
|
|
2502
|
+
return { ...token, balance: null, formatted: null };
|
|
2503
|
+
}
|
|
2504
|
+
})
|
|
2505
|
+
);
|
|
2506
|
+
if (disposed || own !== generation) return;
|
|
2507
|
+
tokenBalances.value = results;
|
|
2508
|
+
} catch (cause) {
|
|
2509
|
+
if (disposed || own !== generation) return;
|
|
2510
|
+
tokenBalances.value = [];
|
|
2511
|
+
error.value = cause instanceof Error ? cause : new Error("Failed to fetch token balances");
|
|
2512
|
+
} finally {
|
|
2513
|
+
if (!disposed && own === generation) isFetching.value = false;
|
|
2514
|
+
}
|
|
2515
|
+
};
|
|
2516
|
+
const stopTimer = () => {
|
|
2517
|
+
if (timer) clearInterval(timer);
|
|
2518
|
+
timer = null;
|
|
2519
|
+
};
|
|
2520
|
+
watch13(
|
|
2521
|
+
[
|
|
2522
|
+
() => toValue27(account),
|
|
2523
|
+
() => toValue27(client),
|
|
2524
|
+
() => tokensKey(toValue27(tokens) ?? []),
|
|
2525
|
+
() => toValue27(options.refreshInterval) ?? 0
|
|
2526
|
+
],
|
|
2527
|
+
([, , , interval]) => {
|
|
2528
|
+
stopTimer();
|
|
2529
|
+
void refetch();
|
|
2530
|
+
if (interval > 0) timer = setInterval(() => void refetch(), interval);
|
|
2531
|
+
},
|
|
2532
|
+
{ immediate: true }
|
|
2533
|
+
);
|
|
2534
|
+
onScopeDispose30(() => {
|
|
2535
|
+
disposed = true;
|
|
2536
|
+
generation++;
|
|
2537
|
+
stopTimer();
|
|
2538
|
+
});
|
|
2539
|
+
return {
|
|
2540
|
+
tokenBalances,
|
|
2541
|
+
isFetching,
|
|
2542
|
+
error,
|
|
2543
|
+
refetch,
|
|
2544
|
+
getTokenBalance: (tokenAddress) => tokenBalances.value.find(
|
|
2545
|
+
(t) => t.address.toLowerCase() === tokenAddress.toLowerCase()
|
|
2546
|
+
)
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
// src/useDelegation.ts
|
|
2551
|
+
import { bareEvmAddress as bareEvmAddress7 } from "@naculus/connect-appkit-core";
|
|
2552
|
+
import {
|
|
2553
|
+
readDelegation,
|
|
2554
|
+
UNKNOWN_DELEGATION
|
|
2555
|
+
} from "@naculus/connect-core";
|
|
2556
|
+
import { computed as computed20, onScopeDispose as onScopeDispose31, shallowRef as shallowRef32, toValue as toValue28, watch as watch14 } from "vue";
|
|
2557
|
+
function useDelegation(account, client, chainId) {
|
|
2558
|
+
const status = shallowRef32(UNKNOWN_DELEGATION);
|
|
2559
|
+
const isFetching = shallowRef32(false);
|
|
2560
|
+
const error = shallowRef32(null);
|
|
2561
|
+
let generation = 0;
|
|
2562
|
+
let disposed = false;
|
|
2563
|
+
const refetch = async () => {
|
|
2564
|
+
const mine = ++generation;
|
|
2565
|
+
const reader = toValue28(client);
|
|
2566
|
+
const address = bareEvmAddress7(toValue28(account));
|
|
2567
|
+
status.value = UNKNOWN_DELEGATION;
|
|
2568
|
+
error.value = null;
|
|
2569
|
+
if (!reader || !address) {
|
|
2570
|
+
isFetching.value = false;
|
|
2571
|
+
return;
|
|
2572
|
+
}
|
|
2573
|
+
isFetching.value = true;
|
|
2574
|
+
try {
|
|
2575
|
+
const code = await reader.getCode({ address });
|
|
2576
|
+
if (!disposed && mine === generation) {
|
|
2577
|
+
status.value = readDelegation(code ?? "0x");
|
|
2578
|
+
}
|
|
2579
|
+
} catch (cause) {
|
|
2580
|
+
if (!disposed && mine === generation) {
|
|
2581
|
+
status.value = UNKNOWN_DELEGATION;
|
|
2582
|
+
error.value = cause instanceof Error ? cause : new Error("Code read failed");
|
|
2583
|
+
}
|
|
2584
|
+
} finally {
|
|
2585
|
+
if (!disposed && mine === generation) isFetching.value = false;
|
|
2586
|
+
}
|
|
2587
|
+
};
|
|
2588
|
+
watch14(
|
|
2589
|
+
[() => toValue28(account), () => toValue28(client), () => toValue28(chainId)],
|
|
2590
|
+
() => {
|
|
2591
|
+
void refetch();
|
|
2592
|
+
},
|
|
2593
|
+
{ immediate: true, flush: "sync" }
|
|
2594
|
+
);
|
|
2595
|
+
onScopeDispose31(() => {
|
|
2596
|
+
disposed = true;
|
|
2597
|
+
generation++;
|
|
2598
|
+
});
|
|
2599
|
+
return {
|
|
2600
|
+
delegated: computed20(() => status.value.delegated),
|
|
2601
|
+
delegate: computed20(() => status.value.delegate),
|
|
2602
|
+
isFetching,
|
|
2603
|
+
error,
|
|
2604
|
+
refetch
|
|
2605
|
+
};
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
// src/name-lookup.ts
|
|
2609
|
+
import { getResolver } from "@naculus/connect-appkit-core";
|
|
2610
|
+
import { computed as computed21, onScopeDispose as onScopeDispose32, shallowRef as shallowRef33, toValue as toValue29, watch as watch15 } from "vue";
|
|
2611
|
+
function useNameLookup(options) {
|
|
2612
|
+
const data = shallowRef33(null);
|
|
2613
|
+
const loading = shallowRef33(false);
|
|
2614
|
+
const error = shallowRef33(null);
|
|
2615
|
+
let generation = 0;
|
|
2616
|
+
let disposed = false;
|
|
2617
|
+
const run = () => {
|
|
2618
|
+
const input = toValue29(options.input).trim();
|
|
2619
|
+
const skip = toValue29(options.skip) ?? false;
|
|
2620
|
+
const scope = toValue29(options.scope);
|
|
2621
|
+
const config = toValue29(options.resolverConfig);
|
|
2622
|
+
const mine = ++generation;
|
|
2623
|
+
if (!input || skip) {
|
|
2624
|
+
data.value = null;
|
|
2625
|
+
loading.value = false;
|
|
2626
|
+
error.value = null;
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
data.value = null;
|
|
2630
|
+
loading.value = true;
|
|
2631
|
+
error.value = null;
|
|
2632
|
+
Promise.resolve().then(() => options.query(getResolver(config), input, scope)).then((result) => {
|
|
2633
|
+
if (disposed || mine !== generation) return;
|
|
2634
|
+
data.value = result;
|
|
2635
|
+
loading.value = false;
|
|
2636
|
+
}).catch((cause) => {
|
|
2637
|
+
if (disposed || mine !== generation) return;
|
|
2638
|
+
data.value = null;
|
|
2639
|
+
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
2640
|
+
loading.value = false;
|
|
2641
|
+
});
|
|
2642
|
+
};
|
|
2643
|
+
watch15(
|
|
2644
|
+
() => [
|
|
2645
|
+
toValue29(options.input),
|
|
2646
|
+
toValue29(options.skip),
|
|
2647
|
+
toValue29(options.scope),
|
|
2648
|
+
toValue29(options.resolverConfig)
|
|
2649
|
+
],
|
|
2650
|
+
run,
|
|
2651
|
+
{ immediate: true, flush: "sync", deep: true }
|
|
2652
|
+
);
|
|
2653
|
+
onScopeDispose32(() => {
|
|
2654
|
+
disposed = true;
|
|
2655
|
+
generation++;
|
|
2656
|
+
});
|
|
2657
|
+
return {
|
|
2658
|
+
data,
|
|
2659
|
+
isLoading: computed21(() => loading.value),
|
|
2660
|
+
error,
|
|
2661
|
+
refetch: run
|
|
2662
|
+
};
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
// src/useResolveName.ts
|
|
2666
|
+
function useResolveName(name, options) {
|
|
2667
|
+
return useNameLookup({
|
|
2668
|
+
input: name,
|
|
2669
|
+
skip: options?.skip,
|
|
2670
|
+
resolverConfig: options?.resolverConfig,
|
|
2671
|
+
query: (resolver, input) => resolver.resolveName(input)
|
|
2672
|
+
});
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
// src/useLookupAddress.ts
|
|
2676
|
+
function useLookupAddress(address, options) {
|
|
2677
|
+
return useNameLookup({
|
|
2678
|
+
input: address,
|
|
2679
|
+
scope: options?.chainId,
|
|
2680
|
+
skip: options?.skip,
|
|
2681
|
+
resolverConfig: options?.resolverConfig,
|
|
2682
|
+
query: (resolver, input, scope) => resolver.lookupAddress(input, scope)
|
|
2683
|
+
});
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
// src/useSolanaAccount.ts
|
|
2687
|
+
import { computed as computed22, toValue as toValue30 } from "vue";
|
|
2688
|
+
function useSolanaAccount(accounts, connected) {
|
|
2689
|
+
const isConnected = computed22(() => toValue30(connected));
|
|
2690
|
+
const caip10 = computed22(
|
|
2691
|
+
() => isConnected.value ? (toValue30(accounts) ?? []).find(
|
|
2692
|
+
(account) => account.startsWith("solana:")
|
|
2693
|
+
) ?? null : null
|
|
2694
|
+
);
|
|
2695
|
+
const parts = computed22(() => caip10.value?.split(":") ?? []);
|
|
2696
|
+
return {
|
|
2697
|
+
address: computed22(
|
|
2698
|
+
() => parts.value.length >= 3 ? parts.value.at(-1) ?? null : null
|
|
2699
|
+
),
|
|
2700
|
+
caip10,
|
|
2701
|
+
chainId: computed22(
|
|
2702
|
+
() => parts.value.length >= 3 ? parts.value.slice(0, -1).join(":") : null
|
|
2703
|
+
),
|
|
2704
|
+
isConnected
|
|
2705
|
+
};
|
|
2706
|
+
}
|
|
2707
|
+
|
|
212
2708
|
// src/useChain.ts
|
|
213
2709
|
import {
|
|
214
2710
|
chainNamespace,
|
|
215
|
-
chainNumber,
|
|
2711
|
+
chainNumber as chainNumber2,
|
|
216
2712
|
chainsForNamespace,
|
|
217
2713
|
describeChain,
|
|
218
2714
|
resolveChain
|
|
219
2715
|
} from "@naculus/connect-appkit-core";
|
|
220
|
-
import { computed as
|
|
2716
|
+
import { computed as computed23, toValue as toValue31 } from "vue";
|
|
221
2717
|
function useChain(chains, chainId) {
|
|
222
|
-
const list =
|
|
223
|
-
const id =
|
|
224
|
-
const currentChain =
|
|
2718
|
+
const list = computed23(() => toValue31(chains) ?? []);
|
|
2719
|
+
const id = computed23(() => toValue31(chainId) ?? null);
|
|
2720
|
+
const currentChain = computed23(() => resolveChain(list.value, id.value));
|
|
225
2721
|
return {
|
|
226
2722
|
currentChain,
|
|
227
|
-
chainInfo:
|
|
228
|
-
availableChains:
|
|
229
|
-
currentChainNumber:
|
|
230
|
-
() => currentChain.value ?
|
|
2723
|
+
chainInfo: computed23(() => describeChain(list.value, id.value)),
|
|
2724
|
+
availableChains: computed23(() => chainsForNamespace(list.value, id.value)),
|
|
2725
|
+
currentChainNumber: computed23(
|
|
2726
|
+
() => currentChain.value ? chainNumber2(currentChain.value) : null
|
|
231
2727
|
),
|
|
232
|
-
namespace:
|
|
2728
|
+
namespace: computed23(
|
|
233
2729
|
() => currentChain.value ? chainNamespace(currentChain.value) : null
|
|
234
2730
|
)
|
|
235
2731
|
};
|
|
236
2732
|
}
|
|
237
2733
|
|
|
238
2734
|
// src/usePassphraseGate.ts
|
|
239
|
-
import { onScopeDispose, readonly, shallowRef } from "vue";
|
|
2735
|
+
import { onScopeDispose as onScopeDispose33, readonly, shallowRef as shallowRef34 } from "vue";
|
|
240
2736
|
function usePassphraseGate(gate) {
|
|
241
|
-
const request =
|
|
2737
|
+
const request = shallowRef34(gate.getSnapshot());
|
|
242
2738
|
const unsubscribe = gate.subscribe(() => {
|
|
243
2739
|
request.value = gate.getSnapshot();
|
|
244
2740
|
});
|
|
245
|
-
|
|
2741
|
+
onScopeDispose33(unsubscribe);
|
|
246
2742
|
return {
|
|
247
2743
|
request: readonly(request),
|
|
248
2744
|
submit: (passphrase) => gate.submit(passphrase),
|
|
@@ -255,16 +2751,16 @@ function usePassphraseGate(gate) {
|
|
|
255
2751
|
import {
|
|
256
2752
|
getSolanaBalance
|
|
257
2753
|
} from "@naculus/connect-core";
|
|
258
|
-
import { onScopeDispose as
|
|
2754
|
+
import { onScopeDispose as onScopeDispose34, ref, shallowRef as shallowRef35, toValue as toValue32, watchEffect } from "vue";
|
|
259
2755
|
function useSolanaBalance(address, rpcUrl) {
|
|
260
|
-
const balance =
|
|
2756
|
+
const balance = shallowRef35(null);
|
|
261
2757
|
const isFetching = ref(false);
|
|
262
|
-
const error =
|
|
2758
|
+
const error = shallowRef35(null);
|
|
263
2759
|
let generation = 0;
|
|
264
2760
|
let disposed = false;
|
|
265
2761
|
const refetch = async () => {
|
|
266
|
-
const addr =
|
|
267
|
-
const url =
|
|
2762
|
+
const addr = toValue32(address);
|
|
2763
|
+
const url = toValue32(rpcUrl);
|
|
268
2764
|
if (!addr || !url) {
|
|
269
2765
|
balance.value = null;
|
|
270
2766
|
return;
|
|
@@ -285,34 +2781,224 @@ function useSolanaBalance(address, rpcUrl) {
|
|
|
285
2781
|
}
|
|
286
2782
|
};
|
|
287
2783
|
watchEffect(() => {
|
|
288
|
-
|
|
289
|
-
|
|
2784
|
+
toValue32(address);
|
|
2785
|
+
toValue32(rpcUrl);
|
|
290
2786
|
void refetch();
|
|
291
2787
|
});
|
|
292
|
-
|
|
2788
|
+
onScopeDispose34(() => {
|
|
293
2789
|
disposed = true;
|
|
294
2790
|
});
|
|
295
2791
|
return { balance, isFetching, error, refetch };
|
|
296
2792
|
}
|
|
297
2793
|
|
|
2794
|
+
// src/useLastTx.ts
|
|
2795
|
+
import { shallowRef as shallowRef36, toValue as toValue33, watch as watch16 } from "vue";
|
|
2796
|
+
function useLastTx(monitor) {
|
|
2797
|
+
const lastTx = shallowRef36(null);
|
|
2798
|
+
const lastConfirmedTx = shallowRef36(null);
|
|
2799
|
+
const lastFailedTx = shallowRef36(null);
|
|
2800
|
+
watch16(
|
|
2801
|
+
() => toValue33(monitor),
|
|
2802
|
+
(activeMonitor, _previous, onCleanup) => {
|
|
2803
|
+
if (!activeMonitor) return;
|
|
2804
|
+
const recordLatest = (entry) => {
|
|
2805
|
+
if (!lastTx.value || entry.createdAt >= lastTx.value.createdAt) {
|
|
2806
|
+
lastTx.value = entry;
|
|
2807
|
+
}
|
|
2808
|
+
};
|
|
2809
|
+
const onConfirmed = (entry) => {
|
|
2810
|
+
lastConfirmedTx.value = entry;
|
|
2811
|
+
recordLatest(entry);
|
|
2812
|
+
};
|
|
2813
|
+
const onFailed = (entry) => {
|
|
2814
|
+
lastFailedTx.value = entry;
|
|
2815
|
+
recordLatest(entry);
|
|
2816
|
+
};
|
|
2817
|
+
activeMonitor.on("confirmed", onConfirmed);
|
|
2818
|
+
activeMonitor.on("failed", onFailed);
|
|
2819
|
+
onCleanup(() => {
|
|
2820
|
+
activeMonitor.off("confirmed", onConfirmed);
|
|
2821
|
+
activeMonitor.off("failed", onFailed);
|
|
2822
|
+
});
|
|
2823
|
+
},
|
|
2824
|
+
{ immediate: true }
|
|
2825
|
+
);
|
|
2826
|
+
return {
|
|
2827
|
+
lastTx,
|
|
2828
|
+
lastConfirmedTx,
|
|
2829
|
+
lastFailedTx,
|
|
2830
|
+
clear: () => {
|
|
2831
|
+
lastTx.value = null;
|
|
2832
|
+
lastConfirmedTx.value = null;
|
|
2833
|
+
lastFailedTx.value = null;
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
// src/useTxHistory.ts
|
|
2839
|
+
import { computed as computed24, shallowRef as shallowRef37, toValue as toValue34, watch as watch17 } from "vue";
|
|
2840
|
+
function useTxHistory(address, chainId, monitor) {
|
|
2841
|
+
const entries = shallowRef37([]);
|
|
2842
|
+
const isLoading = shallowRef37(false);
|
|
2843
|
+
const error = shallowRef37(null);
|
|
2844
|
+
let generation = 0;
|
|
2845
|
+
const refresh = async () => {
|
|
2846
|
+
const mine = ++generation;
|
|
2847
|
+
const activeMonitor = toValue34(monitor);
|
|
2848
|
+
if (!activeMonitor) {
|
|
2849
|
+
entries.value = [];
|
|
2850
|
+
isLoading.value = false;
|
|
2851
|
+
error.value = null;
|
|
2852
|
+
return;
|
|
2853
|
+
}
|
|
2854
|
+
isLoading.value = true;
|
|
2855
|
+
error.value = null;
|
|
2856
|
+
try {
|
|
2857
|
+
const result = await activeMonitor.getTxHistory(
|
|
2858
|
+
toValue34(address) ?? void 0,
|
|
2859
|
+
toValue34(chainId) ?? void 0
|
|
2860
|
+
);
|
|
2861
|
+
if (mine === generation) entries.value = result;
|
|
2862
|
+
} catch (err) {
|
|
2863
|
+
if (mine !== generation) return;
|
|
2864
|
+
error.value = err instanceof Error ? err : new Error("Failed to load transaction history");
|
|
2865
|
+
} finally {
|
|
2866
|
+
if (mine === generation) isLoading.value = false;
|
|
2867
|
+
}
|
|
2868
|
+
};
|
|
2869
|
+
watch17(
|
|
2870
|
+
[() => toValue34(monitor), () => toValue34(address), () => toValue34(chainId)],
|
|
2871
|
+
([activeMonitor], _previous, onCleanup) => {
|
|
2872
|
+
if (!activeMonitor) {
|
|
2873
|
+
void refresh();
|
|
2874
|
+
return;
|
|
2875
|
+
}
|
|
2876
|
+
const onStatusChange = () => {
|
|
2877
|
+
void refresh();
|
|
2878
|
+
};
|
|
2879
|
+
activeMonitor.on("statusChange", onStatusChange);
|
|
2880
|
+
onCleanup(() => activeMonitor.off("statusChange", onStatusChange));
|
|
2881
|
+
void refresh();
|
|
2882
|
+
},
|
|
2883
|
+
{ immediate: true }
|
|
2884
|
+
);
|
|
2885
|
+
return {
|
|
2886
|
+
entries,
|
|
2887
|
+
isLoading,
|
|
2888
|
+
error,
|
|
2889
|
+
refresh,
|
|
2890
|
+
summary: computed24(() => ({
|
|
2891
|
+
pending: entries.value.filter((item) => item.status === "pending").length,
|
|
2892
|
+
confirmed: entries.value.filter((item) => item.status === "confirmed").length,
|
|
2893
|
+
failed: entries.value.filter((item) => item.status === "failed").length
|
|
2894
|
+
}))
|
|
2895
|
+
};
|
|
2896
|
+
}
|
|
2897
|
+
|
|
2898
|
+
// src/useTxMonitor.ts
|
|
2899
|
+
import { computed as computed25, shallowRef as shallowRef38, toValue as toValue35, watch as watch18 } from "vue";
|
|
2900
|
+
function useTxMonitor(hash, chainId, monitor) {
|
|
2901
|
+
const entry = shallowRef38(null);
|
|
2902
|
+
const isLoading = shallowRef38(false);
|
|
2903
|
+
const isWatching = shallowRef38(false);
|
|
2904
|
+
const error = shallowRef38(null);
|
|
2905
|
+
let generation = 0;
|
|
2906
|
+
const refresh = async () => {
|
|
2907
|
+
const activeMonitor = toValue35(monitor);
|
|
2908
|
+
const activeHash = toValue35(hash);
|
|
2909
|
+
const activeChainId = toValue35(chainId);
|
|
2910
|
+
if (!activeMonitor || !activeHash) return;
|
|
2911
|
+
isLoading.value = true;
|
|
2912
|
+
error.value = null;
|
|
2913
|
+
try {
|
|
2914
|
+
await activeMonitor.refreshTx(activeHash, activeChainId ?? void 0);
|
|
2915
|
+
const current = activeMonitor.getTxStatus(
|
|
2916
|
+
activeHash,
|
|
2917
|
+
activeChainId ?? void 0
|
|
2918
|
+
);
|
|
2919
|
+
if (current) entry.value = current;
|
|
2920
|
+
} catch (err) {
|
|
2921
|
+
error.value = err instanceof Error ? err : new Error("Failed to refresh transaction");
|
|
2922
|
+
} finally {
|
|
2923
|
+
isLoading.value = false;
|
|
2924
|
+
}
|
|
2925
|
+
};
|
|
2926
|
+
const stopWatching = () => {
|
|
2927
|
+
const activeMonitor = toValue35(monitor);
|
|
2928
|
+
const activeHash = toValue35(hash);
|
|
2929
|
+
const activeChainId = toValue35(chainId);
|
|
2930
|
+
if (!activeMonitor || !activeHash) return;
|
|
2931
|
+
activeMonitor.stopWatching(activeHash, activeChainId ?? void 0);
|
|
2932
|
+
isWatching.value = false;
|
|
2933
|
+
};
|
|
2934
|
+
watch18(
|
|
2935
|
+
[() => toValue35(monitor), () => toValue35(hash), () => toValue35(chainId)],
|
|
2936
|
+
([activeMonitor, activeHash, activeChainId], _previous, onCleanup) => {
|
|
2937
|
+
const mine = ++generation;
|
|
2938
|
+
if (!activeMonitor || !activeHash || !activeChainId) {
|
|
2939
|
+
entry.value = null;
|
|
2940
|
+
isLoading.value = false;
|
|
2941
|
+
isWatching.value = false;
|
|
2942
|
+
error.value = null;
|
|
2943
|
+
return;
|
|
2944
|
+
}
|
|
2945
|
+
let cancelled = false;
|
|
2946
|
+
const onStatusChange = (updated) => {
|
|
2947
|
+
if (!cancelled && updated.hash === activeHash && updated.chainId === activeChainId) {
|
|
2948
|
+
entry.value = { ...updated };
|
|
2949
|
+
}
|
|
2950
|
+
};
|
|
2951
|
+
activeMonitor.on("statusChange", onStatusChange);
|
|
2952
|
+
onCleanup(() => {
|
|
2953
|
+
cancelled = true;
|
|
2954
|
+
activeMonitor.off("statusChange", onStatusChange);
|
|
2955
|
+
});
|
|
2956
|
+
isWatching.value = true;
|
|
2957
|
+
isLoading.value = true;
|
|
2958
|
+
error.value = null;
|
|
2959
|
+
const current = activeMonitor.getTxStatus(activeHash, activeChainId);
|
|
2960
|
+
if (current) entry.value = current;
|
|
2961
|
+
activeMonitor.watchTx(activeHash, activeChainId, {}).then((initial) => {
|
|
2962
|
+
if (cancelled || mine !== generation) return;
|
|
2963
|
+
entry.value = initial;
|
|
2964
|
+
isLoading.value = false;
|
|
2965
|
+
}).catch((err) => {
|
|
2966
|
+
if (cancelled || mine !== generation) return;
|
|
2967
|
+
error.value = err instanceof Error ? err : new Error("Failed to watch transaction");
|
|
2968
|
+
isLoading.value = false;
|
|
2969
|
+
});
|
|
2970
|
+
},
|
|
2971
|
+
{ immediate: true }
|
|
2972
|
+
);
|
|
2973
|
+
return {
|
|
2974
|
+
entry,
|
|
2975
|
+
status: computed25(() => entry.value?.status ?? "idle"),
|
|
2976
|
+
isLoading,
|
|
2977
|
+
isWatching,
|
|
2978
|
+
error,
|
|
2979
|
+
refresh,
|
|
2980
|
+
stopWatching
|
|
2981
|
+
};
|
|
2982
|
+
}
|
|
2983
|
+
|
|
298
2984
|
// src/useCapabilities.ts
|
|
299
2985
|
import {
|
|
300
2986
|
atomicSupportFor,
|
|
301
2987
|
normalizeCapabilities,
|
|
302
2988
|
selectChainCapabilities
|
|
303
2989
|
} from "@naculus/connect-appkit-core";
|
|
304
|
-
import { computed as
|
|
2990
|
+
import { computed as computed26, shallowRef as shallowRef39, toValue as toValue36, watchEffect as watchEffect2 } from "vue";
|
|
305
2991
|
function useCapabilities(client, session, chainId) {
|
|
306
|
-
const capabilities =
|
|
2992
|
+
const capabilities = shallowRef39(
|
|
307
2993
|
null
|
|
308
2994
|
);
|
|
309
|
-
const isFetching =
|
|
310
|
-
const error =
|
|
2995
|
+
const isFetching = shallowRef39(false);
|
|
2996
|
+
const error = shallowRef39(null);
|
|
311
2997
|
let generation = 0;
|
|
312
2998
|
const refetch = async () => {
|
|
313
2999
|
const mine = ++generation;
|
|
314
|
-
const activeClient =
|
|
315
|
-
const activeSession =
|
|
3000
|
+
const activeClient = toValue36(client);
|
|
3001
|
+
const activeSession = toValue36(session);
|
|
316
3002
|
if (!activeClient?.getCapabilities || !activeSession) {
|
|
317
3003
|
capabilities.value = null;
|
|
318
3004
|
isFetching.value = false;
|
|
@@ -334,17 +3020,17 @@ function useCapabilities(client, session, chainId) {
|
|
|
334
3020
|
}
|
|
335
3021
|
};
|
|
336
3022
|
watchEffect2(() => {
|
|
337
|
-
void
|
|
338
|
-
void
|
|
3023
|
+
void toValue36(client);
|
|
3024
|
+
void toValue36(session);
|
|
339
3025
|
void refetch();
|
|
340
3026
|
});
|
|
341
3027
|
return {
|
|
342
3028
|
capabilities,
|
|
343
|
-
current:
|
|
344
|
-
() => selectChainCapabilities(capabilities.value,
|
|
3029
|
+
current: computed26(
|
|
3030
|
+
() => selectChainCapabilities(capabilities.value, toValue36(chainId))
|
|
345
3031
|
),
|
|
346
|
-
atomic:
|
|
347
|
-
() => atomicSupportFor(capabilities.value,
|
|
3032
|
+
atomic: computed26(
|
|
3033
|
+
() => atomicSupportFor(capabilities.value, toValue36(chainId))
|
|
348
3034
|
),
|
|
349
3035
|
isFetching,
|
|
350
3036
|
error,
|
|
@@ -356,17 +3042,17 @@ function useCapabilities(client, session, chainId) {
|
|
|
356
3042
|
import {
|
|
357
3043
|
readSolanaRoles
|
|
358
3044
|
} from "@naculus/connect-appkit-core";
|
|
359
|
-
import { computed as
|
|
3045
|
+
import { computed as computed27, toValue as toValue37 } from "vue";
|
|
360
3046
|
function useSolanaRoles(connector, session) {
|
|
361
|
-
const state =
|
|
362
|
-
() => readSolanaRoles(
|
|
3047
|
+
const state = computed27(
|
|
3048
|
+
() => readSolanaRoles(toValue37(connector), toValue37(session))
|
|
363
3049
|
);
|
|
364
3050
|
return {
|
|
365
|
-
roles:
|
|
366
|
-
absence:
|
|
367
|
-
identity:
|
|
368
|
-
signer:
|
|
369
|
-
payer:
|
|
3051
|
+
roles: computed27(() => state.value.roles),
|
|
3052
|
+
absence: computed27(() => state.value.absence),
|
|
3053
|
+
identity: computed27(() => state.value.roles?.identity ?? null),
|
|
3054
|
+
signer: computed27(() => state.value.roles?.signer ?? null),
|
|
3055
|
+
payer: computed27(() => state.value.roles?.payer ?? null)
|
|
370
3056
|
};
|
|
371
3057
|
}
|
|
372
3058
|
export {
|
|
@@ -398,11 +3084,56 @@ export {
|
|
|
398
3084
|
AppkitTabs,
|
|
399
3085
|
AppkitToggleGroup,
|
|
400
3086
|
AppkitTooltip,
|
|
3087
|
+
useAccount,
|
|
401
3088
|
useAccounts,
|
|
3089
|
+
useBalance,
|
|
402
3090
|
useCapabilities,
|
|
403
3091
|
useChain,
|
|
3092
|
+
useCompareCosts,
|
|
3093
|
+
useConnect,
|
|
3094
|
+
useCreateSessionKey,
|
|
3095
|
+
useDelegation,
|
|
3096
|
+
useDelegationPolicy,
|
|
3097
|
+
useDisconnect,
|
|
3098
|
+
useERC20Approve,
|
|
3099
|
+
useERC20Transfer,
|
|
3100
|
+
useERC20TransferSimulation,
|
|
3101
|
+
useEmbeddedWallet,
|
|
3102
|
+
useExecuteCalls,
|
|
3103
|
+
useExecuteRoute,
|
|
3104
|
+
useLastTx,
|
|
3105
|
+
useLookupAddress,
|
|
3106
|
+
useNotification,
|
|
404
3107
|
usePassphraseGate,
|
|
3108
|
+
useResolveName,
|
|
3109
|
+
useRevokeSession,
|
|
3110
|
+
useRouteQuote,
|
|
3111
|
+
useSIWxLogin,
|
|
3112
|
+
useSIWxSession,
|
|
3113
|
+
useSendCalls,
|
|
3114
|
+
useSendTransaction,
|
|
3115
|
+
useSendUserOperation,
|
|
3116
|
+
useSendWithSession,
|
|
3117
|
+
useSession,
|
|
3118
|
+
useSessionKeys,
|
|
3119
|
+
useSignInWithEthereum,
|
|
3120
|
+
useSignInWithX,
|
|
3121
|
+
useSignMessage,
|
|
3122
|
+
useSimulateTransfer,
|
|
3123
|
+
useSiwxAuthSession,
|
|
3124
|
+
useSmartAccount,
|
|
3125
|
+
useSolanaAccount,
|
|
405
3126
|
useSolanaBalance,
|
|
406
|
-
useSolanaRoles
|
|
3127
|
+
useSolanaRoles,
|
|
3128
|
+
useSolanaTransaction,
|
|
3129
|
+
useSwitchChain,
|
|
3130
|
+
useTokenBalance,
|
|
3131
|
+
useTokenList,
|
|
3132
|
+
useTokenSearch,
|
|
3133
|
+
useTransactionSimulation,
|
|
3134
|
+
useTxHistory,
|
|
3135
|
+
useTxMonitor,
|
|
3136
|
+
useUserOpStatus,
|
|
3137
|
+
useValidateDestination
|
|
407
3138
|
};
|
|
408
3139
|
//# sourceMappingURL=index.js.map
|