@aurum-sdk/core 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -8,13 +8,12 @@ import {
8
8
  generateCompleteStyles,
9
9
  getDefaultThemeConfig,
10
10
  initSentry,
11
- isMobile,
12
11
  sentryLogger,
13
12
  sortWallets,
14
13
  useAurumStore,
15
14
  useNavigation,
16
15
  waitForStoreHydration
17
- } from "./chunk-BSMOPBPL.mjs";
16
+ } from "./chunk-DPFIEHZ6.mjs";
18
17
 
19
18
  // src/AurumCore.ts
20
19
  import { checksumAddress } from "viem";
@@ -101,7 +100,6 @@ function createModalContainer(id, brandConfig) {
101
100
  }
102
101
 
103
102
  // src/components/ConnectModal/renderConnectModal.tsx
104
- import { WalletId } from "@aurum-sdk/types";
105
103
  import { jsx as jsx2 } from "react/jsx-runtime";
106
104
  var CONTAINER_ID = "aurum-modal-container";
107
105
  function renderConnectModal({
@@ -109,11 +107,7 @@ function renderConnectModal({
109
107
  brandConfig
110
108
  }) {
111
109
  return new Promise((resolve, reject) => {
112
- let sortedWallets = sortWallets(displayedWallets, { filterHidden: false });
113
- const hasAppKit = sortedWallets.some((w) => w.id === WalletId.AppKit);
114
- if (isMobile() && !hasAppKit) {
115
- sortedWallets = sortedWallets.filter((w) => w.id !== WalletId.WalletConnect);
116
- }
110
+ const sortedWallets = sortWallets(displayedWallets, { filterHidden: false });
117
111
  const { root, cleanup } = createModalContainer(CONTAINER_ID, brandConfig);
118
112
  const onConnect = (result) => {
119
113
  cleanup();
@@ -129,276 +123,15 @@ function renderConnectModal({
129
123
  });
130
124
  }
131
125
 
132
- // src/wallet-adapters/AppKitAdapter.ts
133
- import { getLogoDataUri } from "@aurum-sdk/logos";
134
- import { WalletId as WalletId2, WalletName } from "@aurum-sdk/types";
135
- var AppKitAdapter = class {
136
- constructor(config) {
137
- this.id = WalletId2.AppKit;
138
- this.name = WalletName.AppKit;
139
- this.icon = getLogoDataUri(WalletId2.AppKit, "brand") ?? "";
140
- this.hide = true;
141
- this.downloadUrl = null;
142
- this.wcDeepLinkUrl = null;
143
- this.modal = null;
144
- this.wagmiAdapter = null;
145
- this.provider = null;
146
- this.address = null;
147
- this.accountsChangedCallback = null;
148
- this.unsubscribeFunctions = [];
149
- this.initPromise = null;
150
- this.config = {
151
- projectId: config.projectId,
152
- appName: config.appName,
153
- modalZIndex: config.modalZIndex,
154
- theme: config.theme
155
- };
156
- }
157
- async ensureInitialized() {
158
- if (this.modal) return;
159
- if (!this.initPromise) {
160
- this.initPromise = this.initializeAppKit();
161
- }
162
- await this.initPromise;
163
- }
164
- async initializeAppKit() {
165
- if (typeof window === "undefined") return;
166
- const [{ createAppKit }, { WagmiAdapter }, { mainnet: mainnet2 }] = await Promise.all([
167
- import("@reown/appkit"),
168
- import("@reown/appkit-adapter-wagmi"),
169
- import("@reown/appkit/networks")
170
- ]);
171
- const networks = [mainnet2];
172
- this.wagmiAdapter = new WagmiAdapter({
173
- projectId: this.config.projectId,
174
- networks,
175
- ssr: true
176
- });
177
- this.modal = createAppKit({
178
- adapters: [this.wagmiAdapter],
179
- networks,
180
- projectId: this.config.projectId,
181
- metadata: {
182
- name: this.config.appName,
183
- description: this.config.appName,
184
- url: window.location.origin,
185
- icons: []
186
- },
187
- allowUnsupportedChain: true,
188
- themeMode: this.config.theme,
189
- themeVariables: {
190
- "--apkt-z-index": this.config.modalZIndex + 1
191
- }
192
- });
193
- this.setupEventListeners();
194
- }
195
- setupEventListeners() {
196
- if (!this.modal) return;
197
- const unsubscribeProviders = this.modal.subscribeProviders((state) => {
198
- const eip155Provider = state["eip155"];
199
- this.provider = eip155Provider || null;
200
- if (!eip155Provider) {
201
- this.address = null;
202
- }
203
- });
204
- this.unsubscribeFunctions.push(unsubscribeProviders);
205
- }
206
- syncAddressFromWagmi() {
207
- if (!this.wagmiAdapter?.wagmiConfig) return;
208
- const { state } = this.wagmiAdapter.wagmiConfig;
209
- if (state.current && state.connections) {
210
- const connection = state.connections.get(state.current);
211
- if (connection?.accounts?.[0]) {
212
- this.address = connection.accounts[0];
213
- }
214
- }
215
- }
216
- async syncProviderFromModal() {
217
- if (!this.modal) return;
218
- try {
219
- const getProvidersFn = this.modal.getProviders;
220
- if (typeof getProvidersFn === "function") {
221
- const providers = getProvidersFn.call(this.modal);
222
- const eip155Provider = providers?.["eip155"];
223
- if (eip155Provider) {
224
- this.provider = eip155Provider;
225
- return;
226
- }
227
- }
228
- if (this.wagmiAdapter?.wagmiConfig) {
229
- const { state } = this.wagmiAdapter.wagmiConfig;
230
- if (state.current && state.connections) {
231
- const connection = state.connections.get(state.current);
232
- const connector = connection?.connector;
233
- if (connector && typeof connector.getProvider === "function") {
234
- try {
235
- const provider = await connector.getProvider();
236
- if (provider) {
237
- this.provider = provider;
238
- }
239
- } catch (error) {
240
- sentryLogger.warn("Failed to get provider from wagmi connector", { error });
241
- }
242
- }
243
- }
244
- }
245
- } catch (error) {
246
- sentryLogger.warn("Failed to get provider from AppKit", { error });
247
- }
248
- }
249
- isInstalled() {
250
- return true;
251
- }
252
- async connect() {
253
- if (!this.config.projectId) {
254
- throw createConfigError("AppKit");
255
- }
256
- await this.ensureInitialized();
257
- if (!this.modal) {
258
- sentryLogger.error("AppKit is not available");
259
- throw new Error("AppKit is not available");
260
- }
261
- const existingAddress = this.modal.getAddress();
262
- if (this.modal.getIsConnectedState() && existingAddress) {
263
- await this.syncProviderFromModal();
264
- if (this.provider) {
265
- this.address = existingAddress;
266
- return {
267
- address: existingAddress,
268
- provider: this.provider,
269
- walletId: this.id
270
- };
271
- }
272
- await this.disconnect();
273
- }
274
- this.modal.open({ view: "AllWallets" });
275
- return await this.waitForConnection();
276
- }
277
- waitForConnection(timeout = 6e4) {
278
- return new Promise((resolve, reject) => {
279
- const startTime = Date.now();
280
- let unsubscribeState = null;
281
- let isResolved = false;
282
- const cleanup = () => {
283
- unsubscribeState?.();
284
- };
285
- const checkConnection = async () => {
286
- if (isResolved) return true;
287
- this.syncAddressFromWagmi();
288
- if (this.address && !this.provider) {
289
- await this.syncProviderFromModal();
290
- }
291
- if (this.provider && this.address) {
292
- try {
293
- const accounts = await this.provider.request({ method: "eth_accounts" });
294
- if (accounts && accounts.length > 0) {
295
- isResolved = true;
296
- cleanup();
297
- this.modal?.close();
298
- resolve({
299
- address: this.address,
300
- provider: this.provider,
301
- walletId: this.id
302
- });
303
- return true;
304
- }
305
- return false;
306
- } catch {
307
- return false;
308
- }
309
- }
310
- return false;
311
- };
312
- unsubscribeState = this.modal.subscribeState(async (state) => {
313
- if (await checkConnection()) return;
314
- if (state.open === false && !this.address && !isResolved) {
315
- cleanup();
316
- reject(new Error("Connection rejected by user"));
317
- }
318
- });
319
- const pollTimeout = async () => {
320
- if (await checkConnection()) return;
321
- if (Date.now() - startTime > timeout) {
322
- cleanup();
323
- reject(new Error("Connection timeout"));
324
- return;
325
- }
326
- setTimeout(pollTimeout, 500);
327
- };
328
- pollTimeout();
329
- });
330
- }
331
- async tryRestoreConnection() {
332
- await this.ensureInitialized();
333
- if (!this.modal || !this.wagmiAdapter) return null;
334
- try {
335
- await new Promise((resolve) => setTimeout(resolve, 1e3));
336
- const wagmiConfig = this.wagmiAdapter.wagmiConfig;
337
- if (wagmiConfig?.state?.current && wagmiConfig.state.connections) {
338
- const connection = wagmiConfig.state.connections.get(wagmiConfig.state.current);
339
- if (connection?.accounts?.[0]) {
340
- this.address = connection.accounts[0];
341
- if (this.provider && this.address) {
342
- return {
343
- address: this.address,
344
- provider: this.provider,
345
- walletId: this.id
346
- };
347
- }
348
- }
349
- }
350
- return null;
351
- } catch {
352
- return null;
353
- }
354
- }
355
- async disconnect() {
356
- if (!this.modal) {
357
- this.address = null;
358
- this.provider = null;
359
- return;
360
- }
361
- await this.modal.disconnect("eip155");
362
- const timeout = Date.now() + 2e3;
363
- while (Date.now() < timeout && (this.modal.getIsConnectedState() || this.modal.getAddress())) {
364
- await new Promise((r) => setTimeout(r, 100));
365
- }
366
- this.address = null;
367
- this.provider = null;
368
- }
369
- getProvider() {
370
- return this.provider;
371
- }
372
- onAccountsChanged(callback) {
373
- if (!this.provider?.on) return;
374
- if (this.accountsChangedCallback) {
375
- this.provider.removeListener?.("accountsChanged", this.accountsChangedCallback);
376
- }
377
- this.accountsChangedCallback = (accounts) => {
378
- this.address = accounts[0] || null;
379
- callback(accounts);
380
- };
381
- this.provider.on("accountsChanged", this.accountsChangedCallback);
382
- }
383
- removeListeners() {
384
- if (this.provider?.removeListener && this.accountsChangedCallback) {
385
- this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
386
- this.accountsChangedCallback = null;
387
- }
388
- this.unsubscribeFunctions.forEach((unsub) => unsub());
389
- this.unsubscribeFunctions = [];
390
- }
391
- };
392
-
393
126
  // src/wallet-adapters/RabbyAdapter.ts
394
- import { getLogoDataUri as getLogoDataUri2 } from "@aurum-sdk/logos";
395
- import { WalletId as WalletId3, WalletName as WalletName2 } from "@aurum-sdk/types";
127
+ import { getLogoDataUri } from "@aurum-sdk/logos";
128
+ import { WalletId, WalletName } from "@aurum-sdk/types";
396
129
  var RABBY_RDNS = "io.rabby";
397
130
  var RabbyAdapter = class {
398
131
  constructor() {
399
- this.id = WalletId3.Rabby;
400
- this.name = WalletName2.Rabby;
401
- this.icon = getLogoDataUri2(WalletId3.Rabby, "brand") ?? "";
132
+ this.id = WalletId.Rabby;
133
+ this.name = WalletName.Rabby;
134
+ this.icon = getLogoDataUri(WalletId.Rabby, "brand") ?? "";
402
135
  this.hide = false;
403
136
  this.downloadUrl = "https://rabby.io";
404
137
  this.wcDeepLinkUrl = null;
@@ -450,7 +183,7 @@ var RabbyAdapter = class {
450
183
  return null;
451
184
  }
452
185
  isInstalled() {
453
- return Boolean(this.provider);
186
+ return Boolean(this.provider ?? this.detectLegacyProvider());
454
187
  }
455
188
  async connect() {
456
189
  if (!this.provider && this.providerPromise) {
@@ -460,27 +193,23 @@ var RabbyAdapter = class {
460
193
  sentryLogger.error("Rabby is not available");
461
194
  throw new Error("Rabby is not available");
462
195
  }
463
- try {
464
- await this.provider.request({
465
- method: "wallet_requestPermissions",
466
- params: [{ eth_accounts: {} }]
467
- });
468
- const accounts = await this.provider.request({
469
- method: "eth_requestAccounts",
470
- params: []
471
- });
472
- if (!accounts || accounts.length === 0 || !accounts[0]) {
473
- sentryLogger.error("No accounts returned from Rabby");
474
- throw new Error("No accounts returned from Rabby");
475
- }
476
- return {
477
- address: accounts[0],
478
- provider: this.provider,
479
- walletId: this.id
480
- };
481
- } catch {
482
- throw new Error("Failed to connect to Rabby");
196
+ await this.provider.request({
197
+ method: "wallet_requestPermissions",
198
+ params: [{ eth_accounts: {} }]
199
+ });
200
+ const accounts = await this.provider.request({
201
+ method: "eth_requestAccounts",
202
+ params: []
203
+ });
204
+ if (!accounts || accounts.length === 0 || !accounts[0]) {
205
+ sentryLogger.error("No accounts returned from Rabby");
206
+ throw new Error("No accounts returned from Rabby");
483
207
  }
208
+ return {
209
+ address: accounts[0],
210
+ provider: this.provider,
211
+ walletId: this.id
212
+ };
484
213
  }
485
214
  async tryRestoreConnection() {
486
215
  if (!this.provider && this.providerPromise) {
@@ -529,8 +258,8 @@ var RabbyAdapter = class {
529
258
  };
530
259
 
531
260
  // src/wallet-adapters/BraveAdapter.ts
532
- import { getLogoDataUri as getLogoDataUri3 } from "@aurum-sdk/logos";
533
- import { WalletId as WalletId4, WalletName as WalletName3 } from "@aurum-sdk/types";
261
+ import { getLogoDataUri as getLogoDataUri2 } from "@aurum-sdk/logos";
262
+ import { WalletId as WalletId2, WalletName as WalletName2 } from "@aurum-sdk/types";
534
263
 
535
264
  // src/utils/platform/isBraveBrowser.ts
536
265
  function isBraveBrowser() {
@@ -542,9 +271,9 @@ function isBraveBrowser() {
542
271
  var BRAVE_RDNS = "com.brave.wallet";
543
272
  var BraveAdapter = class {
544
273
  constructor() {
545
- this.id = WalletId4.Brave;
546
- this.name = WalletName3.Brave;
547
- this.icon = getLogoDataUri3(WalletId4.Brave, "brand") ?? "";
274
+ this.id = WalletId2.Brave;
275
+ this.name = WalletName2.Brave;
276
+ this.icon = getLogoDataUri2(WalletId2.Brave, "brand") ?? "";
548
277
  this.downloadUrl = "https://brave.com/download";
549
278
  this.wcDeepLinkUrl = null;
550
279
  this.provider = null;
@@ -600,7 +329,7 @@ var BraveAdapter = class {
600
329
  return null;
601
330
  }
602
331
  isInstalled() {
603
- return Boolean(this.provider);
332
+ return Boolean(this.provider ?? this.detectLegacyProvider());
604
333
  }
605
334
  async connect() {
606
335
  if (!this.provider && this.providerPromise) {
@@ -610,27 +339,23 @@ var BraveAdapter = class {
610
339
  sentryLogger.error("Brave Wallet is not available");
611
340
  throw new Error("Brave Wallet is not available");
612
341
  }
613
- try {
614
- await this.provider.request({
615
- method: "wallet_requestPermissions",
616
- params: [{ eth_accounts: {} }]
617
- });
618
- const accounts = await this.provider.request({
619
- method: "eth_requestAccounts",
620
- params: []
621
- });
622
- if (!accounts || accounts.length === 0 || !accounts[0]) {
623
- sentryLogger.error("No accounts returned from Brave Wallet");
624
- throw new Error("No accounts returned from Brave Wallet");
625
- }
626
- return {
627
- address: accounts[0],
628
- provider: this.provider,
629
- walletId: this.id
630
- };
631
- } catch {
632
- throw new Error("Failed to connect to Brave Wallet");
342
+ await this.provider.request({
343
+ method: "wallet_requestPermissions",
344
+ params: [{ eth_accounts: {} }]
345
+ });
346
+ const accounts = await this.provider.request({
347
+ method: "eth_requestAccounts",
348
+ params: []
349
+ });
350
+ if (!accounts || accounts.length === 0 || !accounts[0]) {
351
+ sentryLogger.error("No accounts returned from Brave Wallet");
352
+ throw new Error("No accounts returned from Brave Wallet");
633
353
  }
354
+ return {
355
+ address: accounts[0],
356
+ provider: this.provider,
357
+ walletId: this.id
358
+ };
634
359
  }
635
360
  async tryRestoreConnection() {
636
361
  if (!this.provider && this.providerPromise) {
@@ -678,132 +403,15 @@ var BraveAdapter = class {
678
403
  }
679
404
  };
680
405
 
681
- // src/wallet-adapters/LedgerAdapter.ts
682
- import { getLogoDataUri as getLogoDataUri4 } from "@aurum-sdk/logos";
683
- import { WalletId as WalletId5, WalletName as WalletName4 } from "@aurum-sdk/types";
684
- import { SupportedProviders } from "@ledgerhq/connect-kit-loader";
685
- import { mainnet } from "viem/chains";
686
- var LedgerAdapter = class {
687
- constructor(config) {
688
- this.id = WalletId5.Ledger;
689
- this.name = WalletName4.Ledger;
690
- this.icon = getLogoDataUri4(WalletId5.Ledger, "brand") ?? "";
691
- this.hide = false;
692
- this.downloadUrl = "https://www.ledger.com/ledger-live";
693
- this.wcDeepLinkUrl = "ledgerlive://wc?uri=";
694
- this.provider = null;
695
- this.accountsChangedCallback = null;
696
- this.walletConnectProjectId = config?.walletConnectProjectId;
697
- }
698
- isInstalled() {
699
- return true;
700
- }
701
- async connect() {
702
- try {
703
- if (!this.walletConnectProjectId) {
704
- throw createConfigError("Ledger");
705
- }
706
- const { loadConnectKit } = await import("@ledgerhq/connect-kit-loader");
707
- const connectKit = await loadConnectKit();
708
- connectKit.enableDebugLogs();
709
- connectKit.checkSupport({
710
- providerType: SupportedProviders.Ethereum,
711
- chainId: 1,
712
- walletConnectVersion: 2,
713
- projectId: this.walletConnectProjectId,
714
- rpc: { 1: mainnet.rpcUrls.default.http[0] }
715
- });
716
- this.provider = await connectKit.getProvider();
717
- if (!this.provider) {
718
- sentryLogger.error("Failed to get Ledger provider");
719
- throw new Error("Failed to get Ledger provider");
720
- }
721
- const accounts = await this.provider.request({
722
- method: "eth_requestAccounts",
723
- params: []
724
- });
725
- if (!accounts || accounts.length === 0 || !accounts[0]) {
726
- sentryLogger.error("No accounts returned from Ledger");
727
- throw new Error("No accounts returned from Ledger");
728
- }
729
- return {
730
- address: accounts[0],
731
- provider: this.provider,
732
- walletId: this.id
733
- };
734
- } catch {
735
- throw new Error("Failed to connect to Ledger");
736
- }
737
- }
738
- async tryRestoreConnection() {
739
- try {
740
- const { loadConnectKit } = await import("@ledgerhq/connect-kit-loader");
741
- const connectKit = await loadConnectKit();
742
- connectKit.checkSupport({
743
- providerType: SupportedProviders.Ethereum,
744
- chainId: 1,
745
- walletConnectVersion: 2,
746
- projectId: this.walletConnectProjectId,
747
- rpc: { 1: mainnet.rpcUrls.default.http[0] }
748
- });
749
- this.provider = await connectKit.getProvider();
750
- if (!this.provider) {
751
- return null;
752
- }
753
- const accounts = await this.provider.request({
754
- method: "eth_accounts",
755
- params: []
756
- });
757
- if (!accounts || accounts.length === 0 || !accounts[0]) {
758
- return null;
759
- }
760
- return {
761
- address: accounts[0],
762
- provider: this.provider,
763
- walletId: this.id
764
- };
765
- } catch {
766
- return null;
767
- }
768
- }
769
- async disconnect() {
770
- try {
771
- const provider = this.provider;
772
- if (provider?.disconnect) {
773
- await provider.disconnect();
774
- }
775
- this.provider = null;
776
- } catch (error) {
777
- sentryLogger.warn("Failed to disconnect from Ledger", { error });
778
- }
779
- }
780
- getProvider() {
781
- return this.provider;
782
- }
783
- onAccountsChanged(callback) {
784
- if (!this.provider?.on) return;
785
- if (this.accountsChangedCallback) {
786
- this.provider.removeListener?.("accountsChanged", this.accountsChangedCallback);
787
- }
788
- this.accountsChangedCallback = callback;
789
- this.provider.on("accountsChanged", this.accountsChangedCallback);
790
- }
791
- removeListeners() {
792
- if (!this.provider?.removeListener || !this.accountsChangedCallback) return;
793
- this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
794
- this.accountsChangedCallback = null;
795
- }
796
- };
797
-
798
406
  // src/wallet-adapters/PhantomAdapter.ts
799
- import { getLogoDataUri as getLogoDataUri5 } from "@aurum-sdk/logos";
800
- import { WalletId as WalletId6, WalletName as WalletName5 } from "@aurum-sdk/types";
407
+ import { getLogoDataUri as getLogoDataUri3 } from "@aurum-sdk/logos";
408
+ import { WalletId as WalletId3, WalletName as WalletName3 } from "@aurum-sdk/types";
801
409
  var PHANTOM_RDNS = "app.phantom";
802
410
  var PhantomAdapter = class {
803
411
  constructor() {
804
- this.id = WalletId6.Phantom;
805
- this.name = WalletName5.Phantom;
806
- this.icon = getLogoDataUri5(WalletId6.Phantom, "brand") ?? "";
412
+ this.id = WalletId3.Phantom;
413
+ this.name = WalletName3.Phantom;
414
+ this.icon = getLogoDataUri3(WalletId3.Phantom, "brand") ?? "";
807
415
  this.hide = false;
808
416
  this.downloadUrl = "https://phantom.com/download";
809
417
  this.wcDeepLinkUrl = "phantom://wc?uri=";
@@ -860,7 +468,7 @@ var PhantomAdapter = class {
860
468
  return null;
861
469
  }
862
470
  isInstalled() {
863
- return Boolean(this.provider);
471
+ return Boolean(this.provider ?? this.detectLegacyProvider());
864
472
  }
865
473
  async connect() {
866
474
  if (!this.provider && this.providerPromise) {
@@ -870,27 +478,23 @@ var PhantomAdapter = class {
870
478
  sentryLogger.error("Phantom is not available");
871
479
  throw new Error("Phantom is not available");
872
480
  }
873
- try {
874
- await this.provider.request({
875
- method: "wallet_requestPermissions",
876
- params: [{ eth_accounts: {} }]
877
- });
878
- const accounts = await this.provider.request({
879
- method: "eth_requestAccounts",
880
- params: []
881
- });
882
- if (!accounts || accounts.length === 0 || !accounts[0]) {
883
- sentryLogger.error("No accounts returned from Phantom");
884
- throw new Error("No accounts returned from Phantom");
885
- }
886
- return {
887
- address: accounts[0],
888
- provider: this.provider,
889
- walletId: this.id
890
- };
891
- } catch {
892
- throw new Error("Failed to connect to Phantom");
481
+ await this.provider.request({
482
+ method: "wallet_requestPermissions",
483
+ params: [{ eth_accounts: {} }]
484
+ });
485
+ const accounts = await this.provider.request({
486
+ method: "eth_requestAccounts",
487
+ params: []
488
+ });
489
+ if (!accounts || accounts.length === 0 || !accounts[0]) {
490
+ sentryLogger.error("No accounts returned from Phantom");
491
+ throw new Error("No accounts returned from Phantom");
893
492
  }
493
+ return {
494
+ address: accounts[0],
495
+ provider: this.provider,
496
+ walletId: this.id
497
+ };
894
498
  }
895
499
  async tryRestoreConnection() {
896
500
  if (!this.provider && this.providerPromise) {
@@ -940,26 +544,34 @@ var PhantomAdapter = class {
940
544
 
941
545
  // src/wallet-adapters/CoinbaseWalletAdapter.ts
942
546
  import { createCoinbaseWalletSDK } from "@coinbase/wallet-sdk";
943
- import { getLogoDataUri as getLogoDataUri6 } from "@aurum-sdk/logos";
944
- import { WalletId as WalletId7, WalletName as WalletName6 } from "@aurum-sdk/types";
547
+ import { getLogoDataUri as getLogoDataUri4 } from "@aurum-sdk/logos";
548
+ import { WalletId as WalletId4, WalletName as WalletName4 } from "@aurum-sdk/types";
945
549
  var CoinbaseWalletAdapter = class {
946
- constructor({ appName, appLogoUrl }) {
947
- this.id = WalletId7.CoinbaseWallet;
948
- this.name = WalletName6.CoinbaseWallet;
949
- this.icon = getLogoDataUri6(WalletId7.CoinbaseWallet, "brand") ?? "";
550
+ constructor({ appName, appLogoUrl, telemetry }) {
551
+ this.id = WalletId4.CoinbaseWallet;
552
+ this.name = WalletName4.CoinbaseWallet;
553
+ this.icon = getLogoDataUri4(WalletId4.CoinbaseWallet, "brand") ?? "";
950
554
  this.hide = false;
951
555
  this.downloadUrl = "https://www.coinbase.com/wallet/downloads";
952
556
  this.wcDeepLinkUrl = "cbwallet://wc?uri=";
953
557
  this.provider = null;
954
558
  this.accountsChangedCallback = null;
955
- this.provider = this.detectProvider({ appName, appLogoUrl });
559
+ this.provider = this.detectProvider({ appName, appLogoUrl, telemetry: telemetry ?? false });
956
560
  }
957
- detectProvider({ appName, appLogoUrl }) {
561
+ detectProvider({
562
+ appName,
563
+ appLogoUrl,
564
+ telemetry
565
+ }) {
958
566
  if (typeof window === "undefined") return null;
959
567
  try {
960
568
  const coinbaseSdk = createCoinbaseWalletSDK({
961
569
  appName,
962
- appLogoUrl
570
+ appLogoUrl,
571
+ preference: {
572
+ options: "all",
573
+ telemetry
574
+ }
963
575
  });
964
576
  return coinbaseSdk.getProvider();
965
577
  } catch (error) {
@@ -975,23 +587,19 @@ var CoinbaseWalletAdapter = class {
975
587
  sentryLogger.error("Coinbase Wallet is not available");
976
588
  throw new Error("Coinbase Wallet is not available");
977
589
  }
978
- try {
979
- const accounts = await this.provider.request({
980
- method: "eth_requestAccounts",
981
- params: []
982
- });
983
- if (!accounts || accounts.length === 0 || !accounts[0]) {
984
- sentryLogger.error("No accounts returned from Coinbase Wallet");
985
- throw new Error("No accounts returned from Coinbase Wallet");
986
- }
987
- return {
988
- address: accounts[0],
989
- provider: this.provider,
990
- walletId: this.id
991
- };
992
- } catch {
993
- throw new Error("Failed to connect to Coinbase Wallet");
590
+ const accounts = await this.provider.request({
591
+ method: "eth_requestAccounts",
592
+ params: []
593
+ });
594
+ if (!accounts || accounts.length === 0 || !accounts[0]) {
595
+ sentryLogger.error("No accounts returned from Coinbase Wallet");
596
+ throw new Error("No accounts returned from Coinbase Wallet");
994
597
  }
598
+ return {
599
+ address: accounts[0],
600
+ provider: this.provider,
601
+ walletId: this.id
602
+ };
995
603
  }
996
604
  async tryRestoreConnection() {
997
605
  if (!this.isInstalled() || !this.provider) {
@@ -1061,14 +669,14 @@ var CoinbaseWalletAdapter = class {
1061
669
  };
1062
670
 
1063
671
  // src/wallet-adapters/MetaMaskAdapter.ts
1064
- import { getLogoDataUri as getLogoDataUri7 } from "@aurum-sdk/logos";
1065
- import { WalletId as WalletId8, WalletName as WalletName7 } from "@aurum-sdk/types";
672
+ import { getLogoDataUri as getLogoDataUri5 } from "@aurum-sdk/logos";
673
+ import { WalletId as WalletId5, WalletName as WalletName5 } from "@aurum-sdk/types";
1066
674
  var METAMASK_RDNS = "io.metamask";
1067
675
  var MetaMaskAdapter = class {
1068
676
  constructor() {
1069
- this.id = WalletId8.MetaMask;
1070
- this.name = WalletName7.MetaMask;
1071
- this.icon = getLogoDataUri7(WalletId8.MetaMask, "brand") ?? "";
677
+ this.id = WalletId5.MetaMask;
678
+ this.name = WalletName5.MetaMask;
679
+ this.icon = getLogoDataUri5(WalletId5.MetaMask, "brand") ?? "";
1072
680
  this.hide = false;
1073
681
  this.downloadUrl = "https://metamask.io/download";
1074
682
  this.wcDeepLinkUrl = "metamask://wc?uri=";
@@ -1126,37 +734,33 @@ var MetaMaskAdapter = class {
1126
734
  return null;
1127
735
  }
1128
736
  isInstalled() {
1129
- return Boolean(this.provider);
737
+ return Boolean(this.provider ?? this.detectLegacyProvider());
1130
738
  }
1131
739
  async connect() {
1132
740
  if (!this.provider && this.providerPromise) {
1133
741
  await this.providerPromise;
1134
742
  }
1135
743
  if (!this.provider) {
1136
- sentryLogger.error("MetaMask is not available");
1137
- throw new Error("MetaMask is not available");
1138
- }
1139
- try {
1140
- await this.provider.request({
1141
- method: "wallet_requestPermissions",
1142
- params: [{ eth_accounts: {} }]
1143
- });
1144
- const accounts = await this.provider.request({
1145
- method: "eth_requestAccounts",
1146
- params: []
1147
- });
1148
- if (!accounts || accounts.length === 0 || !accounts[0]) {
1149
- sentryLogger.error("No accounts returned from MetaMask");
1150
- throw new Error("No accounts returned from MetaMask");
1151
- }
1152
- return {
1153
- address: accounts[0],
1154
- provider: this.provider,
1155
- walletId: this.id
1156
- };
1157
- } catch {
1158
- throw new Error("Failed to connect to MetaMask");
744
+ sentryLogger.error("MetaMask is not available");
745
+ throw new Error("MetaMask is not available");
746
+ }
747
+ await this.provider.request({
748
+ method: "wallet_requestPermissions",
749
+ params: [{ eth_accounts: {} }]
750
+ });
751
+ const accounts = await this.provider.request({
752
+ method: "eth_requestAccounts",
753
+ params: []
754
+ });
755
+ if (!accounts || accounts.length === 0 || !accounts[0]) {
756
+ sentryLogger.error("No accounts returned from MetaMask");
757
+ throw new Error("No accounts returned from MetaMask");
1159
758
  }
759
+ return {
760
+ address: accounts[0],
761
+ provider: this.provider,
762
+ walletId: this.id
763
+ };
1160
764
  }
1161
765
  async tryRestoreConnection() {
1162
766
  if (!this.provider && this.providerPromise) {
@@ -1205,132 +809,335 @@ var MetaMaskAdapter = class {
1205
809
  };
1206
810
 
1207
811
  // src/wallet-adapters/WalletConnectAdapter.ts
1208
- import { getLogoDataUri as getLogoDataUri8 } from "@aurum-sdk/logos";
1209
- import { WalletId as WalletId9, WalletName as WalletName8 } from "@aurum-sdk/types";
812
+ import { getLogoDataUri as getLogoDataUri6 } from "@aurum-sdk/logos";
813
+ import { WalletId as WalletId6, WalletName as WalletName6 } from "@aurum-sdk/types";
814
+
815
+ // src/constants/adapters.ts
816
+ var WALLETCONNECT_NAMESPACE = {
817
+ eip155: {
818
+ methods: [
819
+ // Transaction methods
820
+ "eth_sendTransaction",
821
+ "eth_signTransaction",
822
+ "eth_sendRawTransaction",
823
+ // Signing methods
824
+ "eth_sign",
825
+ "personal_sign",
826
+ "eth_signTypedData",
827
+ "eth_signTypedData_v3",
828
+ "eth_signTypedData_v4",
829
+ // Account methods
830
+ "eth_accounts",
831
+ "eth_requestAccounts",
832
+ // Chain management
833
+ "wallet_switchEthereumChain",
834
+ "wallet_addEthereumChain",
835
+ // Permissions (EIP-2255)
836
+ "wallet_requestPermissions",
837
+ "wallet_getPermissions"
838
+ ],
839
+ chains: [
840
+ // Ethereum
841
+ "eip155:1",
842
+ // Mainnet
843
+ "eip155:11155111",
844
+ // Sepolia
845
+ // Base
846
+ "eip155:8453",
847
+ // Mainnet
848
+ "eip155:84532",
849
+ // Sepolia
850
+ // Optimism
851
+ "eip155:10",
852
+ // Mainnet
853
+ "eip155:11155420",
854
+ // Sepolia
855
+ // Arbitrum
856
+ "eip155:42161",
857
+ // Mainnet
858
+ "eip155:421614",
859
+ // Sepolia
860
+ // BNB Chain
861
+ "eip155:56",
862
+ // Mainnet
863
+ "eip155:97",
864
+ // Testnet
865
+ // Polygon
866
+ "eip155:137",
867
+ // Mainnet
868
+ "eip155:80002",
869
+ // Amoy
870
+ // Fantom
871
+ "eip155:250",
872
+ // Mainnet
873
+ "eip155:4002",
874
+ // Testnet
875
+ // Linea
876
+ "eip155:59144",
877
+ // Mainnet
878
+ "eip155:59141",
879
+ // Sepolia
880
+ // Gnosis
881
+ "eip155:100",
882
+ // Mainnet
883
+ "eip155:10200",
884
+ // Chiado
885
+ // Polygon zkEVM
886
+ "eip155:1101",
887
+ // Mainnet
888
+ "eip155:2442",
889
+ // Cardona
890
+ // Avalanche C-Chain
891
+ "eip155:43114",
892
+ // Mainnet
893
+ "eip155:43113"
894
+ // Fuji
895
+ ],
896
+ events: ["chainChanged", "accountsChanged"]
897
+ }
898
+ };
899
+
900
+ // src/wallet-adapters/WalletConnectAdapter.ts
901
+ function extractAddressFromSession(namespaces) {
902
+ const accounts = namespaces?.eip155?.accounts || [];
903
+ const firstAccount = accounts[0];
904
+ return firstAccount?.split(":")[2] ?? null;
905
+ }
1210
906
  var WalletConnectAdapter = class {
1211
907
  constructor(config) {
1212
- this.id = WalletId9.WalletConnect;
1213
- this.name = WalletName8.WalletConnect;
1214
- this.icon = getLogoDataUri8(WalletId9.WalletConnect, "brand") ?? "";
908
+ this.id = WalletId6.WalletConnect;
909
+ this.name = WalletName6.WalletConnect;
910
+ this.icon = getLogoDataUri6(WalletId6.WalletConnect, "brand") ?? "";
1215
911
  this.hide = false;
1216
912
  this.downloadUrl = null;
1217
913
  this.wcDeepLinkUrl = null;
914
+ this.modal = null;
915
+ this.wagmiAdapter = null;
916
+ this.universalProvider = null;
1218
917
  this.provider = null;
918
+ this.address = null;
1219
919
  this.connectionUri = null;
1220
920
  this.accountsChangedCallback = null;
921
+ this.chainChangedCallback = null;
922
+ this.disconnectCallback = null;
923
+ this.sessionUpdateHandler = null;
924
+ this.unsubscribeFunctions = [];
1221
925
  this.initPromise = null;
1222
- this.config = {
1223
- projectId: config.projectId,
1224
- appName: config.appName
1225
- };
926
+ this.lastKnownAccounts = [];
927
+ this.lastKnownChainId = null;
928
+ this.config = config;
1226
929
  }
1227
930
  async ensureInitialized() {
1228
- if (this.provider) return;
931
+ if (this.modal) return;
1229
932
  if (!this.initPromise) {
1230
- this.initPromise = this.initializeProvider();
933
+ this.initPromise = this.initializeAppKit();
1231
934
  }
1232
935
  await this.initPromise;
1233
936
  }
1234
- async initializeProvider() {
937
+ async initializeAppKit() {
1235
938
  if (typeof window === "undefined") return;
1236
- const { EthereumProvider } = await import("@walletconnect/ethereum-provider");
1237
- this.provider = await EthereumProvider.init({
1238
- projectId: this.config.projectId ?? "",
1239
- optionalChains: [1],
1240
- showQrModal: false,
939
+ const [{ createAppKit }, { WagmiAdapter }, { mainnet }] = await Promise.all([
940
+ import("@reown/appkit"),
941
+ import("@reown/appkit-adapter-wagmi"),
942
+ import("@reown/appkit/networks")
943
+ ]);
944
+ const networks = [mainnet];
945
+ this.wagmiAdapter = new WagmiAdapter({
946
+ projectId: this.config.projectId,
947
+ networks,
948
+ ssr: true
949
+ });
950
+ this.modal = createAppKit({
951
+ adapters: [this.wagmiAdapter],
952
+ networks,
953
+ projectId: this.config.projectId,
1241
954
  metadata: {
1242
955
  name: this.config.appName,
1243
956
  description: this.config.appName,
1244
957
  url: window.location.origin,
1245
958
  icons: []
959
+ },
960
+ allowUnsupportedChain: true,
961
+ themeMode: this.config.theme,
962
+ themeVariables: {
963
+ "--apkt-z-index": this.config.modalZIndex + 1
964
+ },
965
+ features: {
966
+ analytics: this.config.telemetry ?? false
1246
967
  }
1247
968
  });
1248
- this.provider.on("display_uri", (uri) => {
1249
- this.connectionUri = uri;
1250
- if (typeof window !== "undefined") {
1251
- window.dispatchEvent(new CustomEvent("walletconnect:uri", { detail: { uri } }));
969
+ this.universalProvider = await this.modal.getUniversalProvider() ?? null;
970
+ this.setupEventListeners();
971
+ }
972
+ setupEventListeners() {
973
+ if (!this.modal) return;
974
+ const unsubscribeProviders = this.modal.subscribeProviders((state) => {
975
+ const eip155Provider = state["eip155"];
976
+ this.provider = eip155Provider || null;
977
+ if (!eip155Provider) {
978
+ this.address = null;
1252
979
  }
1253
980
  });
1254
- this.provider.on("connect", (session) => {
1255
- if (typeof window !== "undefined") {
1256
- window.dispatchEvent(new CustomEvent("walletconnect:connect", { detail: { session } }));
981
+ this.unsubscribeFunctions.push(unsubscribeProviders);
982
+ if (this.universalProvider) {
983
+ this.universalProvider.on("display_uri", (uri) => {
984
+ this.connectionUri = uri;
985
+ if (typeof window !== "undefined") {
986
+ window.dispatchEvent(new CustomEvent("walletconnect:uri", { detail: { uri } }));
987
+ }
988
+ });
989
+ this.universalProvider.on("session_delete", () => {
990
+ this.handleRemoteDisconnect();
991
+ });
992
+ this.universalProvider.on("session_expire", () => {
993
+ this.handleRemoteDisconnect();
994
+ });
995
+ }
996
+ }
997
+ /** Called when user disconnects from the wallet side (mobile app) */
998
+ handleRemoteDisconnect() {
999
+ this.connectionUri = null;
1000
+ this.address = null;
1001
+ this.provider = null;
1002
+ this.lastKnownAccounts = [];
1003
+ this.lastKnownChainId = null;
1004
+ if (this.accountsChangedCallback) {
1005
+ this.accountsChangedCallback([]);
1006
+ }
1007
+ if (this.disconnectCallback) {
1008
+ this.disconnectCallback();
1009
+ }
1010
+ if (typeof window !== "undefined") {
1011
+ window.dispatchEvent(new CustomEvent("walletconnect:disconnect"));
1012
+ }
1013
+ }
1014
+ syncAddressFromWagmi() {
1015
+ if (!this.wagmiAdapter?.wagmiConfig) return;
1016
+ const { state } = this.wagmiAdapter.wagmiConfig;
1017
+ if (state.current && state.connections) {
1018
+ const connection = state.connections.get(state.current);
1019
+ if (connection?.accounts?.[0]) {
1020
+ this.address = connection.accounts[0];
1257
1021
  }
1258
- });
1259
- this.provider.on("disconnect", () => {
1260
- this.connectionUri = null;
1261
- });
1262
- this.provider.on("session_delete", () => {
1263
- if (typeof window !== "undefined") {
1264
- window.dispatchEvent(new CustomEvent("walletconnect:disconnect"));
1022
+ }
1023
+ }
1024
+ async syncProviderFromModal() {
1025
+ if (!this.modal) return;
1026
+ try {
1027
+ const getProvidersFn = this.modal.getProviders;
1028
+ if (typeof getProvidersFn === "function") {
1029
+ const providers = getProvidersFn.call(this.modal);
1030
+ const eip155Provider = providers?.["eip155"];
1031
+ if (eip155Provider) {
1032
+ this.provider = eip155Provider;
1033
+ return;
1034
+ }
1265
1035
  }
1266
- });
1036
+ if (this.wagmiAdapter?.wagmiConfig) {
1037
+ const { state } = this.wagmiAdapter.wagmiConfig;
1038
+ if (state.current && state.connections) {
1039
+ const connection = state.connections.get(state.current);
1040
+ const connector = connection?.connector;
1041
+ if (connector && typeof connector.getProvider === "function") {
1042
+ try {
1043
+ const provider = await connector.getProvider();
1044
+ if (provider) {
1045
+ this.provider = provider;
1046
+ }
1047
+ } catch (error) {
1048
+ sentryLogger.warn("Failed to get provider from wagmi connector", { error });
1049
+ }
1050
+ }
1051
+ }
1052
+ }
1053
+ } catch (error) {
1054
+ sentryLogger.warn("Failed to get provider from WalletConnect", { error });
1055
+ }
1267
1056
  }
1268
1057
  isInstalled() {
1269
1058
  return true;
1270
1059
  }
1271
- async connect() {
1272
- if (!this.config.projectId) {
1273
- throw createConfigError("WalletConnect");
1274
- }
1060
+ getConnectionUri() {
1061
+ return this.connectionUri;
1062
+ }
1063
+ /** Resets connection state for a fresh connection flow */
1064
+ async resetConnectionState() {
1065
+ this.connectionUri = null;
1066
+ this.address = null;
1067
+ this.lastKnownAccounts = [];
1068
+ this.lastKnownChainId = null;
1275
1069
  try {
1276
- await this.ensureInitialized();
1277
- if (!this.provider) {
1278
- sentryLogger.error("connect: WalletConnect is not available");
1279
- throw new Error("WalletConnect is not available");
1280
- }
1281
- const accounts = await this.provider.enable();
1282
- if (!accounts || accounts.length === 0 || !accounts[0]) {
1283
- sentryLogger.error("connect: No accounts returned from WalletConnect");
1284
- throw new Error("No accounts returned from WalletConnect");
1070
+ const { state } = this.wagmiAdapter?.wagmiConfig || {};
1071
+ const connection = state?.current && state.connections?.get(state.current);
1072
+ if (connection && typeof connection !== "string" && connection.connector?.disconnect) {
1073
+ await connection.connector.disconnect();
1285
1074
  }
1286
- return {
1287
- address: accounts[0],
1288
- provider: this.provider,
1289
- walletId: this.id
1290
- };
1291
1075
  } catch {
1292
- this.connectionUri = null;
1293
- throw new Error("Failed to connect to WalletConnect");
1294
1076
  }
1077
+ if (this.modal?.getIsConnectedState()) {
1078
+ try {
1079
+ await this.modal.disconnect("eip155");
1080
+ } catch {
1081
+ }
1082
+ }
1083
+ if (this.universalProvider?.session) {
1084
+ try {
1085
+ await this.universalProvider.disconnect();
1086
+ } catch {
1087
+ }
1088
+ }
1089
+ await new Promise((r) => setTimeout(r, 200));
1090
+ this.provider = null;
1295
1091
  }
1296
- getConnectionUri() {
1297
- return this.connectionUri;
1092
+ /**
1093
+ * Connects via WalletConnect QR code flow.
1094
+ * Emits walletconnect:uri event for QR code display.
1095
+ */
1096
+ async connect() {
1097
+ if (!this.config.projectId) throw createConfigError("WalletConnect");
1098
+ await this.ensureInitialized();
1099
+ if (!this.universalProvider) throw new Error("WalletConnect is not available");
1100
+ await this.resetConnectionState();
1101
+ try {
1102
+ const session = await this.universalProvider.connect({ namespaces: WALLETCONNECT_NAMESPACE });
1103
+ if (!session) throw new Error("Failed to establish WalletConnect session");
1104
+ const address = extractAddressFromSession(session.namespaces);
1105
+ if (!address) throw new Error("No accounts returned from WalletConnect");
1106
+ this.provider = this.universalProvider;
1107
+ this.address = address;
1108
+ this.lastKnownAccounts = [address];
1109
+ return { address, provider: this.provider, walletId: this.id };
1110
+ } catch (error) {
1111
+ this.connectionUri = null;
1112
+ throw error;
1113
+ }
1298
1114
  }
1299
1115
  /**
1300
1116
  * Starts a WalletConnect session for headless/custom QR code flows.
1301
1117
  * Returns the URI immediately and a function to wait for the connection.
1302
1118
  */
1303
1119
  async startSession(timeout = 1e4) {
1304
- if (!this.config.projectId) {
1305
- throw new Error("WalletConnect projectId is required");
1306
- }
1120
+ if (!this.config.projectId) throw new Error("WalletConnect projectId is required");
1307
1121
  await this.ensureInitialized();
1308
- if (!this.provider) {
1309
- sentryLogger.error("startSession: WalletConnect is not available");
1310
- throw new Error("WalletConnect is not available");
1311
- }
1312
- this.connectionUri = null;
1122
+ if (!this.universalProvider) throw new Error("WalletConnect is not available");
1123
+ await this.resetConnectionState();
1313
1124
  const uriPromise = new Promise((resolve, reject) => {
1314
- const timeoutId = setTimeout(() => {
1315
- reject(new Error("Timeout waiting for WalletConnect URI"));
1316
- }, timeout);
1317
- this.provider.once("display_uri", (uri2) => {
1125
+ const timeoutId = setTimeout(() => reject(new Error("Timeout waiting for WalletConnect URI")), timeout);
1126
+ this.universalProvider.once("display_uri", (uri2) => {
1318
1127
  clearTimeout(timeoutId);
1319
1128
  this.connectionUri = uri2;
1320
1129
  resolve(uri2);
1321
1130
  });
1322
1131
  });
1323
1132
  const connectionPromise = (async () => {
1324
- const accounts = await this.provider.enable();
1325
- if (!accounts || accounts.length === 0 || !accounts[0]) {
1326
- sentryLogger.error("startSession: No accounts returned from WalletConnect");
1327
- throw new Error("No accounts returned from WalletConnect");
1328
- }
1329
- return {
1330
- address: accounts[0],
1331
- provider: this.provider,
1332
- walletId: this.id
1333
- };
1133
+ const session = await this.universalProvider.connect({ namespaces: WALLETCONNECT_NAMESPACE });
1134
+ if (!session) throw new Error("Failed to establish WalletConnect session");
1135
+ const address = extractAddressFromSession(session.namespaces);
1136
+ if (!address) throw new Error("No accounts returned from WalletConnect");
1137
+ this.provider = this.universalProvider;
1138
+ this.address = address;
1139
+ this.lastKnownAccounts = [address];
1140
+ return { address, provider: this.provider, walletId: this.id };
1334
1141
  })();
1335
1142
  const uri = await uriPromise;
1336
1143
  return {
@@ -1338,71 +1145,201 @@ var WalletConnectAdapter = class {
1338
1145
  waitForConnection: async () => {
1339
1146
  try {
1340
1147
  return await connectionPromise;
1341
- } catch {
1148
+ } catch (error) {
1342
1149
  this.connectionUri = null;
1343
- throw new Error("Failed to connect via WalletConnect");
1150
+ throw error;
1344
1151
  }
1345
1152
  }
1346
1153
  };
1347
1154
  }
1155
+ /**
1156
+ * Opens the AppKit modal for wallet selection.
1157
+ * Used on mobile and when user clicks "Open Modal" button.
1158
+ */
1159
+ async openModal() {
1160
+ if (!this.config.projectId) throw createConfigError("WalletConnect");
1161
+ await this.ensureInitialized();
1162
+ if (!this.modal) throw new Error("AppKit is not available");
1163
+ await this.resetConnectionState();
1164
+ this.modal.open({ view: "AllWallets" });
1165
+ return this.waitForModalConnection();
1166
+ }
1167
+ waitForModalConnection(timeout = 6e4) {
1168
+ return new Promise((resolve, reject) => {
1169
+ const startTime = Date.now();
1170
+ let unsubscribe = null;
1171
+ let resolved = false;
1172
+ const cleanup = () => unsubscribe?.();
1173
+ const checkConnection = async () => {
1174
+ if (resolved) return true;
1175
+ this.syncAddressFromWagmi();
1176
+ if (this.address && !this.provider) await this.syncProviderFromModal();
1177
+ if (this.provider && this.address) {
1178
+ try {
1179
+ const accounts = await this.provider.request({ method: "eth_accounts" });
1180
+ if (accounts?.length) {
1181
+ resolved = true;
1182
+ cleanup();
1183
+ this.modal?.close();
1184
+ this.lastKnownAccounts = accounts;
1185
+ resolve({ address: this.address, provider: this.provider, walletId: this.id });
1186
+ return true;
1187
+ }
1188
+ } catch {
1189
+ }
1190
+ }
1191
+ return false;
1192
+ };
1193
+ unsubscribe = this.modal.subscribeState(async (state) => {
1194
+ if (await checkConnection()) return;
1195
+ if (!state.open && !this.address && !resolved) {
1196
+ cleanup();
1197
+ reject(new Error("Connection rejected by user"));
1198
+ }
1199
+ });
1200
+ const poll = async () => {
1201
+ if (await checkConnection()) return;
1202
+ if (Date.now() - startTime > timeout) {
1203
+ cleanup();
1204
+ reject(new Error("Connection timeout"));
1205
+ return;
1206
+ }
1207
+ setTimeout(poll, 500);
1208
+ };
1209
+ poll();
1210
+ });
1211
+ }
1348
1212
  async tryRestoreConnection() {
1213
+ await this.ensureInitialized();
1214
+ if (!this.wagmiAdapter) return null;
1349
1215
  try {
1350
- await this.ensureInitialized();
1351
- if (!this.provider) {
1352
- return null;
1353
- }
1354
- const accounts = this.provider.accounts;
1355
- if (!accounts || accounts.length === 0 || !accounts[0]) {
1356
- return null;
1216
+ await new Promise((r) => setTimeout(r, 1e3));
1217
+ const { state } = this.wagmiAdapter.wagmiConfig || {};
1218
+ const connection = state?.current && state.connections?.get(state.current);
1219
+ if (!connection || typeof connection === "string") return null;
1220
+ const address = connection.accounts?.[0];
1221
+ if (address && this.provider) {
1222
+ this.address = address;
1223
+ this.lastKnownAccounts = [...connection.accounts || []];
1224
+ return { address, provider: this.provider, walletId: this.id };
1357
1225
  }
1358
- return {
1359
- address: accounts[0],
1360
- provider: this.provider,
1361
- walletId: this.id
1362
- };
1226
+ return null;
1363
1227
  } catch {
1364
1228
  return null;
1365
1229
  }
1366
1230
  }
1367
1231
  async disconnect() {
1368
- try {
1369
- if (this.provider) {
1370
- await this.provider.disconnect();
1232
+ if (this.modal) {
1233
+ await this.modal.disconnect("eip155");
1234
+ const deadline = Date.now() + 2e3;
1235
+ while (Date.now() < deadline && (this.modal.getIsConnectedState() || this.modal.getAddress())) {
1236
+ await new Promise((r) => setTimeout(r, 100));
1371
1237
  }
1372
- } finally {
1373
- this.connectionUri = null;
1374
- this.provider = null;
1375
- this.initPromise = null;
1376
1238
  }
1239
+ this.address = null;
1240
+ this.provider = null;
1241
+ this.connectionUri = null;
1242
+ this.lastKnownAccounts = [];
1243
+ this.lastKnownChainId = null;
1377
1244
  }
1378
1245
  getProvider() {
1379
1246
  return this.provider;
1380
1247
  }
1381
- // Called by Aurum when user connects wallet
1382
- // Passes Aurum.ts --> syncStateFromAccountsChanged() to handle the provider accounts changed event
1383
1248
  onAccountsChanged(callback) {
1384
- if (!this.provider?.on) return;
1385
- if (this.accountsChangedCallback) {
1386
- this.provider.removeListener?.("accountsChanged", this.accountsChangedCallback);
1249
+ if (this.accountsChangedCallback && this.provider?.removeListener) {
1250
+ this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
1387
1251
  }
1388
- this.accountsChangedCallback = callback;
1389
- this.provider.on("accountsChanged", this.accountsChangedCallback);
1252
+ if (this.sessionUpdateHandler && this.universalProvider?.removeListener) {
1253
+ this.universalProvider.removeListener("session_update", this.sessionUpdateHandler);
1254
+ }
1255
+ if (!this.lastKnownAccounts.length && this.address) this.lastKnownAccounts = [this.address];
1256
+ this.accountsChangedCallback = (accounts) => {
1257
+ this.address = accounts[0] || null;
1258
+ this.lastKnownAccounts = accounts;
1259
+ callback(accounts);
1260
+ };
1261
+ if (this.provider?.on) {
1262
+ this.provider.on("accountsChanged", this.accountsChangedCallback);
1263
+ }
1264
+ if (this.universalProvider?.on) {
1265
+ this.sessionUpdateHandler = (args) => {
1266
+ const accounts = this.extractAccountsFromNamespaces(args?.params?.namespaces);
1267
+ if (accounts.length && this.hasAccountsChanged(accounts)) {
1268
+ this.lastKnownAccounts = accounts;
1269
+ this.address = accounts[0];
1270
+ callback(accounts);
1271
+ }
1272
+ };
1273
+ this.universalProvider.on("session_update", this.sessionUpdateHandler);
1274
+ }
1275
+ }
1276
+ onChainChanged(callback) {
1277
+ if (!this.provider?.on) return;
1278
+ if (this.chainChangedCallback) this.provider.removeListener?.("chainChanged", this.chainChangedCallback);
1279
+ this.chainChangedCallback = (chainId) => {
1280
+ const normalized = typeof chainId === "string" ? chainId : `0x${Number(chainId).toString(16)}`;
1281
+ if (normalized !== this.lastKnownChainId) {
1282
+ this.lastKnownChainId = normalized;
1283
+ callback(normalized);
1284
+ }
1285
+ };
1286
+ this.provider.on("chainChanged", this.chainChangedCallback);
1287
+ }
1288
+ /** Called when remote wallet disconnects (user disconnects from mobile app) */
1289
+ onDisconnect(callback) {
1290
+ this.disconnectCallback = callback;
1291
+ }
1292
+ /** Updates the AppKit modal theme */
1293
+ updateTheme(theme) {
1294
+ this.config.theme = theme;
1295
+ if (this.modal && typeof this.modal.setThemeMode === "function") {
1296
+ this.modal.setThemeMode(theme);
1297
+ }
1298
+ }
1299
+ extractAccountsFromNamespaces(namespaces) {
1300
+ if (!namespaces) return [];
1301
+ const accounts = [];
1302
+ Object.values(namespaces).forEach((ns) => {
1303
+ ns?.accounts?.forEach((account) => {
1304
+ const address = account.split(":")[2];
1305
+ if (address) accounts.push(address);
1306
+ });
1307
+ });
1308
+ return [...new Set(accounts)];
1309
+ }
1310
+ hasAccountsChanged(newAccounts) {
1311
+ if (newAccounts.length !== this.lastKnownAccounts.length) return true;
1312
+ return newAccounts.some((acc, i) => acc.toLowerCase() !== this.lastKnownAccounts[i]?.toLowerCase());
1390
1313
  }
1391
1314
  removeListeners() {
1392
- if (!this.provider?.removeListener || !this.accountsChangedCallback) return;
1393
- this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
1394
- this.accountsChangedCallback = null;
1315
+ if (this.accountsChangedCallback) {
1316
+ this.provider?.removeListener?.("accountsChanged", this.accountsChangedCallback);
1317
+ this.accountsChangedCallback = null;
1318
+ }
1319
+ if (this.chainChangedCallback) {
1320
+ this.provider?.removeListener?.("chainChanged", this.chainChangedCallback);
1321
+ this.chainChangedCallback = null;
1322
+ }
1323
+ if (this.sessionUpdateHandler) {
1324
+ this.universalProvider?.removeListener?.("session_update", this.sessionUpdateHandler);
1325
+ this.sessionUpdateHandler = null;
1326
+ }
1327
+ this.disconnectCallback = null;
1328
+ this.unsubscribeFunctions.forEach((unsub) => unsub());
1329
+ this.unsubscribeFunctions = [];
1330
+ this.lastKnownAccounts = [];
1331
+ this.lastKnownChainId = null;
1395
1332
  }
1396
1333
  };
1397
1334
 
1398
1335
  // src/wallet-adapters/EmailAdapter.ts
1399
- import { WalletId as WalletId10, WalletName as WalletName9 } from "@aurum-sdk/types";
1400
- import { getLogoDataUri as getLogoDataUri9 } from "@aurum-sdk/logos";
1336
+ import { WalletId as WalletId7, WalletName as WalletName7 } from "@aurum-sdk/types";
1337
+ import { getLogoDataUri as getLogoDataUri7 } from "@aurum-sdk/logos";
1401
1338
  var _EmailAdapter = class _EmailAdapter {
1402
1339
  constructor(config) {
1403
- this.id = WalletId10.Email;
1404
- this.name = WalletName9.Email;
1405
- this.icon = getLogoDataUri9(WalletId10.Email, "brand") ?? "";
1340
+ this.id = WalletId7.Email;
1341
+ this.name = WalletName7.Email;
1342
+ this.icon = getLogoDataUri7(WalletId7.Email, "brand") ?? "";
1406
1343
  this.hide = true;
1407
1344
  this.downloadUrl = null;
1408
1345
  this.wcDeepLinkUrl = null;
@@ -1410,6 +1347,7 @@ var _EmailAdapter = class _EmailAdapter {
1410
1347
  this.initPromise = null;
1411
1348
  this.publicClientCache = /* @__PURE__ */ new Map();
1412
1349
  this.projectId = config?.projectId || "";
1350
+ this.telemetry = config?.telemetry ?? false;
1413
1351
  }
1414
1352
  async ensureInitialized() {
1415
1353
  if (this.provider) return;
@@ -1430,14 +1368,9 @@ var _EmailAdapter = class _EmailAdapter {
1430
1368
  sentryLogger.error("Email is not available");
1431
1369
  throw new Error("Email is not available");
1432
1370
  }
1433
- try {
1434
- const { signInWithEmail } = await import("@coinbase/cdp-core");
1435
- const authResult = await signInWithEmail({ email });
1436
- return authResult;
1437
- } catch (error) {
1438
- sentryLogger.error("Failed to start email authentication", { error });
1439
- throw error;
1440
- }
1371
+ const { signInWithEmail } = await import("@coinbase/cdp-core");
1372
+ const authResult = await signInWithEmail({ email });
1373
+ return authResult;
1441
1374
  }
1442
1375
  async emailAuthVerify(flowId, otp) {
1443
1376
  if (!flowId || !otp) {
@@ -1531,7 +1464,8 @@ var _EmailAdapter = class _EmailAdapter {
1531
1464
  projectId: this.projectId,
1532
1465
  ethereum: {
1533
1466
  createOnLogin: "eoa"
1534
- }
1467
+ },
1468
+ disableAnalytics: !this.telemetry
1535
1469
  });
1536
1470
  this.provider = await this.createProvider();
1537
1471
  }
@@ -1601,25 +1535,50 @@ function createWalletAdapters({
1601
1535
  appName,
1602
1536
  appLogoUrl,
1603
1537
  modalZIndex,
1604
- theme
1538
+ theme,
1539
+ telemetry
1605
1540
  }) {
1606
1541
  return [
1607
- new EmailAdapter({ projectId: walletsConfig?.embedded?.projectId }),
1542
+ new EmailAdapter({ projectId: walletsConfig?.embedded?.projectId, telemetry }),
1608
1543
  new MetaMaskAdapter(),
1609
- new WalletConnectAdapter({ projectId: walletsConfig?.walletConnect?.projectId, appName }),
1610
- new CoinbaseWalletAdapter({ appName, appLogoUrl }),
1544
+ new WalletConnectAdapter({
1545
+ projectId: walletsConfig?.walletConnect?.projectId,
1546
+ appName,
1547
+ modalZIndex,
1548
+ theme,
1549
+ telemetry
1550
+ }),
1551
+ new CoinbaseWalletAdapter({ appName, appLogoUrl, telemetry }),
1611
1552
  new PhantomAdapter(),
1612
1553
  new RabbyAdapter(),
1613
- new BraveAdapter(),
1614
- new LedgerAdapter({ walletConnectProjectId: walletsConfig?.walletConnect?.projectId }),
1615
- new AppKitAdapter({ projectId: walletsConfig?.walletConnect?.projectId, appName, modalZIndex, theme })
1554
+ new BraveAdapter()
1616
1555
  ];
1617
1556
  }
1618
1557
 
1619
1558
  // src/AurumCore.ts
1620
- import { WalletId as WalletId11 } from "@aurum-sdk/types";
1559
+ import { WalletId as WalletId8 } from "@aurum-sdk/types";
1621
1560
 
1622
1561
  // src/providers/RpcProvider.ts
1562
+ var ProviderRpcError = class extends Error {
1563
+ constructor(code, message, data) {
1564
+ super(message);
1565
+ this.name = "ProviderRpcError";
1566
+ this.code = code;
1567
+ this.data = data;
1568
+ }
1569
+ };
1570
+ var ProviderErrorCode = {
1571
+ USER_REJECTED: 4001,
1572
+ // User rejected the request
1573
+ UNAUTHORIZED: 4100,
1574
+ // The requested account/method has not been authorized
1575
+ UNSUPPORTED_METHOD: 4200,
1576
+ // The provider does not support the requested method
1577
+ DISCONNECTED: 4900,
1578
+ // The provider is disconnected from all chains
1579
+ CHAIN_DISCONNECTED: 4901
1580
+ // The provider is not connected to the requested chain
1581
+ };
1623
1582
  var RpcProvider = class {
1624
1583
  constructor(handleConnect) {
1625
1584
  this.isConnected = false;
@@ -1641,7 +1600,10 @@ var RpcProvider = class {
1641
1600
  const address = await this.handleConnect();
1642
1601
  return [address];
1643
1602
  } else {
1644
- throw new Error("No wallet connection available. Please use aurum.connect() instead.");
1603
+ throw new ProviderRpcError(
1604
+ ProviderErrorCode.DISCONNECTED,
1605
+ "No wallet connection available. Please use aurum.connect() instead."
1606
+ );
1645
1607
  }
1646
1608
  // Chain/network information
1647
1609
  case "eth_chainId":
@@ -1650,8 +1612,9 @@ var RpcProvider = class {
1650
1612
  return this.networkVersion;
1651
1613
  // Default case for rest of methods
1652
1614
  default:
1653
- throw new Error(
1654
- `Method ${method} requires an active connection to a JSON-RPC provider. Please connect a wallet.`
1615
+ throw new ProviderRpcError(
1616
+ ProviderErrorCode.DISCONNECTED,
1617
+ `Method ${method} requires an active wallet connection. Please connect a wallet first.`
1655
1618
  );
1656
1619
  }
1657
1620
  }
@@ -1687,7 +1650,8 @@ var _AurumCore = class _AurumCore {
1687
1650
  appName: this.brandConfig.appName,
1688
1651
  appLogoUrl: this.brandConfig.logo,
1689
1652
  modalZIndex: this.brandConfig.modalZIndex,
1690
- theme: this.brandConfig.theme
1653
+ theme: this.brandConfig.theme,
1654
+ telemetry: telemetryEnabled
1691
1655
  });
1692
1656
  this.skeletonProvider = new RpcProvider(() => this.connect());
1693
1657
  this.currentProvider = this.skeletonProvider;
@@ -1717,9 +1681,6 @@ var _AurumCore = class _AurumCore {
1717
1681
  if (walletId === "email") {
1718
1682
  throw new Error("Use emailAuthStart() and emailAuthVerify() for email wallet connections");
1719
1683
  }
1720
- if (walletId === "walletconnect") {
1721
- throw new Error("Use getWalletConnectSession() for WalletConnect connections");
1722
- }
1723
1684
  if (this.userInfo?.publicAddress && this.connectedWalletAdapter?.getProvider()) {
1724
1685
  if (!walletId || this.userInfo.walletId === walletId) {
1725
1686
  return this.userInfo.publicAddress;
@@ -1736,10 +1697,14 @@ var _AurumCore = class _AurumCore {
1736
1697
  if (!adapter) {
1737
1698
  throw new Error(`${walletId} is not configured`);
1738
1699
  }
1739
- if (!adapter.isInstalled()) {
1740
- throw new Error(`${adapter.name} is not installed`);
1700
+ if (walletId === WalletId8.WalletConnect && adapter.openModal) {
1701
+ result = await adapter.openModal();
1702
+ } else {
1703
+ if (!adapter.isInstalled()) {
1704
+ throw new Error(`${adapter.name} is not installed`);
1705
+ }
1706
+ result = await adapter.connect();
1741
1707
  }
1742
- result = await adapter.connect();
1743
1708
  } else {
1744
1709
  const displayedWallets = this.wallets.filter((w) => !this.excludedWallets.has(w.id));
1745
1710
  const modalResult = await renderConnectModal({ displayedWallets, brandConfig: this.brandConfig });
@@ -1850,6 +1815,10 @@ var _AurumCore = class _AurumCore {
1850
1815
  font: "font" in newConfig ? newConfig.font ?? defaultTheme.font : this.brandConfig.font,
1851
1816
  walletLayout: "walletLayout" in newConfig ? newConfig.walletLayout ?? defaultTheme.walletLayout : this.brandConfig.walletLayout
1852
1817
  };
1818
+ if ("theme" in newConfig && this.brandConfig.theme) {
1819
+ const wcAdapter = this.wallets.find((w) => w.id === WalletId8.WalletConnect);
1820
+ wcAdapter?.updateTheme(this.brandConfig.theme);
1821
+ }
1853
1822
  }
1854
1823
  updateWalletsConfig(newConfig) {
1855
1824
  if (newConfig.exclude !== void 0) {
@@ -1863,7 +1832,7 @@ var _AurumCore = class _AurumCore {
1863
1832
  */
1864
1833
  async emailAuthStart(email) {
1865
1834
  await this.whenReady();
1866
- const emailAdapter = this.wallets.find((w) => w.id === WalletId11.Email);
1835
+ const emailAdapter = this.wallets.find((w) => w.id === WalletId8.Email);
1867
1836
  if (!emailAdapter || !emailAdapter.emailAuthStart) {
1868
1837
  throw new Error("Email wallet is not configured");
1869
1838
  }
@@ -1878,7 +1847,7 @@ var _AurumCore = class _AurumCore {
1878
1847
  */
1879
1848
  async emailAuthVerify(flowId, otp) {
1880
1849
  await this.whenReady();
1881
- const emailAdapter = this.wallets.find((w) => w.id === WalletId11.Email);
1850
+ const emailAdapter = this.wallets.find((w) => w.id === WalletId8.Email);
1882
1851
  if (!emailAdapter || !emailAdapter.emailAuthVerify) {
1883
1852
  throw new Error("Email wallet is not configured");
1884
1853
  }
@@ -1917,7 +1886,7 @@ var _AurumCore = class _AurumCore {
1917
1886
  */
1918
1887
  async getWalletConnectSession() {
1919
1888
  await this.whenReady();
1920
- const wcAdapter = this.wallets.find((w) => w.id === WalletId11.WalletConnect);
1889
+ const wcAdapter = this.wallets.find((w) => w.id === WalletId8.WalletConnect);
1921
1890
  if (!wcAdapter) {
1922
1891
  throw new Error("WalletConnect is not enabled");
1923
1892
  }
@@ -2359,7 +2328,7 @@ var Aurum = class {
2359
2328
  * import { WalletId } from '@aurum-sdk/types';
2360
2329
  *
2361
2330
  * aurum.updateWalletsConfig({
2362
- * exclude: [WalletId.Email, WalletId.AppKit],
2331
+ * exclude: [WalletId.Email, WalletId.WalletConnect],
2363
2332
  * });
2364
2333
  * ```
2365
2334
  */