@tronweb3/tronwallet-adapter-trust 1.0.3 → 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/lib/umd/index.js CHANGED
@@ -363,82 +363,7 @@
363
363
  return eventemitter3.exports;
364
364
  }
365
365
 
366
- var hasRequiredAdapter$2;
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
- Object.defineProperty(utils$2, "__esModule", { value: true });
615
- utils$2.isInBrowser = isInBrowser;
616
- utils$2.checkAdapterState = checkAdapterState;
617
- utils$2.isInMobileBrowser = isInMobileBrowser;
618
- /**
619
- * check simply if current environment is browser or not
620
- * @returns boolean
621
- */
622
- function isInBrowser() {
623
- return typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';
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
- function checkAdapterState(check) {
631
- if (!isInBrowser())
632
- return;
633
- const disposers = [];
634
- function dispose() {
635
- for (const dispose of disposers) {
636
- dispose();
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
- function checkAndDispose() {
640
- if (check()) {
641
- dispose();
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
- const interval = setInterval(checkAndDispose, 500);
645
- disposers.push(() => clearInterval(interval));
646
- if (document.readyState === 'loading') {
647
- document.addEventListener('DOMContentLoaded', checkAndDispose, { once: true });
648
- disposers.push(() => document.removeEventListener('DOMContentLoaded', checkAndDispose));
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
- if (document.readyState !== 'complete') {
651
- window.addEventListener('load', checkAndDispose, { once: true });
652
- disposers.push(() => window.removeEventListener('load', checkAndDispose));
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 utils$2;
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.Adapter {
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,iVBORw0KGgoAAAANSUhEUgAAAF0AAABdCAYAAADHcWrDAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAUGVYSWZNTQAqAAAACAACARIAAwAAAAEAAQAAh2kABAAAAAEAAAAmAAAAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAABdoAMABAAAAAEAAABdAAAAAMkTBfIAAAFZaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Chle4QcAABZhSURBVHgB7V0JlBTVuf6runtWllkA2QeYQQRBZHNFxZjw4jFqMEFxCWIS1yOaTeJ76nk5Lyc5CUZNfCoa0BgUxRh3QD2CJs8lELaIgOCw78sszN4z0131vu/W1NDTfbtneqa7Zx5v/nN6prrq1q2q77//ev9bbUgcNHjm/sya7PIiIxA43TCNUbYEcw3bsOLo4v98U9sWAxSwbbvYI7LDCDZ+dezl847G82BGWxrnzVl/nmF5bhCxviG2FBoen0+Ep9ptOf0UbOPAZlsNhOCYmOYawzaXirfynZLnpla19sAxQc+5ac14jyf9IbHsqw1vute2GoF78P8x2Bo4DVMME2OQqAQDW8W2flv64oQXMCijjsiooOfP3jAXvf0SHfa2A/XsUnXc/ScGAgAfqgfgB18zGqvvKVk69ZCudSTot63z5fvNRw0z7W7bCpB9uvO698VAwPBmAraGzXbQuq5sycSt4U3NljtsA4D/wfBk3I2TugFvCU6bv9mBOigJ71jTY7zd++Z1heEntgA976b1P8YIv9MO+NGuW52EgxXPdzsIlexJK/Ra5uK+d23pEXpuM+h9blo30TS9/6WMZTfgoRi1e5uD1/BmXGBV1j0Y2okD+i9smGDjV2L6smF9Q493b3cQATXiTc/c3BvXjXO7UqD32bn2Itv0TlcN3CPd/xODAAax4UnP8pjmvW6HCnTbNm+B4sd2tx53gUnkfw5mW6wZUOED2K+ZM2djDoLLy+wgAp9uSg4CarRn5Ikpl/ICpinWGfBvBnXr8uTg3dwrIlfkbS5yQLdkPNxEBEndqqUZoGRsqCDTHK1At2yZZnd7LMmAuUWfDsZ236LLV6SbGPXZ3aO8BT7J/OLx98iBSre79UoyUW7RN3Jh/O4ERy2OdH9JNgLdoCcbYU3/3aBrQEn2rm7Qk42wpn+vZl/cuzgTUtvgJMo8piEesNLE/8gZkri7PiVP6DDojUFb5s0YIIPz02TDzhr58oBf9hyrl9KqgGIEZq/ABEOY2UEFQTcjMIw6DHoAoO891iAPfHeg3HxpH4a6cryyUXYfrZdNe+tk055aMKJO9h5vUIyog0ScZASYQGackuM5+kN1GPR0nykrN1XIobIGGZiXpgDt19sn/Jx7ujNhgqhXjlU4jPhiby0YUdfEiHopg0TUNbKYxJUIgwmhU5o6DDo0hhw90Sjvb6yQWy7rqwWLbfrn+NTn/FEnGcHzdh7xyxeQCDKDqmlficOI+iZGeHGyxwNGnELi0GHQiTIBeWNNucz5Wl81YrXIh+3kOQNyfeozdXRPdTQIkThWEZAdh/1QTY5EbD9YB0Y0SFl1QBpOEUYkBPQ0WMm1xTVCgM4YnBkGb9u/0uC6jLhojMMI2gxKxI4j9UoaaCO2HfTLfjCinIwIOKrJC2ng+WRmV6eEgE59XFEblHfWnugQ6DqwCOYgeEb8XHLmSUYcLm+U4kNQTfsc1bTdZURNQBq7OCMSAjrB8gGcd9adkHuv7C9p3uQONzJiSJ809fnaWb0Ur+i6HgEjviIjqJrwISMOQCJO1ASFxykFtA+dLREJBX0zRt16+OqusdSN3GTtI9NdRlzWxAiqHkrEV4coDScl4kCpwwiqrs5gRMJAp7Ptr7fkzdXlnQK6jpmUuIK+aerzjfG9VRN6RXRvt0MiNkMayAxKBxlBFekywrURVJ2JpsSBjjvjQ77/rwp5YOZA6ZWF6u02Ui2YRXvQI9OUcUOz4O/7hA+dDEr3GTL8tHT1+eYElxGWHCxrVOqIqsllxEEyoi4owSaJSBQjEgo6b2oXItGPv6ySKybltBmzrHRTRgCIW5/ardTBqEEZws+4giwZOzRTRg7IkP5wL6lCkkEM8Hh9fi6f6DDCj8iZo9+RCETWYAYN90FISWWtJXRvGcSpOAI6Kh6JMPJnr38LtV9XCSt0E0AM82dNzZdn7x4ed29MFcx5fJd8AqZRaphS4P/cHl6lr88AI84a1sSIgRlyGgIuPnSqiM9GV5UGevM+RyJcRlTVtcIIE+PbDmzLrKufmHDQLSQb83p65ONfj1E+d7yAlFQG1IhnhEsJIDGNQBEPYMNlRB4YMRT6mnHBuIJMSESWnE5G9PaqDGe8121ve6pGMmIbYhSqJTKj+FC9shvVfqgm4KEkwusTjxHcluVPAui8eY6IBbcPk9lIgLWHqv2WzF24R175pEwyAbxuLIczgrqajCjomw5GQCKgms6EaiqCako1I2pw/4yiGSwqGwGvrvhIQI6W1W3zVPsTP9IJcn2jJV+Ht/D6/SO1gG3YVQs9nS49M6MbW7p7//7Cfnnm/WNCndsWnUkpozRQ31IiyIj8ng4jRkMixg/LBCOypLB/uvRFQi6FmkmofpB53bNkU81ZCTWk7qhmWmDNV9XK8FDkw6myNiB3PH1YnoI09I7i5VCX/27OUKXP579xWHkzrYFEMU5TjU7KBrOYzOesxv2QERlppmLEMKim0UOomhwb4TLi5Jnhd92x7z3hmcE58BTu8FO7J544KhkF0g386dX9Iy5wwRk9Zd6f98u1D++QxfeOUAYxohF2sJ8H4X7m9fDIgy8dVCOY0WQ8xBks4Mze1GnAXUqR72c+57Pt1WofJalPL68M65cuY5ptRCa8mQxIROIgYgxA8mSNv/16zCSMSnQtI7unSN14cb4Ku9XVmv4QuEr4vwveOyb/RKLskrG91IgObRO6PWVkDxXgrNxUqRJcBLK9xDO5GIv3QBdUuaHYWQOjR4O4DhH1uxsqlD1Z+kmpLENqYyPUISNbgkYpdg18vPeAnFDlF/vqFySOjWF34IN6oCXfsLtGzgVo4fStybny6NtHZO2OGvnub4vlT/eMgM7NCm/W/H3WRfmSA0N5x4LdSPMGlSvZfLCDG2QEmcC53VCJ4MQLwf5kK5aGolEmRKavKxFQTXRfx8FYD4N/TyPeVkraSOeD0J3KyfLCqDpJqdCbooH7eGu1mk8liO/CRTx7eJbyPkLbhW7TE+Fs1EdfVCKtG0xa1Mpr8v5NVyIwgCgRjvQG1dQjJXTF+hNKIuhlrYB0fL67Vo6CUXQTacTJpFAKBqVy0z7/gqSBzotRJxPQG6BiqDdDicfq4aFQfGncqG64TcOrM77uuUxqXQp1xKiXWcVkpQvc64X+1zICnKjCve/GPDGdBz4D1dJfwAgOJOb/jyH2AAvBNKuy5EjjgoQHR6E3yW26fq/8rKg5vA49fhj5jqn/sVUxhqLt6sxHbhki35sW28ffe7xebvnv3bIGxpC+fFciekkW/gSwBFelC8Ct7Kx0yc+2vyrq0zgh6XfLi76xpkyLyQAktqZh1DYEII8gjtpGyOY9i/bJH5bFfscBgyAyczqSVlRjXYkoxbQRVDE0upRkDqhD5Y3Wxi0NWFWXZKK//dEXVcpF011qxnm5CI8puA7xZvn1wSUH5BdLD6oR4x4L/0+jRpfzuql5qsaGOrerEp/JVYVJB50gMn+98vMKLR4XYy50BCJERpIu4RTlnTz85mH50bP7xI8INxoxqn3mzuFyx7/1k3qkHyjaXZ2SDjoBIJdfX3NCCwjz7tPP7q1m+kPB4jm0/os+OC63Prkb6dTo7yigND2C6PX+7wxU03Ih/AvtstO3OXd74ABNagqIAcVqGDzWuOhoxrm5Su/pBil14mv/KJcbH9sZVUWxT6WSEL3+5nuD8c3Jv+iu1Vn7mI+aMDw77aNFRU44kOwbobpguQTdKR1NKspWkxVumBzehsB/iGiUaQNOksSiuy4/TZ68bZhyUaP1F+v8ZByjoZ8Fu/PKzwp9PTP6pgZ0PgiNyNvIxeiAoHr41uQcVToR7aHpFq7fheh1frHyfaO14/7rEb0+P3eE9M72KJc1VttkHqN9YZr7tun95KnbhkpOthfPUJ4a9cIHY1qAgcK/ELXp6MopOSrjGMsQZiDA4kzNTIx4zi7Fom9i2m3pT4tkENxSTkanmmhX6AqzovnR7w9FROvEIbyPlOh0XggaRvnTb6L8TkejBmXKlJHZrY5MRraMRG94dGdUdeX2z1KQV+eNFE7zcc4zVeTk82351U1D5D+vGxSRt08Z6HxgqpH3EBozoxdO1Ps0qIzkWiNKDb2ZHzyxW174W0nM5pzY/uvPi+QcJN0o6skmqk/maR7/YYHcc8Vp2sulFHTqdaqHT7c5eezwO6LryMlmzgC1RuyLKYZ7Fu2Vx9sSvd5XKNMxm5XM6JUuIeOGZ+8eETONkVLQCSSDIFb46oj1igyW3LSArk3oProBzI2fjF5Dj7bc7tvLJ4t/1BS9wptoXZ5ant/aNw6AfjleWfLjQqF9ikUpB50qhu4fc9U6mnFenvK5dcd0+6iWqG6c6HWvmp/VteM+Fb3ekfjolREzC5heva9ILm4qctXdgw+5GFLKQWdagEU8qwC8jliZywcITQvo2oXuC41ef9ha9IoHf+SWofLzaxITvdJOcPLltXlFmA/Aiv8Y9MHnlf4nH14bSDnovCeC9AZqHnWUA99alxbQtQ3fF0/0+tC1jF6HqC7obbSHaB+oDukhcYIlFj31fqnM/v3O4KaqCqtTQGda4B9IC+yKkhb4NtMCcA3bA4WKXjGz1LbotZ88cWuBpON+dEFbLBAJOHX3Sz8plIEo+YtGfIZf//UQykkOqGnowYMHp1698Oaoh7nkcfl6feZxCtICY4ZkxA2E++BMlLFkm3OvDMhiEWe1nsf8bFujV4JYB8A5yfInRL0s+YtGarnn8/sV6PS2zKYyn04Z6bxJJy1QrgWWAdAVraQFoj2ou58TB8WH69scvb78E0avaTENMUMIJq7mwv9+8raCmFUBrPK68+k98uR7RyUd90KV6lKngU6PgykB1v/p6Kopuarcug2xku50tY8zN270ujxKss09+YIzGL0WoSAoUxtEudVjD84cJL+ZPaR5QsI9P/Q/C5xYCPvS/5RKFgEPPYjtTgOdN8LREC0twDK4yYWtpwXCnifiqxu9fv+JXfLi31uPXumFsGQkNHqloeVInQ+w779GvXAu4jruDnpmsx7ZKcs3nIgqCZ0GOm+SPvsK3JwuSmSJHA1qsCNDvQkJN3qdu7AN0SuqvJCCFa7c4H1RL9OoL7hjmNyO2alYxBLqmfN3IOKuUiOcbWkDLDCNwVPz+xOSVeEV6+bcY6zUYmn0+SizY0F+OLHIk6UM/qb1o+HH4/nOGham3eArKwAuHtOrhZ4N7Ss7w6Nsyh6UVVA9PYew/upzckObRGzTcDMJxwXIzL0Q5AA+XFiWhxqfsQXZMu3MHhWXFHj+GN30RnSbnB0cSfTZv960OCv0KqxxoR/8+uoyNbMUeqw92/SaKF2MXjmpMv/moWrGXtcXo9enMbqpLmLV4fDc5Sg6cqcUaYwL+qE4VdVEOuXaHFDMKUFo0579sNzT6aC7aQGOeBZxhtOM83OjlnCEt23Ldw54ejYLMffKQih6IdHWR9Hnbw1wLiT+++YqFLoOUhVqnGQ/DRIa6q2491UDdUWKfEq3RYr+My2wv7RePmRAc2FexFWnIS1QAD17EMWdFNVEEHtxotcyrKgLyMK7hketHG7tekWos59/sxPZttbWPd6phtS9CVqbaGkBBh80aizBSzQR+FXQ8df+bgfK4mLPvUa7dnvWPHUJ0NPgHdDiR3twTm6kwedOPOwo8+DcKyqHv8PoFSvoUkFdAnQaOOr0d2GQdHQOpvFYrB9vfkTXl26fil6xOIvuXmtzr7rz27rPrbnsEqDzppFzkrf+iWoBTcaPoHBdKmdmkkWMXlmLfj3cvk9bmfSO5x6YNuDrtT74vFp+/86RhpWfHg52uiF1H8AH1DeixGIz0gKsUw+nq87JkceXH1WjXecZhLdvz3d6UiVNr8K6sOkdNPH0Q4BRJKqmJJne4Mo6Lv51Vl6jODbQ2JhvNXYd0AkklzK+vbZcC/oYrHyYWJiFUVitfO14wIinLdO8g/tEBmrhfbC6gKunnYW8dbJlP94xAPeR+yo0b93web0ImiDOSDV5YZ26zCvkONKWr6uQ+64eEFFzTtfy24gK6ROzXTKIGQdmBHXxAq/H1Rer8L4yBTBG8CHU17MqgbaGdsl9rQnzPfxEI6TA7MSsT492hTj2M0fCBa+ri/XVApdPzFEvZNOo/TiuEr0pLUY2vBkuzdERl1Y+gBJuvumDo5q5GQ4Aup60Owz/CX4Msr3Z9bZpW57PDDe7HqN1qg65aQHd9bgs/UKkYNtaLaDrI9Y+JqZyUfrGFEA48VhpVaP0RF6GAKtJidgAt+jC4LsQxa7Y8/y0euSBrA34obsWDTrzC0cOly4yJ60jLiKI41l1XUTdRwlicoqjPZyqMaqZNmhlJIefdvI7QbfNYiTdbNMTSNuCtzOUqrdSnmzSaVvU3fvwNowPN+urBS4d1wtvxEhXa3kSfZMczXyPgM474gt4KvB+ML5Ftb1kiPUZzzWPvTzuKK7yqfvzju3tMLHnOZlHXZ/Ut1wimYyiUI50ZgN1pF5ji9HeLsjBRfzsTq0R9Kxi30qO8GuCLzjpdt3lUr+P1QKMDLmCTkcqLRDDO9Cd09Z9fEWhjo6jOIr5H50U6NqH7jM8aYDXXnX8pQlQL02g9/L1WQZObFQHQ1t30jYl+DheosDl4jriAl6++YhGN5FEQJkP1xEnM9qXhsAotwKWYdiPuf2qkb7n+eF+6PmH8LvJSPi2S4Dc/hL2n7r9LdQ86gqB6KJ1tFpAd6N0+aKpF/rk7Zk5xA8G4rzAKyWLJ3/kXrPZTJf8efJysRueMXyxK5XcE5P9n17MBqQFGIjoiNUCPTJQkJSgwa4CI2Q7+WJmHTEvE7dqwS/x2kH/Pgn65oX22Qw6d5p1mfPwc46r+MuxnU18QL5F4x0kwXQ0Fq+QmjAC1QIJUjHkXTaYyFdh6ehweUN8oKu3uliVhhW8uWzJ+AOhfbYA/firZ1Y3NFqzwJ0PDS+TTp2rahhKc/4xtBzCvXlOHnCymO/2SgTRXeQLf3RTdzx2HKnn0EXGMa9Jwyn2CSMYuKHkxSl/C2/bAnQerHp5cgl+6niGHax7Tsitpl8KDz8xFd8Z9fGF93x5so4un9Rb5Uno6nWU2AdfH5KVHjnSObdZjmBNBZWxLoQGSkvYwS3A8IqSF6GyNRQBOtuULTmvsnTxxB9YVuB6VG1sxW9O4zc1wb24lZrminHsopzRH482lTccc6eszEpEWoDLbmhEdbEPk1p8U5NTxqF5AAxORyUbVWI1PNbQEJhW9uI5n2laql36zE5T6/IXJi7Nu3H1CsO0r4OmmY2M5CT8oGmmw3IMjURZsWh3h/3pGbas3OKXE5hJy4lMs8s1WESwbAMOejwdUoaIVaR/nt6JKK1GoVAQDEF61lG4+Ks2GPRgQbId3InZl7cxQBeWLJ70ZYzHUYdigs4WHPX4txA9L8qfs34UfM7J2B6NFVmDxLB6i92q0KkLtfcPhX0vSqq3H6geC/98RHg/VwL0MW8e/hjvVy/Xim34CVG+21h+ePawjAk4HDG1byFN4q+r/dQH74aaDGOtFvnw4wC+2BJzo8db/XnJc1Njr7EMua7DuJAdXXXTrq8fI2lpUyPvz8LSjjXLjCEXHIw8Ft8eu65sqmTkjok4K+AvNnyZH0Xsb+eO/wWrg46Do/7gYAAAAABJRU5ErkJggg==';
@@ -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, _j;
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 = this.state;
865
- let address = this.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
- state = address ? tronwallet_abstract_adapter_1.AdapterState.Connected : tronwallet_abstract_adapter_1.AdapterState.Disconnect;
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 (window.tron && window.tron.isTronLink) {
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 = 30 * 1000, dappIcon = '', dappName = '', openUrlWhenWalletNotFound = true, openTronLinkAppOnMobile = true, openAppWithDeeplink = true, } = config;
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, utils_js_1.supportTron)() || ((0, tronwallet_abstract_adapter_1.isInMobileBrowser)() && (window.tronLink || window.tronWeb))) {
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
- connect() {
1616
+ _connect() {
993
1617
  return __awaiter(this, void 0, void 0, function* () {
994
1618
  var _a, _b;
995
1619
  try {
996
- this.checkIfOpenTronLink();
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
- try {
1037
- const res = yield wallet.request({ method: 'tron_requestAccounts' });
1038
- if (!res) {
1039
- // 1. wallet is locked
1040
- // 2. tronlink is first installed and there is no wallet account
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
- catch (error) {
1051
- throw new tronwallet_abstract_adapter_1.WalletConnectionError(error === null || error === void 0 ? void 0 : error.message, error);
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
- this.emit('error', error);
1070
- throw error;
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.checkIfOpenTronLink();
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
- checkIfOpenTronLink() {
1189
- const { dappName = '', dappIcon = '' } = this.config;
1190
- if (this.config.openTronLinkAppOnMobile === false || this.config.openAppWithDeeplink === false) {
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
- this._checkPromise = new Promise((resolve) => {
1930
+ const detection = new Promise((resolve) => {
1227
1931
  const check = () => {
1228
1932
  times++;
1229
- const isSupport = times < checkTronTimes && !(0, tronwallet_abstract_adapter_1.isInMobileBrowser)() ? (0, utils_js_1.supportTron)() : (0, utils_js_1.supportTronLink)();
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
- return this._checkPromise;
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) {
@@ -1378,27 +2092,63 @@
1378
2092
  const tronwallet_adapter_tronlink_1 = /*@__PURE__*/ requireCjs$1();
1379
2093
  const utils_js_1 = requireUtils();
1380
2094
  exports$1.TrustAdapterName = 'Trust';
1381
- class TrustAdapter extends tronwallet_abstract_adapter_1.Adapter {
2095
+ class TrustAdapter extends tronwallet_abstract_adapter_1.AddonAdapter {
1382
2096
  constructor(config = {}) {
1383
- super();
2097
+ super(config);
1384
2098
  this.name = exports$1.TrustAdapterName;
1385
2099
  this.url = 'https://trustwallet.com';
1386
2100
  this.icon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTgiIGhlaWdodD0iNjUiIHZpZXdCb3g9IjAgMCA1OCA2NSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgOS4zODk0OUwyOC44OTA3IDBWNjUuMDA0MkM4LjI1NDUgNTYuMzM2OSAwIDM5LjcyNDggMCAzMC4zMzUzVjkuMzg5NDlaIiBmaWxsPSIjMDUwMEZGIi8+CjxwYXRoIGQ9Ik01Ny43ODIyIDkuMzg5NDlMMjguODkxNSAwVjY1LjAwNDJDNDkuNTI3NyA1Ni4zMzY5IDU3Ljc4MjIgMzkuNzI0OCA1Ny43ODIyIDMwLjMzNTNWOS4zODk0OVoiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8yMjAxXzY5NDIpIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMjIwMV82OTQyIiB4MT0iNTEuMzYxNSIgeTE9Ii00LjE1MjkzIiB4Mj0iMjkuNTM4NCIgeTI9IjY0LjUxNDciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agb2Zmc2V0PSIwLjAyMTEyIiBzdG9wLWNvbG9yPSIjMDAwMEZGIi8+CjxzdG9wIG9mZnNldD0iMC4wNzYyNDIzIiBzdG9wLWNvbG9yPSIjMDA5NEZGIi8+CjxzdG9wIG9mZnNldD0iMC4xNjMwODkiIHN0b3AtY29sb3I9IiM0OEZGOTEiLz4KPHN0b3Agb2Zmc2V0PSIwLjQyMDA0OSIgc3RvcC1jb2xvcj0iIzAwOTRGRiIvPgo8c3RvcCBvZmZzZXQ9IjAuNjgyODg2IiBzdG9wLWNvbG9yPSIjMDAzOEZGIi8+CjxzdG9wIG9mZnNldD0iMC45MDI0NjUiIHN0b3AtY29sb3I9IiMwNTAwRkYiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K';
1387
2101
  this._readyState = (0, tronwallet_abstract_adapter_1.isInBrowser)() ? tronwallet_abstract_adapter_1.WalletReadyState.Loading : tronwallet_abstract_adapter_1.WalletReadyState.NotFound;
1388
2102
  this._state = tronwallet_abstract_adapter_1.AdapterState.Loading;
1389
- this.messageHandler = (e) => {
1390
- var _a, _b, _c;
2103
+ this._accountsChangedTimer = null;
2104
+ /**
2105
+ * Incremented whenever the listening session ends. Deferred `accountsChanged`
2106
+ * work and the awaited `connect` handler capture the value before they yield and
2107
+ * abandon themselves if it no longer matches, so an event that started before
2108
+ * `disconnect()` cannot write state after it.
2109
+ */
2110
+ this._eventGeneration = 0;
2111
+ this.messageHandler = (e) => __awaiter(this, void 0, void 0, function* () {
2112
+ var _a, _b, _c, _d, _e;
2113
+ if (e.origin !== window.location.origin) {
2114
+ return;
2115
+ }
1391
2116
  const message = (_a = e.data) === null || _a === void 0 ? void 0 : _a.message;
1392
2117
  if (!message) {
1393
2118
  return;
1394
2119
  }
1395
2120
  if (message.action === 'accountsChanged') {
1396
- setTimeout(() => {
2121
+ if (this._accountsChangedTimer) {
2122
+ clearTimeout(this._accountsChangedTimer);
2123
+ }
2124
+ const generation = this._eventGeneration;
2125
+ this._accountsChangedTimer = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
1397
2126
  var _a;
2127
+ this._accountsChangedTimer = null;
2128
+ if (generation !== this._eventGeneration)
2129
+ return;
1398
2130
  const preAddr = this.address || '';
1399
- if ((_a = this._wallet) === null || _a === void 0 ? void 0 : _a.ready) {
1400
- const address = message.data.address;
1401
- this.setAddress(address);
2131
+ const curAddr = message.data.address || '';
2132
+ // An empty account is a disconnection, not a connection to the empty
2133
+ // address. Going Connected here leaves `connected === true` with no
2134
+ // address, and the block below then emits `disconnect` against a state
2135
+ // that still says Connected.
2136
+ if (curAddr && ((_a = this._wallet) === null || _a === void 0 ? void 0 : _a.ready)) {
2137
+ try {
2138
+ yield this.checkSecurity();
2139
+ }
2140
+ catch (_b) {
2141
+ if (generation !== this._eventGeneration)
2142
+ return;
2143
+ this.setAddress(null);
2144
+ this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
2145
+ return;
2146
+ }
2147
+ // `checkSecurity()` was awaited, so the session may have ended while it
2148
+ // was pending — re-check before writing any state.
2149
+ if (generation !== this._eventGeneration)
2150
+ return;
2151
+ this.setAddress(curAddr);
1402
2152
  this.setState(tronwallet_abstract_adapter_1.AdapterState.Connected);
1403
2153
  }
1404
2154
  else {
@@ -1415,12 +2165,38 @@
1415
2165
  else if (preAddr && !this.address) {
1416
2166
  this.emit('disconnect');
1417
2167
  }
1418
- }, 200);
2168
+ }), 200);
1419
2169
  }
1420
2170
  else if (message.action === 'connect') {
2171
+ const generation = this._eventGeneration;
2172
+ // Trust may post a `connect` message before the address is available;
2173
+ // ignore it so we don't report a connection (and emit connect) with no address.
2174
+ if (!((_c = (_b = this._wallet.tronWeb) === null || _b === void 0 ? void 0 : _b.defaultAddress) === null || _c === void 0 ? void 0 : _c.base58)) {
2175
+ return;
2176
+ }
2177
+ try {
2178
+ yield this.checkSecurity();
2179
+ }
2180
+ catch (_f) {
2181
+ // A stale rejection must not tear down a session that has since been
2182
+ // re-established, so the generation is honoured on this path too.
2183
+ if (generation !== this._eventGeneration)
2184
+ return;
2185
+ this.setAddress(null);
2186
+ this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
2187
+ return;
2188
+ }
2189
+ // `checkSecurity()` was awaited, so the session may have ended while it
2190
+ // was pending — re-check before writing any state.
2191
+ if (generation !== this._eventGeneration)
2192
+ return;
2193
+ // Re-read after the await: the account may have changed or been cleared
2194
+ // while the check was pending.
2195
+ const address = ((_e = (_d = this._wallet.tronWeb) === null || _d === void 0 ? void 0 : _d.defaultAddress) === null || _e === void 0 ? void 0 : _e.base58) || '';
2196
+ if (!address)
2197
+ return;
1421
2198
  const isCurConnected = this.connected;
1422
2199
  const preAddress = this.address || '';
1423
- const address = ((_c = (_b = this._wallet.tronWeb) === null || _b === void 0 ? void 0 : _b.defaultAddress) === null || _c === void 0 ? void 0 : _c.base58) || '';
1424
2200
  this.setAddress(address);
1425
2201
  this.setState(tronwallet_abstract_adapter_1.AdapterState.Connected);
1426
2202
  if (!isCurConnected) {
@@ -1435,17 +2211,36 @@
1435
2211
  this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
1436
2212
  this.emit('disconnect');
1437
2213
  }
1438
- };
2214
+ });
1439
2215
  this._checkPromise = null;
1440
- this._updateWallet = () => {
2216
+ /**
2217
+ * Detection polls for the full `checkTimeout` only once. Later attempts re-check a
2218
+ * single time, so retrying is free when the wallet is genuinely absent.
2219
+ */
2220
+ this._hasRunInitialDetection = false;
2221
+ this._updateWallet = () => __awaiter(this, void 0, void 0, function* () {
1441
2222
  var _a, _b;
1442
- let state = this.state;
1443
- let address = this.address;
2223
+ let state;
2224
+ let address;
1444
2225
  if ((0, utils_js_1.supportTrust)()) {
1445
2226
  this._wallet = window.trustwallet.tronLink;
1446
2227
  this._listenEvent();
1447
2228
  address = ((_b = (_a = this._wallet.tronWeb) === null || _a === void 0 ? void 0 : _a.defaultAddress) === null || _b === void 0 ? void 0 : _b.base58) || null;
1448
- state = this._wallet.ready ? tronwallet_abstract_adapter_1.AdapterState.Connected : tronwallet_abstract_adapter_1.AdapterState.Disconnect;
2229
+ if (address) {
2230
+ // Only run the security check once the wallet is actually connected.
2231
+ try {
2232
+ yield this.checkSecurity();
2233
+ }
2234
+ catch (_c) {
2235
+ this.setAddress(null);
2236
+ this.setState(tronwallet_abstract_adapter_1.AdapterState.Disconnect);
2237
+ return;
2238
+ }
2239
+ state = tronwallet_abstract_adapter_1.AdapterState.Connected;
2240
+ }
2241
+ else {
2242
+ state = tronwallet_abstract_adapter_1.AdapterState.Disconnect;
2243
+ }
1449
2244
  }
1450
2245
  else {
1451
2246
  this._wallet = null;
@@ -1454,16 +2249,8 @@
1454
2249
  }
1455
2250
  this.setAddress(address);
1456
2251
  this.setState(state);
1457
- };
1458
- const { checkTimeout = 2 * 1000, openUrlWhenWalletNotFound = true, openAppWithDeeplink = true } = config;
1459
- if (typeof checkTimeout !== 'number') {
1460
- throw new Error('[TrustAdapter] config.checkTimeout should be a number');
1461
- }
1462
- this.config = {
1463
- checkTimeout,
1464
- openAppWithDeeplink,
1465
- openUrlWhenWalletNotFound,
1466
- };
2252
+ });
2253
+ this.config = Object.assign({}, this.commonConfig);
1467
2254
  this._connecting = false;
1468
2255
  this._wallet = null;
1469
2256
  this._address = null;
@@ -1474,7 +2261,11 @@
1474
2261
  }
1475
2262
  if ((0, utils_js_1.supportTrust)()) {
1476
2263
  this._readyState = tronwallet_abstract_adapter_1.WalletReadyState.Found;
1477
- this._updateWallet();
2264
+ this._updateWallet().then(() => {
2265
+ if (this.connected) {
2266
+ this.emit('connect', this.address || '');
2267
+ }
2268
+ });
1478
2269
  }
1479
2270
  else {
1480
2271
  this._checkWallet().then(() => {
@@ -1522,48 +2313,36 @@
1522
2313
  }
1523
2314
  });
1524
2315
  }
1525
- connect() {
2316
+ _connect() {
1526
2317
  return __awaiter(this, void 0, void 0, function* () {
1527
2318
  var _a;
1528
2319
  try {
1529
- this.checkIfopenTrustWallet();
1530
- if (this.connected || this.connecting)
2320
+ if (!(yield this._beforeConnect()))
1531
2321
  return;
1532
- yield this._checkWallet();
1533
- if (this.state === tronwallet_abstract_adapter_1.AdapterState.NotFound) {
1534
- if (this.config.openUrlWhenWalletNotFound !== false && (0, tronwallet_abstract_adapter_1.isInBrowser)()) {
1535
- window.open(this.url, '_blank');
1536
- }
1537
- throw new tronwallet_abstract_adapter_1.WalletNotFoundError();
1538
- }
1539
2322
  if (!this._wallet)
1540
2323
  return;
1541
2324
  this._connecting = true;
1542
2325
  const wallet = this._wallet;
1543
- try {
1544
- const res = yield wallet.request({ method: 'tron_requestAccounts' });
1545
- if (!res) {
1546
- throw new tronwallet_abstract_adapter_1.WalletConnectionError('Request connect error.');
1547
- }
1548
- if (res.code === 4000) {
1549
- throw new tronwallet_abstract_adapter_1.WalletConnectionError('The same DApp has already initiated a request to connect to trustwallet, and the pop-up window has not been closed.');
1550
- }
1551
- if (res.code === 4001) {
1552
- throw new tronwallet_abstract_adapter_1.WalletConnectionError('The user rejected connection.');
1553
- }
2326
+ const res = yield wallet.request({ method: 'tron_requestAccounts' });
2327
+ if (!res) {
2328
+ throw new tronwallet_abstract_adapter_1.WalletConnectionError('Request connect error.');
1554
2329
  }
1555
- catch (error) {
1556
- throw new tronwallet_abstract_adapter_1.WalletConnectionError(error === null || error === void 0 ? void 0 : error.message, error);
2330
+ if (res.code === 4000) {
2331
+ throw new tronwallet_abstract_adapter_1.WalletConnectionError('The same DApp has already initiated a request to connect to trustwallet, and the pop-up window has not been closed.');
2332
+ }
2333
+ if (res.code === 4001) {
2334
+ throw new tronwallet_abstract_adapter_1.WalletConnectionError('The user rejected connection.');
1557
2335
  }
1558
- const address = ((_a = wallet.tronWeb.defaultAddress) === null || _a === void 0 ? void 0 : _a.base58) || '';
2336
+ const address = (0, tronwallet_abstract_adapter_1.assertConnectAddress)((_a = wallet.tronWeb.defaultAddress) === null || _a === void 0 ? void 0 : _a.base58);
1559
2337
  this.setAddress(address);
1560
2338
  this.setState(tronwallet_abstract_adapter_1.AdapterState.Connected);
1561
2339
  this._listenEvent();
1562
2340
  this.connected && this.emit('connect', this.address || '');
1563
2341
  }
1564
2342
  catch (error) {
1565
- this.emit('error', error);
1566
- throw error;
2343
+ 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);
2344
+ this.emit('error', err);
2345
+ throw err;
1567
2346
  }
1568
2347
  finally {
1569
2348
  this._connecting = false;
@@ -1673,6 +2452,11 @@
1673
2452
  window.addEventListener('message', this.messageHandler);
1674
2453
  }
1675
2454
  _stopListenEvent() {
2455
+ this._eventGeneration++;
2456
+ if (this._accountsChangedTimer) {
2457
+ clearTimeout(this._accountsChangedTimer);
2458
+ this._accountsChangedTimer = null;
2459
+ }
1676
2460
  window.removeEventListener('message', this.messageHandler);
1677
2461
  }
1678
2462
  checkIfopenTrustWallet() {
@@ -1683,6 +2467,12 @@
1683
2467
  throw new tronwallet_abstract_adapter_1.WalletNotFoundError();
1684
2468
  }
1685
2469
  }
2470
+ _openAppByDeepLinkIfNeed() {
2471
+ if (this.config.openAppWithDeeplink === false) {
2472
+ return false;
2473
+ }
2474
+ return (0, utils_js_1.openTrustWallet)();
2475
+ }
1686
2476
  /**
1687
2477
  * check if wallet exists by interval, the promise only resolve when wallet detected or timeout
1688
2478
  * @returns if trustwallet exists
@@ -1695,9 +2485,10 @@
1695
2485
  return this._checkPromise;
1696
2486
  }
1697
2487
  const interval = 100;
1698
- const maxTimes = Math.floor(this.config.checkTimeout / interval);
2488
+ const maxTimes = this._hasRunInitialDetection ? 0 : Math.floor(this.config.checkTimeout / interval);
2489
+ this._hasRunInitialDetection = true;
1699
2490
  let times = 0, timer;
1700
- this._checkPromise = new Promise((resolve) => {
2491
+ const detection = new Promise((resolve) => {
1701
2492
  const check = () => {
1702
2493
  times++;
1703
2494
  const isSupport = (0, utils_js_1.supportTrust)();
@@ -1712,7 +2503,16 @@
1712
2503
  timer = setInterval(check, interval);
1713
2504
  check();
1714
2505
  });
1715
- return this._checkPromise;
2506
+ this._checkPromise = detection;
2507
+ // Never cache a failed detection. The extension may inject late, be switched on at
2508
+ // runtime, or a mobile WebView may still be initialising — in all of those cases the
2509
+ // next call has to look again instead of replaying the old negative answer.
2510
+ void detection.then((found) => {
2511
+ if (!found && this._checkPromise === detection) {
2512
+ this._checkPromise = null;
2513
+ }
2514
+ });
2515
+ return detection;
1716
2516
  }
1717
2517
  setAddress(address) {
1718
2518
  this._address = address;