@naculus/connect-appkit-vue 0.2.4 → 0.2.5
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/dist/index.cjs +1154 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +376 -4
- package/dist/index.d.ts +376 -4
- package/dist/index.js +1154 -40
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -209,6 +209,904 @@ 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/useAccount.ts
|
|
291
|
+
import { computed as computed3, toValue as toValue2 } from "vue";
|
|
292
|
+
function useAccount(accounts, connected) {
|
|
293
|
+
const parsed = useAccounts(accounts);
|
|
294
|
+
const isConnected = computed3(() => toValue2(connected));
|
|
295
|
+
const accountList = computed3(() => toValue2(accounts) ?? []);
|
|
296
|
+
return {
|
|
297
|
+
accounts: computed3(
|
|
298
|
+
() => isConnected.value && accountList.value.length > 0 ? parsed.accounts.value : null
|
|
299
|
+
),
|
|
300
|
+
evmAccount: computed3(
|
|
301
|
+
() => isConnected.value ? parsed.evmAccount.value : null
|
|
302
|
+
),
|
|
303
|
+
primaryAccount: computed3(() => accountList.value[0] ?? null),
|
|
304
|
+
isConnected,
|
|
305
|
+
count: computed3(() => accountList.value.length)
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/useSession.ts
|
|
310
|
+
import { computed as computed4, shallowRef as shallowRef2, toValue as toValue3, watch } from "vue";
|
|
311
|
+
function readSession(manager) {
|
|
312
|
+
const bundle = manager?.getActiveBundle();
|
|
313
|
+
if (!bundle) {
|
|
314
|
+
return {
|
|
315
|
+
session: null,
|
|
316
|
+
chainSessions: [],
|
|
317
|
+
activeChainId: null,
|
|
318
|
+
connectorId: null
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
session: bundle.walletSession,
|
|
323
|
+
chainSessions: Array.from(bundle.chainSessions.values()),
|
|
324
|
+
activeChainId: bundle.activeChainId,
|
|
325
|
+
connectorId: bundle.walletSession.walletType
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
function useSession(manager) {
|
|
329
|
+
const snapshot = shallowRef2(readSession(toValue3(manager)));
|
|
330
|
+
watch(
|
|
331
|
+
() => toValue3(manager),
|
|
332
|
+
(current, _previous, onCleanup) => {
|
|
333
|
+
const update = () => {
|
|
334
|
+
snapshot.value = readSession(current);
|
|
335
|
+
};
|
|
336
|
+
update();
|
|
337
|
+
if (!current) return;
|
|
338
|
+
current.on("sessionConnected", update);
|
|
339
|
+
current.on("sessionDisconnected", update);
|
|
340
|
+
current.on("chainChanged", update);
|
|
341
|
+
onCleanup(() => {
|
|
342
|
+
current.off("sessionConnected", update);
|
|
343
|
+
current.off("sessionDisconnected", update);
|
|
344
|
+
current.off("chainChanged", update);
|
|
345
|
+
});
|
|
346
|
+
},
|
|
347
|
+
{ immediate: true }
|
|
348
|
+
);
|
|
349
|
+
return {
|
|
350
|
+
session: computed4(() => snapshot.value.session),
|
|
351
|
+
chainSessions: computed4(() => snapshot.value.chainSessions),
|
|
352
|
+
activeChainId: computed4(() => snapshot.value.activeChainId),
|
|
353
|
+
isConnected: computed4(() => snapshot.value.session !== null),
|
|
354
|
+
connectorId: computed4(() => snapshot.value.connectorId)
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// src/useConnect.ts
|
|
359
|
+
import { WalletError } from "@naculus/connect-core";
|
|
360
|
+
import { computed as computed5, onScopeDispose as onScopeDispose2, shallowRef as shallowRef3, toValue as toValue4, unref as unref2 } from "vue";
|
|
361
|
+
function useConnect(action, status) {
|
|
362
|
+
const isLoading = shallowRef3(false);
|
|
363
|
+
const error = shallowRef3(null);
|
|
364
|
+
let disposed = false;
|
|
365
|
+
let inFlight = null;
|
|
366
|
+
const connect = () => {
|
|
367
|
+
if (inFlight) return inFlight;
|
|
368
|
+
const invoke = unref2(action);
|
|
369
|
+
isLoading.value = true;
|
|
370
|
+
error.value = null;
|
|
371
|
+
const pending = Promise.resolve().then(() => invoke()).catch((cause) => {
|
|
372
|
+
if (disposed) return;
|
|
373
|
+
const message = cause instanceof Error ? cause.message : "Connection failed";
|
|
374
|
+
error.value = cause instanceof WalletError ? cause : new Error(message);
|
|
375
|
+
}).finally(() => {
|
|
376
|
+
if (inFlight === pending) inFlight = null;
|
|
377
|
+
if (!disposed) isLoading.value = false;
|
|
378
|
+
});
|
|
379
|
+
inFlight = pending;
|
|
380
|
+
return pending;
|
|
381
|
+
};
|
|
382
|
+
onScopeDispose2(() => {
|
|
383
|
+
disposed = true;
|
|
384
|
+
});
|
|
385
|
+
return {
|
|
386
|
+
connect,
|
|
387
|
+
isConnecting: computed5(
|
|
388
|
+
() => isLoading.value || toValue4(status) === "connecting"
|
|
389
|
+
),
|
|
390
|
+
error
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/useDisconnect.ts
|
|
395
|
+
import { onScopeDispose as onScopeDispose3, shallowRef as shallowRef4, toValue as toValue5, unref as unref3 } from "vue";
|
|
396
|
+
function useDisconnect(action, status) {
|
|
397
|
+
const isDisconnecting = shallowRef4(false);
|
|
398
|
+
const error = shallowRef4(null);
|
|
399
|
+
let disposed = false;
|
|
400
|
+
let inFlight = null;
|
|
401
|
+
const disconnect = () => {
|
|
402
|
+
if (inFlight) return inFlight;
|
|
403
|
+
if (toValue5(status) === "disconnected") return Promise.resolve();
|
|
404
|
+
const invoke = unref3(action);
|
|
405
|
+
isDisconnecting.value = true;
|
|
406
|
+
error.value = null;
|
|
407
|
+
const pending = Promise.resolve().then(() => invoke()).catch((cause) => {
|
|
408
|
+
if (!disposed) {
|
|
409
|
+
error.value = cause instanceof Error ? cause : new Error("Disconnect failed");
|
|
410
|
+
}
|
|
411
|
+
}).finally(() => {
|
|
412
|
+
if (inFlight === pending) inFlight = null;
|
|
413
|
+
if (!disposed) isDisconnecting.value = false;
|
|
414
|
+
});
|
|
415
|
+
inFlight = pending;
|
|
416
|
+
return pending;
|
|
417
|
+
};
|
|
418
|
+
const cleanup = () => {
|
|
419
|
+
disposed = true;
|
|
420
|
+
};
|
|
421
|
+
onScopeDispose3(cleanup);
|
|
422
|
+
return { disconnect, isDisconnecting, error, cleanup };
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// src/useSwitchChain.ts
|
|
426
|
+
import { toChainSwitchError } from "@naculus/connect-appkit-core";
|
|
427
|
+
import { computed as computed6, onScopeDispose as onScopeDispose4, shallowRef as shallowRef5, toValue as toValue6, unref as unref4 } from "vue";
|
|
428
|
+
function useSwitchChain(action, chainId) {
|
|
429
|
+
const isSwitching = shallowRef5(false);
|
|
430
|
+
const error = shallowRef5(null);
|
|
431
|
+
let generation = 0;
|
|
432
|
+
let active = 0;
|
|
433
|
+
let disposed = false;
|
|
434
|
+
const switchChain = async (targetChainId) => {
|
|
435
|
+
const invoke = unref4(action);
|
|
436
|
+
const mine = ++generation;
|
|
437
|
+
active++;
|
|
438
|
+
isSwitching.value = true;
|
|
439
|
+
error.value = null;
|
|
440
|
+
try {
|
|
441
|
+
await invoke(targetChainId);
|
|
442
|
+
} catch (cause) {
|
|
443
|
+
const walletError = toChainSwitchError(cause);
|
|
444
|
+
if (!disposed && mine === generation) error.value = walletError;
|
|
445
|
+
throw walletError;
|
|
446
|
+
} finally {
|
|
447
|
+
active--;
|
|
448
|
+
if (!disposed) isSwitching.value = active > 0;
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
onScopeDispose4(() => {
|
|
452
|
+
disposed = true;
|
|
453
|
+
generation++;
|
|
454
|
+
});
|
|
455
|
+
return {
|
|
456
|
+
switchChain,
|
|
457
|
+
isSwitching,
|
|
458
|
+
currentChainId: computed6(() => toValue6(chainId) ?? null),
|
|
459
|
+
error,
|
|
460
|
+
clearError: () => {
|
|
461
|
+
error.value = null;
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// src/useBalance.ts
|
|
467
|
+
import { bareEvmAddress } from "@naculus/connect-appkit-core";
|
|
468
|
+
import { formatUnits } from "@naculus/connect-core";
|
|
469
|
+
import { computed as computed7, onScopeDispose as onScopeDispose5, shallowRef as shallowRef6, toValue as toValue7, watch as watch2 } from "vue";
|
|
470
|
+
function useBalance(account, client, options = {}) {
|
|
471
|
+
const balance = shallowRef6(null);
|
|
472
|
+
const isFetching = shallowRef6(false);
|
|
473
|
+
const error = shallowRef6(null);
|
|
474
|
+
let generation = 0;
|
|
475
|
+
let disposed = false;
|
|
476
|
+
let timer = null;
|
|
477
|
+
const refetch = async () => {
|
|
478
|
+
const reader = toValue7(client);
|
|
479
|
+
const address = bareEvmAddress(toValue7(account));
|
|
480
|
+
const own = ++generation;
|
|
481
|
+
if (!reader || !address) {
|
|
482
|
+
balance.value = null;
|
|
483
|
+
error.value = null;
|
|
484
|
+
isFetching.value = false;
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
isFetching.value = true;
|
|
488
|
+
error.value = null;
|
|
489
|
+
try {
|
|
490
|
+
const next = await reader.getBalance({ address });
|
|
491
|
+
if (disposed || own !== generation) return;
|
|
492
|
+
balance.value = next.toString();
|
|
493
|
+
} catch (cause) {
|
|
494
|
+
if (disposed || own !== generation) return;
|
|
495
|
+
balance.value = null;
|
|
496
|
+
error.value = cause instanceof Error ? cause : new Error("Balance read failed");
|
|
497
|
+
} finally {
|
|
498
|
+
if (!disposed && own === generation) isFetching.value = false;
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
const stopTimer = () => {
|
|
502
|
+
if (timer) clearInterval(timer);
|
|
503
|
+
timer = null;
|
|
504
|
+
};
|
|
505
|
+
watch2(
|
|
506
|
+
[
|
|
507
|
+
() => toValue7(account),
|
|
508
|
+
() => toValue7(client),
|
|
509
|
+
() => toValue7(options.refreshInterval) ?? 0
|
|
510
|
+
],
|
|
511
|
+
([, , interval]) => {
|
|
512
|
+
stopTimer();
|
|
513
|
+
void refetch();
|
|
514
|
+
if (interval > 0) timer = setInterval(() => void refetch(), interval);
|
|
515
|
+
},
|
|
516
|
+
{ immediate: true }
|
|
517
|
+
);
|
|
518
|
+
onScopeDispose5(() => {
|
|
519
|
+
disposed = true;
|
|
520
|
+
generation++;
|
|
521
|
+
stopTimer();
|
|
522
|
+
});
|
|
523
|
+
return {
|
|
524
|
+
balance,
|
|
525
|
+
formatted: computed7(
|
|
526
|
+
() => balance.value === null ? null : formatUnits(BigInt(balance.value), toValue7(options.decimals) ?? 18)
|
|
527
|
+
),
|
|
528
|
+
symbol: computed7(() => toValue7(options.symbol) ?? null),
|
|
529
|
+
isFetching,
|
|
530
|
+
error,
|
|
531
|
+
refetch
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// src/useRouteQuote.ts
|
|
536
|
+
import {
|
|
537
|
+
isQuotableInput
|
|
538
|
+
} from "@naculus/connect-appkit-core";
|
|
539
|
+
import { onScopeDispose as onScopeDispose6, shallowRef as shallowRef7, toValue as toValue8, unref as unref5, watch as watch3 } from "vue";
|
|
540
|
+
function useRouteQuote(input, getQuotes, options = {}) {
|
|
541
|
+
const quotes = shallowRef7([]);
|
|
542
|
+
const loading = shallowRef7(false);
|
|
543
|
+
const error = shallowRef7(null);
|
|
544
|
+
let generation = 0;
|
|
545
|
+
let disposed = false;
|
|
546
|
+
let timer = null;
|
|
547
|
+
const clearTimer = () => {
|
|
548
|
+
if (timer) clearTimeout(timer);
|
|
549
|
+
timer = null;
|
|
550
|
+
};
|
|
551
|
+
const fetchQuotes = async () => {
|
|
552
|
+
const current = toValue8(input);
|
|
553
|
+
const fn = unref5(getQuotes);
|
|
554
|
+
const own = ++generation;
|
|
555
|
+
if (!isQuotableInput(current)) {
|
|
556
|
+
quotes.value = [];
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (!fn) return;
|
|
560
|
+
loading.value = true;
|
|
561
|
+
error.value = null;
|
|
562
|
+
try {
|
|
563
|
+
const result = await fn(
|
|
564
|
+
current.fromChain,
|
|
565
|
+
current.toChain,
|
|
566
|
+
current.fromToken,
|
|
567
|
+
current.amount,
|
|
568
|
+
current.options,
|
|
569
|
+
current.toToken
|
|
570
|
+
);
|
|
571
|
+
if (disposed || own !== generation) return;
|
|
572
|
+
quotes.value = result;
|
|
573
|
+
} catch (cause) {
|
|
574
|
+
if (disposed || own !== generation) return;
|
|
575
|
+
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
576
|
+
quotes.value = [];
|
|
577
|
+
} finally {
|
|
578
|
+
if (!disposed && own === generation) loading.value = false;
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
watch3(
|
|
582
|
+
[
|
|
583
|
+
() => toValue8(input).fromChain,
|
|
584
|
+
() => toValue8(input).toChain,
|
|
585
|
+
() => toValue8(input).fromToken,
|
|
586
|
+
() => toValue8(input).toToken,
|
|
587
|
+
() => toValue8(input).amount,
|
|
588
|
+
() => unref5(getQuotes)
|
|
589
|
+
],
|
|
590
|
+
([fromChain, toChain, fromToken, , amount]) => {
|
|
591
|
+
clearTimer();
|
|
592
|
+
if (!fromChain || !toChain || !fromToken || !amount) {
|
|
593
|
+
quotes.value = [];
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
timer = setTimeout(() => {
|
|
597
|
+
timer = null;
|
|
598
|
+
void fetchQuotes();
|
|
599
|
+
}, options.debounceMs ?? 300);
|
|
600
|
+
},
|
|
601
|
+
{ immediate: true }
|
|
602
|
+
);
|
|
603
|
+
onScopeDispose6(() => {
|
|
604
|
+
disposed = true;
|
|
605
|
+
generation++;
|
|
606
|
+
clearTimer();
|
|
607
|
+
});
|
|
608
|
+
return {
|
|
609
|
+
quotes,
|
|
610
|
+
loading,
|
|
611
|
+
error,
|
|
612
|
+
refresh: fetchQuotes,
|
|
613
|
+
clear: () => {
|
|
614
|
+
clearTimer();
|
|
615
|
+
generation++;
|
|
616
|
+
quotes.value = [];
|
|
617
|
+
error.value = null;
|
|
618
|
+
loading.value = false;
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// src/useCompareCosts.ts
|
|
624
|
+
import {
|
|
625
|
+
compareCostsKey
|
|
626
|
+
} from "@naculus/connect-appkit-core";
|
|
627
|
+
import { onScopeDispose as onScopeDispose7, shallowRef as shallowRef8, toValue as toValue9, unref as unref6, watch as watch4 } from "vue";
|
|
628
|
+
function useCompareCosts(input, compareCosts) {
|
|
629
|
+
const comparisons = shallowRef8([]);
|
|
630
|
+
const loading = shallowRef8(false);
|
|
631
|
+
const error = shallowRef8(null);
|
|
632
|
+
let generation = 0;
|
|
633
|
+
let disposed = false;
|
|
634
|
+
const fetchComparisons = async () => {
|
|
635
|
+
const { operation, chains, options } = toValue9(input);
|
|
636
|
+
const fn = unref6(compareCosts);
|
|
637
|
+
const own = ++generation;
|
|
638
|
+
if (!chains || chains.length === 0) {
|
|
639
|
+
comparisons.value = [];
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
if (!fn) return;
|
|
643
|
+
loading.value = true;
|
|
644
|
+
error.value = null;
|
|
645
|
+
try {
|
|
646
|
+
const result = await fn(operation, chains, options);
|
|
647
|
+
if (disposed || own !== generation) return;
|
|
648
|
+
comparisons.value = result;
|
|
649
|
+
} catch (cause) {
|
|
650
|
+
if (disposed || own !== generation) return;
|
|
651
|
+
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
652
|
+
comparisons.value = [];
|
|
653
|
+
} finally {
|
|
654
|
+
if (!disposed && own === generation) loading.value = false;
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
watch4(
|
|
658
|
+
[() => compareCostsKey(toValue9(input)), () => unref6(compareCosts)],
|
|
659
|
+
() => {
|
|
660
|
+
void fetchComparisons();
|
|
661
|
+
},
|
|
662
|
+
{ immediate: true }
|
|
663
|
+
);
|
|
664
|
+
onScopeDispose7(() => {
|
|
665
|
+
disposed = true;
|
|
666
|
+
generation++;
|
|
667
|
+
});
|
|
668
|
+
return { comparisons, loading, error, refresh: fetchComparisons };
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// src/useExecuteRoute.ts
|
|
672
|
+
import {
|
|
673
|
+
toExecuteRouteError,
|
|
674
|
+
validateRouteRecipient
|
|
675
|
+
} from "@naculus/connect-appkit-core";
|
|
676
|
+
import { onScopeDispose as onScopeDispose8, shallowRef as shallowRef9, unref as unref7 } from "vue";
|
|
677
|
+
function useExecuteRoute(executeRoute) {
|
|
678
|
+
const executing = shallowRef9(false);
|
|
679
|
+
const result = shallowRef9(null);
|
|
680
|
+
const error = shallowRef9(null);
|
|
681
|
+
let inFlight = false;
|
|
682
|
+
let disposed = false;
|
|
683
|
+
const execute = async (quote, recipient, options) => {
|
|
684
|
+
const fn = unref7(executeRoute);
|
|
685
|
+
if (!fn) {
|
|
686
|
+
error.value = {
|
|
687
|
+
code: "no_executor",
|
|
688
|
+
message: "No executeRoute function provided"
|
|
689
|
+
};
|
|
690
|
+
result.value = null;
|
|
691
|
+
return null;
|
|
692
|
+
}
|
|
693
|
+
const recipientError = validateRouteRecipient(quote, recipient);
|
|
694
|
+
if (recipientError) {
|
|
695
|
+
error.value = recipientError;
|
|
696
|
+
result.value = null;
|
|
697
|
+
return null;
|
|
698
|
+
}
|
|
699
|
+
if (inFlight) {
|
|
700
|
+
error.value = {
|
|
701
|
+
code: "execution_in_progress",
|
|
702
|
+
message: "A route execution is already in progress"
|
|
703
|
+
};
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
inFlight = true;
|
|
707
|
+
executing.value = true;
|
|
708
|
+
error.value = null;
|
|
709
|
+
result.value = null;
|
|
710
|
+
try {
|
|
711
|
+
const execResult = await fn(quote, recipient, options);
|
|
712
|
+
if (!disposed) result.value = execResult;
|
|
713
|
+
return execResult;
|
|
714
|
+
} catch (cause) {
|
|
715
|
+
if (!disposed) error.value = toExecuteRouteError(cause);
|
|
716
|
+
return null;
|
|
717
|
+
} finally {
|
|
718
|
+
inFlight = false;
|
|
719
|
+
if (!disposed) executing.value = false;
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
onScopeDispose8(() => {
|
|
723
|
+
disposed = true;
|
|
724
|
+
});
|
|
725
|
+
return {
|
|
726
|
+
execute,
|
|
727
|
+
executing,
|
|
728
|
+
result,
|
|
729
|
+
error,
|
|
730
|
+
reset: () => {
|
|
731
|
+
result.value = null;
|
|
732
|
+
error.value = null;
|
|
733
|
+
executing.value = false;
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// src/useTokenList.ts
|
|
739
|
+
import { eip155ChainIdToNumber } from "@naculus/connect-appkit-core";
|
|
740
|
+
import {
|
|
741
|
+
TokenListManager
|
|
742
|
+
} from "@naculus/connect-core";
|
|
743
|
+
import { onScopeDispose as onScopeDispose9, shallowRef as shallowRef10, toValue as toValue10, watch as watch5 } from "vue";
|
|
744
|
+
function useTokenList(chainId, options = {}) {
|
|
745
|
+
const config = {};
|
|
746
|
+
if (options.sources) config.sources = options.sources;
|
|
747
|
+
const manager = options.manager ?? new TokenListManager(config);
|
|
748
|
+
const tokens = shallowRef10([]);
|
|
749
|
+
const isLoading = shallowRef10(options.autoLoad !== false);
|
|
750
|
+
const isLoaded = shallowRef10(false);
|
|
751
|
+
const error = shallowRef10(null);
|
|
752
|
+
let generation = 0;
|
|
753
|
+
let disposed = false;
|
|
754
|
+
const select = () => {
|
|
755
|
+
const id = toValue10(chainId);
|
|
756
|
+
const numeric = id ? eip155ChainIdToNumber(id) : void 0;
|
|
757
|
+
return manager.getTokens(
|
|
758
|
+
numeric !== void 0 ? { chainId: numeric } : void 0
|
|
759
|
+
);
|
|
760
|
+
};
|
|
761
|
+
const run = async (op) => {
|
|
762
|
+
const own = ++generation;
|
|
763
|
+
isLoading.value = true;
|
|
764
|
+
error.value = null;
|
|
765
|
+
try {
|
|
766
|
+
await op();
|
|
767
|
+
if (disposed || own !== generation) return;
|
|
768
|
+
tokens.value = select();
|
|
769
|
+
isLoaded.value = true;
|
|
770
|
+
} catch (cause) {
|
|
771
|
+
if (disposed || own !== generation) return;
|
|
772
|
+
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
773
|
+
} finally {
|
|
774
|
+
if (!disposed && own === generation) isLoading.value = false;
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
watch5(
|
|
778
|
+
() => toValue10(chainId),
|
|
779
|
+
() => {
|
|
780
|
+
if (options.autoLoad !== false) void run(() => manager.load());
|
|
781
|
+
},
|
|
782
|
+
{ immediate: true }
|
|
783
|
+
);
|
|
784
|
+
onScopeDispose9(() => {
|
|
785
|
+
disposed = true;
|
|
786
|
+
generation++;
|
|
787
|
+
});
|
|
788
|
+
return {
|
|
789
|
+
tokens,
|
|
790
|
+
isLoading,
|
|
791
|
+
isLoaded,
|
|
792
|
+
error,
|
|
793
|
+
refetch: () => run(() => manager.refresh())
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// src/useTokenSearch.ts
|
|
798
|
+
import { eip155ChainIdToNumber as eip155ChainIdToNumber2 } from "@naculus/connect-appkit-core";
|
|
799
|
+
import {
|
|
800
|
+
TokenListManager as TokenListManager2
|
|
801
|
+
} from "@naculus/connect-core";
|
|
802
|
+
import { onScopeDispose as onScopeDispose10, shallowRef as shallowRef11, toValue as toValue11, watch as watch6 } from "vue";
|
|
803
|
+
var DEBOUNCE_MS = 300;
|
|
804
|
+
var EMPTY = { exact: [], fuzzy: [], hasMore: false };
|
|
805
|
+
var sharedManager = null;
|
|
806
|
+
function getSharedManager() {
|
|
807
|
+
if (!sharedManager) {
|
|
808
|
+
sharedManager = new TokenListManager2();
|
|
809
|
+
sharedManager.load().catch(() => {
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
return sharedManager;
|
|
813
|
+
}
|
|
814
|
+
function useTokenSearch(query, chainId, options = {}) {
|
|
815
|
+
const results = shallowRef11(EMPTY);
|
|
816
|
+
const isSearching = shallowRef11(false);
|
|
817
|
+
let timer = null;
|
|
818
|
+
const clear = () => {
|
|
819
|
+
if (timer) clearTimeout(timer);
|
|
820
|
+
timer = null;
|
|
821
|
+
};
|
|
822
|
+
watch6(
|
|
823
|
+
[() => (toValue11(query) ?? "").trim(), () => toValue11(chainId)],
|
|
824
|
+
([q, id]) => {
|
|
825
|
+
clear();
|
|
826
|
+
if (!q) {
|
|
827
|
+
results.value = EMPTY;
|
|
828
|
+
isSearching.value = false;
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
isSearching.value = true;
|
|
832
|
+
timer = setTimeout(() => {
|
|
833
|
+
timer = null;
|
|
834
|
+
const manager = options.manager ?? getSharedManager();
|
|
835
|
+
const numeric = id ? eip155ChainIdToNumber2(id) : void 0;
|
|
836
|
+
results.value = manager.search(q, {
|
|
837
|
+
chainId: numeric,
|
|
838
|
+
limit: options.limit ?? 20
|
|
839
|
+
});
|
|
840
|
+
isSearching.value = false;
|
|
841
|
+
}, options.debounceMs ?? DEBOUNCE_MS);
|
|
842
|
+
},
|
|
843
|
+
{ immediate: true }
|
|
844
|
+
);
|
|
845
|
+
onScopeDispose10(clear);
|
|
846
|
+
return { results, isSearching };
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// src/useValidateDestination.ts
|
|
850
|
+
import {
|
|
851
|
+
validateDestination
|
|
852
|
+
} from "@naculus/connect-appkit-core";
|
|
853
|
+
import { computed as computed8, toValue as toValue12 } from "vue";
|
|
854
|
+
function useValidateDestination(address) {
|
|
855
|
+
return {
|
|
856
|
+
validation: computed8(() => validateDestination(toValue12(address) ?? ""))
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// src/useTokenBalance.ts
|
|
861
|
+
import { bareEvmAddress as bareEvmAddress2 } from "@naculus/connect-appkit-core";
|
|
862
|
+
import { ERC20_MIN_ABI, formatUnits as formatUnits2 } from "@naculus/connect-core";
|
|
863
|
+
import { onScopeDispose as onScopeDispose11, shallowRef as shallowRef12, toValue as toValue13, watch as watch7 } from "vue";
|
|
864
|
+
function tokensKey(tokens) {
|
|
865
|
+
return tokens.map((t) => `${t.address.toLowerCase()}|${t.decimals}|${t.symbol}`).join(",");
|
|
866
|
+
}
|
|
867
|
+
function useTokenBalance(account, client, tokens, options = {}) {
|
|
868
|
+
const tokenBalances = shallowRef12([]);
|
|
869
|
+
const isFetching = shallowRef12(false);
|
|
870
|
+
const error = shallowRef12(null);
|
|
871
|
+
let generation = 0;
|
|
872
|
+
let disposed = false;
|
|
873
|
+
let timer = null;
|
|
874
|
+
const refetch = async () => {
|
|
875
|
+
const reader = toValue13(client);
|
|
876
|
+
const address = bareEvmAddress2(toValue13(account));
|
|
877
|
+
const list = toValue13(tokens) ?? [];
|
|
878
|
+
const own = ++generation;
|
|
879
|
+
if (!reader || !address || list.length === 0) {
|
|
880
|
+
tokenBalances.value = [];
|
|
881
|
+
error.value = null;
|
|
882
|
+
isFetching.value = false;
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
isFetching.value = true;
|
|
886
|
+
error.value = null;
|
|
887
|
+
try {
|
|
888
|
+
const results = await Promise.all(
|
|
889
|
+
list.map(async (token) => {
|
|
890
|
+
try {
|
|
891
|
+
const raw = await reader.readContract({
|
|
892
|
+
address: token.address,
|
|
893
|
+
abi: ERC20_MIN_ABI,
|
|
894
|
+
functionName: "balanceOf",
|
|
895
|
+
args: [address]
|
|
896
|
+
});
|
|
897
|
+
const value = BigInt(raw);
|
|
898
|
+
return {
|
|
899
|
+
...token,
|
|
900
|
+
balance: value.toString(),
|
|
901
|
+
formatted: formatUnits2(value, token.decimals)
|
|
902
|
+
};
|
|
903
|
+
} catch {
|
|
904
|
+
return { ...token, balance: null, formatted: null };
|
|
905
|
+
}
|
|
906
|
+
})
|
|
907
|
+
);
|
|
908
|
+
if (disposed || own !== generation) return;
|
|
909
|
+
tokenBalances.value = results;
|
|
910
|
+
} catch (cause) {
|
|
911
|
+
if (disposed || own !== generation) return;
|
|
912
|
+
tokenBalances.value = [];
|
|
913
|
+
error.value = cause instanceof Error ? cause : new Error("Failed to fetch token balances");
|
|
914
|
+
} finally {
|
|
915
|
+
if (!disposed && own === generation) isFetching.value = false;
|
|
916
|
+
}
|
|
917
|
+
};
|
|
918
|
+
const stopTimer = () => {
|
|
919
|
+
if (timer) clearInterval(timer);
|
|
920
|
+
timer = null;
|
|
921
|
+
};
|
|
922
|
+
watch7(
|
|
923
|
+
[
|
|
924
|
+
() => toValue13(account),
|
|
925
|
+
() => toValue13(client),
|
|
926
|
+
() => tokensKey(toValue13(tokens) ?? []),
|
|
927
|
+
() => toValue13(options.refreshInterval) ?? 0
|
|
928
|
+
],
|
|
929
|
+
([, , , interval]) => {
|
|
930
|
+
stopTimer();
|
|
931
|
+
void refetch();
|
|
932
|
+
if (interval > 0) timer = setInterval(() => void refetch(), interval);
|
|
933
|
+
},
|
|
934
|
+
{ immediate: true }
|
|
935
|
+
);
|
|
936
|
+
onScopeDispose11(() => {
|
|
937
|
+
disposed = true;
|
|
938
|
+
generation++;
|
|
939
|
+
stopTimer();
|
|
940
|
+
});
|
|
941
|
+
return {
|
|
942
|
+
tokenBalances,
|
|
943
|
+
isFetching,
|
|
944
|
+
error,
|
|
945
|
+
refetch,
|
|
946
|
+
getTokenBalance: (tokenAddress) => tokenBalances.value.find(
|
|
947
|
+
(t) => t.address.toLowerCase() === tokenAddress.toLowerCase()
|
|
948
|
+
)
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
// src/useDelegation.ts
|
|
953
|
+
import { bareEvmAddress as bareEvmAddress3 } from "@naculus/connect-appkit-core";
|
|
954
|
+
import {
|
|
955
|
+
readDelegation,
|
|
956
|
+
UNKNOWN_DELEGATION
|
|
957
|
+
} from "@naculus/connect-core";
|
|
958
|
+
import { computed as computed9, onScopeDispose as onScopeDispose12, shallowRef as shallowRef13, toValue as toValue14, watch as watch8 } from "vue";
|
|
959
|
+
function useDelegation(account, client, chainId) {
|
|
960
|
+
const status = shallowRef13(UNKNOWN_DELEGATION);
|
|
961
|
+
const isFetching = shallowRef13(false);
|
|
962
|
+
const error = shallowRef13(null);
|
|
963
|
+
let generation = 0;
|
|
964
|
+
let disposed = false;
|
|
965
|
+
const refetch = async () => {
|
|
966
|
+
const mine = ++generation;
|
|
967
|
+
const reader = toValue14(client);
|
|
968
|
+
const address = bareEvmAddress3(toValue14(account));
|
|
969
|
+
status.value = UNKNOWN_DELEGATION;
|
|
970
|
+
error.value = null;
|
|
971
|
+
if (!reader || !address) {
|
|
972
|
+
isFetching.value = false;
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
isFetching.value = true;
|
|
976
|
+
try {
|
|
977
|
+
const code = await reader.getCode({ address });
|
|
978
|
+
if (!disposed && mine === generation) {
|
|
979
|
+
status.value = readDelegation(code ?? "0x");
|
|
980
|
+
}
|
|
981
|
+
} catch (cause) {
|
|
982
|
+
if (!disposed && mine === generation) {
|
|
983
|
+
status.value = UNKNOWN_DELEGATION;
|
|
984
|
+
error.value = cause instanceof Error ? cause : new Error("Code read failed");
|
|
985
|
+
}
|
|
986
|
+
} finally {
|
|
987
|
+
if (!disposed && mine === generation) isFetching.value = false;
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
watch8(
|
|
991
|
+
() => [toValue14(account), toValue14(client), toValue14(chainId)],
|
|
992
|
+
() => {
|
|
993
|
+
void refetch();
|
|
994
|
+
},
|
|
995
|
+
{ immediate: true, flush: "sync" }
|
|
996
|
+
);
|
|
997
|
+
onScopeDispose12(() => {
|
|
998
|
+
disposed = true;
|
|
999
|
+
generation++;
|
|
1000
|
+
});
|
|
1001
|
+
return {
|
|
1002
|
+
delegated: computed9(() => status.value.delegated),
|
|
1003
|
+
delegate: computed9(() => status.value.delegate),
|
|
1004
|
+
isFetching,
|
|
1005
|
+
error,
|
|
1006
|
+
refetch
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// src/name-lookup.ts
|
|
1011
|
+
import { getResolver } from "@naculus/connect-appkit-core";
|
|
1012
|
+
import { computed as computed10, onScopeDispose as onScopeDispose13, shallowRef as shallowRef14, toValue as toValue15, watch as watch9 } from "vue";
|
|
1013
|
+
function useNameLookup(options) {
|
|
1014
|
+
const data = shallowRef14(null);
|
|
1015
|
+
const loading = shallowRef14(false);
|
|
1016
|
+
const error = shallowRef14(null);
|
|
1017
|
+
let generation = 0;
|
|
1018
|
+
let disposed = false;
|
|
1019
|
+
const run = () => {
|
|
1020
|
+
const input = toValue15(options.input).trim();
|
|
1021
|
+
const skip = toValue15(options.skip) ?? false;
|
|
1022
|
+
const scope = toValue15(options.scope);
|
|
1023
|
+
const config = toValue15(options.resolverConfig);
|
|
1024
|
+
const mine = ++generation;
|
|
1025
|
+
if (!input || skip) {
|
|
1026
|
+
data.value = null;
|
|
1027
|
+
loading.value = false;
|
|
1028
|
+
error.value = null;
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
data.value = null;
|
|
1032
|
+
loading.value = true;
|
|
1033
|
+
error.value = null;
|
|
1034
|
+
Promise.resolve().then(() => options.query(getResolver(config), input, scope)).then((result) => {
|
|
1035
|
+
if (disposed || mine !== generation) return;
|
|
1036
|
+
data.value = result;
|
|
1037
|
+
loading.value = false;
|
|
1038
|
+
}).catch((cause) => {
|
|
1039
|
+
if (disposed || mine !== generation) return;
|
|
1040
|
+
data.value = null;
|
|
1041
|
+
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
1042
|
+
loading.value = false;
|
|
1043
|
+
});
|
|
1044
|
+
};
|
|
1045
|
+
watch9(
|
|
1046
|
+
() => [
|
|
1047
|
+
toValue15(options.input),
|
|
1048
|
+
toValue15(options.skip),
|
|
1049
|
+
toValue15(options.scope),
|
|
1050
|
+
toValue15(options.resolverConfig)
|
|
1051
|
+
],
|
|
1052
|
+
run,
|
|
1053
|
+
{ immediate: true, flush: "sync", deep: true }
|
|
1054
|
+
);
|
|
1055
|
+
onScopeDispose13(() => {
|
|
1056
|
+
disposed = true;
|
|
1057
|
+
generation++;
|
|
1058
|
+
});
|
|
1059
|
+
return {
|
|
1060
|
+
data,
|
|
1061
|
+
isLoading: computed10(() => loading.value),
|
|
1062
|
+
error,
|
|
1063
|
+
refetch: run
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/useResolveName.ts
|
|
1068
|
+
function useResolveName(name, options) {
|
|
1069
|
+
return useNameLookup({
|
|
1070
|
+
input: name,
|
|
1071
|
+
skip: options?.skip,
|
|
1072
|
+
resolverConfig: options?.resolverConfig,
|
|
1073
|
+
query: (resolver, input) => resolver.resolveName(input)
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
// src/useLookupAddress.ts
|
|
1078
|
+
function useLookupAddress(address, options) {
|
|
1079
|
+
return useNameLookup({
|
|
1080
|
+
input: address,
|
|
1081
|
+
scope: options?.chainId,
|
|
1082
|
+
skip: options?.skip,
|
|
1083
|
+
resolverConfig: options?.resolverConfig,
|
|
1084
|
+
query: (resolver, input, scope) => resolver.lookupAddress(input, scope)
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// src/useSolanaAccount.ts
|
|
1089
|
+
import { computed as computed11, toValue as toValue16 } from "vue";
|
|
1090
|
+
function useSolanaAccount(accounts, connected) {
|
|
1091
|
+
const isConnected = computed11(() => toValue16(connected));
|
|
1092
|
+
const caip10 = computed11(
|
|
1093
|
+
() => isConnected.value ? (toValue16(accounts) ?? []).find(
|
|
1094
|
+
(account) => account.startsWith("solana:")
|
|
1095
|
+
) ?? null : null
|
|
1096
|
+
);
|
|
1097
|
+
const parts = computed11(() => caip10.value?.split(":") ?? []);
|
|
1098
|
+
return {
|
|
1099
|
+
address: computed11(
|
|
1100
|
+
() => parts.value.length >= 3 ? parts.value.at(-1) ?? null : null
|
|
1101
|
+
),
|
|
1102
|
+
caip10,
|
|
1103
|
+
chainId: computed11(
|
|
1104
|
+
() => parts.value.length >= 3 ? parts.value.slice(0, -1).join(":") : null
|
|
1105
|
+
),
|
|
1106
|
+
isConnected
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
|
|
212
1110
|
// src/useChain.ts
|
|
213
1111
|
import {
|
|
214
1112
|
chainNamespace,
|
|
@@ -217,32 +1115,32 @@ import {
|
|
|
217
1115
|
describeChain,
|
|
218
1116
|
resolveChain
|
|
219
1117
|
} from "@naculus/connect-appkit-core";
|
|
220
|
-
import { computed as
|
|
1118
|
+
import { computed as computed12, toValue as toValue17 } from "vue";
|
|
221
1119
|
function useChain(chains, chainId) {
|
|
222
|
-
const list =
|
|
223
|
-
const id =
|
|
224
|
-
const currentChain =
|
|
1120
|
+
const list = computed12(() => toValue17(chains) ?? []);
|
|
1121
|
+
const id = computed12(() => toValue17(chainId) ?? null);
|
|
1122
|
+
const currentChain = computed12(() => resolveChain(list.value, id.value));
|
|
225
1123
|
return {
|
|
226
1124
|
currentChain,
|
|
227
|
-
chainInfo:
|
|
228
|
-
availableChains:
|
|
229
|
-
currentChainNumber:
|
|
1125
|
+
chainInfo: computed12(() => describeChain(list.value, id.value)),
|
|
1126
|
+
availableChains: computed12(() => chainsForNamespace(list.value, id.value)),
|
|
1127
|
+
currentChainNumber: computed12(
|
|
230
1128
|
() => currentChain.value ? chainNumber(currentChain.value) : null
|
|
231
1129
|
),
|
|
232
|
-
namespace:
|
|
1130
|
+
namespace: computed12(
|
|
233
1131
|
() => currentChain.value ? chainNamespace(currentChain.value) : null
|
|
234
1132
|
)
|
|
235
1133
|
};
|
|
236
1134
|
}
|
|
237
1135
|
|
|
238
1136
|
// src/usePassphraseGate.ts
|
|
239
|
-
import { onScopeDispose, readonly, shallowRef } from "vue";
|
|
1137
|
+
import { onScopeDispose as onScopeDispose14, readonly, shallowRef as shallowRef15 } from "vue";
|
|
240
1138
|
function usePassphraseGate(gate) {
|
|
241
|
-
const request =
|
|
1139
|
+
const request = shallowRef15(gate.getSnapshot());
|
|
242
1140
|
const unsubscribe = gate.subscribe(() => {
|
|
243
1141
|
request.value = gate.getSnapshot();
|
|
244
1142
|
});
|
|
245
|
-
|
|
1143
|
+
onScopeDispose14(unsubscribe);
|
|
246
1144
|
return {
|
|
247
1145
|
request: readonly(request),
|
|
248
1146
|
submit: (passphrase) => gate.submit(passphrase),
|
|
@@ -255,16 +1153,16 @@ function usePassphraseGate(gate) {
|
|
|
255
1153
|
import {
|
|
256
1154
|
getSolanaBalance
|
|
257
1155
|
} from "@naculus/connect-core";
|
|
258
|
-
import { onScopeDispose as
|
|
1156
|
+
import { onScopeDispose as onScopeDispose15, ref, shallowRef as shallowRef16, toValue as toValue18, watchEffect } from "vue";
|
|
259
1157
|
function useSolanaBalance(address, rpcUrl) {
|
|
260
|
-
const balance =
|
|
1158
|
+
const balance = shallowRef16(null);
|
|
261
1159
|
const isFetching = ref(false);
|
|
262
|
-
const error =
|
|
1160
|
+
const error = shallowRef16(null);
|
|
263
1161
|
let generation = 0;
|
|
264
1162
|
let disposed = false;
|
|
265
1163
|
const refetch = async () => {
|
|
266
|
-
const addr =
|
|
267
|
-
const url =
|
|
1164
|
+
const addr = toValue18(address);
|
|
1165
|
+
const url = toValue18(rpcUrl);
|
|
268
1166
|
if (!addr || !url) {
|
|
269
1167
|
balance.value = null;
|
|
270
1168
|
return;
|
|
@@ -285,34 +1183,229 @@ function useSolanaBalance(address, rpcUrl) {
|
|
|
285
1183
|
}
|
|
286
1184
|
};
|
|
287
1185
|
watchEffect(() => {
|
|
288
|
-
|
|
289
|
-
|
|
1186
|
+
toValue18(address);
|
|
1187
|
+
toValue18(rpcUrl);
|
|
290
1188
|
void refetch();
|
|
291
1189
|
});
|
|
292
|
-
|
|
1190
|
+
onScopeDispose15(() => {
|
|
293
1191
|
disposed = true;
|
|
294
1192
|
});
|
|
295
1193
|
return { balance, isFetching, error, refetch };
|
|
296
1194
|
}
|
|
297
1195
|
|
|
1196
|
+
// src/useLastTx.ts
|
|
1197
|
+
import { shallowRef as shallowRef17, toValue as toValue19, watch as watch10 } from "vue";
|
|
1198
|
+
function useLastTx(monitor) {
|
|
1199
|
+
const lastTx = shallowRef17(null);
|
|
1200
|
+
const lastConfirmedTx = shallowRef17(null);
|
|
1201
|
+
const lastFailedTx = shallowRef17(null);
|
|
1202
|
+
watch10(
|
|
1203
|
+
() => toValue19(monitor),
|
|
1204
|
+
(activeMonitor, _previous, onCleanup) => {
|
|
1205
|
+
if (!activeMonitor) return;
|
|
1206
|
+
const recordLatest = (entry) => {
|
|
1207
|
+
if (!lastTx.value || entry.createdAt >= lastTx.value.createdAt) {
|
|
1208
|
+
lastTx.value = entry;
|
|
1209
|
+
}
|
|
1210
|
+
};
|
|
1211
|
+
const onConfirmed = (entry) => {
|
|
1212
|
+
lastConfirmedTx.value = entry;
|
|
1213
|
+
recordLatest(entry);
|
|
1214
|
+
};
|
|
1215
|
+
const onFailed = (entry) => {
|
|
1216
|
+
lastFailedTx.value = entry;
|
|
1217
|
+
recordLatest(entry);
|
|
1218
|
+
};
|
|
1219
|
+
activeMonitor.on("confirmed", onConfirmed);
|
|
1220
|
+
activeMonitor.on("failed", onFailed);
|
|
1221
|
+
onCleanup(() => {
|
|
1222
|
+
activeMonitor.off("confirmed", onConfirmed);
|
|
1223
|
+
activeMonitor.off("failed", onFailed);
|
|
1224
|
+
});
|
|
1225
|
+
},
|
|
1226
|
+
{ immediate: true }
|
|
1227
|
+
);
|
|
1228
|
+
return {
|
|
1229
|
+
lastTx,
|
|
1230
|
+
lastConfirmedTx,
|
|
1231
|
+
lastFailedTx,
|
|
1232
|
+
clear: () => {
|
|
1233
|
+
lastTx.value = null;
|
|
1234
|
+
lastConfirmedTx.value = null;
|
|
1235
|
+
lastFailedTx.value = null;
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// src/useTxHistory.ts
|
|
1241
|
+
import { computed as computed13, shallowRef as shallowRef18, toValue as toValue20, watch as watch11 } from "vue";
|
|
1242
|
+
function useTxHistory(address, chainId, monitor) {
|
|
1243
|
+
const entries = shallowRef18([]);
|
|
1244
|
+
const isLoading = shallowRef18(false);
|
|
1245
|
+
const error = shallowRef18(null);
|
|
1246
|
+
let generation = 0;
|
|
1247
|
+
const refresh = async () => {
|
|
1248
|
+
const mine = ++generation;
|
|
1249
|
+
const activeMonitor = toValue20(monitor);
|
|
1250
|
+
if (!activeMonitor) {
|
|
1251
|
+
entries.value = [];
|
|
1252
|
+
isLoading.value = false;
|
|
1253
|
+
error.value = null;
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
isLoading.value = true;
|
|
1257
|
+
error.value = null;
|
|
1258
|
+
try {
|
|
1259
|
+
const result = await activeMonitor.getTxHistory(
|
|
1260
|
+
toValue20(address) ?? void 0,
|
|
1261
|
+
toValue20(chainId) ?? void 0
|
|
1262
|
+
);
|
|
1263
|
+
if (mine === generation) entries.value = result;
|
|
1264
|
+
} catch (err) {
|
|
1265
|
+
if (mine !== generation) return;
|
|
1266
|
+
error.value = err instanceof Error ? err : new Error("Failed to load transaction history");
|
|
1267
|
+
} finally {
|
|
1268
|
+
if (mine === generation) isLoading.value = false;
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
watch11(
|
|
1272
|
+
() => [toValue20(monitor), toValue20(address), toValue20(chainId)],
|
|
1273
|
+
([activeMonitor], _previous, onCleanup) => {
|
|
1274
|
+
if (!activeMonitor) {
|
|
1275
|
+
void refresh();
|
|
1276
|
+
return;
|
|
1277
|
+
}
|
|
1278
|
+
const onStatusChange = () => {
|
|
1279
|
+
void refresh();
|
|
1280
|
+
};
|
|
1281
|
+
activeMonitor.on("statusChange", onStatusChange);
|
|
1282
|
+
onCleanup(() => activeMonitor.off("statusChange", onStatusChange));
|
|
1283
|
+
void refresh();
|
|
1284
|
+
},
|
|
1285
|
+
{ immediate: true }
|
|
1286
|
+
);
|
|
1287
|
+
return {
|
|
1288
|
+
entries,
|
|
1289
|
+
isLoading,
|
|
1290
|
+
error,
|
|
1291
|
+
refresh,
|
|
1292
|
+
summary: computed13(() => ({
|
|
1293
|
+
pending: entries.value.filter((item) => item.status === "pending").length,
|
|
1294
|
+
confirmed: entries.value.filter((item) => item.status === "confirmed").length,
|
|
1295
|
+
failed: entries.value.filter((item) => item.status === "failed").length
|
|
1296
|
+
}))
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
// src/useTxMonitor.ts
|
|
1301
|
+
import {
|
|
1302
|
+
computed as computed14,
|
|
1303
|
+
shallowRef as shallowRef19,
|
|
1304
|
+
toValue as toValue21,
|
|
1305
|
+
watch as watch12
|
|
1306
|
+
} from "vue";
|
|
1307
|
+
function useTxMonitor(hash, chainId, monitor) {
|
|
1308
|
+
const entry = shallowRef19(null);
|
|
1309
|
+
const isLoading = shallowRef19(false);
|
|
1310
|
+
const isWatching = shallowRef19(false);
|
|
1311
|
+
const error = shallowRef19(null);
|
|
1312
|
+
let generation = 0;
|
|
1313
|
+
const refresh = async () => {
|
|
1314
|
+
const activeMonitor = toValue21(monitor);
|
|
1315
|
+
const activeHash = toValue21(hash);
|
|
1316
|
+
const activeChainId = toValue21(chainId);
|
|
1317
|
+
if (!activeMonitor || !activeHash) return;
|
|
1318
|
+
isLoading.value = true;
|
|
1319
|
+
error.value = null;
|
|
1320
|
+
try {
|
|
1321
|
+
await activeMonitor.refreshTx(activeHash, activeChainId ?? void 0);
|
|
1322
|
+
const current = activeMonitor.getTxStatus(
|
|
1323
|
+
activeHash,
|
|
1324
|
+
activeChainId ?? void 0
|
|
1325
|
+
);
|
|
1326
|
+
if (current) entry.value = current;
|
|
1327
|
+
} catch (err) {
|
|
1328
|
+
error.value = err instanceof Error ? err : new Error("Failed to refresh transaction");
|
|
1329
|
+
} finally {
|
|
1330
|
+
isLoading.value = false;
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
const stopWatching = () => {
|
|
1334
|
+
const activeMonitor = toValue21(monitor);
|
|
1335
|
+
const activeHash = toValue21(hash);
|
|
1336
|
+
const activeChainId = toValue21(chainId);
|
|
1337
|
+
if (!activeMonitor || !activeHash) return;
|
|
1338
|
+
activeMonitor.stopWatching(activeHash, activeChainId ?? void 0);
|
|
1339
|
+
isWatching.value = false;
|
|
1340
|
+
};
|
|
1341
|
+
watch12(
|
|
1342
|
+
() => [toValue21(monitor), toValue21(hash), toValue21(chainId)],
|
|
1343
|
+
([activeMonitor, activeHash, activeChainId], _previous, onCleanup) => {
|
|
1344
|
+
const mine = ++generation;
|
|
1345
|
+
if (!activeMonitor || !activeHash || !activeChainId) {
|
|
1346
|
+
entry.value = null;
|
|
1347
|
+
isLoading.value = false;
|
|
1348
|
+
isWatching.value = false;
|
|
1349
|
+
error.value = null;
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
let cancelled = false;
|
|
1353
|
+
const onStatusChange = (updated) => {
|
|
1354
|
+
if (!cancelled && updated.hash === activeHash && updated.chainId === activeChainId) {
|
|
1355
|
+
entry.value = { ...updated };
|
|
1356
|
+
}
|
|
1357
|
+
};
|
|
1358
|
+
activeMonitor.on("statusChange", onStatusChange);
|
|
1359
|
+
onCleanup(() => {
|
|
1360
|
+
cancelled = true;
|
|
1361
|
+
activeMonitor.off("statusChange", onStatusChange);
|
|
1362
|
+
});
|
|
1363
|
+
isWatching.value = true;
|
|
1364
|
+
isLoading.value = true;
|
|
1365
|
+
error.value = null;
|
|
1366
|
+
const current = activeMonitor.getTxStatus(activeHash, activeChainId);
|
|
1367
|
+
if (current) entry.value = current;
|
|
1368
|
+
activeMonitor.watchTx(activeHash, activeChainId, {}).then((initial) => {
|
|
1369
|
+
if (cancelled || mine !== generation) return;
|
|
1370
|
+
entry.value = initial;
|
|
1371
|
+
isLoading.value = false;
|
|
1372
|
+
}).catch((err) => {
|
|
1373
|
+
if (cancelled || mine !== generation) return;
|
|
1374
|
+
error.value = err instanceof Error ? err : new Error("Failed to watch transaction");
|
|
1375
|
+
isLoading.value = false;
|
|
1376
|
+
});
|
|
1377
|
+
},
|
|
1378
|
+
{ immediate: true }
|
|
1379
|
+
);
|
|
1380
|
+
return {
|
|
1381
|
+
entry,
|
|
1382
|
+
status: computed14(() => entry.value?.status ?? "idle"),
|
|
1383
|
+
isLoading,
|
|
1384
|
+
isWatching,
|
|
1385
|
+
error,
|
|
1386
|
+
refresh,
|
|
1387
|
+
stopWatching
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
|
|
298
1391
|
// src/useCapabilities.ts
|
|
299
1392
|
import {
|
|
300
1393
|
atomicSupportFor,
|
|
301
1394
|
normalizeCapabilities,
|
|
302
1395
|
selectChainCapabilities
|
|
303
1396
|
} from "@naculus/connect-appkit-core";
|
|
304
|
-
import { computed as
|
|
1397
|
+
import { computed as computed15, shallowRef as shallowRef20, toValue as toValue22, watchEffect as watchEffect2 } from "vue";
|
|
305
1398
|
function useCapabilities(client, session, chainId) {
|
|
306
|
-
const capabilities =
|
|
1399
|
+
const capabilities = shallowRef20(
|
|
307
1400
|
null
|
|
308
1401
|
);
|
|
309
|
-
const isFetching =
|
|
310
|
-
const error =
|
|
1402
|
+
const isFetching = shallowRef20(false);
|
|
1403
|
+
const error = shallowRef20(null);
|
|
311
1404
|
let generation = 0;
|
|
312
1405
|
const refetch = async () => {
|
|
313
1406
|
const mine = ++generation;
|
|
314
|
-
const activeClient =
|
|
315
|
-
const activeSession =
|
|
1407
|
+
const activeClient = toValue22(client);
|
|
1408
|
+
const activeSession = toValue22(session);
|
|
316
1409
|
if (!activeClient?.getCapabilities || !activeSession) {
|
|
317
1410
|
capabilities.value = null;
|
|
318
1411
|
isFetching.value = false;
|
|
@@ -334,17 +1427,17 @@ function useCapabilities(client, session, chainId) {
|
|
|
334
1427
|
}
|
|
335
1428
|
};
|
|
336
1429
|
watchEffect2(() => {
|
|
337
|
-
void
|
|
338
|
-
void
|
|
1430
|
+
void toValue22(client);
|
|
1431
|
+
void toValue22(session);
|
|
339
1432
|
void refetch();
|
|
340
1433
|
});
|
|
341
1434
|
return {
|
|
342
1435
|
capabilities,
|
|
343
|
-
current:
|
|
344
|
-
() => selectChainCapabilities(capabilities.value,
|
|
1436
|
+
current: computed15(
|
|
1437
|
+
() => selectChainCapabilities(capabilities.value, toValue22(chainId))
|
|
345
1438
|
),
|
|
346
|
-
atomic:
|
|
347
|
-
() => atomicSupportFor(capabilities.value,
|
|
1439
|
+
atomic: computed15(
|
|
1440
|
+
() => atomicSupportFor(capabilities.value, toValue22(chainId))
|
|
348
1441
|
),
|
|
349
1442
|
isFetching,
|
|
350
1443
|
error,
|
|
@@ -356,17 +1449,17 @@ function useCapabilities(client, session, chainId) {
|
|
|
356
1449
|
import {
|
|
357
1450
|
readSolanaRoles
|
|
358
1451
|
} from "@naculus/connect-appkit-core";
|
|
359
|
-
import { computed as
|
|
1452
|
+
import { computed as computed16, toValue as toValue23 } from "vue";
|
|
360
1453
|
function useSolanaRoles(connector, session) {
|
|
361
|
-
const state =
|
|
362
|
-
() => readSolanaRoles(
|
|
1454
|
+
const state = computed16(
|
|
1455
|
+
() => readSolanaRoles(toValue23(connector), toValue23(session))
|
|
363
1456
|
);
|
|
364
1457
|
return {
|
|
365
|
-
roles:
|
|
366
|
-
absence:
|
|
367
|
-
identity:
|
|
368
|
-
signer:
|
|
369
|
-
payer:
|
|
1458
|
+
roles: computed16(() => state.value.roles),
|
|
1459
|
+
absence: computed16(() => state.value.absence),
|
|
1460
|
+
identity: computed16(() => state.value.roles?.identity ?? null),
|
|
1461
|
+
signer: computed16(() => state.value.roles?.signer ?? null),
|
|
1462
|
+
payer: computed16(() => state.value.roles?.payer ?? null)
|
|
370
1463
|
};
|
|
371
1464
|
}
|
|
372
1465
|
export {
|
|
@@ -398,11 +1491,32 @@ export {
|
|
|
398
1491
|
AppkitTabs,
|
|
399
1492
|
AppkitToggleGroup,
|
|
400
1493
|
AppkitTooltip,
|
|
1494
|
+
useAccount,
|
|
401
1495
|
useAccounts,
|
|
1496
|
+
useBalance,
|
|
402
1497
|
useCapabilities,
|
|
403
1498
|
useChain,
|
|
1499
|
+
useCompareCosts,
|
|
1500
|
+
useConnect,
|
|
1501
|
+
useDelegation,
|
|
1502
|
+
useDisconnect,
|
|
1503
|
+
useExecuteRoute,
|
|
1504
|
+
useLastTx,
|
|
1505
|
+
useLookupAddress,
|
|
1506
|
+
useNotification,
|
|
404
1507
|
usePassphraseGate,
|
|
1508
|
+
useResolveName,
|
|
1509
|
+
useRouteQuote,
|
|
1510
|
+
useSession,
|
|
1511
|
+
useSolanaAccount,
|
|
405
1512
|
useSolanaBalance,
|
|
406
|
-
useSolanaRoles
|
|
1513
|
+
useSolanaRoles,
|
|
1514
|
+
useSwitchChain,
|
|
1515
|
+
useTokenBalance,
|
|
1516
|
+
useTokenList,
|
|
1517
|
+
useTokenSearch,
|
|
1518
|
+
useTxHistory,
|
|
1519
|
+
useTxMonitor,
|
|
1520
|
+
useValidateDestination
|
|
407
1521
|
};
|
|
408
1522
|
//# sourceMappingURL=index.js.map
|