@tronweb3/tronwallet-adapter-tokenpocket 1.0.9 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/lib/cjs/adapter.js +91 -51
- package/lib/cjs/adapter.js.map +1 -1
- package/lib/esm/adapter.js +92 -52
- package/lib/esm/adapter.js.map +1 -1
- package/lib/types/adapter.d.ts +12 -16
- package/lib/types/adapter.d.ts.map +1 -1
- package/lib/umd/index.js +998 -244
- package/lib/umd/index.min.js +1 -1
- package/package.json +52 -52
- package/src/adapter.ts +91 -60
package/lib/umd/index.js
CHANGED
|
@@ -363,82 +363,7 @@
|
|
|
363
363
|
return eventemitter3.exports;
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
-
var
|
|
367
|
-
|
|
368
|
-
function requireAdapter$2 () {
|
|
369
|
-
if (hasRequiredAdapter$2) return adapter$1;
|
|
370
|
-
hasRequiredAdapter$2 = 1;
|
|
371
|
-
var __importDefault = (adapter$1 && adapter$1.__importDefault) || function (mod) {
|
|
372
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
373
|
-
};
|
|
374
|
-
Object.defineProperty(adapter$1, "__esModule", { value: true });
|
|
375
|
-
adapter$1.Adapter = adapter$1.AdapterState = adapter$1.WalletReadyState = adapter$1.EventEmitter = void 0;
|
|
376
|
-
const eventemitter3_1 = __importDefault(requireEventemitter3());
|
|
377
|
-
adapter$1.EventEmitter = eventemitter3_1.default;
|
|
378
|
-
/**
|
|
379
|
-
* Wallet ready state.
|
|
380
|
-
*/
|
|
381
|
-
var WalletReadyState;
|
|
382
|
-
(function (WalletReadyState) {
|
|
383
|
-
/**
|
|
384
|
-
* Adapter will start to check if wallet exists after adapter instance is created.
|
|
385
|
-
*/
|
|
386
|
-
WalletReadyState["Loading"] = "Loading";
|
|
387
|
-
/**
|
|
388
|
-
* When checking ends and wallet is not found, readyState will be NotFound.
|
|
389
|
-
*/
|
|
390
|
-
WalletReadyState["NotFound"] = "NotFound";
|
|
391
|
-
/**
|
|
392
|
-
* When checking ends and wallet is found, readyState will be Found.
|
|
393
|
-
*/
|
|
394
|
-
WalletReadyState["Found"] = "Found";
|
|
395
|
-
})(WalletReadyState || (adapter$1.WalletReadyState = WalletReadyState = {}));
|
|
396
|
-
/**
|
|
397
|
-
* Adapter state
|
|
398
|
-
*/
|
|
399
|
-
var AdapterState;
|
|
400
|
-
(function (AdapterState) {
|
|
401
|
-
/**
|
|
402
|
-
* If adapter is checking the wallet, the state is Loading.
|
|
403
|
-
*/
|
|
404
|
-
AdapterState["Loading"] = "Loading";
|
|
405
|
-
/**
|
|
406
|
-
* If wallet is not installed, the state is NotFound.
|
|
407
|
-
*/
|
|
408
|
-
AdapterState["NotFound"] = "NotFound";
|
|
409
|
-
/**
|
|
410
|
-
* If wallet is installed but is not connected to current Dapp, the state is Disconnected.
|
|
411
|
-
*/
|
|
412
|
-
AdapterState["Disconnect"] = "Disconnected";
|
|
413
|
-
/**
|
|
414
|
-
* Wallet is connected to current Dapp.
|
|
415
|
-
*/
|
|
416
|
-
AdapterState["Connected"] = "Connected";
|
|
417
|
-
})(AdapterState || (adapter$1.AdapterState = AdapterState = {}));
|
|
418
|
-
class Adapter extends eventemitter3_1.default {
|
|
419
|
-
get connected() {
|
|
420
|
-
return this.state === AdapterState.Connected;
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* Some wallets such as TronLink don't support disconnect() method.
|
|
424
|
-
*/
|
|
425
|
-
disconnect() {
|
|
426
|
-
console.info("The current adapter doesn't support disconnect by DApp.");
|
|
427
|
-
return Promise.resolve();
|
|
428
|
-
}
|
|
429
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
430
|
-
multiSign(transaction, options = {}) {
|
|
431
|
-
return Promise.reject("The current wallet doesn't support multiSign.");
|
|
432
|
-
}
|
|
433
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
434
|
-
switchChain(_chainId) {
|
|
435
|
-
return Promise.reject("The current wallet doesn't support switch chain.");
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
adapter$1.Adapter = Adapter;
|
|
439
|
-
|
|
440
|
-
return adapter$1;
|
|
441
|
-
}
|
|
366
|
+
var typedData = {};
|
|
442
367
|
|
|
443
368
|
var errors = {};
|
|
444
369
|
|
|
@@ -448,7 +373,7 @@
|
|
|
448
373
|
if (hasRequiredErrors) return errors;
|
|
449
374
|
hasRequiredErrors = 1;
|
|
450
375
|
Object.defineProperty(errors, "__esModule", { value: true });
|
|
451
|
-
errors.WalletGetNetworkError = errors.WalletSwitchChainError = errors.WalletWindowClosedError = errors.WalletWalletLoadError = errors.WalletSignTransactionError = errors.WalletSignMessageError = errors.WalletDisconnectionError = errors.WalletConnectionError = errors.WalletDisconnectedError = errors.WalletNotSelectedError = errors.WalletNotFoundError = errors.WalletError = void 0;
|
|
376
|
+
errors.WalletSignTypedDataError = errors.WalletGetNetworkError = errors.WalletSwitchChainError = errors.WalletWindowClosedError = errors.WalletWalletLoadError = errors.WalletSignTransactionError = errors.WalletSignMessageError = errors.WalletDisconnectionError = errors.WalletConnectionError = errors.WalletDisconnectedError = errors.WalletNotSelectedError = errors.WalletNotFoundError = errors.WalletError = void 0;
|
|
452
377
|
class WalletError extends Error {
|
|
453
378
|
constructor(message, error) {
|
|
454
379
|
super(message);
|
|
@@ -569,10 +494,113 @@
|
|
|
569
494
|
}
|
|
570
495
|
}
|
|
571
496
|
errors.WalletGetNetworkError = WalletGetNetworkError;
|
|
497
|
+
/**
|
|
498
|
+
* Occurs when call `signTypedData()`.
|
|
499
|
+
*/
|
|
500
|
+
class WalletSignTypedDataError extends WalletError {
|
|
501
|
+
constructor() {
|
|
502
|
+
super(...arguments);
|
|
503
|
+
this.name = 'WalletSignTypedDataError';
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
errors.WalletSignTypedDataError = WalletSignTypedDataError;
|
|
572
507
|
|
|
573
508
|
return errors;
|
|
574
509
|
}
|
|
575
510
|
|
|
511
|
+
var hasRequiredTypedData;
|
|
512
|
+
|
|
513
|
+
function requireTypedData () {
|
|
514
|
+
if (hasRequiredTypedData) return typedData;
|
|
515
|
+
hasRequiredTypedData = 1;
|
|
516
|
+
Object.defineProperty(typedData, "__esModule", { value: true });
|
|
517
|
+
typedData.normalizeAndValidateTypedData = normalizeAndValidateTypedData;
|
|
518
|
+
const errors_js_1 = requireErrors();
|
|
519
|
+
function isPlainObject(value) {
|
|
520
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
521
|
+
}
|
|
522
|
+
/** Non-negative decimal integer, e.g. `1`, `728126428`. */
|
|
523
|
+
const DECIMAL_INTEGER = /^[0-9]+$/;
|
|
524
|
+
/** Non-negative hex integer, e.g. `0x2b6653dc`. `BigInt` accepts either prefix case. */
|
|
525
|
+
const HEX_INTEGER = /^0[xX][0-9a-fA-F]+$/;
|
|
526
|
+
/**
|
|
527
|
+
* Convert a `domain.chainId` to the `number` wallets expect, refusing anything
|
|
528
|
+
* that cannot survive the trip.
|
|
529
|
+
*
|
|
530
|
+
* EIP-712 declares `chainId` as `uint256`, but `Number()` maps that domain onto
|
|
531
|
+
* IEEE-754 doubles and quietly accepts values that are not integers at all:
|
|
532
|
+
* `Number('9007199254740993')` yields `9007199254740992`, and `'1.5'`, `'-1'`,
|
|
533
|
+
* `'1e3'` and `''` all pass `Number.isFinite()`. Each of those makes the wallet
|
|
534
|
+
* sign a domain that differs from what the caller supplied, so the signature no
|
|
535
|
+
* longer corresponds to the original payload. Parsing through `BigInt` keeps the
|
|
536
|
+
* value exact and lets the unrepresentable cases fail loudly instead.
|
|
537
|
+
*/
|
|
538
|
+
function toChainIdNumber(chainId) {
|
|
539
|
+
// Reject anything that is not an integer literal before converting. `Number()`
|
|
540
|
+
// happily turns `'1.5'`, `'-1'`, `'1e3'` and `''` into finite numbers, none of
|
|
541
|
+
// which is a uint256.
|
|
542
|
+
if (typeof chainId === 'string') {
|
|
543
|
+
const value = chainId.trim();
|
|
544
|
+
if (!DECIMAL_INTEGER.test(value) && !HEX_INTEGER.test(value)) {
|
|
545
|
+
throw new errors_js_1.WalletSignTypedDataError(`Invalid domain.chainId: ${chainId}. Expected a non-negative decimal or 0x-prefixed hex integer.`);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
const parsed = Number(chainId);
|
|
549
|
+
// Catches NaN, Infinity and fractions, which only a number/bigint input can
|
|
550
|
+
// still be at this point — the string form was already gated by the regexes.
|
|
551
|
+
if (!Number.isInteger(parsed)) {
|
|
552
|
+
throw new errors_js_1.WalletSignTypedDataError(`Invalid domain.chainId: ${chainId}. Expected a non-negative integer.`);
|
|
553
|
+
}
|
|
554
|
+
if (parsed < 0) {
|
|
555
|
+
throw new errors_js_1.WalletSignTypedDataError(`Invalid domain.chainId: ${chainId}. Expected a non-negative integer.`);
|
|
556
|
+
}
|
|
557
|
+
// With integrality established, `isSafeInteger` is an exact bound check rather
|
|
558
|
+
// than an approximation: every integer up to MAX_SAFE_INTEGER converts
|
|
559
|
+
// losslessly, and anything larger necessarily rounds to 2^53 or beyond, which is
|
|
560
|
+
// never "safe". So a value that survives this equals what the caller supplied.
|
|
561
|
+
if (!Number.isSafeInteger(parsed)) {
|
|
562
|
+
throw new errors_js_1.WalletSignTypedDataError(`domain.chainId ${chainId} exceeds Number.MAX_SAFE_INTEGER (${Number.MAX_SAFE_INTEGER}) and cannot be represented as a number without losing precision.`);
|
|
563
|
+
}
|
|
564
|
+
return parsed;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Validate a TypedData payload and return a normalized copy safe to pass to wallets.
|
|
568
|
+
*
|
|
569
|
+
* Current normalization: convert `domain.chainId` to a number (some wallets,
|
|
570
|
+
* e.g. TronLink, require a numeric chainId). `null`/`undefined` are left alone
|
|
571
|
+
* because `chainId` is optional, as are values of other types — a `BigNumber`
|
|
572
|
+
* instance is a legitimate `BigNumberish` and is passed through untouched.
|
|
573
|
+
*
|
|
574
|
+
* Throws {@link WalletSignTypedDataError} if the payload is not a valid TypedData
|
|
575
|
+
* object, or if `domain.chainId` cannot be represented exactly as a number.
|
|
576
|
+
*/
|
|
577
|
+
function normalizeAndValidateTypedData(typedData) {
|
|
578
|
+
if (!isPlainObject(typedData)) {
|
|
579
|
+
throw new errors_js_1.WalletSignTypedDataError('typedData must be an object.');
|
|
580
|
+
}
|
|
581
|
+
if (!isPlainObject(typedData.domain)) {
|
|
582
|
+
throw new errors_js_1.WalletSignTypedDataError('typedData.domain must be an object.');
|
|
583
|
+
}
|
|
584
|
+
if (!isPlainObject(typedData.types)) {
|
|
585
|
+
throw new errors_js_1.WalletSignTypedDataError('typedData.types must be an object.');
|
|
586
|
+
}
|
|
587
|
+
if (!isPlainObject(typedData.message)) {
|
|
588
|
+
throw new errors_js_1.WalletSignTypedDataError('typedData.message must be an object.');
|
|
589
|
+
}
|
|
590
|
+
const { chainId } = typedData.domain;
|
|
591
|
+
if (typeof chainId === 'string' || typeof chainId === 'number' || typeof chainId === 'bigint') {
|
|
592
|
+
const parsed = toChainIdNumber(chainId);
|
|
593
|
+
if (parsed === chainId) {
|
|
594
|
+
return typedData;
|
|
595
|
+
}
|
|
596
|
+
return Object.assign(Object.assign({}, typedData), { domain: Object.assign(Object.assign({}, typedData.domain), { chainId: parsed }) });
|
|
597
|
+
}
|
|
598
|
+
return typedData;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return typedData;
|
|
602
|
+
}
|
|
603
|
+
|
|
576
604
|
var types$1 = {};
|
|
577
605
|
|
|
578
606
|
var hasRequiredTypes$1;
|
|
@@ -581,7 +609,47 @@
|
|
|
581
609
|
if (hasRequiredTypes$1) return types$1;
|
|
582
610
|
hasRequiredTypes$1 = 1;
|
|
583
611
|
Object.defineProperty(types$1, "__esModule", { value: true });
|
|
584
|
-
types$1.TIP6963RequestProviderEventName = types$1.TIP6963AnnounceProviderEventName = types$1.ChainNetwork = types$1.NetworkType = void 0;
|
|
612
|
+
types$1.TIP6963RequestProviderEventName = types$1.TIP6963AnnounceProviderEventName = types$1.ChainNetwork = types$1.NetworkType = types$1.AdapterState = types$1.WalletReadyState = void 0;
|
|
613
|
+
/**
|
|
614
|
+
* Wallet ready state.
|
|
615
|
+
*/
|
|
616
|
+
var WalletReadyState;
|
|
617
|
+
(function (WalletReadyState) {
|
|
618
|
+
/**
|
|
619
|
+
* Adapter will start to check if wallet exists after adapter instance is created.
|
|
620
|
+
*/
|
|
621
|
+
WalletReadyState["Loading"] = "Loading";
|
|
622
|
+
/**
|
|
623
|
+
* When checking ends and wallet is not found, readyState will be NotFound.
|
|
624
|
+
*/
|
|
625
|
+
WalletReadyState["NotFound"] = "NotFound";
|
|
626
|
+
/**
|
|
627
|
+
* When checking ends and wallet is found, readyState will be Found.
|
|
628
|
+
*/
|
|
629
|
+
WalletReadyState["Found"] = "Found";
|
|
630
|
+
})(WalletReadyState || (types$1.WalletReadyState = WalletReadyState = {}));
|
|
631
|
+
/**
|
|
632
|
+
* Adapter state
|
|
633
|
+
*/
|
|
634
|
+
var AdapterState;
|
|
635
|
+
(function (AdapterState) {
|
|
636
|
+
/**
|
|
637
|
+
* If adapter is checking the wallet, the state is Loading.
|
|
638
|
+
*/
|
|
639
|
+
AdapterState["Loading"] = "Loading";
|
|
640
|
+
/**
|
|
641
|
+
* If wallet is not installed, the state is NotFound.
|
|
642
|
+
*/
|
|
643
|
+
AdapterState["NotFound"] = "NotFound";
|
|
644
|
+
/**
|
|
645
|
+
* If wallet is installed but is not connected to current Dapp, the state is Disconnected.
|
|
646
|
+
*/
|
|
647
|
+
AdapterState["Disconnect"] = "Disconnected";
|
|
648
|
+
/**
|
|
649
|
+
* Wallet is connected to current Dapp.
|
|
650
|
+
*/
|
|
651
|
+
AdapterState["Connected"] = "Connected";
|
|
652
|
+
})(AdapterState || (types$1.AdapterState = AdapterState = {}));
|
|
585
653
|
var NetworkType;
|
|
586
654
|
(function (NetworkType) {
|
|
587
655
|
NetworkType["Mainnet"] = "Mainnet";
|
|
@@ -604,6 +672,59 @@
|
|
|
604
672
|
return types$1;
|
|
605
673
|
}
|
|
606
674
|
|
|
675
|
+
var hasRequiredAdapter$2;
|
|
676
|
+
|
|
677
|
+
function requireAdapter$2 () {
|
|
678
|
+
if (hasRequiredAdapter$2) return adapter$1;
|
|
679
|
+
hasRequiredAdapter$2 = 1;
|
|
680
|
+
var __importDefault = (adapter$1 && adapter$1.__importDefault) || function (mod) {
|
|
681
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
682
|
+
};
|
|
683
|
+
Object.defineProperty(adapter$1, "__esModule", { value: true });
|
|
684
|
+
adapter$1.Adapter = adapter$1.EventEmitter = void 0;
|
|
685
|
+
const eventemitter3_1 = __importDefault(requireEventemitter3());
|
|
686
|
+
adapter$1.EventEmitter = eventemitter3_1.default;
|
|
687
|
+
const typedData_js_1 = requireTypedData();
|
|
688
|
+
const types_js_1 = requireTypes$1();
|
|
689
|
+
class Adapter extends eventemitter3_1.default {
|
|
690
|
+
get connected() {
|
|
691
|
+
return this.state === types_js_1.AdapterState.Connected;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Some wallets such as TronLink don't support disconnect() method.
|
|
695
|
+
*/
|
|
696
|
+
disconnect() {
|
|
697
|
+
console.info("The current adapter doesn't support disconnect by DApp.");
|
|
698
|
+
return Promise.resolve();
|
|
699
|
+
}
|
|
700
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
701
|
+
multiSign(transaction, options = {}) {
|
|
702
|
+
return Promise.reject("The current wallet doesn't support multiSign.");
|
|
703
|
+
}
|
|
704
|
+
signTypedData(typedData) {
|
|
705
|
+
let normalized;
|
|
706
|
+
try {
|
|
707
|
+
normalized = (0, typedData_js_1.normalizeAndValidateTypedData)(typedData);
|
|
708
|
+
}
|
|
709
|
+
catch (error) {
|
|
710
|
+
return Promise.reject(error);
|
|
711
|
+
}
|
|
712
|
+
return this._signTypedData(normalized);
|
|
713
|
+
}
|
|
714
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
715
|
+
_signTypedData(_typedData) {
|
|
716
|
+
return Promise.reject("The current wallet doesn't support signTypedData.");
|
|
717
|
+
}
|
|
718
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
719
|
+
switchChain(_chainId) {
|
|
720
|
+
return Promise.reject("The current wallet doesn't support switch chain.");
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
adapter$1.Adapter = Adapter;
|
|
724
|
+
|
|
725
|
+
return adapter$1;
|
|
726
|
+
}
|
|
727
|
+
|
|
607
728
|
var utils$2 = {};
|
|
608
729
|
|
|
609
730
|
var hasRequiredUtils$2;
|
|
@@ -611,59 +732,543 @@
|
|
|
611
732
|
function requireUtils$2 () {
|
|
612
733
|
if (hasRequiredUtils$2) return utils$2;
|
|
613
734
|
hasRequiredUtils$2 = 1;
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
735
|
+
(function (exports$1) {
|
|
736
|
+
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
737
|
+
exports$1.MAX_CHECK_TIMEOUT = void 0;
|
|
738
|
+
exports$1.validateCheckTimeout = validateCheckTimeout;
|
|
739
|
+
exports$1.omitUndefined = omitUndefined;
|
|
740
|
+
exports$1.assertConnectAddress = assertConnectAddress;
|
|
741
|
+
exports$1.isInBrowser = isInBrowser;
|
|
742
|
+
exports$1.checkAdapterState = checkAdapterState;
|
|
743
|
+
exports$1.isInMobileBrowser = isInMobileBrowser;
|
|
744
|
+
const errors_js_1 = requireErrors();
|
|
745
|
+
/**
|
|
746
|
+
* Upper bound for `config.checkTimeout`, in milliseconds.
|
|
747
|
+
*
|
|
748
|
+
* Wallet detection polls on a fixed interval and gives up after
|
|
749
|
+
* `checkTimeout / interval` ticks. An unbounded value makes that loop
|
|
750
|
+
* indistinguishable from one that never stops, so it is capped. Ten minutes is
|
|
751
|
+
* far beyond any realistic detection window.
|
|
752
|
+
*/
|
|
753
|
+
exports$1.MAX_CHECK_TIMEOUT = 10 * 60 * 1000;
|
|
754
|
+
/**
|
|
755
|
+
* Validate `config.checkTimeout` and throw when it cannot produce a terminating
|
|
756
|
+
* detection loop.
|
|
757
|
+
*
|
|
758
|
+
* `typeof value === 'number'` is not enough on its own: `NaN` and `Infinity` are
|
|
759
|
+
* numbers, and adapters derive their polling bound from
|
|
760
|
+
* `Math.floor(checkTimeout / interval)`. With `NaN` that bound is `NaN`, so
|
|
761
|
+
* `times > maxTimes` is never true — the interval is never cleared and the
|
|
762
|
+
* detection promise never settles, hanging `connect()` for the life of the page.
|
|
763
|
+
* TypeScript cannot prevent this because adapters are also constructed from
|
|
764
|
+
* plain JavaScript, JSON config and `as any`.
|
|
765
|
+
*
|
|
766
|
+
* @param value the raw value taken from the adapter config
|
|
767
|
+
* @param prefix prefix used in the thrown message, e.g. `[TronLinkAdapter]`
|
|
768
|
+
*/
|
|
769
|
+
function validateCheckTimeout(value, prefix = '[WalletAdapter]') {
|
|
770
|
+
if (typeof value !== 'number') {
|
|
771
|
+
throw new Error(`${prefix} config.checkTimeout should be a number`);
|
|
772
|
+
}
|
|
773
|
+
if (!Number.isFinite(value) || value < 0 || value > exports$1.MAX_CHECK_TIMEOUT) {
|
|
774
|
+
throw new Error(`${prefix} config.checkTimeout should be a finite number between 0 and ${exports$1.MAX_CHECK_TIMEOUT}, but got ${value}`);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Copy an object without the keys whose value is exactly `undefined`.
|
|
779
|
+
*
|
|
780
|
+
* Spreading a caller's config over a set of defaults is only safe when explicit
|
|
781
|
+
* `undefined`s have been dropped first: `{ ...defaults, ...{ checkTimeout: undefined } }`
|
|
782
|
+
* yields `checkTimeout: undefined`, which defeats the default and every validation
|
|
783
|
+
* that ran against it. Callers routinely produce such objects by spreading their own
|
|
784
|
+
* optional config, so adapters must sanitise before merging rather than trusting the
|
|
785
|
+
* `Required<...>` type on the resulting field.
|
|
786
|
+
*
|
|
787
|
+
* @param params the raw config object, possibly `undefined`
|
|
788
|
+
* @returns a shallow copy containing only the keys that were actually set
|
|
789
|
+
*/
|
|
790
|
+
function omitUndefined(params) {
|
|
791
|
+
return Object.fromEntries(Object.entries(params !== null && params !== void 0 ? params : {}).filter(([, value]) => value !== undefined));
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Guard the transition into `AdapterState.Connected`.
|
|
795
|
+
*
|
|
796
|
+
* A resolved account request is not the same thing as a connection. Wallets
|
|
797
|
+
* answer `tron_requestAccounts`/`eth_requestAccounts` with a success code while
|
|
798
|
+
* still returning an empty account list, and injected `tronWeb.defaultAddress`
|
|
799
|
+
* is frequently not populated yet at the moment the request resolves. Treating
|
|
800
|
+
* either as "connected" leaves the adapter reporting `connected === true` with
|
|
801
|
+
* no address, and emits `connect('')` to the dapp; every later signMessage or
|
|
802
|
+
* signTransaction then passes the state guard only to fail inside the provider.
|
|
803
|
+
*
|
|
804
|
+
* @param address the address the adapter is about to store. `false` is accepted
|
|
805
|
+
* because tronweb types `tronWeb.defaultAddress.base58` as `string | false`.
|
|
806
|
+
* @returns the same address, narrowed to a non-empty string
|
|
807
|
+
* @throws {WalletConnectionError} when no usable address was obtained
|
|
808
|
+
*/
|
|
809
|
+
function assertConnectAddress(address) {
|
|
810
|
+
if (!address) {
|
|
811
|
+
throw new errors_js_1.WalletConnectionError('Request connect error.');
|
|
812
|
+
}
|
|
813
|
+
return address;
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* check simply if current environment is browser or not
|
|
817
|
+
* @returns boolean
|
|
818
|
+
*/
|
|
819
|
+
function isInBrowser() {
|
|
820
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
*
|
|
824
|
+
* @param {Function} check funcion to check if wallet is installed. return true if wallet is detected.
|
|
825
|
+
* @returns
|
|
826
|
+
*/
|
|
827
|
+
function checkAdapterState(check) {
|
|
828
|
+
if (!isInBrowser())
|
|
829
|
+
return;
|
|
830
|
+
const disposers = [];
|
|
831
|
+
function dispose() {
|
|
832
|
+
for (const dispose of disposers) {
|
|
833
|
+
dispose();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
function checkAndDispose() {
|
|
837
|
+
if (check()) {
|
|
838
|
+
dispose();
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
const interval = setInterval(checkAndDispose, 500);
|
|
842
|
+
disposers.push(() => clearInterval(interval));
|
|
843
|
+
if (document.readyState === 'loading') {
|
|
844
|
+
document.addEventListener('DOMContentLoaded', checkAndDispose, { once: true });
|
|
845
|
+
disposers.push(() => document.removeEventListener('DOMContentLoaded', checkAndDispose));
|
|
846
|
+
}
|
|
847
|
+
if (document.readyState !== 'complete') {
|
|
848
|
+
window.addEventListener('load', checkAndDispose, { once: true });
|
|
849
|
+
disposers.push(() => window.removeEventListener('load', checkAndDispose));
|
|
850
|
+
}
|
|
851
|
+
checkAndDispose();
|
|
852
|
+
// stop all task after 1min
|
|
853
|
+
setTimeout(dispose, 60 * 1000);
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Simplily detect mobile device
|
|
857
|
+
*/
|
|
858
|
+
function isInMobileBrowser() {
|
|
859
|
+
return (typeof navigator !== 'undefined' &&
|
|
860
|
+
navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i));
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
} (utils$2));
|
|
864
|
+
return utils$2;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
var addonAdapter = {};
|
|
868
|
+
|
|
869
|
+
var security = {};
|
|
870
|
+
|
|
871
|
+
var hasRequiredSecurity;
|
|
872
|
+
|
|
873
|
+
function requireSecurity () {
|
|
874
|
+
if (hasRequiredSecurity) return security;
|
|
875
|
+
hasRequiredSecurity = 1;
|
|
876
|
+
(function (exports$1) {
|
|
877
|
+
var __awaiter = (security && security.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
878
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
879
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
880
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
881
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
882
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
883
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
884
|
+
});
|
|
885
|
+
};
|
|
886
|
+
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
887
|
+
exports$1.defaultSecurityOptions = void 0;
|
|
888
|
+
exports$1.validateSecurityOptions = validateSecurityOptions;
|
|
889
|
+
exports$1.clearCache = clearCache;
|
|
890
|
+
exports$1.fetchJsonWithCache = fetchJsonWithCache;
|
|
891
|
+
exports$1.defaultSecurityOptions = {
|
|
892
|
+
onRiskDetected: (result) => __awaiter(void 0, void 0, void 0, function* () {
|
|
893
|
+
console.log(`[WalletAdapter] Risk detected:`, result);
|
|
894
|
+
}),
|
|
895
|
+
configUrls: [],
|
|
896
|
+
enabled: false,
|
|
897
|
+
timeout: 2000,
|
|
898
|
+
retries: 0,
|
|
899
|
+
cacheTTL: 10 * 60 * 1000,
|
|
900
|
+
};
|
|
901
|
+
/** A config fetch that takes longer than this is never worth waiting for. */
|
|
902
|
+
const MAX_SECURITY_TIMEOUT = 60 * 1000;
|
|
903
|
+
/** `retries` multiplies the time `connect()` can block, so it is capped. */
|
|
904
|
+
const MAX_SECURITY_RETRIES = 10;
|
|
905
|
+
function assertFiniteNumber(value, field, min, max) {
|
|
906
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < min || value > max) {
|
|
907
|
+
throw new Error(`[WalletAdapter] config.securityOptions.${field} should be a finite number between ${min} and ${max}, but got ${String(value)}`);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
function parseAbsoluteUrl(url) {
|
|
911
|
+
try {
|
|
912
|
+
return new URL(url);
|
|
913
|
+
}
|
|
914
|
+
catch (_a) {
|
|
915
|
+
// Not absolute — a relative path, which `fetch` resolves against the page.
|
|
916
|
+
return null;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
function validateConfigUrls(configUrls) {
|
|
920
|
+
if (!Array.isArray(configUrls)) {
|
|
921
|
+
throw new Error(`[WalletAdapter] config.securityOptions.configUrls should be an array of URLs, but got ${typeof configUrls}`);
|
|
922
|
+
}
|
|
923
|
+
for (const url of configUrls) {
|
|
924
|
+
if (typeof url !== 'string' || url.trim() === '') {
|
|
925
|
+
throw new Error(`[WalletAdapter] config.securityOptions.configUrls should only contain non-empty URL strings, but got ${String(url)}`);
|
|
926
|
+
}
|
|
927
|
+
// Relative paths are legitimate — they resolve against the page and `new URL`
|
|
928
|
+
// rejects them — so only values that parse as an absolute URL are checked,
|
|
929
|
+
// and then only for the scheme `fetch` can actually retrieve.
|
|
930
|
+
const parsed = parseAbsoluteUrl(url);
|
|
931
|
+
if (parsed && parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
932
|
+
throw new Error(`[WalletAdapter] config.securityOptions.configUrls only supports http(s) URLs, but got ${url}`);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Validate `config.securityOptions` at construction time.
|
|
938
|
+
*
|
|
939
|
+
* Every field here is consumed much later, inside `connect()` — a `configUrls`
|
|
940
|
+
* string instead of an array only fails when `fetchJsonWithCache` calls `.map`
|
|
941
|
+
* on it, and a `NaN` timeout or a negative `retries` silently changes the fetch
|
|
942
|
+
* behaviour rather than reporting anything. Failing fast in the constructor puts
|
|
943
|
+
* the error where the caller can act on it.
|
|
944
|
+
*/
|
|
945
|
+
function validateSecurityOptions(securityOptions) {
|
|
946
|
+
const { enabled, configUrls, timeout, retries, cacheTTL, onRiskDetected, onConfigFallback } = securityOptions;
|
|
947
|
+
// `enabled` is read as a plain truthy value in `checkSecurity()` and again just
|
|
948
|
+
// below, so a non-boolean silently resolves to the opposite of what it reads like:
|
|
949
|
+
// `'false'` is truthy and turns the check on. Check it before the `configUrls`
|
|
950
|
+
// requirement below, or `{ enabled: 'false' }` reports a missing `configUrls`
|
|
951
|
+
// "when enabled is true" — for a caller who wrote `false`.
|
|
952
|
+
if (enabled !== undefined && typeof enabled !== 'boolean') {
|
|
953
|
+
throw new Error(`[WalletAdapter] config.securityOptions.enabled should be a boolean, but got ${typeof enabled}`);
|
|
954
|
+
}
|
|
955
|
+
if (configUrls !== undefined) {
|
|
956
|
+
validateConfigUrls(configUrls);
|
|
957
|
+
}
|
|
958
|
+
if (enabled && (!configUrls || configUrls.length === 0)) {
|
|
959
|
+
throw new Error(`[WalletAdapter] config.securityOptions.configUrls is required when securityOptions.enabled is true`);
|
|
960
|
+
}
|
|
961
|
+
if (timeout !== undefined) {
|
|
962
|
+
assertFiniteNumber(timeout, 'timeout', 1, MAX_SECURITY_TIMEOUT);
|
|
963
|
+
}
|
|
964
|
+
if (cacheTTL !== undefined) {
|
|
965
|
+
// No upper bound: caching the risk config for a long time is a valid choice.
|
|
966
|
+
assertFiniteNumber(cacheTTL, 'cacheTTL', 0, Number.MAX_SAFE_INTEGER);
|
|
967
|
+
}
|
|
968
|
+
if (retries !== undefined && (!Number.isInteger(retries) || retries < 0 || retries > MAX_SECURITY_RETRIES)) {
|
|
969
|
+
throw new Error(`[WalletAdapter] config.securityOptions.retries should be an integer between 0 and ${MAX_SECURITY_RETRIES}, but got ${String(retries)}`);
|
|
970
|
+
}
|
|
971
|
+
if (onRiskDetected !== undefined && typeof onRiskDetected !== 'function') {
|
|
972
|
+
throw new Error(`[WalletAdapter] config.securityOptions.onRiskDetected should be a function, but got ${typeof onRiskDetected}`);
|
|
973
|
+
}
|
|
974
|
+
if (onConfigFallback !== undefined && typeof onConfigFallback !== 'function') {
|
|
975
|
+
throw new Error(`[WalletAdapter] config.securityOptions.onConfigFallback should be a function, but got ${typeof onConfigFallback}`);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
function isValidRisk(risk) {
|
|
979
|
+
return (!!risk &&
|
|
980
|
+
typeof risk === 'object' &&
|
|
981
|
+
typeof risk.title === 'string' &&
|
|
982
|
+
risk.title.length > 0 &&
|
|
983
|
+
(risk.noticeType === 1 || risk.noticeType === 2 || risk.noticeType === 3));
|
|
984
|
+
}
|
|
985
|
+
function sanitizeRisk(risk) {
|
|
986
|
+
const clean = { title: risk.title, noticeType: risk.noticeType };
|
|
987
|
+
if (typeof risk.ext === 'string')
|
|
988
|
+
clean.ext = risk.ext;
|
|
989
|
+
if (typeof risk.ios === 'string')
|
|
990
|
+
clean.ios = risk.ios;
|
|
991
|
+
if (typeof risk.and === 'string')
|
|
992
|
+
clean.and = risk.and;
|
|
993
|
+
return clean;
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Defensively coerce an arbitrary remote payload into a well-formed RiskConfig.
|
|
997
|
+
*
|
|
998
|
+
* The config comes from a remote URL, so a bad release (or a tampered response)
|
|
999
|
+
* must never break the connect flow. Anything malformed is dropped with a
|
|
1000
|
+
* warning rather than thrown: `wallets` must be a record whose values are
|
|
1001
|
+
* arrays, and each risk must have a non-empty string `title` and a `noticeType`
|
|
1002
|
+
* of 1/2/3. Invalid entries are discarded so downstream merging/consumption
|
|
1003
|
+
* only ever sees clean `Risk[]`.
|
|
1004
|
+
*/
|
|
1005
|
+
function normalizeRiskConfig(data) {
|
|
1006
|
+
const source = data && typeof data === 'object' ? data : {};
|
|
1007
|
+
const wallets = {};
|
|
1008
|
+
if (source.wallets && typeof source.wallets === 'object') {
|
|
1009
|
+
for (const [walletName, rawRisks] of Object.entries(source.wallets)) {
|
|
1010
|
+
if (!Array.isArray(rawRisks)) {
|
|
1011
|
+
console.warn(`[WalletAdapter] Ignoring malformed risks for "${walletName}": expected an array, got ${typeof rawRisks}.`);
|
|
1012
|
+
continue;
|
|
1013
|
+
}
|
|
1014
|
+
const validRisks = [];
|
|
1015
|
+
for (const risk of rawRisks) {
|
|
1016
|
+
if (isValidRisk(risk)) {
|
|
1017
|
+
validRisks.push(sanitizeRisk(risk));
|
|
1018
|
+
}
|
|
1019
|
+
else {
|
|
1020
|
+
console.warn(`[WalletAdapter] Dropping malformed risk entry for "${walletName}":`, risk);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
if (validRisks.length > 0) {
|
|
1024
|
+
wallets[walletName] = validRisks;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
return {
|
|
1029
|
+
v: typeof source.v === 'string' ? source.v : '',
|
|
1030
|
+
ts: typeof source.ts === 'number' ? source.ts : 0,
|
|
1031
|
+
wallets,
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
const _jsonCache = {};
|
|
1035
|
+
function clearCache() {
|
|
1036
|
+
Object.keys(_jsonCache).forEach((key) => {
|
|
1037
|
+
Reflect.deleteProperty(_jsonCache, key);
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
function fetchJsonWithCache(options) {
|
|
1041
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1042
|
+
const { configUrls = exports$1.defaultSecurityOptions.configUrls, timeout = exports$1.defaultSecurityOptions.timeout, retries = exports$1.defaultSecurityOptions.retries, onConfigFallback, cacheTTL = exports$1.defaultSecurityOptions.cacheTTL, } = options;
|
|
1043
|
+
const now = Date.now();
|
|
1044
|
+
function fetchOneUrl(url) {
|
|
1045
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1046
|
+
const cache = _jsonCache[url];
|
|
1047
|
+
if (cache && now - cache.timestamp < cacheTTL) {
|
|
1048
|
+
return cache.data;
|
|
1049
|
+
}
|
|
1050
|
+
function fetchWithTimeout() {
|
|
1051
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1052
|
+
return new Promise((resolve, reject) => {
|
|
1053
|
+
const controller = new AbortController();
|
|
1054
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
1055
|
+
fetch(url, { signal: controller.signal })
|
|
1056
|
+
.then((resp) => {
|
|
1057
|
+
clearTimeout(timer);
|
|
1058
|
+
if (!resp.ok)
|
|
1059
|
+
reject(new Error('Fetch failed with code: ' + resp.status));
|
|
1060
|
+
else
|
|
1061
|
+
resp.json().then((data) => resolve(normalizeRiskConfig(data)), reject);
|
|
1062
|
+
})
|
|
1063
|
+
.catch((err) => {
|
|
1064
|
+
clearTimeout(timer);
|
|
1065
|
+
reject(err);
|
|
1066
|
+
});
|
|
1067
|
+
});
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
for (let i = 0; i <= retries; i++) {
|
|
1071
|
+
try {
|
|
1072
|
+
const data = yield fetchWithTimeout();
|
|
1073
|
+
_jsonCache[url] = { data, timestamp: Date.now() };
|
|
1074
|
+
return data;
|
|
1075
|
+
}
|
|
1076
|
+
catch (e) {
|
|
1077
|
+
console.warn(`[WalletAdapter] Fetch attempt ${i + 1} for ${url} failed:`, e);
|
|
1078
|
+
// continue to next retry
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
// All retries failed — let the outer caller decide (onConfigFallback or safe empty config)
|
|
1082
|
+
return null;
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
const results = yield Promise.all(configUrls.map(fetchOneUrl));
|
|
1086
|
+
const configs = results.filter((r) => r !== null);
|
|
1087
|
+
if (configs.length > 0) {
|
|
1088
|
+
return configs.reduce((merged, config) => {
|
|
1089
|
+
var _a;
|
|
1090
|
+
if (config.ts > merged.ts) {
|
|
1091
|
+
merged.v = config.v;
|
|
1092
|
+
merged.ts = config.ts;
|
|
1093
|
+
}
|
|
1094
|
+
// Pass every risk from every source through to the DApp without
|
|
1095
|
+
// deduplication. Conflict resolution (highest severity wins, source
|
|
1096
|
+
// weighting, etc.) is the DApp's responsibility — the adapter just
|
|
1097
|
+
// delivers the union.
|
|
1098
|
+
for (const [wallet, risks] of Object.entries(config.wallets)) {
|
|
1099
|
+
merged.wallets[wallet] = [...((_a = merged.wallets[wallet]) !== null && _a !== void 0 ? _a : []), ...risks];
|
|
1100
|
+
}
|
|
1101
|
+
return merged;
|
|
1102
|
+
}, { v: '', ts: 0, wallets: {} });
|
|
1103
|
+
}
|
|
1104
|
+
// All URLs failed with no cache — call custom fallback or default to safe (allow connection)
|
|
1105
|
+
if (onConfigFallback) {
|
|
1106
|
+
return normalizeRiskConfig(yield onConfigFallback());
|
|
1107
|
+
}
|
|
1108
|
+
return { v: '', ts: 0, wallets: {} };
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
} (security));
|
|
1113
|
+
return security;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
var hasRequiredAddonAdapter;
|
|
1117
|
+
|
|
1118
|
+
function requireAddonAdapter () {
|
|
1119
|
+
if (hasRequiredAddonAdapter) return addonAdapter;
|
|
1120
|
+
hasRequiredAddonAdapter = 1;
|
|
1121
|
+
var __awaiter = (addonAdapter && addonAdapter.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1122
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1123
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1124
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1125
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1126
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1127
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1128
|
+
});
|
|
1129
|
+
};
|
|
1130
|
+
Object.defineProperty(addonAdapter, "__esModule", { value: true });
|
|
1131
|
+
addonAdapter.AddonAdapter = void 0;
|
|
1132
|
+
const adapter_js_1 = requireAdapter$2();
|
|
1133
|
+
const errors_js_1 = requireErrors();
|
|
1134
|
+
const security_js_1 = requireSecurity();
|
|
1135
|
+
const types_js_1 = requireTypes$1();
|
|
1136
|
+
const utils_js_1 = requireUtils$2();
|
|
625
1137
|
/**
|
|
626
|
-
*
|
|
627
|
-
* @param {Function} check funcion to check if wallet is installed. return true if wallet is detected.
|
|
628
|
-
* @returns
|
|
1138
|
+
* Class to provide security check for wallets.
|
|
629
1139
|
*/
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
1140
|
+
class AddonAdapter extends adapter_js_1.Adapter {
|
|
1141
|
+
constructor(params) {
|
|
1142
|
+
super();
|
|
1143
|
+
this.commonConfig = {
|
|
1144
|
+
checkTimeout: 2 * 1000,
|
|
1145
|
+
openAppWithDeeplink: true,
|
|
1146
|
+
openUrlWhenWalletNotFound: true,
|
|
1147
|
+
securityOptions: security_js_1.defaultSecurityOptions,
|
|
1148
|
+
};
|
|
1149
|
+
this._connectPromise = null;
|
|
1150
|
+
this._securityCheckCache = null;
|
|
1151
|
+
// Drop explicit `undefined`s before merging: spreading them would overwrite
|
|
1152
|
+
// the defaults with `undefined` and make `Required<BaseAdapterConfig>` a lie,
|
|
1153
|
+
// which matters because callers routinely spread optional config objects.
|
|
1154
|
+
// Subclasses that re-merge their own config on top of `commonConfig` must
|
|
1155
|
+
// sanitise it the same way — see `omitUndefined`.
|
|
1156
|
+
this.commonConfig = Object.assign(Object.assign({}, this.commonConfig), (0, utils_js_1.omitUndefined)(params));
|
|
1157
|
+
(0, utils_js_1.validateCheckTimeout)(this.commonConfig.checkTimeout);
|
|
1158
|
+
(0, security_js_1.validateSecurityOptions)(this.commonConfig.securityOptions);
|
|
638
1159
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
1160
|
+
/**
|
|
1161
|
+
* Update the security options at runtime. The given options are merged into
|
|
1162
|
+
* the existing config, validated, and the cached security check result is
|
|
1163
|
+
* cleared so the next connect runs a fresh check with the new configuration.
|
|
1164
|
+
*/
|
|
1165
|
+
updateSecurityOptions(securityOptions) {
|
|
1166
|
+
const merged = Object.assign(Object.assign({}, this.commonConfig.securityOptions), securityOptions);
|
|
1167
|
+
(0, security_js_1.validateSecurityOptions)(merged);
|
|
1168
|
+
this.commonConfig.securityOptions = merged;
|
|
1169
|
+
this._securityCheckCache = null;
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Serialise `connect()` so that concurrent callers cannot each reach the wallet.
|
|
1173
|
+
*
|
|
1174
|
+
* The `connecting` flag alone cannot do this. Subclasses only raise it *after*
|
|
1175
|
+
* `await this._beforeConnect()` resolves, and `_beforeConnect()` itself awaits
|
|
1176
|
+
* wallet discovery and the security check — so two calls made in the same tick
|
|
1177
|
+
* both pass the guard while it is still `false`, and both go on to call
|
|
1178
|
+
* `tron_requestAccounts`. That produces a second authorisation popup, a `4000`
|
|
1179
|
+
* "pending request" error from the provider, and duplicated connect events.
|
|
1180
|
+
*
|
|
1181
|
+
* Claiming the in-flight promise here is synchronous — there is no `await`
|
|
1182
|
+
* between the check and the assignment — so a second caller always observes it
|
|
1183
|
+
* and simply shares the first call's result. Because the whole subclass
|
|
1184
|
+
* `_connect()` runs inside it, discovery, the security check and the provider
|
|
1185
|
+
* request are all in the same critical section.
|
|
1186
|
+
*/
|
|
1187
|
+
connect(options) {
|
|
1188
|
+
if (this._connectPromise) {
|
|
1189
|
+
return this._connectPromise;
|
|
642
1190
|
}
|
|
1191
|
+
// Deliberately not `async`: that would wrap the shared promise in a fresh one
|
|
1192
|
+
// per caller. The IIFE still turns a synchronous throw from `_connect()` into
|
|
1193
|
+
// a rejection, so callers never see one thrown at them directly.
|
|
1194
|
+
const promise = (() => __awaiter(this, void 0, void 0, function* () { return this._connect(options); }))().finally(() => {
|
|
1195
|
+
if (this._connectPromise === promise) {
|
|
1196
|
+
this._connectPromise = null;
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
this._connectPromise = promise;
|
|
1200
|
+
return promise;
|
|
643
1201
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
1202
|
+
/**
|
|
1203
|
+
* Run the pre-connect pipeline (wallet discovery, deeplink/url fallback,
|
|
1204
|
+
* security check).
|
|
1205
|
+
*
|
|
1206
|
+
* @returns `true` when the caller should continue with the actual connect
|
|
1207
|
+
* flow, `false` when the adapter is already connected/connecting and the
|
|
1208
|
+
* caller should bail out. Throws `WalletNotFoundError` when the wallet
|
|
1209
|
+
* cannot be found.
|
|
1210
|
+
*/
|
|
1211
|
+
_beforeConnect() {
|
|
1212
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1213
|
+
if (this.connected || this.connecting)
|
|
1214
|
+
return false;
|
|
1215
|
+
yield this._checkWallet();
|
|
1216
|
+
if (this.readyState === types_js_1.WalletReadyState.NotFound) {
|
|
1217
|
+
if ((0, utils_js_1.isInBrowser)() &&
|
|
1218
|
+
!this._openAppByDeepLinkIfNeed() &&
|
|
1219
|
+
this.commonConfig.openUrlWhenWalletNotFound !== false) {
|
|
1220
|
+
window.open(this.url, '_blank');
|
|
1221
|
+
}
|
|
1222
|
+
throw new errors_js_1.WalletNotFoundError();
|
|
1223
|
+
}
|
|
1224
|
+
yield this.checkSecurity();
|
|
1225
|
+
return true;
|
|
1226
|
+
});
|
|
649
1227
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
1228
|
+
/**
|
|
1229
|
+
* Fetch remote config and do risk check.
|
|
1230
|
+
* In-flight calls share the same promise (so `onRiskDetected` fires at most
|
|
1231
|
+
* once even on a slow network). After the promise settles, the result is
|
|
1232
|
+
* cached for SECURITY_CHECK_CACHE_TTL; the next call after that window
|
|
1233
|
+
* runs a fresh check.
|
|
1234
|
+
*/
|
|
1235
|
+
checkSecurity() {
|
|
1236
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1237
|
+
if (!this.commonConfig.securityOptions.enabled)
|
|
1238
|
+
return;
|
|
1239
|
+
const cache = this._securityCheckCache;
|
|
1240
|
+
if (cache &&
|
|
1241
|
+
(cache.settledAt === null || Date.now() - cache.settledAt < AddonAdapter.SECURITY_CHECK_CACHE_TTL)) {
|
|
1242
|
+
return cache.promise;
|
|
1243
|
+
}
|
|
1244
|
+
const promise = (() => __awaiter(this, void 0, void 0, function* () {
|
|
1245
|
+
const result = yield (0, security_js_1.fetchJsonWithCache)(this.commonConfig.securityOptions);
|
|
1246
|
+
const risks = result.wallets[this.name];
|
|
1247
|
+
if (risks && risks.length > 0) {
|
|
1248
|
+
const callback = this.commonConfig.securityOptions.onRiskDetected || security_js_1.defaultSecurityOptions.onRiskDetected;
|
|
1249
|
+
yield callback({ risks });
|
|
1250
|
+
}
|
|
1251
|
+
}))();
|
|
1252
|
+
const entry = { promise, settledAt: null };
|
|
1253
|
+
this._securityCheckCache = entry;
|
|
1254
|
+
// The `.finally` chain returns a new promise that mirrors `promise`'s rejection.
|
|
1255
|
+
// Attach a noop `.catch` to avoid an unhandled rejection on that chain — the
|
|
1256
|
+
// original `promise` is still surfaced to callers via the return below.
|
|
1257
|
+
promise
|
|
1258
|
+
.finally(() => {
|
|
1259
|
+
if (this._securityCheckCache === entry) {
|
|
1260
|
+
entry.settledAt = Date.now();
|
|
1261
|
+
}
|
|
1262
|
+
})
|
|
1263
|
+
.catch(() => { });
|
|
1264
|
+
return promise;
|
|
1265
|
+
});
|
|
653
1266
|
}
|
|
654
|
-
checkAndDispose();
|
|
655
|
-
// stop all task after 1min
|
|
656
|
-
setTimeout(dispose, 60 * 1000);
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Simplily detect mobile device
|
|
660
|
-
*/
|
|
661
|
-
function isInMobileBrowser() {
|
|
662
|
-
return (typeof navigator !== 'undefined' &&
|
|
663
|
-
navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i));
|
|
664
1267
|
}
|
|
1268
|
+
addonAdapter.AddonAdapter = AddonAdapter;
|
|
1269
|
+
AddonAdapter.SECURITY_CHECK_CACHE_TTL = 5 * 1000;
|
|
665
1270
|
|
|
666
|
-
return
|
|
1271
|
+
return addonAdapter;
|
|
667
1272
|
}
|
|
668
1273
|
|
|
669
1274
|
var hasRequiredCjs$2;
|
|
@@ -690,7 +1295,10 @@
|
|
|
690
1295
|
__exportStar(requireAdapter$2(), exports$1);
|
|
691
1296
|
__exportStar(requireErrors(), exports$1);
|
|
692
1297
|
__exportStar(requireTypes$1(), exports$1);
|
|
1298
|
+
__exportStar(requireTypedData(), exports$1);
|
|
693
1299
|
__exportStar(requireUtils$2(), exports$1);
|
|
1300
|
+
__exportStar(requireAddonAdapter(), exports$1);
|
|
1301
|
+
__exportStar(requireSecurity(), exports$1);
|
|
694
1302
|
|
|
695
1303
|
} (cjs$1));
|
|
696
1304
|
return cjs$1;
|
|
@@ -829,10 +1437,10 @@
|
|
|
829
1437
|
});
|
|
830
1438
|
}
|
|
831
1439
|
exports$1.TronLinkAdapterName = 'TronLink';
|
|
832
|
-
class TronLinkAdapter extends tronwallet_abstract_adapter_1.
|
|
1440
|
+
class TronLinkAdapter extends tronwallet_abstract_adapter_1.AddonAdapter {
|
|
833
1441
|
// record if first connect event has emitted or not
|
|
834
1442
|
constructor(config = {}) {
|
|
835
|
-
super();
|
|
1443
|
+
super(config);
|
|
836
1444
|
this.name = exports$1.TronLinkAdapterName;
|
|
837
1445
|
this.url = 'https://www.tronlink.org/';
|
|
838
1446
|
this.icon = 'data:image/png;base64,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';
|
|
@@ -858,11 +1466,11 @@
|
|
|
858
1466
|
}
|
|
859
1467
|
};
|
|
860
1468
|
this._checkPromise = null;
|
|
861
|
-
this._updateWallet = () => {
|
|
862
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
1469
|
+
this._updateWallet = () => __awaiter(this, void 0, void 0, function* () {
|
|
1470
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
863
1471
|
this._supportNewTronProtocol = false;
|
|
864
|
-
let state
|
|
865
|
-
let address
|
|
1472
|
+
let state;
|
|
1473
|
+
let address;
|
|
866
1474
|
if ((0, tronwallet_abstract_adapter_1.isInMobileBrowser)()) {
|
|
867
1475
|
if (window.tronLink) {
|
|
868
1476
|
this._wallet = window.tronLink;
|
|
@@ -875,9 +1483,23 @@
|
|
|
875
1483
|
};
|
|
876
1484
|
}
|
|
877
1485
|
address = ((_c = (_b = this._wallet.tronWeb) === null || _b === void 0 ? void 0 : _b.defaultAddress) === null || _c === void 0 ? void 0 : _c.base58) || null;
|
|
878
|
-
|
|
1486
|
+
if (address) {
|
|
1487
|
+
// Only run the security check once the wallet is actually connected.
|
|
1488
|
+
try {
|
|
1489
|
+
yield this.checkSecurity();
|
|
1490
|
+
}
|
|
1491
|
+
catch (_j) {
|
|
1492
|
+
this.setAddress(null);
|
|
1493
|
+
this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
state = tronwallet_abstract_adapter_1.AdapterState.Connected;
|
|
1497
|
+
}
|
|
1498
|
+
else {
|
|
1499
|
+
state = tronwallet_abstract_adapter_1.AdapterState.Disconnect;
|
|
1500
|
+
}
|
|
879
1501
|
}
|
|
880
|
-
else if (
|
|
1502
|
+
else if (this.isLegacyTronLinkProvider(window.tron)) {
|
|
881
1503
|
this._supportNewTronProtocol = true;
|
|
882
1504
|
this._wallet = window.tron;
|
|
883
1505
|
this._listenTronEvent();
|
|
@@ -887,8 +1509,6 @@
|
|
|
887
1509
|
}
|
|
888
1510
|
catch (e) {
|
|
889
1511
|
console.error('Unknown error: ' + e, ' Please install TronLink extension wallet.');
|
|
890
|
-
address = null;
|
|
891
|
-
state = tronwallet_abstract_adapter_1.AdapterState.Disconnect;
|
|
892
1512
|
this._readyState = tronwallet_abstract_adapter_1.WalletReadyState.NotFound;
|
|
893
1513
|
this.emit('readyStateChanged', this.readyState);
|
|
894
1514
|
return;
|
|
@@ -899,16 +1519,6 @@
|
|
|
899
1519
|
address = ((_h = (_g = this._wallet.tronWeb) === null || _g === void 0 ? void 0 : _g.defaultAddress) === null || _h === void 0 ? void 0 : _h.base58) || null;
|
|
900
1520
|
state = this._wallet.ready ? tronwallet_abstract_adapter_1.AdapterState.Connected : tronwallet_abstract_adapter_1.AdapterState.Disconnect;
|
|
901
1521
|
}
|
|
902
|
-
else if (window.tronWeb) {
|
|
903
|
-
// fake tronLink
|
|
904
|
-
this._wallet = {
|
|
905
|
-
ready: window.tronWeb.ready,
|
|
906
|
-
tronWeb: window.tronWeb,
|
|
907
|
-
request: () => Promise.resolve(true),
|
|
908
|
-
};
|
|
909
|
-
address = ((_j = this._wallet.tronWeb.defaultAddress) === null || _j === void 0 ? void 0 : _j.base58) || null;
|
|
910
|
-
state = this._wallet.ready ? tronwallet_abstract_adapter_1.AdapterState.Connected : tronwallet_abstract_adapter_1.AdapterState.Disconnect;
|
|
911
|
-
}
|
|
912
1522
|
else {
|
|
913
1523
|
// no tronlink support
|
|
914
1524
|
this._wallet = null;
|
|
@@ -921,26 +1531,40 @@
|
|
|
921
1531
|
}
|
|
922
1532
|
this.setAddress(address);
|
|
923
1533
|
this.setState(state);
|
|
924
|
-
};
|
|
1534
|
+
});
|
|
925
1535
|
this.checkReadyInterval = null;
|
|
926
|
-
const { checkTimeout =
|
|
1536
|
+
const { checkTimeout = 5 * 1000, dappIcon = '', dappName = '', openUrlWhenWalletNotFound = true, openTronLinkAppOnMobile = true, openAppWithDeeplink = true, } = config;
|
|
927
1537
|
if (typeof checkTimeout !== 'number') {
|
|
928
1538
|
throw new Error('[TronLinkAdapter] config.checkTimeout should be a number');
|
|
929
1539
|
}
|
|
930
|
-
this.config = {
|
|
931
|
-
checkTimeout,
|
|
1540
|
+
this.config = Object.assign(Object.assign({}, this.commonConfig), { checkTimeout,
|
|
932
1541
|
openTronLinkAppOnMobile,
|
|
933
1542
|
openAppWithDeeplink,
|
|
934
1543
|
openUrlWhenWalletNotFound,
|
|
935
1544
|
dappIcon,
|
|
936
|
-
dappName
|
|
937
|
-
};
|
|
1545
|
+
dappName });
|
|
938
1546
|
this._connecting = false;
|
|
939
1547
|
this._wallet = null;
|
|
940
1548
|
this._address = null;
|
|
941
|
-
if ((0,
|
|
1549
|
+
if (!(0, tronwallet_abstract_adapter_1.isInBrowser)()) {
|
|
1550
|
+
this._readyState = tronwallet_abstract_adapter_1.WalletReadyState.NotFound;
|
|
1551
|
+
this.setState(tronwallet_abstract_adapter_1.AdapterState.NotFound);
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
if (!(0, tronwallet_abstract_adapter_1.isInMobileBrowser)()) {
|
|
1555
|
+
this._checkWallet().then(() => {
|
|
1556
|
+
if (this.connected) {
|
|
1557
|
+
this.emit('connect', this.address || '');
|
|
1558
|
+
}
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
else if ((0, utils_js_1.supportTron)() || ((0, tronwallet_abstract_adapter_1.isInMobileBrowser)() && (window.tronLink || window.tronWeb))) {
|
|
942
1562
|
this._readyState = tronwallet_abstract_adapter_1.WalletReadyState.Found;
|
|
943
|
-
this._updateWallet()
|
|
1563
|
+
this._updateWallet().then(() => {
|
|
1564
|
+
if (this.connected) {
|
|
1565
|
+
this.emit('connect', this.address || '');
|
|
1566
|
+
}
|
|
1567
|
+
});
|
|
944
1568
|
}
|
|
945
1569
|
else {
|
|
946
1570
|
this._checkWallet().then(() => {
|
|
@@ -989,20 +1613,12 @@
|
|
|
989
1613
|
}
|
|
990
1614
|
});
|
|
991
1615
|
}
|
|
992
|
-
|
|
1616
|
+
_connect() {
|
|
993
1617
|
return __awaiter(this, void 0, void 0, function* () {
|
|
994
1618
|
var _a, _b;
|
|
995
1619
|
try {
|
|
996
|
-
this.
|
|
997
|
-
if (this.connected || this.connecting)
|
|
1620
|
+
if (!(yield this._beforeConnect()))
|
|
998
1621
|
return;
|
|
999
|
-
yield this._checkWallet();
|
|
1000
|
-
if (this.state === tronwallet_abstract_adapter_1.AdapterState.NotFound) {
|
|
1001
|
-
if (this.config.openUrlWhenWalletNotFound !== false && (0, tronwallet_abstract_adapter_1.isInBrowser)()) {
|
|
1002
|
-
window.open(this.url, '_blank');
|
|
1003
|
-
}
|
|
1004
|
-
throw new tronwallet_abstract_adapter_1.WalletNotFoundError();
|
|
1005
|
-
}
|
|
1006
1622
|
// lower version only support window.tronWeb, no window.tronLink
|
|
1007
1623
|
if (!this._wallet)
|
|
1008
1624
|
return;
|
|
@@ -1011,7 +1627,7 @@
|
|
|
1011
1627
|
const wallet = this._wallet;
|
|
1012
1628
|
try {
|
|
1013
1629
|
const res = yield wallet.request({ method: 'eth_requestAccounts' });
|
|
1014
|
-
const address = res[0];
|
|
1630
|
+
const address = (0, tronwallet_abstract_adapter_1.assertConnectAddress)(res === null || res === void 0 ? void 0 : res[0]);
|
|
1015
1631
|
this.setAddress(address);
|
|
1016
1632
|
this.setState(tronwallet_abstract_adapter_1.AdapterState.Connected);
|
|
1017
1633
|
this._listenTronEvent();
|
|
@@ -1033,30 +1649,25 @@
|
|
|
1033
1649
|
}
|
|
1034
1650
|
else if (window.tronLink) {
|
|
1035
1651
|
const wallet = this._wallet;
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
throw new tronwallet_abstract_adapter_1.WalletConnectionError('TronLink wallet is locked or no wallet account is avaliable.');
|
|
1042
|
-
}
|
|
1043
|
-
if (res.code === 4000) {
|
|
1044
|
-
throw new tronwallet_abstract_adapter_1.WalletConnectionError('The same DApp has already initiated a request to connect to TronLink wallet, and the pop-up window has not been closed.');
|
|
1045
|
-
}
|
|
1046
|
-
if (res.code === 4001) {
|
|
1047
|
-
throw new tronwallet_abstract_adapter_1.WalletConnectionError('The user rejected connection.');
|
|
1048
|
-
}
|
|
1652
|
+
const res = yield wallet.request({ method: 'tron_requestAccounts' });
|
|
1653
|
+
if (!res) {
|
|
1654
|
+
// 1. wallet is locked
|
|
1655
|
+
// 2. tronlink is first installed and there is no wallet account
|
|
1656
|
+
throw new tronwallet_abstract_adapter_1.WalletConnectionError('TronLink wallet is locked or no wallet account is avaliable.');
|
|
1049
1657
|
}
|
|
1050
|
-
|
|
1051
|
-
throw new tronwallet_abstract_adapter_1.WalletConnectionError(
|
|
1658
|
+
if (res.code === 4000) {
|
|
1659
|
+
throw new tronwallet_abstract_adapter_1.WalletConnectionError('The same DApp has already initiated a request to connect to TronLink wallet, and the pop-up window has not been closed.');
|
|
1660
|
+
}
|
|
1661
|
+
if (res.code === 4001) {
|
|
1662
|
+
throw new tronwallet_abstract_adapter_1.WalletConnectionError('The user rejected connection.');
|
|
1052
1663
|
}
|
|
1053
|
-
const address = ((_a = wallet.tronWeb.defaultAddress) === null || _a === void 0 ? void 0 : _a.base58)
|
|
1664
|
+
const address = (0, tronwallet_abstract_adapter_1.assertConnectAddress)((_a = wallet.tronWeb.defaultAddress) === null || _a === void 0 ? void 0 : _a.base58);
|
|
1054
1665
|
this.setAddress(address);
|
|
1055
1666
|
this.setState(tronwallet_abstract_adapter_1.AdapterState.Connected);
|
|
1056
1667
|
}
|
|
1057
1668
|
else if (window.tronWeb) {
|
|
1058
1669
|
const wallet = this._wallet;
|
|
1059
|
-
const address = ((_b = wallet.tronWeb.defaultAddress) === null || _b === void 0 ? void 0 : _b.base58)
|
|
1670
|
+
const address = (0, tronwallet_abstract_adapter_1.assertConnectAddress)((_b = wallet.tronWeb.defaultAddress) === null || _b === void 0 ? void 0 : _b.base58);
|
|
1060
1671
|
this.setAddress(address);
|
|
1061
1672
|
this.setState(tronwallet_abstract_adapter_1.AdapterState.Connected);
|
|
1062
1673
|
}
|
|
@@ -1066,8 +1677,9 @@
|
|
|
1066
1677
|
this.connected && this.emit('connect', this.address || '');
|
|
1067
1678
|
}
|
|
1068
1679
|
catch (error) {
|
|
1069
|
-
|
|
1070
|
-
|
|
1680
|
+
const err = error instanceof tronwallet_abstract_adapter_1.WalletError ? error : new tronwallet_abstract_adapter_1.WalletConnectionError(error === null || error === void 0 ? void 0 : error.message, error);
|
|
1681
|
+
this.emit('error', err);
|
|
1682
|
+
throw err;
|
|
1071
1683
|
}
|
|
1072
1684
|
finally {
|
|
1073
1685
|
this._connecting = false;
|
|
@@ -1135,6 +1747,11 @@
|
|
|
1135
1747
|
return this._checkAndSign((wallet) => __awaiter(this, void 0, void 0, function* () { return wallet.tronWeb.trx.signMessageV2(message); }), tronwallet_abstract_adapter_1.WalletSignMessageError);
|
|
1136
1748
|
});
|
|
1137
1749
|
}
|
|
1750
|
+
_signTypedData(typedData) {
|
|
1751
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1752
|
+
return this._checkAndSign((wallet) => __awaiter(this, void 0, void 0, function* () { return wallet.tronWeb.trx._signTypedData(typedData.domain, typedData.types, typedData.message); }), tronwallet_abstract_adapter_1.WalletSignTypedDataError);
|
|
1753
|
+
});
|
|
1754
|
+
}
|
|
1138
1755
|
/**
|
|
1139
1756
|
* Switch to target chain. If current chain is the same as target chain, the call will success immediately.
|
|
1140
1757
|
* Available chainIds:
|
|
@@ -1175,7 +1792,9 @@
|
|
|
1175
1792
|
}
|
|
1176
1793
|
checkAndGetWallet() {
|
|
1177
1794
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1178
|
-
this.
|
|
1795
|
+
if (this._openAppByDeepLinkIfNeed()) {
|
|
1796
|
+
throw new tronwallet_abstract_adapter_1.WalletNotFoundError();
|
|
1797
|
+
}
|
|
1179
1798
|
yield this._checkWallet();
|
|
1180
1799
|
if (this.state !== tronwallet_abstract_adapter_1.AdapterState.Connected)
|
|
1181
1800
|
throw new tronwallet_abstract_adapter_1.WalletDisconnectedError();
|
|
@@ -1185,14 +1804,12 @@
|
|
|
1185
1804
|
return wallet;
|
|
1186
1805
|
});
|
|
1187
1806
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
return;
|
|
1192
|
-
}
|
|
1193
|
-
if ((0, utils_js_1.openTronLink)({ dappIcon, dappName })) {
|
|
1194
|
-
throw new tronwallet_abstract_adapter_1.WalletNotFoundError();
|
|
1807
|
+
_openAppByDeepLinkIfNeed() {
|
|
1808
|
+
if (this.config.openAppWithDeeplink === false || this.config.openTronLinkAppOnMobile === false) {
|
|
1809
|
+
return false;
|
|
1195
1810
|
}
|
|
1811
|
+
const { dappName = '', dappIcon = '' } = this.config;
|
|
1812
|
+
return (0, utils_js_1.openTronLink)({ dappIcon, dappName });
|
|
1196
1813
|
}
|
|
1197
1814
|
// following code is for TIP-1193
|
|
1198
1815
|
_listenTronEvent() {
|
|
@@ -1208,6 +1825,12 @@
|
|
|
1208
1825
|
(_a = wallet.removeListener) === null || _a === void 0 ? void 0 : _a.call(wallet, 'chainChanged', this._onChainChanged);
|
|
1209
1826
|
(_b = wallet.removeListener) === null || _b === void 0 ? void 0 : _b.call(wallet, 'accountsChanged', this._onAccountsChanged);
|
|
1210
1827
|
}
|
|
1828
|
+
isLegacyTronLinkProvider(provider) {
|
|
1829
|
+
return !!(provider === null || provider === void 0 ? void 0 : provider.isTronLink);
|
|
1830
|
+
}
|
|
1831
|
+
hasDesktopLegacyTronLinkProvider() {
|
|
1832
|
+
return this.isLegacyTronLinkProvider(window.tron) || !!window.tronLink;
|
|
1833
|
+
}
|
|
1211
1834
|
/**
|
|
1212
1835
|
* check if wallet exists by interval, the promise only resolve when wallet detected or timeout
|
|
1213
1836
|
* @returns if wallet exists
|
|
@@ -1219,18 +1842,99 @@
|
|
|
1219
1842
|
if (this._checkPromise) {
|
|
1220
1843
|
return this._checkPromise;
|
|
1221
1844
|
}
|
|
1845
|
+
if ((0, tronwallet_abstract_adapter_1.isInBrowser)() && !(0, tronwallet_abstract_adapter_1.isInMobileBrowser)()) {
|
|
1846
|
+
// Desktop: use TIP-6963 event-based discovery with fallback
|
|
1847
|
+
const detection = new Promise((resolve) => {
|
|
1848
|
+
let handled = false;
|
|
1849
|
+
let timer = null;
|
|
1850
|
+
let handler = null;
|
|
1851
|
+
const cleanupDesktopDetection = () => {
|
|
1852
|
+
if (timer) {
|
|
1853
|
+
clearTimeout(timer);
|
|
1854
|
+
timer = null;
|
|
1855
|
+
}
|
|
1856
|
+
if (typeof window !== 'undefined' && handler) {
|
|
1857
|
+
window.removeEventListener(tronwallet_abstract_adapter_1.TIP6963AnnounceProviderEventName, handler);
|
|
1858
|
+
}
|
|
1859
|
+
};
|
|
1860
|
+
const finishWithLegacyDetection = () => {
|
|
1861
|
+
if (handled) {
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1864
|
+
handled = true;
|
|
1865
|
+
cleanupDesktopDetection();
|
|
1866
|
+
if (typeof window === 'undefined') {
|
|
1867
|
+
resolve(false);
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
// Fallback to legacy detection
|
|
1871
|
+
this._updateWallet();
|
|
1872
|
+
const isSupport = this.state !== tronwallet_abstract_adapter_1.AdapterState.NotFound;
|
|
1873
|
+
this._readyState = isSupport ? tronwallet_abstract_adapter_1.WalletReadyState.Found : tronwallet_abstract_adapter_1.WalletReadyState.NotFound;
|
|
1874
|
+
this.emit('readyStateChanged', this._readyState);
|
|
1875
|
+
resolve(isSupport);
|
|
1876
|
+
};
|
|
1877
|
+
timer = setTimeout(finishWithLegacyDetection, this.config.checkTimeout);
|
|
1878
|
+
handler = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
1879
|
+
var _a, _b;
|
|
1880
|
+
if (handled) {
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
const { info, provider } = event.detail;
|
|
1884
|
+
const isTronLinkProvider = info.name === 'TronLink';
|
|
1885
|
+
if (isTronLinkProvider) {
|
|
1886
|
+
handled = true;
|
|
1887
|
+
this._supportNewTronProtocol = true;
|
|
1888
|
+
this._wallet = provider;
|
|
1889
|
+
try {
|
|
1890
|
+
yield this.checkSecurity();
|
|
1891
|
+
}
|
|
1892
|
+
catch (_c) {
|
|
1893
|
+
this.setAddress(null);
|
|
1894
|
+
this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
|
|
1895
|
+
this._readyState = tronwallet_abstract_adapter_1.WalletReadyState.Found;
|
|
1896
|
+
this.emit('readyStateChanged', this.readyState);
|
|
1897
|
+
resolve(true);
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
this._listenTronEvent();
|
|
1901
|
+
this._readyState = tronwallet_abstract_adapter_1.WalletReadyState.Found;
|
|
1902
|
+
const address = (((_a = this._wallet) === null || _a === void 0 ? void 0 : _a.tronWeb) && ((_b = this._wallet.tronWeb.defaultAddress) === null || _b === void 0 ? void 0 : _b.base58)) || null;
|
|
1903
|
+
const state = address ? tronwallet_abstract_adapter_1.AdapterState.Connected : tronwallet_abstract_adapter_1.AdapterState.Disconnect;
|
|
1904
|
+
this.setAddress(address);
|
|
1905
|
+
this.setState(state);
|
|
1906
|
+
this.emit('readyStateChanged', this.readyState);
|
|
1907
|
+
cleanupDesktopDetection();
|
|
1908
|
+
resolve(true);
|
|
1909
|
+
}
|
|
1910
|
+
});
|
|
1911
|
+
window.addEventListener(tronwallet_abstract_adapter_1.TIP6963AnnounceProviderEventName, handler);
|
|
1912
|
+
window.dispatchEvent(new Event(tronwallet_abstract_adapter_1.TIP6963RequestProviderEventName));
|
|
1913
|
+
});
|
|
1914
|
+
this._checkPromise = detection;
|
|
1915
|
+
// Never cache a failed detection: the wallet may inject late or be enabled at
|
|
1916
|
+
// runtime. Unlike the polling adapters this keeps the full detection window on a
|
|
1917
|
+
// retry, because the TIP-6963 announce is asynchronous and a shortened window
|
|
1918
|
+
// would race it.
|
|
1919
|
+
void detection.then((found) => {
|
|
1920
|
+
if (!found && this._checkPromise === detection) {
|
|
1921
|
+
this._checkPromise = null;
|
|
1922
|
+
}
|
|
1923
|
+
});
|
|
1924
|
+
return detection;
|
|
1925
|
+
}
|
|
1926
|
+
// Mobile: use legacy polling detection
|
|
1222
1927
|
const interval = 100;
|
|
1223
|
-
const checkTronTimes = Math.floor(2000 / interval);
|
|
1224
1928
|
const maxTimes = Math.floor(this.config.checkTimeout / interval);
|
|
1225
1929
|
let times = 0, timer;
|
|
1226
|
-
|
|
1930
|
+
const detection = new Promise((resolve) => {
|
|
1227
1931
|
const check = () => {
|
|
1228
1932
|
times++;
|
|
1229
|
-
|
|
1933
|
+
this._updateWallet();
|
|
1934
|
+
const isSupport = !!((0, tronwallet_abstract_adapter_1.isInMobileBrowser)() && (window.tronLink || window.tronWeb));
|
|
1230
1935
|
if (isSupport || times > maxTimes) {
|
|
1231
1936
|
timer && clearInterval(timer);
|
|
1232
1937
|
this._readyState = isSupport ? tronwallet_abstract_adapter_1.WalletReadyState.Found : tronwallet_abstract_adapter_1.WalletReadyState.NotFound;
|
|
1233
|
-
this._updateWallet();
|
|
1234
1938
|
this.emit('readyStateChanged', this.readyState);
|
|
1235
1939
|
resolve(isSupport);
|
|
1236
1940
|
}
|
|
@@ -1238,7 +1942,17 @@
|
|
|
1238
1942
|
timer = setInterval(check, interval);
|
|
1239
1943
|
check();
|
|
1240
1944
|
});
|
|
1241
|
-
|
|
1945
|
+
this._checkPromise = detection;
|
|
1946
|
+
// Never cache a failed detection: the wallet may inject late or be enabled at
|
|
1947
|
+
// runtime. Unlike the polling adapters this keeps the full detection window on a
|
|
1948
|
+
// retry, because the TIP-6963 announce is asynchronous and a shortened window
|
|
1949
|
+
// would race it.
|
|
1950
|
+
void detection.then((found) => {
|
|
1951
|
+
if (!found && this._checkPromise === detection) {
|
|
1952
|
+
this._checkPromise = null;
|
|
1953
|
+
}
|
|
1954
|
+
});
|
|
1955
|
+
return detection;
|
|
1242
1956
|
}
|
|
1243
1957
|
checkForWalletReadyForApp() {
|
|
1244
1958
|
if (this.checkReadyInterval) {
|
|
@@ -1389,15 +2103,24 @@
|
|
|
1389
2103
|
const utils_js_1 = requireUtils();
|
|
1390
2104
|
const tronwallet_abstract_adapter_2 = /*@__PURE__*/ requireCjs$2();
|
|
1391
2105
|
exports$1.TokenPocketAdapterName = 'TokenPocket';
|
|
1392
|
-
class TokenPocketAdapter extends tronwallet_abstract_adapter_1.
|
|
2106
|
+
class TokenPocketAdapter extends tronwallet_abstract_adapter_1.AddonAdapter {
|
|
1393
2107
|
constructor(config = {}) {
|
|
1394
|
-
super();
|
|
2108
|
+
super(config);
|
|
1395
2109
|
this.name = exports$1.TokenPocketAdapterName;
|
|
1396
2110
|
this.url = 'https://tokenpocket.pro/';
|
|
1397
2111
|
this.icon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwIiBoZWlnaHQ9IjEyMCIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGc+CjxwYXRoIGQ9Ik0xMDQxLjUyIDBILTI3VjEwMjRIMTA0MS41MlYwWiIgZmlsbD0iIzI5ODBGRSIvPgo8ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDA4XzIyNSkiPgo8cGF0aCBkPSJNNDA2Ljc5NiA0MzguNjQzSDQwNi45MjdDNDA2Ljc5NiA0MzcuODU3IDQwNi43OTYgNDM2Ljk0IDQwNi43OTYgNDM2LjE1NFY0MzguNjQzWiIgZmlsbD0iIzI5QUVGRiIvPgo8cGF0aCBkPSJNNjY3LjYwMiA0NjMuNTMzSDUyMy4yNDlWNzI0LjA3NkM1MjMuMjQ5IDczNi4zODkgNTMzLjIwNCA3NDYuMzQ1IDU0NS41MTcgNzQ2LjM0NUg2NDUuMzMzQzY1Ny42NDcgNzQ2LjM0NSA2NjcuNjAyIDczNi4zODkgNjY3LjYwMiA3MjQuMDc2VjQ2My41MzNaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNDUzLjU2MyAyNzdINDQ4LjcxNkgxOTAuMjY5QzE3Ny45NTUgMjc3IDE2OCAyODYuOTU1IDE2OCAyOTkuMjY5VjM4OS42NTNDMTY4IDQwMS45NjcgMTc3Ljk1NSA0MTEuOTIyIDE5MC4yNjkgNDExLjkyMkgyNTAuOTE4SDI3NS4wMjFWNDM4LjY0NFY3MjQuNzMxQzI3NS4wMjEgNzM3LjA0NSAyODQuOTc2IDc0NyAyOTcuMjg5IDc0N0gzOTIuMTI4QzQwNC40NDEgNzQ3IDQxNC4zOTYgNzM3LjA0NSA0MTQuMzk2IDcyNC43MzFWNDM4LjY0NFY0MzYuMTU2VjQxMS45MjJINDM4LjQ5OUg0NDguMzIzSDQ1My4xN0M0OTAuMzcyIDQxMS45MjIgNTIwLjYzMSAzODEuNjYzIDUyMC42MzEgMzQ0LjQ2MUM1MjEuMDI0IDMwNy4yNTkgNDkwLjc2NSAyNzcgNDUzLjU2MyAyNzdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNjY3LjczNSA0NjMuNTMzVjY0NS4zNUM2NzIuNzEzIDY0Ni41MjkgNjc3LjgyMSA2NDcuNDQ2IDY4My4wNjEgNjQ4LjIzMkM2OTAuMzk3IDY0OS4yOCA2OTcuOTk0IDY0OS45MzUgNzA1LjU5MiA2NTAuMDY2QzcwNS45ODUgNjUwLjA2NiA3MDYuMzc4IDY1MC4wNjYgNzA2LjkwMiA2NTAuMDY2VjUwNS40NUM2ODUuMDI2IDUwNC4wMDkgNjY3LjczNSA0ODUuODAxIDY2Ny43MzUgNDYzLjUzM1oiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl80MDhfMjI1KSIvPgo8cGF0aCBkPSJNNzA5Ljc4MSAyNzdDNjA2LjgyMiAyNzcgNTIzLjI0OSAzNjAuNTczIDUyMy4yNDkgNDYzLjUzM0M1MjMuMjQ5IDU1Mi4wODQgNTg0Ljk0NiA2MjYuMjI1IDY2Ny43MzMgNjQ1LjM1VjQ2My41MzNDNjY3LjczMyA0NDAuMzQ3IDY4Ni41OTYgNDIxLjQ4NCA3MDkuNzgxIDQyMS40ODRDNzMyLjk2NyA0MjEuNDg0IDc1MS44MyA0NDAuMzQ3IDc1MS44MyA0NjMuNTMzQzc1MS44MyA0ODMuMDUxIDczOC42IDQ5OS40MjUgNzIwLjUyMyA1MDQuMTRDNzE3LjExNyA1MDUuMDU3IDcxMy40NDkgNTA1LjU4MSA3MDkuNzgxIDUwNS41ODFWNjUwLjA2NkM3MTMuNDQ5IDY1MC4wNjYgNzE2Ljk4NiA2NDkuOTM1IDcyMC41MjMgNjQ5LjgwNEM4MTguNTA1IDY0NC4xNzEgODk2LjMxNCA1NjIuOTU2IDg5Ni4zMTQgNDYzLjUzM0M4OTYuNDQ1IDM2MC41NzMgODEyLjg3MiAyNzcgNzA5Ljc4MSAyNzdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNzA5Ljc4IDY1MC4wNjZWNTA1LjU4MUM3MDguNzMzIDUwNS41ODEgNzA3LjgxNiA1MDUuNTgxIDcwNi43NjggNTA1LjQ1VjY1MC4wNjZDNzA3LjgxNiA2NTAuMDY2IDcwOC44NjQgNjUwLjA2NiA3MDkuNzggNjUwLjA2NloiIGZpbGw9IndoaXRlIi8+CjwvZz4KPC9nPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzQwOF8yMjUiIHgxPSI3MDkuODQ0IiB5MT0iNTU2LjgyNyIgeDI9IjY2Ny43NTMiIHkyPSI1NTYuODI3IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IndoaXRlIi8+CjxzdG9wIG9mZnNldD0iMC45NjY3IiBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwLjMyMzMiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwLjMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGNsaXBQYXRoIGlkPSJjbGlwMF80MDhfMjI1Ij4KPHJlY3Qgd2lkdGg9IjcyOC40NDgiIGhlaWdodD0iNDcwIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTY4IDI3NykiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K';
|
|
1398
2112
|
this._readyState = (0, tronwallet_abstract_adapter_1.isInBrowser)() ? tronwallet_abstract_adapter_1.WalletReadyState.Loading : tronwallet_abstract_adapter_1.WalletReadyState.NotFound;
|
|
1399
2113
|
this._state = tronwallet_abstract_adapter_1.AdapterState.Loading;
|
|
2114
|
+
/**
|
|
2115
|
+
* Whether the most recent security check passed. Gates the auto-connect
|
|
2116
|
+
* paths (e.g. `onAccountsChanged`) so a wallet that failed the security
|
|
2117
|
+
* check cannot silently connect when the extension emits account events.
|
|
2118
|
+
*/
|
|
2119
|
+
this._securityPassed = false;
|
|
1400
2120
|
this.onAccountsChanged = (accounts) => {
|
|
2121
|
+
// Do not auto-connect via account events when the security check has not passed.
|
|
2122
|
+
if (!this._securityPassed)
|
|
2123
|
+
return;
|
|
1401
2124
|
const preAddr = this.address || '';
|
|
1402
2125
|
const curAddr = (accounts === null || accounts === void 0 ? void 0 : accounts[0]) || '';
|
|
1403
2126
|
if (!curAddr) {
|
|
@@ -1419,11 +2142,22 @@
|
|
|
1419
2142
|
};
|
|
1420
2143
|
this.checkReadyInterval = null;
|
|
1421
2144
|
this._checkPromise = null;
|
|
1422
|
-
this._updateWallet = () => {
|
|
2145
|
+
this._updateWallet = () => __awaiter(this, void 0, void 0, function* () {
|
|
1423
2146
|
var _a, _b, _c, _d, _e;
|
|
1424
|
-
let state
|
|
1425
|
-
let address
|
|
2147
|
+
let state;
|
|
2148
|
+
let address;
|
|
1426
2149
|
if ((0, utils_js_1.supportTokenPocket)()) {
|
|
2150
|
+
try {
|
|
2151
|
+
yield this.checkSecurity();
|
|
2152
|
+
this._securityPassed = true;
|
|
2153
|
+
}
|
|
2154
|
+
catch (_f) {
|
|
2155
|
+
this._securityPassed = false;
|
|
2156
|
+
this.stopListenTronEvent();
|
|
2157
|
+
this.setAddress(null);
|
|
2158
|
+
this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
1427
2161
|
const tron = (_a = window.tokenpocket) === null || _a === void 0 ? void 0 : _a.tron;
|
|
1428
2162
|
this._wallet = (0, tronwallet_abstract_adapter_1.isInMobileBrowser)()
|
|
1429
2163
|
? {
|
|
@@ -1449,22 +2183,18 @@
|
|
|
1449
2183
|
}
|
|
1450
2184
|
this.setAddress(address);
|
|
1451
2185
|
this.setState(state);
|
|
1452
|
-
};
|
|
1453
|
-
|
|
1454
|
-
if (typeof checkTimeout !== 'number') {
|
|
1455
|
-
throw new Error('[TokenPocketAdapter] config.checkTimeout should be a number');
|
|
1456
|
-
}
|
|
1457
|
-
this.config = {
|
|
1458
|
-
checkTimeout,
|
|
1459
|
-
openAppWithDeeplink,
|
|
1460
|
-
openUrlWhenWalletNotFound,
|
|
1461
|
-
};
|
|
2186
|
+
});
|
|
2187
|
+
this.config = Object.assign({}, this.commonConfig);
|
|
1462
2188
|
this._connecting = false;
|
|
1463
2189
|
this._wallet = null;
|
|
1464
2190
|
this._address = null;
|
|
1465
2191
|
if ((0, tronwallet_abstract_adapter_1.isInMobileBrowser)() && (0, utils_js_1.supportTokenPocket)()) {
|
|
1466
2192
|
this._readyState = tronwallet_abstract_adapter_1.WalletReadyState.Found;
|
|
1467
|
-
this._updateWallet()
|
|
2193
|
+
this._updateWallet().then(() => {
|
|
2194
|
+
if (this.connected) {
|
|
2195
|
+
this.emit('connect', this.address || '');
|
|
2196
|
+
}
|
|
2197
|
+
});
|
|
1468
2198
|
}
|
|
1469
2199
|
else {
|
|
1470
2200
|
this._checkWallet().then(() => {
|
|
@@ -1512,45 +2242,29 @@
|
|
|
1512
2242
|
}
|
|
1513
2243
|
});
|
|
1514
2244
|
}
|
|
1515
|
-
|
|
2245
|
+
_connect() {
|
|
1516
2246
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1517
2247
|
try {
|
|
1518
|
-
this.
|
|
1519
|
-
if (this.connected || this.connecting)
|
|
2248
|
+
if (!(yield this._beforeConnect()))
|
|
1520
2249
|
return;
|
|
1521
|
-
|
|
1522
|
-
if (this.readyState === tronwallet_abstract_adapter_1.WalletReadyState.NotFound) {
|
|
1523
|
-
if (this.config.openUrlWhenWalletNotFound !== false && (0, tronwallet_abstract_adapter_1.isInBrowser)()) {
|
|
1524
|
-
window.open(this.url, '_blank');
|
|
1525
|
-
}
|
|
1526
|
-
throw new tronwallet_abstract_adapter_1.WalletNotFoundError();
|
|
1527
|
-
}
|
|
2250
|
+
this._securityPassed = true;
|
|
1528
2251
|
if (!this._wallet)
|
|
1529
2252
|
return;
|
|
1530
2253
|
this._connecting = true;
|
|
1531
2254
|
const wallet = this._wallet;
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
throw new tronwallet_abstract_adapter_1.WalletConnectionError('Request connect error.');
|
|
1536
|
-
}
|
|
1537
|
-
const address = res[0];
|
|
1538
|
-
this.setAddress(address);
|
|
1539
|
-
this.setState(tronwallet_abstract_adapter_1.AdapterState.Connected);
|
|
1540
|
-
this.emit('connect', this.address || '');
|
|
1541
|
-
}
|
|
1542
|
-
catch (e) {
|
|
1543
|
-
if (e instanceof tronwallet_abstract_adapter_1.WalletError) {
|
|
1544
|
-
throw e;
|
|
1545
|
-
}
|
|
1546
|
-
else {
|
|
1547
|
-
throw new tronwallet_abstract_adapter_1.WalletConnectionError(e === null || e === void 0 ? void 0 : e.message, e);
|
|
1548
|
-
}
|
|
2255
|
+
const res = yield wallet.tron.request({ method: 'eth_requestAccounts' });
|
|
2256
|
+
if (!(res === null || res === void 0 ? void 0 : res[0])) {
|
|
2257
|
+
throw new tronwallet_abstract_adapter_1.WalletConnectionError('Request connect error.');
|
|
1549
2258
|
}
|
|
2259
|
+
const address = res[0];
|
|
2260
|
+
this.setAddress(address);
|
|
2261
|
+
this.setState(tronwallet_abstract_adapter_1.AdapterState.Connected);
|
|
2262
|
+
this.emit('connect', this.address || '');
|
|
1550
2263
|
}
|
|
1551
2264
|
catch (error) {
|
|
1552
|
-
|
|
1553
|
-
|
|
2265
|
+
const err = error instanceof tronwallet_abstract_adapter_1.WalletError ? error : new tronwallet_abstract_adapter_1.WalletConnectionError(error === null || error === void 0 ? void 0 : error.message, error);
|
|
2266
|
+
this.emit('error', err);
|
|
2267
|
+
throw err;
|
|
1554
2268
|
}
|
|
1555
2269
|
finally {
|
|
1556
2270
|
this._connecting = false;
|
|
@@ -1562,6 +2276,7 @@
|
|
|
1562
2276
|
if (this.state !== tronwallet_abstract_adapter_1.AdapterState.Connected) {
|
|
1563
2277
|
return;
|
|
1564
2278
|
}
|
|
2279
|
+
this._securityPassed = false;
|
|
1565
2280
|
this.setAddress(null);
|
|
1566
2281
|
this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
|
|
1567
2282
|
this.emit('disconnect');
|
|
@@ -1681,6 +2396,12 @@
|
|
|
1681
2396
|
throw new tronwallet_abstract_adapter_1.WalletNotFoundError();
|
|
1682
2397
|
}
|
|
1683
2398
|
}
|
|
2399
|
+
_openAppByDeepLinkIfNeed() {
|
|
2400
|
+
if (this.config.openAppWithDeeplink === false) {
|
|
2401
|
+
return false;
|
|
2402
|
+
}
|
|
2403
|
+
return (0, utils_js_1.openTokenPocket)();
|
|
2404
|
+
}
|
|
1684
2405
|
checkForWalletReady() {
|
|
1685
2406
|
if (this.checkReadyInterval) {
|
|
1686
2407
|
return;
|
|
@@ -1727,7 +2448,7 @@
|
|
|
1727
2448
|
return this._checkPromise;
|
|
1728
2449
|
}
|
|
1729
2450
|
if ((0, tronwallet_abstract_adapter_1.isInBrowser)() && !(0, tronwallet_abstract_adapter_1.isInMobileBrowser)()) {
|
|
1730
|
-
|
|
2451
|
+
const detection = new Promise((resolve) => {
|
|
1731
2452
|
const timer = setTimeout(() => {
|
|
1732
2453
|
window.removeEventListener(tronwallet_abstract_adapter_2.TIP6963AnnounceProviderEventName, handler);
|
|
1733
2454
|
this._updateWallet();
|
|
@@ -1741,7 +2462,7 @@
|
|
|
1741
2462
|
}
|
|
1742
2463
|
this.emit('readyStateChanged', this._readyState);
|
|
1743
2464
|
}, this.config.checkTimeout);
|
|
1744
|
-
const handler = (event) => {
|
|
2465
|
+
const handler = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
1745
2466
|
var _a, _b, _c;
|
|
1746
2467
|
const { info, provider } = event.detail;
|
|
1747
2468
|
if (info.name === 'TokenPocket') {
|
|
@@ -1754,6 +2475,19 @@
|
|
|
1754
2475
|
this._readyState = tronwallet_abstract_adapter_1.WalletReadyState.Found;
|
|
1755
2476
|
const address = ((_c = this._wallet.tronWeb.defaultAddress) === null || _c === void 0 ? void 0 : _c.base58) || null;
|
|
1756
2477
|
const state = address ? tronwallet_abstract_adapter_1.AdapterState.Connected : tronwallet_abstract_adapter_1.AdapterState.Disconnect;
|
|
2478
|
+
try {
|
|
2479
|
+
yield this.checkSecurity();
|
|
2480
|
+
this._securityPassed = true;
|
|
2481
|
+
}
|
|
2482
|
+
catch (_d) {
|
|
2483
|
+
this._securityPassed = false;
|
|
2484
|
+
this.stopListenTronEvent();
|
|
2485
|
+
this.setAddress(null);
|
|
2486
|
+
this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
|
|
2487
|
+
clearTimeout(timer);
|
|
2488
|
+
resolve(true);
|
|
2489
|
+
return;
|
|
2490
|
+
}
|
|
1757
2491
|
this.setState(state);
|
|
1758
2492
|
this.setAddress(address);
|
|
1759
2493
|
this.emit('readyStateChanged', this.readyState);
|
|
@@ -1764,17 +2498,27 @@
|
|
|
1764
2498
|
this.checkForWalletReady();
|
|
1765
2499
|
}
|
|
1766
2500
|
}
|
|
1767
|
-
};
|
|
2501
|
+
});
|
|
1768
2502
|
window.addEventListener(tronwallet_abstract_adapter_2.TIP6963AnnounceProviderEventName, handler);
|
|
1769
2503
|
window.dispatchEvent(new Event(tronwallet_abstract_adapter_2.TIP6963RequestProviderEventName));
|
|
1770
2504
|
});
|
|
1771
|
-
|
|
2505
|
+
this._checkPromise = detection;
|
|
2506
|
+
// Never cache a failed detection: the wallet may inject late or be enabled at
|
|
2507
|
+
// runtime. Unlike the polling adapters this keeps the full detection window on a
|
|
2508
|
+
// retry, because the TIP-6963 announce is asynchronous and a shortened window
|
|
2509
|
+
// would race it.
|
|
2510
|
+
void detection.then((found) => {
|
|
2511
|
+
if (!found && this._checkPromise === detection) {
|
|
2512
|
+
this._checkPromise = null;
|
|
2513
|
+
}
|
|
2514
|
+
});
|
|
2515
|
+
return detection;
|
|
1772
2516
|
}
|
|
1773
2517
|
// Support TIP-6963 with wallet extension
|
|
1774
2518
|
const interval = 100;
|
|
1775
2519
|
const maxTimes = Math.floor(this.config.checkTimeout / interval);
|
|
1776
2520
|
let times = 0, timer;
|
|
1777
|
-
|
|
2521
|
+
const detection = new Promise((resolve) => {
|
|
1778
2522
|
const check = () => {
|
|
1779
2523
|
times++;
|
|
1780
2524
|
const isSupport = (0, utils_js_1.supportTokenPocket)();
|
|
@@ -1789,7 +2533,17 @@
|
|
|
1789
2533
|
timer = setInterval(check, interval);
|
|
1790
2534
|
check();
|
|
1791
2535
|
});
|
|
1792
|
-
|
|
2536
|
+
this._checkPromise = detection;
|
|
2537
|
+
// Never cache a failed detection: the wallet may inject late or be enabled at
|
|
2538
|
+
// runtime. Unlike the polling adapters this keeps the full detection window on a
|
|
2539
|
+
// retry, because the TIP-6963 announce is asynchronous and a shortened window
|
|
2540
|
+
// would race it.
|
|
2541
|
+
void detection.then((found) => {
|
|
2542
|
+
if (!found && this._checkPromise === detection) {
|
|
2543
|
+
this._checkPromise = null;
|
|
2544
|
+
}
|
|
2545
|
+
});
|
|
2546
|
+
return detection;
|
|
1793
2547
|
}
|
|
1794
2548
|
setAddress(address) {
|
|
1795
2549
|
this._address = address;
|