@aurum-sdk/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +420 -0
- package/dist/chunk-DHEVW7CR.js +2432 -0
- package/dist/chunk-DHEVW7CR.js.map +1 -0
- package/dist/chunk-U5BSED2R.mjs +2432 -0
- package/dist/chunk-U5BSED2R.mjs.map +1 -0
- package/dist/index.css +743 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +273 -0
- package/dist/index.d.ts +273 -0
- package/dist/index.js +2433 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2433 -0
- package/dist/index.mjs.map +1 -0
- package/dist/widgets.css +743 -0
- package/dist/widgets.css.map +1 -0
- package/dist/widgets.d.mts +88 -0
- package/dist/widgets.d.ts +88 -0
- package/dist/widgets.js +78 -0
- package/dist/widgets.js.map +1 -0
- package/dist/widgets.mjs +78 -0
- package/dist/widgets.mjs.map +1 -0
- package/package.json +113 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2433 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
var _chunkDHEVW7CRjs = require('./chunk-DHEVW7CR.js');
|
|
18
|
+
|
|
19
|
+
// src/AurumCore.ts
|
|
20
|
+
var _viem = require('viem');
|
|
21
|
+
|
|
22
|
+
// src/utils/chainHelpers.ts
|
|
23
|
+
function normalizeChainId(chainId) {
|
|
24
|
+
if (typeof chainId === "string" && chainId.startsWith("0x")) return chainId;
|
|
25
|
+
const numericId = typeof chainId === "number" ? chainId : Number(chainId);
|
|
26
|
+
if (Number.isNaN(numericId)) {
|
|
27
|
+
throw new Error(`Invalid chainId: ${chainId}`);
|
|
28
|
+
}
|
|
29
|
+
return `0x${numericId.toString(16)}`;
|
|
30
|
+
}
|
|
31
|
+
function isChainNotAddedError(error) {
|
|
32
|
+
return Boolean(
|
|
33
|
+
_optionalChain([error, 'optionalAccess', _2 => _2.code]) === 4902 || _optionalChain([error, 'optionalAccess', _3 => _3.message, 'optionalAccess', _4 => _4.includes, 'call', _5 => _5("Unrecognized chain ID")]) || _optionalChain([error, 'optionalAccess', _6 => _6.message, 'optionalAccess', _7 => _7.includes, 'call', _8 => _8("Chain ID not supported")])
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function isChainExistsError(error) {
|
|
37
|
+
return Boolean(
|
|
38
|
+
_optionalChain([error, 'optionalAccess', _9 => _9.code]) === 4001 || // User rejected
|
|
39
|
+
_optionalChain([error, 'optionalAccess', _10 => _10.code]) === -32e3 || // Chain already pending/exists
|
|
40
|
+
_optionalChain([error, 'optionalAccess', _11 => _11.message, 'optionalAccess', _12 => _12.includes, 'call', _13 => _13("already exists")]) || _optionalChain([error, 'optionalAccess', _14 => _14.message, 'optionalAccess', _15 => _15.includes, 'call', _16 => _16("already pending")])
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/components/ConnectModal/ModalShell.tsx
|
|
45
|
+
var _react = require('react');
|
|
46
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
47
|
+
var ModalShell = ({ onClose, brandConfig }) => {
|
|
48
|
+
const [isOpen, setIsOpen] = _react.useState.call(void 0, true);
|
|
49
|
+
const { currentPage } = _chunkDHEVW7CRjs.useNavigation.call(void 0, );
|
|
50
|
+
const handleClose = () => {
|
|
51
|
+
setIsOpen(false);
|
|
52
|
+
onClose();
|
|
53
|
+
};
|
|
54
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
55
|
+
_chunkDHEVW7CRjs.Modal,
|
|
56
|
+
{
|
|
57
|
+
isOpen,
|
|
58
|
+
closeOnOverlayClick: true,
|
|
59
|
+
onCloseComplete: handleClose,
|
|
60
|
+
brandConfig,
|
|
61
|
+
transitionKey: currentPage,
|
|
62
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkDHEVW7CRjs.ConnectPages, {})
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// src/utils/createModalContainer.ts
|
|
68
|
+
var _client = require('react-dom/client');
|
|
69
|
+
|
|
70
|
+
// src/utils/createShadowRoot.ts
|
|
71
|
+
function createShadowRoot(container, brandConfig) {
|
|
72
|
+
const shadowRoot = container.attachShadow({ mode: "open" });
|
|
73
|
+
shadowRoot.innerHTML = `
|
|
74
|
+
<style>${_chunkDHEVW7CRjs.generateCompleteStyles.call(void 0, brandConfig)}</style>
|
|
75
|
+
<div class="aurum-modal-root"></div>
|
|
76
|
+
`;
|
|
77
|
+
return shadowRoot.querySelector(".aurum-modal-root");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/utils/createModalContainer.ts
|
|
81
|
+
var activeRoots = /* @__PURE__ */ new Map();
|
|
82
|
+
function createModalContainer(id, brandConfig) {
|
|
83
|
+
const existingRoot = activeRoots.get(id);
|
|
84
|
+
if (existingRoot) {
|
|
85
|
+
existingRoot.unmount();
|
|
86
|
+
_optionalChain([document, 'access', _17 => _17.getElementById, 'call', _18 => _18(id), 'optionalAccess', _19 => _19.remove, 'call', _20 => _20()]);
|
|
87
|
+
activeRoots.delete(id);
|
|
88
|
+
}
|
|
89
|
+
const container = document.createElement("div");
|
|
90
|
+
container.id = id;
|
|
91
|
+
document.body.appendChild(container);
|
|
92
|
+
const shadowDOMRoot = createShadowRoot(container, brandConfig);
|
|
93
|
+
const root = _client.createRoot.call(void 0, shadowDOMRoot);
|
|
94
|
+
activeRoots.set(id, root);
|
|
95
|
+
const cleanup = () => {
|
|
96
|
+
root.unmount();
|
|
97
|
+
container.remove();
|
|
98
|
+
activeRoots.delete(id);
|
|
99
|
+
};
|
|
100
|
+
return { root, cleanup };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// src/components/ConnectModal/renderConnectModal.tsx
|
|
104
|
+
var _types = require('@aurum-sdk/types');
|
|
105
|
+
|
|
106
|
+
var CONTAINER_ID = "aurum-modal-container";
|
|
107
|
+
function renderConnectModal({
|
|
108
|
+
displayedWallets,
|
|
109
|
+
brandConfig
|
|
110
|
+
}) {
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
let sortedWallets = _chunkDHEVW7CRjs.sortWallets.call(void 0, displayedWallets, { filterHidden: false });
|
|
113
|
+
const hasAppKit = sortedWallets.some((w) => w.id === _types.WalletId.AppKit);
|
|
114
|
+
if (_chunkDHEVW7CRjs.isMobile.call(void 0, ) && !hasAppKit) {
|
|
115
|
+
sortedWallets = sortedWallets.filter((w) => w.id !== _types.WalletId.WalletConnect);
|
|
116
|
+
}
|
|
117
|
+
const { root, cleanup } = createModalContainer(CONTAINER_ID, brandConfig);
|
|
118
|
+
const onConnect = (result) => {
|
|
119
|
+
cleanup();
|
|
120
|
+
resolve(result);
|
|
121
|
+
};
|
|
122
|
+
const onClose = () => {
|
|
123
|
+
cleanup();
|
|
124
|
+
reject(new Error("User rejected request"));
|
|
125
|
+
};
|
|
126
|
+
root.render(
|
|
127
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkDHEVW7CRjs.ThemeContainer, { theme: brandConfig.theme, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkDHEVW7CRjs.ConnectUIProviders, { onConnect, displayedWallets: sortedWallets, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ModalShell, { onClose, brandConfig }) }) })
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/wallet-adapters/AppKitAdapter.ts
|
|
133
|
+
var _logos = require('@aurum-sdk/logos');
|
|
134
|
+
|
|
135
|
+
var AppKitAdapter = class {
|
|
136
|
+
constructor(config) {
|
|
137
|
+
this.id = _types.WalletId.AppKit;
|
|
138
|
+
this.name = _types.WalletName.AppKit;
|
|
139
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.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
|
+
Promise.resolve().then(() => _interopRequireWildcard(require("@reown/appkit"))),
|
|
168
|
+
Promise.resolve().then(() => _interopRequireWildcard(require("@reown/appkit-adapter-wagmi"))),
|
|
169
|
+
Promise.resolve().then(() => _interopRequireWildcard(require("@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 (!_optionalChain([this, 'access', _21 => _21.wagmiAdapter, 'optionalAccess', _22 => _22.wagmiConfig])) return;
|
|
208
|
+
const { state } = this.wagmiAdapter.wagmiConfig;
|
|
209
|
+
if (state.current && state.connections) {
|
|
210
|
+
const connection = state.connections.get(state.current);
|
|
211
|
+
if (_optionalChain([connection, 'optionalAccess', _23 => _23.accounts, 'optionalAccess', _24 => _24[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 = _optionalChain([providers, 'optionalAccess', _25 => _25["eip155"]]);
|
|
223
|
+
if (eip155Provider) {
|
|
224
|
+
this.provider = eip155Provider;
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (_optionalChain([this, 'access', _26 => _26.wagmiAdapter, 'optionalAccess', _27 => _27.wagmiConfig])) {
|
|
229
|
+
const { state } = this.wagmiAdapter.wagmiConfig;
|
|
230
|
+
if (state.current && state.connections) {
|
|
231
|
+
const connection = state.connections.get(state.current);
|
|
232
|
+
const connector = _optionalChain([connection, 'optionalAccess', _28 => _28.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
|
+
_chunkDHEVW7CRjs.sentryLogger.warn("Failed to get provider from wagmi connector", { error });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
} catch (error) {
|
|
246
|
+
_chunkDHEVW7CRjs.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 _chunkDHEVW7CRjs.createConfigError.call(void 0, "AppKit");
|
|
255
|
+
}
|
|
256
|
+
await this.ensureInitialized();
|
|
257
|
+
if (!this.modal) {
|
|
258
|
+
_chunkDHEVW7CRjs.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: "Connect" });
|
|
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
|
+
_optionalChain([unsubscribeState, 'optionalCall', _29 => _29()]);
|
|
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
|
+
_optionalChain([this, 'access', _30 => _30.modal, 'optionalAccess', _31 => _31.close, 'call', _32 => _32()]);
|
|
298
|
+
resolve({
|
|
299
|
+
address: this.address,
|
|
300
|
+
provider: this.provider,
|
|
301
|
+
walletId: this.id
|
|
302
|
+
});
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
return false;
|
|
306
|
+
} catch (e) {
|
|
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 (_optionalChain([wagmiConfig, 'optionalAccess', _33 => _33.state, 'optionalAccess', _34 => _34.current]) && wagmiConfig.state.connections) {
|
|
338
|
+
const connection = wagmiConfig.state.connections.get(wagmiConfig.state.current);
|
|
339
|
+
if (_optionalChain([connection, 'optionalAccess', _35 => _35.accounts, 'optionalAccess', _36 => _36[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 (e2) {
|
|
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 (!_optionalChain([this, 'access', _37 => _37.provider, 'optionalAccess', _38 => _38.on])) return;
|
|
374
|
+
if (this.accountsChangedCallback) {
|
|
375
|
+
_optionalChain([this, 'access', _39 => _39.provider, 'access', _40 => _40.removeListener, 'optionalCall', _41 => _41("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 (_optionalChain([this, 'access', _42 => _42.provider, 'optionalAccess', _43 => _43.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
|
+
// src/wallet-adapters/RabbyAdapter.ts
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
var RABBY_RDNS = "io.rabby";
|
|
397
|
+
var RabbyAdapter = class {
|
|
398
|
+
constructor() {
|
|
399
|
+
this.id = _types.WalletId.Rabby;
|
|
400
|
+
this.name = _types.WalletName.Rabby;
|
|
401
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.Rabby, "brand"), () => ( ""));
|
|
402
|
+
this.hide = false;
|
|
403
|
+
this.downloadUrl = "https://rabby.io";
|
|
404
|
+
this.wcDeepLinkUrl = null;
|
|
405
|
+
this.provider = null;
|
|
406
|
+
this.accountsChangedCallback = null;
|
|
407
|
+
this.providerPromise = null;
|
|
408
|
+
this.providerPromise = this.discoverProvider();
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Uses EIP-6963 to discover the Rabby provider by its RDNS identifier.
|
|
412
|
+
* Falls back to window.ethereum for legacy detection.
|
|
413
|
+
*/
|
|
414
|
+
discoverProvider() {
|
|
415
|
+
if (typeof window === "undefined") return Promise.resolve(null);
|
|
416
|
+
return new Promise((resolve) => {
|
|
417
|
+
let resolved = false;
|
|
418
|
+
const onAnnouncement = (event) => {
|
|
419
|
+
const { detail } = event;
|
|
420
|
+
if (detail.info.rdns === RABBY_RDNS) {
|
|
421
|
+
resolved = true;
|
|
422
|
+
this.provider = detail.provider;
|
|
423
|
+
window.removeEventListener("eip6963:announceProvider", onAnnouncement);
|
|
424
|
+
resolve(detail.provider);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
window.addEventListener("eip6963:announceProvider", onAnnouncement);
|
|
428
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
429
|
+
setTimeout(() => {
|
|
430
|
+
if (!resolved) {
|
|
431
|
+
window.removeEventListener("eip6963:announceProvider", onAnnouncement);
|
|
432
|
+
const legacyProvider = this.detectLegacyProvider();
|
|
433
|
+
if (legacyProvider) {
|
|
434
|
+
this.provider = legacyProvider;
|
|
435
|
+
}
|
|
436
|
+
resolve(legacyProvider);
|
|
437
|
+
}
|
|
438
|
+
}, 100);
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Fallback detection for legacy Rabby installations.
|
|
443
|
+
* Checks window.ethereum for Rabby-specific flags.
|
|
444
|
+
*/
|
|
445
|
+
detectLegacyProvider() {
|
|
446
|
+
const ethereum = window.ethereum;
|
|
447
|
+
if (_optionalChain([ethereum, 'optionalAccess', _44 => _44.isRabby])) {
|
|
448
|
+
return ethereum;
|
|
449
|
+
}
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
452
|
+
isInstalled() {
|
|
453
|
+
return Boolean(this.provider);
|
|
454
|
+
}
|
|
455
|
+
async connect() {
|
|
456
|
+
if (!this.provider && this.providerPromise) {
|
|
457
|
+
await this.providerPromise;
|
|
458
|
+
}
|
|
459
|
+
if (!this.provider) {
|
|
460
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Rabby is not available");
|
|
461
|
+
throw new Error("Rabby is not available");
|
|
462
|
+
}
|
|
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
|
+
_chunkDHEVW7CRjs.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 (e3) {
|
|
482
|
+
throw new Error("Failed to connect to Rabby");
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
async tryRestoreConnection() {
|
|
486
|
+
if (!this.provider && this.providerPromise) {
|
|
487
|
+
await this.providerPromise;
|
|
488
|
+
}
|
|
489
|
+
if (!this.provider) {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
const accounts = await this.provider.request({
|
|
494
|
+
method: "eth_accounts",
|
|
495
|
+
params: []
|
|
496
|
+
});
|
|
497
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
address: accounts[0],
|
|
502
|
+
provider: this.provider,
|
|
503
|
+
walletId: this.id
|
|
504
|
+
};
|
|
505
|
+
} catch (e4) {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
async disconnect() {
|
|
510
|
+
}
|
|
511
|
+
getProvider() {
|
|
512
|
+
return this.provider;
|
|
513
|
+
}
|
|
514
|
+
// Called by Aurum when user connects wallet
|
|
515
|
+
// Passes Aurum.ts --> syncStateFromAccountsChanged() to handle the provider accounts changed event
|
|
516
|
+
onAccountsChanged(callback) {
|
|
517
|
+
if (!_optionalChain([this, 'access', _45 => _45.provider, 'optionalAccess', _46 => _46.on])) return;
|
|
518
|
+
if (this.accountsChangedCallback) {
|
|
519
|
+
_optionalChain([this, 'access', _47 => _47.provider, 'access', _48 => _48.removeListener, 'optionalCall', _49 => _49("accountsChanged", this.accountsChangedCallback)]);
|
|
520
|
+
}
|
|
521
|
+
this.accountsChangedCallback = callback;
|
|
522
|
+
this.provider.on("accountsChanged", this.accountsChangedCallback);
|
|
523
|
+
}
|
|
524
|
+
removeListeners() {
|
|
525
|
+
if (!_optionalChain([this, 'access', _50 => _50.provider, 'optionalAccess', _51 => _51.removeListener]) || !this.accountsChangedCallback) return;
|
|
526
|
+
this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
|
|
527
|
+
this.accountsChangedCallback = null;
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
// src/wallet-adapters/BraveAdapter.ts
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
var BRAVE_RDNS = "com.brave.wallet";
|
|
535
|
+
function isBraveBrowser() {
|
|
536
|
+
if (typeof navigator === "undefined") return false;
|
|
537
|
+
return navigator.brave !== void 0;
|
|
538
|
+
}
|
|
539
|
+
var BraveAdapter = class {
|
|
540
|
+
constructor() {
|
|
541
|
+
this.id = _types.WalletId.Brave;
|
|
542
|
+
this.name = _types.WalletName.Brave;
|
|
543
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.Brave, "brand"), () => ( ""));
|
|
544
|
+
this.downloadUrl = "https://brave.com/download";
|
|
545
|
+
this.wcDeepLinkUrl = null;
|
|
546
|
+
this.provider = null;
|
|
547
|
+
this.accountsChangedCallback = null;
|
|
548
|
+
this.providerPromise = null;
|
|
549
|
+
this.hide = !isBraveBrowser();
|
|
550
|
+
this.providerPromise = this.discoverProvider();
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Uses EIP-6963 to discover the Brave Wallet provider by its RDNS identifier.
|
|
554
|
+
* Falls back to window.ethereum for legacy detection.
|
|
555
|
+
*/
|
|
556
|
+
discoverProvider() {
|
|
557
|
+
if (typeof window === "undefined") return Promise.resolve(null);
|
|
558
|
+
return new Promise((resolve) => {
|
|
559
|
+
let resolved = false;
|
|
560
|
+
const onAnnouncement = (event) => {
|
|
561
|
+
const { detail } = event;
|
|
562
|
+
if (detail.info.rdns === BRAVE_RDNS) {
|
|
563
|
+
resolved = true;
|
|
564
|
+
this.provider = detail.provider;
|
|
565
|
+
window.removeEventListener("eip6963:announceProvider", onAnnouncement);
|
|
566
|
+
resolve(detail.provider);
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
window.addEventListener("eip6963:announceProvider", onAnnouncement);
|
|
570
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
571
|
+
setTimeout(() => {
|
|
572
|
+
if (!resolved) {
|
|
573
|
+
window.removeEventListener("eip6963:announceProvider", onAnnouncement);
|
|
574
|
+
const legacyProvider = this.detectLegacyProvider();
|
|
575
|
+
if (legacyProvider) {
|
|
576
|
+
this.provider = legacyProvider;
|
|
577
|
+
}
|
|
578
|
+
resolve(legacyProvider);
|
|
579
|
+
}
|
|
580
|
+
}, 100);
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Fallback detection for legacy Brave Wallet detection.
|
|
585
|
+
* Checks window.ethereum for Brave-specific flags.
|
|
586
|
+
*/
|
|
587
|
+
detectLegacyProvider() {
|
|
588
|
+
const ethereum = window.ethereum;
|
|
589
|
+
if (_optionalChain([ethereum, 'optionalAccess', _52 => _52.isBraveWallet])) {
|
|
590
|
+
return ethereum;
|
|
591
|
+
}
|
|
592
|
+
return null;
|
|
593
|
+
}
|
|
594
|
+
isInstalled() {
|
|
595
|
+
return Boolean(this.provider);
|
|
596
|
+
}
|
|
597
|
+
async connect() {
|
|
598
|
+
if (!this.provider && this.providerPromise) {
|
|
599
|
+
await this.providerPromise;
|
|
600
|
+
}
|
|
601
|
+
if (!this.provider) {
|
|
602
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Brave Wallet is not available");
|
|
603
|
+
throw new Error("Brave Wallet is not available");
|
|
604
|
+
}
|
|
605
|
+
try {
|
|
606
|
+
await this.provider.request({
|
|
607
|
+
method: "wallet_requestPermissions",
|
|
608
|
+
params: [{ eth_accounts: {} }]
|
|
609
|
+
});
|
|
610
|
+
const accounts = await this.provider.request({
|
|
611
|
+
method: "eth_requestAccounts",
|
|
612
|
+
params: []
|
|
613
|
+
});
|
|
614
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
615
|
+
_chunkDHEVW7CRjs.sentryLogger.error("No accounts returned from Brave Wallet");
|
|
616
|
+
throw new Error("No accounts returned from Brave Wallet");
|
|
617
|
+
}
|
|
618
|
+
return {
|
|
619
|
+
address: accounts[0],
|
|
620
|
+
provider: this.provider,
|
|
621
|
+
walletId: this.id
|
|
622
|
+
};
|
|
623
|
+
} catch (e5) {
|
|
624
|
+
throw new Error("Failed to connect to Brave Wallet");
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
async tryRestoreConnection() {
|
|
628
|
+
if (!this.provider && this.providerPromise) {
|
|
629
|
+
await this.providerPromise;
|
|
630
|
+
}
|
|
631
|
+
if (!this.provider) {
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
try {
|
|
635
|
+
const accounts = await this.provider.request({
|
|
636
|
+
method: "eth_accounts",
|
|
637
|
+
params: []
|
|
638
|
+
});
|
|
639
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
640
|
+
return null;
|
|
641
|
+
}
|
|
642
|
+
return {
|
|
643
|
+
address: accounts[0],
|
|
644
|
+
provider: this.provider,
|
|
645
|
+
walletId: this.id
|
|
646
|
+
};
|
|
647
|
+
} catch (e6) {
|
|
648
|
+
return null;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
async disconnect() {
|
|
652
|
+
}
|
|
653
|
+
getProvider() {
|
|
654
|
+
return this.provider;
|
|
655
|
+
}
|
|
656
|
+
// Called by Aurum when user connects wallet
|
|
657
|
+
// Passes Aurum.ts --> syncStateFromAccountsChanged() to handle the provider accounts changed event
|
|
658
|
+
onAccountsChanged(callback) {
|
|
659
|
+
if (!_optionalChain([this, 'access', _53 => _53.provider, 'optionalAccess', _54 => _54.on])) return;
|
|
660
|
+
if (this.accountsChangedCallback) {
|
|
661
|
+
_optionalChain([this, 'access', _55 => _55.provider, 'access', _56 => _56.removeListener, 'optionalCall', _57 => _57("accountsChanged", this.accountsChangedCallback)]);
|
|
662
|
+
}
|
|
663
|
+
this.accountsChangedCallback = callback;
|
|
664
|
+
this.provider.on("accountsChanged", this.accountsChangedCallback);
|
|
665
|
+
}
|
|
666
|
+
removeListeners() {
|
|
667
|
+
if (!_optionalChain([this, 'access', _58 => _58.provider, 'optionalAccess', _59 => _59.removeListener]) || !this.accountsChangedCallback) return;
|
|
668
|
+
this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
|
|
669
|
+
this.accountsChangedCallback = null;
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
// src/wallet-adapters/LedgerAdapter.ts
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
var _connectkitloader = require('@ledgerhq/connect-kit-loader');
|
|
677
|
+
var _chains = require('viem/chains');
|
|
678
|
+
var LedgerAdapter = class {
|
|
679
|
+
constructor(config) {
|
|
680
|
+
this.id = _types.WalletId.Ledger;
|
|
681
|
+
this.name = _types.WalletName.Ledger;
|
|
682
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.Ledger, "brand"), () => ( ""));
|
|
683
|
+
this.hide = false;
|
|
684
|
+
this.downloadUrl = "https://www.ledger.com/ledger-live";
|
|
685
|
+
this.wcDeepLinkUrl = "ledgerlive://wc?uri=";
|
|
686
|
+
this.provider = null;
|
|
687
|
+
this.accountsChangedCallback = null;
|
|
688
|
+
this.walletConnectProjectId = _optionalChain([config, 'optionalAccess', _60 => _60.walletConnectProjectId]);
|
|
689
|
+
}
|
|
690
|
+
isInstalled() {
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
async connect() {
|
|
694
|
+
try {
|
|
695
|
+
if (!this.walletConnectProjectId) {
|
|
696
|
+
throw _chunkDHEVW7CRjs.createConfigError.call(void 0, "Ledger");
|
|
697
|
+
}
|
|
698
|
+
const { loadConnectKit } = await Promise.resolve().then(() => _interopRequireWildcard(require("@ledgerhq/connect-kit-loader")));
|
|
699
|
+
const connectKit = await loadConnectKit();
|
|
700
|
+
connectKit.enableDebugLogs();
|
|
701
|
+
connectKit.checkSupport({
|
|
702
|
+
providerType: _connectkitloader.SupportedProviders.Ethereum,
|
|
703
|
+
chainId: 1,
|
|
704
|
+
walletConnectVersion: 2,
|
|
705
|
+
projectId: this.walletConnectProjectId,
|
|
706
|
+
rpc: { 1: _chains.mainnet.rpcUrls.default.http[0] }
|
|
707
|
+
});
|
|
708
|
+
this.provider = await connectKit.getProvider();
|
|
709
|
+
if (!this.provider) {
|
|
710
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Failed to get Ledger provider");
|
|
711
|
+
throw new Error("Failed to get Ledger provider");
|
|
712
|
+
}
|
|
713
|
+
const accounts = await this.provider.request({
|
|
714
|
+
method: "eth_requestAccounts",
|
|
715
|
+
params: []
|
|
716
|
+
});
|
|
717
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
718
|
+
_chunkDHEVW7CRjs.sentryLogger.error("No accounts returned from Ledger");
|
|
719
|
+
throw new Error("No accounts returned from Ledger");
|
|
720
|
+
}
|
|
721
|
+
return {
|
|
722
|
+
address: accounts[0],
|
|
723
|
+
provider: this.provider,
|
|
724
|
+
walletId: this.id
|
|
725
|
+
};
|
|
726
|
+
} catch (e7) {
|
|
727
|
+
throw new Error("Failed to connect to Ledger");
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
async tryRestoreConnection() {
|
|
731
|
+
try {
|
|
732
|
+
const { loadConnectKit } = await Promise.resolve().then(() => _interopRequireWildcard(require("@ledgerhq/connect-kit-loader")));
|
|
733
|
+
const connectKit = await loadConnectKit();
|
|
734
|
+
connectKit.checkSupport({
|
|
735
|
+
providerType: _connectkitloader.SupportedProviders.Ethereum,
|
|
736
|
+
chainId: 1,
|
|
737
|
+
walletConnectVersion: 2,
|
|
738
|
+
projectId: this.walletConnectProjectId,
|
|
739
|
+
rpc: { 1: _chains.mainnet.rpcUrls.default.http[0] }
|
|
740
|
+
});
|
|
741
|
+
this.provider = await connectKit.getProvider();
|
|
742
|
+
if (!this.provider) {
|
|
743
|
+
return null;
|
|
744
|
+
}
|
|
745
|
+
const accounts = await this.provider.request({
|
|
746
|
+
method: "eth_accounts",
|
|
747
|
+
params: []
|
|
748
|
+
});
|
|
749
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
750
|
+
return null;
|
|
751
|
+
}
|
|
752
|
+
return {
|
|
753
|
+
address: accounts[0],
|
|
754
|
+
provider: this.provider,
|
|
755
|
+
walletId: this.id
|
|
756
|
+
};
|
|
757
|
+
} catch (e8) {
|
|
758
|
+
return null;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
async disconnect() {
|
|
762
|
+
try {
|
|
763
|
+
const provider = this.provider;
|
|
764
|
+
if (_optionalChain([provider, 'optionalAccess', _61 => _61.disconnect])) {
|
|
765
|
+
await provider.disconnect();
|
|
766
|
+
}
|
|
767
|
+
this.provider = null;
|
|
768
|
+
} catch (error) {
|
|
769
|
+
_chunkDHEVW7CRjs.sentryLogger.warn("Failed to disconnect from Ledger", { error });
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
getProvider() {
|
|
773
|
+
return this.provider;
|
|
774
|
+
}
|
|
775
|
+
onAccountsChanged(callback) {
|
|
776
|
+
if (!_optionalChain([this, 'access', _62 => _62.provider, 'optionalAccess', _63 => _63.on])) return;
|
|
777
|
+
if (this.accountsChangedCallback) {
|
|
778
|
+
_optionalChain([this, 'access', _64 => _64.provider, 'access', _65 => _65.removeListener, 'optionalCall', _66 => _66("accountsChanged", this.accountsChangedCallback)]);
|
|
779
|
+
}
|
|
780
|
+
this.accountsChangedCallback = callback;
|
|
781
|
+
this.provider.on("accountsChanged", this.accountsChangedCallback);
|
|
782
|
+
}
|
|
783
|
+
removeListeners() {
|
|
784
|
+
if (!_optionalChain([this, 'access', _67 => _67.provider, 'optionalAccess', _68 => _68.removeListener]) || !this.accountsChangedCallback) return;
|
|
785
|
+
this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
|
|
786
|
+
this.accountsChangedCallback = null;
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
// src/wallet-adapters/PhantomAdapter.ts
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
var PHANTOM_RDNS = "app.phantom";
|
|
794
|
+
var PhantomAdapter = class {
|
|
795
|
+
constructor() {
|
|
796
|
+
this.id = _types.WalletId.Phantom;
|
|
797
|
+
this.name = _types.WalletName.Phantom;
|
|
798
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.Phantom, "brand"), () => ( ""));
|
|
799
|
+
this.hide = false;
|
|
800
|
+
this.downloadUrl = "https://phantom.com/download";
|
|
801
|
+
this.wcDeepLinkUrl = "phantom://wc?uri=";
|
|
802
|
+
this.provider = null;
|
|
803
|
+
this.accountsChangedCallback = null;
|
|
804
|
+
this.providerPromise = null;
|
|
805
|
+
this.providerPromise = this.discoverProvider();
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Uses EIP-6963 to discover the Phantom provider by its RDNS identifier.
|
|
809
|
+
* Falls back to window.phantom.ethereum for in-app browser support (Phantom Mobile).
|
|
810
|
+
* This prevents other wallets from hijacking the connection.
|
|
811
|
+
*/
|
|
812
|
+
discoverProvider() {
|
|
813
|
+
if (typeof window === "undefined") return Promise.resolve(null);
|
|
814
|
+
return new Promise((resolve) => {
|
|
815
|
+
let resolved = false;
|
|
816
|
+
const onAnnouncement = (event) => {
|
|
817
|
+
const { detail } = event;
|
|
818
|
+
if (detail.info.rdns === PHANTOM_RDNS) {
|
|
819
|
+
resolved = true;
|
|
820
|
+
this.provider = detail.provider;
|
|
821
|
+
window.removeEventListener("eip6963:announceProvider", onAnnouncement);
|
|
822
|
+
resolve(detail.provider);
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
window.addEventListener("eip6963:announceProvider", onAnnouncement);
|
|
826
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
827
|
+
setTimeout(() => {
|
|
828
|
+
if (!resolved) {
|
|
829
|
+
window.removeEventListener("eip6963:announceProvider", onAnnouncement);
|
|
830
|
+
const legacyProvider = this.detectLegacyProvider();
|
|
831
|
+
if (legacyProvider) {
|
|
832
|
+
this.provider = legacyProvider;
|
|
833
|
+
}
|
|
834
|
+
resolve(legacyProvider);
|
|
835
|
+
}
|
|
836
|
+
}, 100);
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Fallback detection for in-app browsers (Phantom Mobile) that don't support EIP-6963.
|
|
841
|
+
* Checks window.phantom.ethereum and window.ethereum for Phantom-specific flags.
|
|
842
|
+
*/
|
|
843
|
+
detectLegacyProvider() {
|
|
844
|
+
const phantom = window.phantom;
|
|
845
|
+
if (_optionalChain([phantom, 'optionalAccess', _69 => _69.ethereum, 'optionalAccess', _70 => _70.isPhantom])) {
|
|
846
|
+
return phantom.ethereum;
|
|
847
|
+
}
|
|
848
|
+
const ethereum = window.ethereum;
|
|
849
|
+
if (_optionalChain([ethereum, 'optionalAccess', _71 => _71.isPhantom])) {
|
|
850
|
+
return ethereum;
|
|
851
|
+
}
|
|
852
|
+
return null;
|
|
853
|
+
}
|
|
854
|
+
isInstalled() {
|
|
855
|
+
return Boolean(this.provider);
|
|
856
|
+
}
|
|
857
|
+
async connect() {
|
|
858
|
+
if (!this.provider && this.providerPromise) {
|
|
859
|
+
await this.providerPromise;
|
|
860
|
+
}
|
|
861
|
+
if (!this.provider) {
|
|
862
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Phantom is not available");
|
|
863
|
+
throw new Error("Phantom is not available");
|
|
864
|
+
}
|
|
865
|
+
try {
|
|
866
|
+
await this.provider.request({
|
|
867
|
+
method: "wallet_requestPermissions",
|
|
868
|
+
params: [{ eth_accounts: {} }]
|
|
869
|
+
});
|
|
870
|
+
const accounts = await this.provider.request({
|
|
871
|
+
method: "eth_requestAccounts",
|
|
872
|
+
params: []
|
|
873
|
+
});
|
|
874
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
875
|
+
_chunkDHEVW7CRjs.sentryLogger.error("No accounts returned from Phantom");
|
|
876
|
+
throw new Error("No accounts returned from Phantom");
|
|
877
|
+
}
|
|
878
|
+
return {
|
|
879
|
+
address: accounts[0],
|
|
880
|
+
provider: this.provider,
|
|
881
|
+
walletId: this.id
|
|
882
|
+
};
|
|
883
|
+
} catch (e9) {
|
|
884
|
+
throw new Error("Failed to connect to Phantom");
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
async tryRestoreConnection() {
|
|
888
|
+
if (!this.provider && this.providerPromise) {
|
|
889
|
+
await this.providerPromise;
|
|
890
|
+
}
|
|
891
|
+
if (!this.provider) {
|
|
892
|
+
return null;
|
|
893
|
+
}
|
|
894
|
+
try {
|
|
895
|
+
const accounts = await this.provider.request({
|
|
896
|
+
method: "eth_accounts",
|
|
897
|
+
params: []
|
|
898
|
+
});
|
|
899
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
900
|
+
return null;
|
|
901
|
+
}
|
|
902
|
+
return {
|
|
903
|
+
address: accounts[0],
|
|
904
|
+
provider: this.provider,
|
|
905
|
+
walletId: this.id
|
|
906
|
+
};
|
|
907
|
+
} catch (e10) {
|
|
908
|
+
return null;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
async disconnect() {
|
|
912
|
+
}
|
|
913
|
+
getProvider() {
|
|
914
|
+
return this.provider;
|
|
915
|
+
}
|
|
916
|
+
// Called by Aurum when user connects wallet
|
|
917
|
+
// Passes Aurum.ts --> syncStateFromAccountsChanged() to handle the provider accounts changed event
|
|
918
|
+
onAccountsChanged(callback) {
|
|
919
|
+
if (!_optionalChain([this, 'access', _72 => _72.provider, 'optionalAccess', _73 => _73.on])) return;
|
|
920
|
+
if (this.accountsChangedCallback) {
|
|
921
|
+
_optionalChain([this, 'access', _74 => _74.provider, 'access', _75 => _75.removeListener, 'optionalCall', _76 => _76("accountsChanged", this.accountsChangedCallback)]);
|
|
922
|
+
}
|
|
923
|
+
this.accountsChangedCallback = callback;
|
|
924
|
+
this.provider.on("accountsChanged", this.accountsChangedCallback);
|
|
925
|
+
}
|
|
926
|
+
removeListeners() {
|
|
927
|
+
if (!_optionalChain([this, 'access', _77 => _77.provider, 'optionalAccess', _78 => _78.removeListener]) || !this.accountsChangedCallback) return;
|
|
928
|
+
this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
|
|
929
|
+
this.accountsChangedCallback = null;
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
// src/wallet-adapters/CoinbaseWalletAdapter.ts
|
|
934
|
+
var _walletsdk = require('@coinbase/wallet-sdk');
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
var CoinbaseWalletAdapter = class {
|
|
938
|
+
constructor({ appName, appLogoUrl }) {
|
|
939
|
+
this.id = _types.WalletId.CoinbaseWallet;
|
|
940
|
+
this.name = _types.WalletName.CoinbaseWallet;
|
|
941
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.CoinbaseWallet, "brand"), () => ( ""));
|
|
942
|
+
this.hide = false;
|
|
943
|
+
this.downloadUrl = "https://www.coinbase.com/wallet/downloads";
|
|
944
|
+
this.wcDeepLinkUrl = "cbwallet://wc?uri=";
|
|
945
|
+
this.provider = null;
|
|
946
|
+
this.accountsChangedCallback = null;
|
|
947
|
+
this.provider = this.detectProvider({ appName, appLogoUrl });
|
|
948
|
+
}
|
|
949
|
+
detectProvider({ appName, appLogoUrl }) {
|
|
950
|
+
if (typeof window === "undefined") return null;
|
|
951
|
+
try {
|
|
952
|
+
const coinbaseSdk = _walletsdk.createCoinbaseWalletSDK.call(void 0, {
|
|
953
|
+
appName,
|
|
954
|
+
appLogoUrl
|
|
955
|
+
});
|
|
956
|
+
return coinbaseSdk.getProvider();
|
|
957
|
+
} catch (error) {
|
|
958
|
+
_chunkDHEVW7CRjs.sentryLogger.warn("Failed to initialize Coinbase Wallet provider", { error });
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
isInstalled() {
|
|
963
|
+
return Boolean(this.provider);
|
|
964
|
+
}
|
|
965
|
+
async connect() {
|
|
966
|
+
if (!this.isInstalled() || !this.provider) {
|
|
967
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Coinbase Wallet is not available");
|
|
968
|
+
throw new Error("Coinbase Wallet is not available");
|
|
969
|
+
}
|
|
970
|
+
try {
|
|
971
|
+
const accounts = await this.provider.request({
|
|
972
|
+
method: "eth_requestAccounts",
|
|
973
|
+
params: []
|
|
974
|
+
});
|
|
975
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
976
|
+
_chunkDHEVW7CRjs.sentryLogger.error("No accounts returned from Coinbase Wallet");
|
|
977
|
+
throw new Error("No accounts returned from Coinbase Wallet");
|
|
978
|
+
}
|
|
979
|
+
return {
|
|
980
|
+
address: accounts[0],
|
|
981
|
+
provider: this.provider,
|
|
982
|
+
walletId: this.id
|
|
983
|
+
};
|
|
984
|
+
} catch (e11) {
|
|
985
|
+
throw new Error("Failed to connect to Coinbase Wallet");
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
async tryRestoreConnection() {
|
|
989
|
+
if (!this.isInstalled() || !this.provider) {
|
|
990
|
+
return null;
|
|
991
|
+
}
|
|
992
|
+
try {
|
|
993
|
+
const accounts = await this.provider.request({
|
|
994
|
+
method: "eth_accounts",
|
|
995
|
+
params: []
|
|
996
|
+
});
|
|
997
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
998
|
+
return null;
|
|
999
|
+
}
|
|
1000
|
+
return {
|
|
1001
|
+
address: accounts[0],
|
|
1002
|
+
provider: this.provider,
|
|
1003
|
+
walletId: this.id
|
|
1004
|
+
};
|
|
1005
|
+
} catch (e12) {
|
|
1006
|
+
return null;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
async disconnect() {
|
|
1010
|
+
try {
|
|
1011
|
+
if (_optionalChain([this, 'access', _79 => _79.provider, 'optionalAccess', _80 => _80.close])) {
|
|
1012
|
+
await this.provider.close();
|
|
1013
|
+
} else if (_optionalChain([this, 'access', _81 => _81.provider, 'optionalAccess', _82 => _82.disconnect])) {
|
|
1014
|
+
await this.provider.disconnect();
|
|
1015
|
+
}
|
|
1016
|
+
} catch (error) {
|
|
1017
|
+
_chunkDHEVW7CRjs.sentryLogger.warn("Error disconnecting from Coinbase Wallet", { error });
|
|
1018
|
+
} finally {
|
|
1019
|
+
this.clearLocalStorage();
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
clearLocalStorage() {
|
|
1023
|
+
if (typeof window === "undefined" || !window.localStorage) return;
|
|
1024
|
+
const keysToRemove = [];
|
|
1025
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
1026
|
+
const key = localStorage.key(i);
|
|
1027
|
+
if (key && (key.startsWith("-walletlink") || key.startsWith("-CBWSDK") || key.startsWith("walletlink:") || key.startsWith("CBWSDK:"))) {
|
|
1028
|
+
keysToRemove.push(key);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
keysToRemove.forEach((key) => {
|
|
1032
|
+
localStorage.removeItem(key);
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
getProvider() {
|
|
1036
|
+
return this.provider;
|
|
1037
|
+
}
|
|
1038
|
+
// Called by Aurum when user connects wallet
|
|
1039
|
+
// Passes Aurum.ts --> syncStateFromAccountsChanged() to handle the provider accounts changed event
|
|
1040
|
+
onAccountsChanged(callback) {
|
|
1041
|
+
if (!_optionalChain([this, 'access', _83 => _83.provider, 'optionalAccess', _84 => _84.on])) return;
|
|
1042
|
+
if (this.accountsChangedCallback) {
|
|
1043
|
+
_optionalChain([this, 'access', _85 => _85.provider, 'access', _86 => _86.removeListener, 'optionalCall', _87 => _87("accountsChanged", this.accountsChangedCallback)]);
|
|
1044
|
+
}
|
|
1045
|
+
this.accountsChangedCallback = callback;
|
|
1046
|
+
this.provider.on("accountsChanged", this.accountsChangedCallback);
|
|
1047
|
+
}
|
|
1048
|
+
removeListeners() {
|
|
1049
|
+
if (!_optionalChain([this, 'access', _88 => _88.provider, 'optionalAccess', _89 => _89.removeListener]) || !this.accountsChangedCallback) return;
|
|
1050
|
+
this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
|
|
1051
|
+
this.accountsChangedCallback = null;
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
// src/wallet-adapters/MetaMaskAdapter.ts
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
var METAMASK_RDNS = "io.metamask";
|
|
1059
|
+
var MetaMaskAdapter = class {
|
|
1060
|
+
constructor() {
|
|
1061
|
+
this.id = _types.WalletId.MetaMask;
|
|
1062
|
+
this.name = _types.WalletName.MetaMask;
|
|
1063
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.MetaMask, "brand"), () => ( ""));
|
|
1064
|
+
this.hide = false;
|
|
1065
|
+
this.downloadUrl = "https://metamask.io/download";
|
|
1066
|
+
this.wcDeepLinkUrl = "metamask://wc?uri=";
|
|
1067
|
+
this.provider = null;
|
|
1068
|
+
this.accountsChangedCallback = null;
|
|
1069
|
+
this.providerPromise = null;
|
|
1070
|
+
this.providerPromise = this.discoverProvider();
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Uses EIP-6963 to discover the MetaMask provider by its RDNS identifier.
|
|
1074
|
+
* Falls back to window.ethereum for in-app browser support (MetaMask Mobile).
|
|
1075
|
+
* This prevents other wallets (like Rabby) from hijacking the connection.
|
|
1076
|
+
*/
|
|
1077
|
+
discoverProvider() {
|
|
1078
|
+
if (typeof window === "undefined") return Promise.resolve(null);
|
|
1079
|
+
return new Promise((resolve) => {
|
|
1080
|
+
let resolved = false;
|
|
1081
|
+
const onAnnouncement = (event) => {
|
|
1082
|
+
const { detail } = event;
|
|
1083
|
+
if (detail.info.rdns === METAMASK_RDNS) {
|
|
1084
|
+
resolved = true;
|
|
1085
|
+
this.provider = detail.provider;
|
|
1086
|
+
window.removeEventListener("eip6963:announceProvider", onAnnouncement);
|
|
1087
|
+
resolve(detail.provider);
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
window.addEventListener("eip6963:announceProvider", onAnnouncement);
|
|
1091
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
1092
|
+
setTimeout(() => {
|
|
1093
|
+
if (!resolved) {
|
|
1094
|
+
window.removeEventListener("eip6963:announceProvider", onAnnouncement);
|
|
1095
|
+
const legacyProvider = this.detectLegacyProvider();
|
|
1096
|
+
if (legacyProvider) {
|
|
1097
|
+
this.provider = legacyProvider;
|
|
1098
|
+
}
|
|
1099
|
+
resolve(legacyProvider);
|
|
1100
|
+
}
|
|
1101
|
+
}, 100);
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Fallback detection for in-app browsers (MetaMask Mobile) that don't support EIP-6963.
|
|
1106
|
+
* Checks window.ethereum for MetaMask-specific flags.
|
|
1107
|
+
*/
|
|
1108
|
+
detectLegacyProvider() {
|
|
1109
|
+
const ethereum = window.ethereum;
|
|
1110
|
+
if (!ethereum) return null;
|
|
1111
|
+
if (_optionalChain([ethereum, 'access', _90 => _90.providers, 'optionalAccess', _91 => _91.length])) {
|
|
1112
|
+
const metaMaskProvider = ethereum.providers.find((p) => p.isMetaMask && !p.isBraveWallet);
|
|
1113
|
+
if (metaMaskProvider) return metaMaskProvider;
|
|
1114
|
+
}
|
|
1115
|
+
if (ethereum.isMetaMask && !ethereum.isBraveWallet) {
|
|
1116
|
+
return ethereum;
|
|
1117
|
+
}
|
|
1118
|
+
return null;
|
|
1119
|
+
}
|
|
1120
|
+
isInstalled() {
|
|
1121
|
+
return Boolean(this.provider);
|
|
1122
|
+
}
|
|
1123
|
+
async connect() {
|
|
1124
|
+
if (!this.provider && this.providerPromise) {
|
|
1125
|
+
await this.providerPromise;
|
|
1126
|
+
}
|
|
1127
|
+
if (!this.provider) {
|
|
1128
|
+
_chunkDHEVW7CRjs.sentryLogger.error("MetaMask is not available");
|
|
1129
|
+
throw new Error("MetaMask is not available");
|
|
1130
|
+
}
|
|
1131
|
+
try {
|
|
1132
|
+
await this.provider.request({
|
|
1133
|
+
method: "wallet_requestPermissions",
|
|
1134
|
+
params: [{ eth_accounts: {} }]
|
|
1135
|
+
});
|
|
1136
|
+
const accounts = await this.provider.request({
|
|
1137
|
+
method: "eth_requestAccounts",
|
|
1138
|
+
params: []
|
|
1139
|
+
});
|
|
1140
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
1141
|
+
_chunkDHEVW7CRjs.sentryLogger.error("No accounts returned from MetaMask");
|
|
1142
|
+
throw new Error("No accounts returned from MetaMask");
|
|
1143
|
+
}
|
|
1144
|
+
return {
|
|
1145
|
+
address: accounts[0],
|
|
1146
|
+
provider: this.provider,
|
|
1147
|
+
walletId: this.id
|
|
1148
|
+
};
|
|
1149
|
+
} catch (e13) {
|
|
1150
|
+
throw new Error("Failed to connect to MetaMask");
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
async tryRestoreConnection() {
|
|
1154
|
+
if (!this.provider && this.providerPromise) {
|
|
1155
|
+
await this.providerPromise;
|
|
1156
|
+
}
|
|
1157
|
+
if (!this.provider) {
|
|
1158
|
+
return null;
|
|
1159
|
+
}
|
|
1160
|
+
try {
|
|
1161
|
+
const accounts = await this.provider.request({
|
|
1162
|
+
method: "eth_accounts",
|
|
1163
|
+
params: []
|
|
1164
|
+
});
|
|
1165
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
1166
|
+
return null;
|
|
1167
|
+
}
|
|
1168
|
+
return {
|
|
1169
|
+
address: accounts[0],
|
|
1170
|
+
provider: this.provider,
|
|
1171
|
+
walletId: this.id
|
|
1172
|
+
};
|
|
1173
|
+
} catch (e14) {
|
|
1174
|
+
return null;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
async disconnect() {
|
|
1178
|
+
}
|
|
1179
|
+
getProvider() {
|
|
1180
|
+
return this.provider;
|
|
1181
|
+
}
|
|
1182
|
+
// Called by Aurum when user connects wallet
|
|
1183
|
+
// Passes Aurum.ts --> syncStateFromAccountsChanged() to handle the provider accounts changed event
|
|
1184
|
+
onAccountsChanged(callback) {
|
|
1185
|
+
if (!_optionalChain([this, 'access', _92 => _92.provider, 'optionalAccess', _93 => _93.on])) return;
|
|
1186
|
+
if (this.accountsChangedCallback) {
|
|
1187
|
+
_optionalChain([this, 'access', _94 => _94.provider, 'access', _95 => _95.removeListener, 'optionalCall', _96 => _96("accountsChanged", this.accountsChangedCallback)]);
|
|
1188
|
+
}
|
|
1189
|
+
this.accountsChangedCallback = callback;
|
|
1190
|
+
this.provider.on("accountsChanged", this.accountsChangedCallback);
|
|
1191
|
+
}
|
|
1192
|
+
removeListeners() {
|
|
1193
|
+
if (!_optionalChain([this, 'access', _97 => _97.provider, 'optionalAccess', _98 => _98.removeListener]) || !this.accountsChangedCallback) return;
|
|
1194
|
+
this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
|
|
1195
|
+
this.accountsChangedCallback = null;
|
|
1196
|
+
}
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
// src/wallet-adapters/WalletConnectAdapter.ts
|
|
1200
|
+
|
|
1201
|
+
|
|
1202
|
+
var WalletConnectAdapter = class {
|
|
1203
|
+
constructor(config) {
|
|
1204
|
+
this.id = _types.WalletId.WalletConnect;
|
|
1205
|
+
this.name = _types.WalletName.WalletConnect;
|
|
1206
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.WalletConnect, "brand"), () => ( ""));
|
|
1207
|
+
this.hide = false;
|
|
1208
|
+
this.downloadUrl = null;
|
|
1209
|
+
this.wcDeepLinkUrl = null;
|
|
1210
|
+
this.provider = null;
|
|
1211
|
+
this.connectionUri = null;
|
|
1212
|
+
this.accountsChangedCallback = null;
|
|
1213
|
+
this.initPromise = null;
|
|
1214
|
+
this.config = {
|
|
1215
|
+
projectId: config.projectId,
|
|
1216
|
+
appName: config.appName
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
async ensureInitialized() {
|
|
1220
|
+
if (this.provider) return;
|
|
1221
|
+
if (!this.initPromise) {
|
|
1222
|
+
this.initPromise = this.initializeProvider();
|
|
1223
|
+
}
|
|
1224
|
+
await this.initPromise;
|
|
1225
|
+
}
|
|
1226
|
+
async initializeProvider() {
|
|
1227
|
+
if (typeof window === "undefined") return;
|
|
1228
|
+
const { EthereumProvider } = await Promise.resolve().then(() => _interopRequireWildcard(require("@walletconnect/ethereum-provider")));
|
|
1229
|
+
this.provider = await EthereumProvider.init({
|
|
1230
|
+
projectId: _nullishCoalesce(this.config.projectId, () => ( "")),
|
|
1231
|
+
optionalChains: [1],
|
|
1232
|
+
showQrModal: false,
|
|
1233
|
+
metadata: {
|
|
1234
|
+
name: this.config.appName,
|
|
1235
|
+
description: this.config.appName,
|
|
1236
|
+
url: window.location.origin,
|
|
1237
|
+
icons: []
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
this.provider.on("display_uri", (uri) => {
|
|
1241
|
+
this.connectionUri = uri;
|
|
1242
|
+
if (typeof window !== "undefined") {
|
|
1243
|
+
window.dispatchEvent(new CustomEvent("walletconnect:uri", { detail: { uri } }));
|
|
1244
|
+
}
|
|
1245
|
+
});
|
|
1246
|
+
this.provider.on("connect", (session) => {
|
|
1247
|
+
if (typeof window !== "undefined") {
|
|
1248
|
+
window.dispatchEvent(new CustomEvent("walletconnect:connect", { detail: { session } }));
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1251
|
+
this.provider.on("disconnect", () => {
|
|
1252
|
+
this.connectionUri = null;
|
|
1253
|
+
});
|
|
1254
|
+
this.provider.on("session_delete", () => {
|
|
1255
|
+
if (typeof window !== "undefined") {
|
|
1256
|
+
window.dispatchEvent(new CustomEvent("walletconnect:disconnect"));
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
isInstalled() {
|
|
1261
|
+
return true;
|
|
1262
|
+
}
|
|
1263
|
+
async connect() {
|
|
1264
|
+
if (!this.config.projectId) {
|
|
1265
|
+
throw _chunkDHEVW7CRjs.createConfigError.call(void 0, "WalletConnect");
|
|
1266
|
+
}
|
|
1267
|
+
try {
|
|
1268
|
+
await this.ensureInitialized();
|
|
1269
|
+
if (!this.provider) {
|
|
1270
|
+
_chunkDHEVW7CRjs.sentryLogger.error("connect: WalletConnect is not available");
|
|
1271
|
+
throw new Error("WalletConnect is not available");
|
|
1272
|
+
}
|
|
1273
|
+
const accounts = await this.provider.enable();
|
|
1274
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
1275
|
+
_chunkDHEVW7CRjs.sentryLogger.error("connect: No accounts returned from WalletConnect");
|
|
1276
|
+
throw new Error("No accounts returned from WalletConnect");
|
|
1277
|
+
}
|
|
1278
|
+
return {
|
|
1279
|
+
address: accounts[0],
|
|
1280
|
+
provider: this.provider,
|
|
1281
|
+
walletId: this.id
|
|
1282
|
+
};
|
|
1283
|
+
} catch (e15) {
|
|
1284
|
+
this.connectionUri = null;
|
|
1285
|
+
throw new Error("Failed to connect to WalletConnect");
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
getConnectionUri() {
|
|
1289
|
+
return this.connectionUri;
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Starts a WalletConnect session for headless/custom QR code flows.
|
|
1293
|
+
* Returns the URI immediately and a function to wait for the connection.
|
|
1294
|
+
*/
|
|
1295
|
+
async startSession(timeout = 1e4) {
|
|
1296
|
+
if (!this.config.projectId) {
|
|
1297
|
+
throw new Error("WalletConnect projectId is required");
|
|
1298
|
+
}
|
|
1299
|
+
await this.ensureInitialized();
|
|
1300
|
+
if (!this.provider) {
|
|
1301
|
+
_chunkDHEVW7CRjs.sentryLogger.error("startSession: WalletConnect is not available");
|
|
1302
|
+
throw new Error("WalletConnect is not available");
|
|
1303
|
+
}
|
|
1304
|
+
this.connectionUri = null;
|
|
1305
|
+
const uriPromise = new Promise((resolve, reject) => {
|
|
1306
|
+
const timeoutId = setTimeout(() => {
|
|
1307
|
+
reject(new Error("Timeout waiting for WalletConnect URI"));
|
|
1308
|
+
}, timeout);
|
|
1309
|
+
this.provider.once("display_uri", (uri2) => {
|
|
1310
|
+
clearTimeout(timeoutId);
|
|
1311
|
+
this.connectionUri = uri2;
|
|
1312
|
+
resolve(uri2);
|
|
1313
|
+
});
|
|
1314
|
+
});
|
|
1315
|
+
const connectionPromise = (async () => {
|
|
1316
|
+
const accounts = await this.provider.enable();
|
|
1317
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
1318
|
+
_chunkDHEVW7CRjs.sentryLogger.error("startSession: No accounts returned from WalletConnect");
|
|
1319
|
+
throw new Error("No accounts returned from WalletConnect");
|
|
1320
|
+
}
|
|
1321
|
+
return {
|
|
1322
|
+
address: accounts[0],
|
|
1323
|
+
provider: this.provider,
|
|
1324
|
+
walletId: this.id
|
|
1325
|
+
};
|
|
1326
|
+
})();
|
|
1327
|
+
const uri = await uriPromise;
|
|
1328
|
+
return {
|
|
1329
|
+
uri,
|
|
1330
|
+
waitForConnection: async () => {
|
|
1331
|
+
try {
|
|
1332
|
+
return await connectionPromise;
|
|
1333
|
+
} catch (e16) {
|
|
1334
|
+
this.connectionUri = null;
|
|
1335
|
+
throw new Error("Failed to connect via WalletConnect");
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
async tryRestoreConnection() {
|
|
1341
|
+
try {
|
|
1342
|
+
await this.ensureInitialized();
|
|
1343
|
+
if (!this.provider) {
|
|
1344
|
+
return null;
|
|
1345
|
+
}
|
|
1346
|
+
const accounts = this.provider.accounts;
|
|
1347
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
1348
|
+
return null;
|
|
1349
|
+
}
|
|
1350
|
+
return {
|
|
1351
|
+
address: accounts[0],
|
|
1352
|
+
provider: this.provider,
|
|
1353
|
+
walletId: this.id
|
|
1354
|
+
};
|
|
1355
|
+
} catch (e17) {
|
|
1356
|
+
return null;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
async disconnect() {
|
|
1360
|
+
try {
|
|
1361
|
+
if (this.provider) {
|
|
1362
|
+
await this.provider.disconnect();
|
|
1363
|
+
}
|
|
1364
|
+
} finally {
|
|
1365
|
+
this.connectionUri = null;
|
|
1366
|
+
this.provider = null;
|
|
1367
|
+
this.initPromise = null;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
getProvider() {
|
|
1371
|
+
return this.provider;
|
|
1372
|
+
}
|
|
1373
|
+
// Called by Aurum when user connects wallet
|
|
1374
|
+
// Passes Aurum.ts --> syncStateFromAccountsChanged() to handle the provider accounts changed event
|
|
1375
|
+
onAccountsChanged(callback) {
|
|
1376
|
+
if (!_optionalChain([this, 'access', _99 => _99.provider, 'optionalAccess', _100 => _100.on])) return;
|
|
1377
|
+
if (this.accountsChangedCallback) {
|
|
1378
|
+
_optionalChain([this, 'access', _101 => _101.provider, 'access', _102 => _102.removeListener, 'optionalCall', _103 => _103("accountsChanged", this.accountsChangedCallback)]);
|
|
1379
|
+
}
|
|
1380
|
+
this.accountsChangedCallback = callback;
|
|
1381
|
+
this.provider.on("accountsChanged", this.accountsChangedCallback);
|
|
1382
|
+
}
|
|
1383
|
+
removeListeners() {
|
|
1384
|
+
if (!_optionalChain([this, 'access', _104 => _104.provider, 'optionalAccess', _105 => _105.removeListener]) || !this.accountsChangedCallback) return;
|
|
1385
|
+
this.provider.removeListener("accountsChanged", this.accountsChangedCallback);
|
|
1386
|
+
this.accountsChangedCallback = null;
|
|
1387
|
+
}
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1390
|
+
// src/wallet-adapters/EmailAdapter.ts
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
var _EmailAdapter = class _EmailAdapter {
|
|
1394
|
+
constructor(config) {
|
|
1395
|
+
this.id = _types.WalletId.Email;
|
|
1396
|
+
this.name = _types.WalletName.Email;
|
|
1397
|
+
this.icon = _nullishCoalesce(_logos.getLogoDataUri.call(void 0, _types.WalletId.Email, "brand"), () => ( ""));
|
|
1398
|
+
this.hide = true;
|
|
1399
|
+
this.downloadUrl = null;
|
|
1400
|
+
this.wcDeepLinkUrl = null;
|
|
1401
|
+
this.provider = null;
|
|
1402
|
+
this.initPromise = null;
|
|
1403
|
+
this.publicClientCache = /* @__PURE__ */ new Map();
|
|
1404
|
+
this.projectId = _optionalChain([config, 'optionalAccess', _106 => _106.projectId]) || "";
|
|
1405
|
+
}
|
|
1406
|
+
async ensureInitialized() {
|
|
1407
|
+
if (this.provider) return;
|
|
1408
|
+
if (!this.initPromise) {
|
|
1409
|
+
this.initPromise = this.initializeProvider();
|
|
1410
|
+
}
|
|
1411
|
+
await this.initPromise;
|
|
1412
|
+
}
|
|
1413
|
+
isInstalled() {
|
|
1414
|
+
return true;
|
|
1415
|
+
}
|
|
1416
|
+
async emailAuthStart(email) {
|
|
1417
|
+
if (!this.projectId) {
|
|
1418
|
+
throw _chunkDHEVW7CRjs.createConfigError.call(void 0, "Email");
|
|
1419
|
+
}
|
|
1420
|
+
await this.ensureInitialized();
|
|
1421
|
+
if (!this.provider) {
|
|
1422
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Email is not available");
|
|
1423
|
+
throw new Error("Email is not available");
|
|
1424
|
+
}
|
|
1425
|
+
try {
|
|
1426
|
+
const { signInWithEmail } = await Promise.resolve().then(() => _interopRequireWildcard(require("@coinbase/cdp-core")));
|
|
1427
|
+
const authResult = await signInWithEmail({ email });
|
|
1428
|
+
return authResult;
|
|
1429
|
+
} catch (error) {
|
|
1430
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Failed to start email authentication", { error });
|
|
1431
|
+
throw error;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
async emailAuthVerify(flowId, otp) {
|
|
1435
|
+
if (!flowId || !otp) {
|
|
1436
|
+
throw new Error("flowId and otp are required");
|
|
1437
|
+
}
|
|
1438
|
+
await this.ensureInitialized();
|
|
1439
|
+
if (!this.provider) {
|
|
1440
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Email provider not initialized");
|
|
1441
|
+
throw new Error("Email provider not initialized");
|
|
1442
|
+
}
|
|
1443
|
+
const { verifyEmailOTP } = await Promise.resolve().then(() => _interopRequireWildcard(require("@coinbase/cdp-core")));
|
|
1444
|
+
return verifyEmailOTP({ flowId, otp });
|
|
1445
|
+
}
|
|
1446
|
+
async connect() {
|
|
1447
|
+
_chunkDHEVW7CRjs.sentryLogger.error("EmailAdapter.connect() is not implemented");
|
|
1448
|
+
throw new Error("EmailAdapter.connect() is not implemented");
|
|
1449
|
+
}
|
|
1450
|
+
async tryRestoreConnection() {
|
|
1451
|
+
await this.ensureInitialized();
|
|
1452
|
+
if (!this.provider) {
|
|
1453
|
+
return null;
|
|
1454
|
+
}
|
|
1455
|
+
try {
|
|
1456
|
+
const accounts = await this.provider.request({
|
|
1457
|
+
method: "eth_accounts",
|
|
1458
|
+
params: []
|
|
1459
|
+
});
|
|
1460
|
+
if (!accounts || accounts.length === 0 || !accounts[0]) {
|
|
1461
|
+
return null;
|
|
1462
|
+
}
|
|
1463
|
+
return {
|
|
1464
|
+
address: accounts[0],
|
|
1465
|
+
provider: this.provider,
|
|
1466
|
+
walletId: this.id
|
|
1467
|
+
};
|
|
1468
|
+
} catch (e18) {
|
|
1469
|
+
return null;
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
async disconnect() {
|
|
1473
|
+
try {
|
|
1474
|
+
await this.ensureInitialized();
|
|
1475
|
+
const { signOut } = await Promise.resolve().then(() => _interopRequireWildcard(require("@coinbase/cdp-core")));
|
|
1476
|
+
await signOut();
|
|
1477
|
+
} catch (e19) {
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
getProvider() {
|
|
1481
|
+
return this.provider;
|
|
1482
|
+
}
|
|
1483
|
+
static async initializeChainData() {
|
|
1484
|
+
if (this.chainIdMap !== null) return;
|
|
1485
|
+
const [allChains, { http }] = await Promise.all([Promise.resolve().then(() => _interopRequireWildcard(require("viem/chains"))), Promise.resolve().then(() => _interopRequireWildcard(require("viem")))]);
|
|
1486
|
+
const chains = Object.values(allChains).filter(
|
|
1487
|
+
(chain) => typeof chain === "object" && chain !== null && "id" in chain
|
|
1488
|
+
);
|
|
1489
|
+
this.chainIdMap = new Map(chains.map((chain) => [chain.id, chain]));
|
|
1490
|
+
this.viemChains = chains;
|
|
1491
|
+
this.viemTransports = chains.reduce(
|
|
1492
|
+
(acc, chain) => {
|
|
1493
|
+
acc[chain.id] = http();
|
|
1494
|
+
return acc;
|
|
1495
|
+
},
|
|
1496
|
+
{}
|
|
1497
|
+
);
|
|
1498
|
+
}
|
|
1499
|
+
async getPublicClientForChain(chainId) {
|
|
1500
|
+
if (this.publicClientCache.has(chainId)) {
|
|
1501
|
+
return this.publicClientCache.get(chainId);
|
|
1502
|
+
}
|
|
1503
|
+
await _EmailAdapter.initializeChainData();
|
|
1504
|
+
const viemChain = _EmailAdapter.chainIdMap.get(chainId);
|
|
1505
|
+
if (!viemChain) {
|
|
1506
|
+
throw new Error(`Chain ${chainId} not supported`);
|
|
1507
|
+
}
|
|
1508
|
+
const { createPublicClient, http } = await Promise.resolve().then(() => _interopRequireWildcard(require("viem")));
|
|
1509
|
+
const publicClient = createPublicClient({
|
|
1510
|
+
chain: viemChain,
|
|
1511
|
+
transport: http()
|
|
1512
|
+
});
|
|
1513
|
+
this.publicClientCache.set(chainId, publicClient);
|
|
1514
|
+
return publicClient;
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Initializes CDP and creates the provider.
|
|
1518
|
+
* Called by ensureInitialized() - deduplication handled via initPromise.
|
|
1519
|
+
*/
|
|
1520
|
+
async initializeProvider() {
|
|
1521
|
+
const { initialize } = await Promise.resolve().then(() => _interopRequireWildcard(require("@coinbase/cdp-core")));
|
|
1522
|
+
await initialize({
|
|
1523
|
+
projectId: this.projectId,
|
|
1524
|
+
ethereum: {
|
|
1525
|
+
createOnLogin: "eoa"
|
|
1526
|
+
}
|
|
1527
|
+
});
|
|
1528
|
+
this.provider = await this.createProvider();
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Special case:
|
|
1532
|
+
* Coinbase default provider does not support generic read methods like eth_getBalance.
|
|
1533
|
+
* Wraps the provider to send unsupported methods to a public RPC endpoint.
|
|
1534
|
+
*/
|
|
1535
|
+
async createProvider() {
|
|
1536
|
+
try {
|
|
1537
|
+
await _EmailAdapter.initializeChainData();
|
|
1538
|
+
const { createCDPEmbeddedWallet } = await Promise.resolve().then(() => _interopRequireWildcard(require("@coinbase/cdp-core")));
|
|
1539
|
+
const wallet = createCDPEmbeddedWallet({
|
|
1540
|
+
chains: _EmailAdapter.viemChains,
|
|
1541
|
+
transports: _EmailAdapter.viemTransports
|
|
1542
|
+
});
|
|
1543
|
+
const base = wallet.provider;
|
|
1544
|
+
const getPublicClient = this.getPublicClientForChain.bind(this);
|
|
1545
|
+
const wrapped = {
|
|
1546
|
+
...base,
|
|
1547
|
+
async request(args) {
|
|
1548
|
+
try {
|
|
1549
|
+
return await base.request(args);
|
|
1550
|
+
} catch (err) {
|
|
1551
|
+
const msg = String(_optionalChain([err, 'optionalAccess', _107 => _107.message]) || "");
|
|
1552
|
+
const isUnsupported = msg.includes("not supported") || msg.includes("Unsupported") || _optionalChain([err, 'optionalAccess', _108 => _108.code]) === -32601;
|
|
1553
|
+
if (isUnsupported) {
|
|
1554
|
+
let chainId;
|
|
1555
|
+
try {
|
|
1556
|
+
const chainIdHex = await base.request({ method: "eth_chainId", params: [] });
|
|
1557
|
+
chainId = parseInt(chainIdHex, 16);
|
|
1558
|
+
} catch (e20) {
|
|
1559
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Failed to get chainId for fallback request");
|
|
1560
|
+
throw new Error("Failed to get chainId for fallback request");
|
|
1561
|
+
}
|
|
1562
|
+
const publicClient = await getPublicClient(chainId);
|
|
1563
|
+
return await publicClient.transport.request({
|
|
1564
|
+
method: args.method,
|
|
1565
|
+
params: Array.isArray(args.params) ? args.params : args.params ? [args.params] : void 0
|
|
1566
|
+
});
|
|
1567
|
+
}
|
|
1568
|
+
throw err;
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
};
|
|
1572
|
+
return wrapped;
|
|
1573
|
+
} catch (error) {
|
|
1574
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Failed to initialize Email provider", { error });
|
|
1575
|
+
return null;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
// Email wallets don't support account switching - user must re-authenticate to change accounts
|
|
1579
|
+
onAccountsChanged() {
|
|
1580
|
+
}
|
|
1581
|
+
removeListeners() {
|
|
1582
|
+
}
|
|
1583
|
+
};
|
|
1584
|
+
// Static variables - computed once across all instances
|
|
1585
|
+
_EmailAdapter.chainIdMap = null;
|
|
1586
|
+
_EmailAdapter.viemChains = null;
|
|
1587
|
+
_EmailAdapter.viemTransports = null;
|
|
1588
|
+
var EmailAdapter = _EmailAdapter;
|
|
1589
|
+
|
|
1590
|
+
// src/utils/createWalletAdapters.ts
|
|
1591
|
+
function createWalletAdapters({
|
|
1592
|
+
walletsConfig,
|
|
1593
|
+
appName,
|
|
1594
|
+
appLogoUrl,
|
|
1595
|
+
modalZIndex,
|
|
1596
|
+
theme
|
|
1597
|
+
}) {
|
|
1598
|
+
return [
|
|
1599
|
+
new EmailAdapter({ projectId: _optionalChain([walletsConfig, 'optionalAccess', _109 => _109.email, 'optionalAccess', _110 => _110.projectId]) }),
|
|
1600
|
+
new MetaMaskAdapter(),
|
|
1601
|
+
new WalletConnectAdapter({ projectId: _optionalChain([walletsConfig, 'optionalAccess', _111 => _111.walletConnect, 'optionalAccess', _112 => _112.projectId]), appName }),
|
|
1602
|
+
new CoinbaseWalletAdapter({ appName, appLogoUrl }),
|
|
1603
|
+
new PhantomAdapter(),
|
|
1604
|
+
new RabbyAdapter(),
|
|
1605
|
+
new BraveAdapter(),
|
|
1606
|
+
new LedgerAdapter({ walletConnectProjectId: _optionalChain([walletsConfig, 'optionalAccess', _113 => _113.walletConnect, 'optionalAccess', _114 => _114.projectId]) }),
|
|
1607
|
+
new AppKitAdapter({ projectId: _optionalChain([walletsConfig, 'optionalAccess', _115 => _115.walletConnect, 'optionalAccess', _116 => _116.projectId]), appName, modalZIndex, theme })
|
|
1608
|
+
];
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
// src/AurumCore.ts
|
|
1612
|
+
|
|
1613
|
+
|
|
1614
|
+
// src/providers/RpcProvider.ts
|
|
1615
|
+
var RpcProvider = class {
|
|
1616
|
+
constructor(handleConnect) {
|
|
1617
|
+
this.isConnected = false;
|
|
1618
|
+
this.chainId = "0x1";
|
|
1619
|
+
this.networkVersion = "1";
|
|
1620
|
+
this.selectedAddress = null;
|
|
1621
|
+
this.handleConnect = handleConnect;
|
|
1622
|
+
}
|
|
1623
|
+
async request(args) {
|
|
1624
|
+
const { method } = args;
|
|
1625
|
+
switch (method) {
|
|
1626
|
+
// Account methods - return empty when not connected
|
|
1627
|
+
case "eth_accounts":
|
|
1628
|
+
return [];
|
|
1629
|
+
// Trigger connection flow
|
|
1630
|
+
case "enable":
|
|
1631
|
+
case "eth_requestAccounts":
|
|
1632
|
+
if (this.handleConnect) {
|
|
1633
|
+
const address = await this.handleConnect();
|
|
1634
|
+
return [address];
|
|
1635
|
+
} else {
|
|
1636
|
+
throw new Error("No wallet connection available. Please use aurum.connect() instead.");
|
|
1637
|
+
}
|
|
1638
|
+
// Chain/network information
|
|
1639
|
+
case "eth_chainId":
|
|
1640
|
+
return this.chainId;
|
|
1641
|
+
case "net_version":
|
|
1642
|
+
return this.networkVersion;
|
|
1643
|
+
// Default case for rest of methods
|
|
1644
|
+
default:
|
|
1645
|
+
throw new Error(
|
|
1646
|
+
`Method ${method} requires an active connection to a JSON-RPC provider. Please connect a wallet.`
|
|
1647
|
+
);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
// No-op: disconnected provider doesn't emit events
|
|
1651
|
+
on() {
|
|
1652
|
+
}
|
|
1653
|
+
// No-op: disconnected provider doesn't manage listeners
|
|
1654
|
+
removeListener() {
|
|
1655
|
+
}
|
|
1656
|
+
// No listeners to notify in disconnected state
|
|
1657
|
+
emit() {
|
|
1658
|
+
return false;
|
|
1659
|
+
}
|
|
1660
|
+
};
|
|
1661
|
+
|
|
1662
|
+
// src/AurumCore.ts
|
|
1663
|
+
var _AurumCore = class _AurumCore {
|
|
1664
|
+
constructor(config) {
|
|
1665
|
+
// `true` once we have restored the connection state
|
|
1666
|
+
this.ready = false;
|
|
1667
|
+
this.userInfo = void 0;
|
|
1668
|
+
this.connectedWalletAdapter = null;
|
|
1669
|
+
this.eventListeners = /* @__PURE__ */ new Map();
|
|
1670
|
+
if (_AurumCore.instance) {
|
|
1671
|
+
return _AurumCore.instance;
|
|
1672
|
+
}
|
|
1673
|
+
const telemetryEnabled = config.telemetry !== false;
|
|
1674
|
+
_chunkDHEVW7CRjs.initSentry.call(void 0, telemetryEnabled);
|
|
1675
|
+
this.brandConfig = this.resolveBrandConfig(config);
|
|
1676
|
+
this.excludedWallets = new Set(_nullishCoalesce(_optionalChain([config, 'access', _117 => _117.wallets, 'optionalAccess', _118 => _118.exclude]), () => ( [])));
|
|
1677
|
+
this.wallets = createWalletAdapters({
|
|
1678
|
+
walletsConfig: config.wallets,
|
|
1679
|
+
appName: this.brandConfig.appName,
|
|
1680
|
+
appLogoUrl: this.brandConfig.logo,
|
|
1681
|
+
modalZIndex: this.brandConfig.modalZIndex,
|
|
1682
|
+
theme: this.brandConfig.theme
|
|
1683
|
+
});
|
|
1684
|
+
this.skeletonProvider = new RpcProvider(() => this.connect());
|
|
1685
|
+
this.currentProvider = this.skeletonProvider;
|
|
1686
|
+
this.rpcProvider = this.createProviderProxy();
|
|
1687
|
+
this.readyPromise = this.tryRestoreConnection();
|
|
1688
|
+
_AurumCore.instance = this;
|
|
1689
|
+
}
|
|
1690
|
+
async whenReady() {
|
|
1691
|
+
try {
|
|
1692
|
+
await this.readyPromise;
|
|
1693
|
+
} catch (e21) {
|
|
1694
|
+
this.resetConnectionState();
|
|
1695
|
+
this.ready = true;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
get resolvedBrandConfig() {
|
|
1699
|
+
return this.brandConfig;
|
|
1700
|
+
}
|
|
1701
|
+
get walletAdapters() {
|
|
1702
|
+
return this.wallets;
|
|
1703
|
+
}
|
|
1704
|
+
get excludedWalletIds() {
|
|
1705
|
+
return this.excludedWallets;
|
|
1706
|
+
}
|
|
1707
|
+
async connect(walletId) {
|
|
1708
|
+
await this.whenReady();
|
|
1709
|
+
if (walletId === "email") {
|
|
1710
|
+
throw new Error("Use emailAuthStart() and emailAuthVerify() for email wallet connections");
|
|
1711
|
+
}
|
|
1712
|
+
if (walletId === "walletconnect") {
|
|
1713
|
+
throw new Error("Use getWalletConnectSession() for WalletConnect connections");
|
|
1714
|
+
}
|
|
1715
|
+
if (_optionalChain([this, 'access', _119 => _119.userInfo, 'optionalAccess', _120 => _120.publicAddress]) && _optionalChain([this, 'access', _121 => _121.connectedWalletAdapter, 'optionalAccess', _122 => _122.getProvider, 'call', _123 => _123()])) {
|
|
1716
|
+
if (!walletId || this.userInfo.walletId === walletId) {
|
|
1717
|
+
return this.userInfo.publicAddress;
|
|
1718
|
+
}
|
|
1719
|
+
await this.disconnect();
|
|
1720
|
+
}
|
|
1721
|
+
let adapter = null;
|
|
1722
|
+
let result;
|
|
1723
|
+
if (walletId) {
|
|
1724
|
+
if (this.excludedWallets.has(walletId)) {
|
|
1725
|
+
throw new Error(`${walletId} is excluded from wallet options`);
|
|
1726
|
+
}
|
|
1727
|
+
adapter = this.wallets.find((w) => w.id === walletId) || null;
|
|
1728
|
+
if (!adapter) {
|
|
1729
|
+
throw new Error(`${walletId} is not configured`);
|
|
1730
|
+
}
|
|
1731
|
+
if (!adapter.isInstalled()) {
|
|
1732
|
+
throw new Error(`${adapter.name} is not installed`);
|
|
1733
|
+
}
|
|
1734
|
+
result = await adapter.connect();
|
|
1735
|
+
} else {
|
|
1736
|
+
const displayedWallets = this.wallets.filter((w) => !this.excludedWallets.has(w.id));
|
|
1737
|
+
const modalResult = await renderConnectModal({ displayedWallets, brandConfig: this.brandConfig });
|
|
1738
|
+
if (!modalResult) {
|
|
1739
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Missing modal result");
|
|
1740
|
+
throw new Error("Missing modal result");
|
|
1741
|
+
}
|
|
1742
|
+
adapter = this.wallets.find((w) => w.id === modalResult.walletId) || null;
|
|
1743
|
+
if (!adapter) {
|
|
1744
|
+
_chunkDHEVW7CRjs.sentryLogger.error(`Selected wallet adapter not found: ${modalResult.walletId}`);
|
|
1745
|
+
throw new Error("Selected wallet adapter not found");
|
|
1746
|
+
}
|
|
1747
|
+
result = modalResult;
|
|
1748
|
+
}
|
|
1749
|
+
const provider = _nullishCoalesce(result.provider, () => ( adapter.getProvider()));
|
|
1750
|
+
if (!provider) {
|
|
1751
|
+
_chunkDHEVW7CRjs.sentryLogger.error(`Error fetching provider on login: ${adapter.id}`);
|
|
1752
|
+
throw new Error("Error fetching provider. Please try again.");
|
|
1753
|
+
}
|
|
1754
|
+
const checksumAdr = _viem.checksumAddress.call(void 0, result.address);
|
|
1755
|
+
this.connectedWalletAdapter = adapter;
|
|
1756
|
+
this.updateProvider(provider);
|
|
1757
|
+
this.userInfo = {
|
|
1758
|
+
publicAddress: checksumAdr,
|
|
1759
|
+
walletName: adapter.name,
|
|
1760
|
+
walletId: adapter.id,
|
|
1761
|
+
email: result.email
|
|
1762
|
+
};
|
|
1763
|
+
this.persistConnectionState(adapter, checksumAdr, result.email);
|
|
1764
|
+
this.setInternalAccountChangeListener(adapter);
|
|
1765
|
+
const chainId = await provider.request({ method: "eth_chainId" });
|
|
1766
|
+
this.emitConnect(chainId);
|
|
1767
|
+
this.emitAccountsChanged([checksumAdr]);
|
|
1768
|
+
_chunkDHEVW7CRjs.sentryLogger.info(`Wallet connected: ${adapter.id} (${walletId ? "headless" : "modal"})`);
|
|
1769
|
+
return checksumAdr;
|
|
1770
|
+
}
|
|
1771
|
+
async disconnect() {
|
|
1772
|
+
await this.whenReady();
|
|
1773
|
+
if (this.connectedWalletAdapter) {
|
|
1774
|
+
this.connectedWalletAdapter.removeListeners();
|
|
1775
|
+
await this.connectedWalletAdapter.disconnect();
|
|
1776
|
+
}
|
|
1777
|
+
this.resetConnectionState();
|
|
1778
|
+
this.emitDisconnect();
|
|
1779
|
+
this.emitAccountsChanged([]);
|
|
1780
|
+
}
|
|
1781
|
+
async getUserInfo() {
|
|
1782
|
+
await this.whenReady();
|
|
1783
|
+
return this.userInfo;
|
|
1784
|
+
}
|
|
1785
|
+
async isConnected() {
|
|
1786
|
+
await this.whenReady();
|
|
1787
|
+
return Boolean(
|
|
1788
|
+
_optionalChain([this, 'access', _124 => _124.userInfo, 'optionalAccess', _125 => _125.publicAddress]) && _optionalChain([this, 'access', _126 => _126.userInfo, 'optionalAccess', _127 => _127.walletName]) && _optionalChain([this, 'access', _128 => _128.connectedWalletAdapter, 'optionalAccess', _129 => _129.getProvider, 'call', _130 => _130()])
|
|
1789
|
+
);
|
|
1790
|
+
}
|
|
1791
|
+
async handleWidgetConnection(result) {
|
|
1792
|
+
await this.whenReady();
|
|
1793
|
+
const adapter = this.wallets.find((w) => w.id === result.walletId) || null;
|
|
1794
|
+
if (!adapter) throw new Error("Selected wallet adapter not found");
|
|
1795
|
+
const provider = _nullishCoalesce(result.provider, () => ( adapter.getProvider()));
|
|
1796
|
+
if (!provider) {
|
|
1797
|
+
_chunkDHEVW7CRjs.sentryLogger.error(`Error fetching provider on widget login: ${_optionalChain([result, 'optionalAccess', _131 => _131.walletId])}`);
|
|
1798
|
+
throw new Error("Error fetching provider. Please try again.");
|
|
1799
|
+
}
|
|
1800
|
+
const checksumAdr = _viem.checksumAddress.call(void 0, result.address);
|
|
1801
|
+
this.connectedWalletAdapter = adapter;
|
|
1802
|
+
this.updateProvider(provider);
|
|
1803
|
+
this.userInfo = {
|
|
1804
|
+
publicAddress: checksumAdr,
|
|
1805
|
+
walletName: adapter.name,
|
|
1806
|
+
walletId: adapter.id,
|
|
1807
|
+
email: result.email
|
|
1808
|
+
};
|
|
1809
|
+
this.persistConnectionState(adapter, checksumAdr, result.email);
|
|
1810
|
+
this.setInternalAccountChangeListener(adapter);
|
|
1811
|
+
const chainId = await provider.request({ method: "eth_chainId" });
|
|
1812
|
+
this.emitConnect(chainId);
|
|
1813
|
+
this.emitAccountsChanged([checksumAdr]);
|
|
1814
|
+
_chunkDHEVW7CRjs.sentryLogger.info(`Wallet connected: ${adapter.id} (widget)`);
|
|
1815
|
+
}
|
|
1816
|
+
async getChainId() {
|
|
1817
|
+
await this.whenReady();
|
|
1818
|
+
const chainId = await this.rpcProvider.request({ method: "eth_chainId" });
|
|
1819
|
+
return Number(chainId);
|
|
1820
|
+
}
|
|
1821
|
+
async switchChain(chainId, chain) {
|
|
1822
|
+
await this.whenReady();
|
|
1823
|
+
const hexChainId = normalizeChainId(chainId);
|
|
1824
|
+
try {
|
|
1825
|
+
await this.attemptSwitchChain(hexChainId);
|
|
1826
|
+
} catch (switchError) {
|
|
1827
|
+
if (!isChainNotAddedError(switchError) || !chain) throw switchError;
|
|
1828
|
+
await this.handleMissingChain(hexChainId, chain);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
updateBrandConfig(newConfig) {
|
|
1832
|
+
const defaultTheme = _chunkDHEVW7CRjs.getDefaultThemeConfig.call(void 0, _nullishCoalesce(newConfig.theme, () => ( this.brandConfig.theme)));
|
|
1833
|
+
this.brandConfig = {
|
|
1834
|
+
logo: "logo" in newConfig ? _nullishCoalesce(newConfig.logo, () => ( defaultTheme.logo)) : this.brandConfig.logo,
|
|
1835
|
+
theme: "theme" in newConfig ? _nullishCoalesce(newConfig.theme, () => ( defaultTheme.theme)) : this.brandConfig.theme,
|
|
1836
|
+
primaryColor: "primaryColor" in newConfig ? _nullishCoalesce(newConfig.primaryColor, () => ( defaultTheme.primaryColor)) : this.brandConfig.primaryColor,
|
|
1837
|
+
borderRadius: "borderRadius" in newConfig ? _nullishCoalesce(newConfig.borderRadius, () => ( defaultTheme.borderRadius)) : this.brandConfig.borderRadius,
|
|
1838
|
+
modalZIndex: "modalZIndex" in newConfig ? typeof newConfig.modalZIndex === "number" ? newConfig.modalZIndex : defaultTheme.modalZIndex : this.brandConfig.modalZIndex,
|
|
1839
|
+
appName: "appName" in newConfig ? _nullishCoalesce(newConfig.appName, () => ( defaultTheme.appName)) : this.brandConfig.appName,
|
|
1840
|
+
hideFooter: "hideFooter" in newConfig ? _nullishCoalesce(newConfig.hideFooter, () => ( defaultTheme.hideFooter)) : this.brandConfig.hideFooter,
|
|
1841
|
+
font: "font" in newConfig ? _nullishCoalesce(newConfig.font, () => ( defaultTheme.font)) : this.brandConfig.font,
|
|
1842
|
+
walletLayout: "walletLayout" in newConfig ? _nullishCoalesce(newConfig.walletLayout, () => ( defaultTheme.walletLayout)) : this.brandConfig.walletLayout
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
updateWalletsConfig(newConfig) {
|
|
1846
|
+
if (newConfig.exclude !== void 0) {
|
|
1847
|
+
this.excludedWallets = new Set(_nullishCoalesce(newConfig.exclude, () => ( [])));
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
/* HEADLESS / WHITELABEL API */
|
|
1851
|
+
/**
|
|
1852
|
+
* Starts the email authentication flow by sending an OTP to the provided email.
|
|
1853
|
+
* @returns flowId to use with emailAuthVerify
|
|
1854
|
+
*/
|
|
1855
|
+
async emailAuthStart(email) {
|
|
1856
|
+
await this.whenReady();
|
|
1857
|
+
const emailAdapter = this.wallets.find((w) => w.id === _types.WalletId.Email);
|
|
1858
|
+
if (!emailAdapter || !emailAdapter.emailAuthStart) {
|
|
1859
|
+
throw new Error("Email wallet is not configured");
|
|
1860
|
+
}
|
|
1861
|
+
const result = await emailAdapter.emailAuthStart(email);
|
|
1862
|
+
return { flowId: result.flowId };
|
|
1863
|
+
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Verifies the email OTP and completes the connection.
|
|
1866
|
+
* @param flowId - The flowId returned from emailAuthStart
|
|
1867
|
+
* @param otp - The OTP code the user received via email
|
|
1868
|
+
* @returns The connected wallet address and email
|
|
1869
|
+
*/
|
|
1870
|
+
async emailAuthVerify(flowId, otp) {
|
|
1871
|
+
await this.whenReady();
|
|
1872
|
+
const emailAdapter = this.wallets.find((w) => w.id === _types.WalletId.Email);
|
|
1873
|
+
if (!emailAdapter || !emailAdapter.emailAuthVerify) {
|
|
1874
|
+
throw new Error("Email wallet is not configured");
|
|
1875
|
+
}
|
|
1876
|
+
const verifyResult = await emailAdapter.emailAuthVerify(flowId, otp);
|
|
1877
|
+
const provider = emailAdapter.getProvider();
|
|
1878
|
+
if (!provider) {
|
|
1879
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Failed to get provider after email verification");
|
|
1880
|
+
throw new Error("Failed to get provider after email verification");
|
|
1881
|
+
}
|
|
1882
|
+
const address = _optionalChain([verifyResult, 'access', _132 => _132.user, 'optionalAccess', _133 => _133.evmAccounts, 'optionalAccess', _134 => _134[0]]);
|
|
1883
|
+
const email = _optionalChain([verifyResult, 'access', _135 => _135.user, 'optionalAccess', _136 => _136.authenticationMethods, 'optionalAccess', _137 => _137.email, 'optionalAccess', _138 => _138.email]);
|
|
1884
|
+
if (!address || !email) {
|
|
1885
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Address or email not found after email verification");
|
|
1886
|
+
throw new Error("Address or email not found after email verification");
|
|
1887
|
+
}
|
|
1888
|
+
const checksumAdr = _viem.checksumAddress.call(void 0, address);
|
|
1889
|
+
this.connectedWalletAdapter = emailAdapter;
|
|
1890
|
+
this.updateProvider(provider);
|
|
1891
|
+
this.userInfo = {
|
|
1892
|
+
publicAddress: checksumAdr,
|
|
1893
|
+
walletName: emailAdapter.name,
|
|
1894
|
+
walletId: emailAdapter.id,
|
|
1895
|
+
email
|
|
1896
|
+
};
|
|
1897
|
+
this.persistConnectionState(emailAdapter, checksumAdr, email);
|
|
1898
|
+
this.setInternalAccountChangeListener(emailAdapter);
|
|
1899
|
+
const chainId = await provider.request({ method: "eth_chainId" });
|
|
1900
|
+
this.emitConnect(chainId);
|
|
1901
|
+
this.emitAccountsChanged([checksumAdr]);
|
|
1902
|
+
_chunkDHEVW7CRjs.sentryLogger.info(`Wallet connected: ${emailAdapter.id} (headless)`);
|
|
1903
|
+
return { address: checksumAdr, email: _nullishCoalesce(email, () => ( "")), isNewUser: _nullishCoalesce(verifyResult.isNewUser, () => ( false)) };
|
|
1904
|
+
}
|
|
1905
|
+
/**
|
|
1906
|
+
* Initiates a WalletConnect session and returns the URI for displaying a custom QR code.
|
|
1907
|
+
* @returns URI string and a promise that resolves when the user connects
|
|
1908
|
+
*/
|
|
1909
|
+
async getWalletConnectSession() {
|
|
1910
|
+
await this.whenReady();
|
|
1911
|
+
const wcAdapter = this.wallets.find((w) => w.id === _types.WalletId.WalletConnect);
|
|
1912
|
+
if (!wcAdapter) {
|
|
1913
|
+
throw new Error("WalletConnect is not enabled");
|
|
1914
|
+
}
|
|
1915
|
+
const session = await wcAdapter.startSession();
|
|
1916
|
+
return {
|
|
1917
|
+
uri: session.uri,
|
|
1918
|
+
waitForConnection: async () => {
|
|
1919
|
+
const result = await session.waitForConnection();
|
|
1920
|
+
const provider = _nullishCoalesce(result.provider, () => ( wcAdapter.getProvider()));
|
|
1921
|
+
if (!provider) {
|
|
1922
|
+
_chunkDHEVW7CRjs.sentryLogger.error("Failed to get provider after WalletConnect connection");
|
|
1923
|
+
throw new Error("Failed to get provider after WalletConnect connection");
|
|
1924
|
+
}
|
|
1925
|
+
const checksumAdr = _viem.checksumAddress.call(void 0, result.address);
|
|
1926
|
+
this.connectedWalletAdapter = wcAdapter;
|
|
1927
|
+
this.updateProvider(provider);
|
|
1928
|
+
this.userInfo = {
|
|
1929
|
+
publicAddress: checksumAdr,
|
|
1930
|
+
walletName: wcAdapter.name,
|
|
1931
|
+
walletId: wcAdapter.id
|
|
1932
|
+
};
|
|
1933
|
+
this.persistConnectionState(wcAdapter, checksumAdr);
|
|
1934
|
+
this.setInternalAccountChangeListener(wcAdapter);
|
|
1935
|
+
const chainId = await provider.request({ method: "eth_chainId" });
|
|
1936
|
+
this.emitConnect(chainId);
|
|
1937
|
+
this.emitAccountsChanged([checksumAdr]);
|
|
1938
|
+
_chunkDHEVW7CRjs.sentryLogger.info(`Wallet connected: ${wcAdapter.id} (headless)`);
|
|
1939
|
+
return checksumAdr;
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1943
|
+
/* PROVIDER METHODS */
|
|
1944
|
+
createProviderProxy() {
|
|
1945
|
+
const handler = {
|
|
1946
|
+
get: (_, prop) => {
|
|
1947
|
+
if (prop === "on") {
|
|
1948
|
+
return (event, callback) => {
|
|
1949
|
+
if (!this.eventListeners.has(event)) {
|
|
1950
|
+
this.eventListeners.set(event, /* @__PURE__ */ new Set());
|
|
1951
|
+
}
|
|
1952
|
+
this.eventListeners.get(event).add(callback);
|
|
1953
|
+
if (!_AurumCore.MANAGED_EVENTS.includes(event)) {
|
|
1954
|
+
_optionalChain([this, 'access', _139 => _139.currentProvider, 'access', _140 => _140.on, 'optionalCall', _141 => _141(event, callback)]);
|
|
1955
|
+
}
|
|
1956
|
+
};
|
|
1957
|
+
}
|
|
1958
|
+
if (prop === "removeListener") {
|
|
1959
|
+
return (event, callback) => {
|
|
1960
|
+
_optionalChain([this, 'access', _142 => _142.eventListeners, 'access', _143 => _143.get, 'call', _144 => _144(event), 'optionalAccess', _145 => _145.delete, 'call', _146 => _146(callback)]);
|
|
1961
|
+
if (!_AurumCore.MANAGED_EVENTS.includes(event)) {
|
|
1962
|
+
_optionalChain([this, 'access', _147 => _147.currentProvider, 'access', _148 => _148.removeListener, 'optionalCall', _149 => _149(event, callback)]);
|
|
1963
|
+
}
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
const provider = this.currentProvider;
|
|
1967
|
+
const value = provider[prop];
|
|
1968
|
+
if (typeof value === "function") {
|
|
1969
|
+
return (...args) => {
|
|
1970
|
+
const currentValue = this.currentProvider[prop];
|
|
1971
|
+
if (typeof currentValue === "function") {
|
|
1972
|
+
return currentValue.apply(this.currentProvider, args);
|
|
1973
|
+
}
|
|
1974
|
+
return currentValue;
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
return value;
|
|
1978
|
+
}
|
|
1979
|
+
};
|
|
1980
|
+
return new Proxy({}, handler);
|
|
1981
|
+
}
|
|
1982
|
+
updateProvider(newProvider) {
|
|
1983
|
+
this.currentProvider = newProvider;
|
|
1984
|
+
this.eventListeners.forEach((callbacks, event) => {
|
|
1985
|
+
if (!_AurumCore.MANAGED_EVENTS.includes(event)) {
|
|
1986
|
+
callbacks.forEach((callback) => {
|
|
1987
|
+
_optionalChain([newProvider, 'access', _150 => _150.on, 'optionalCall', _151 => _151(event, callback)]);
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
});
|
|
1991
|
+
}
|
|
1992
|
+
/* BRAND & THEME METHODS */
|
|
1993
|
+
resolveBrandConfig(config) {
|
|
1994
|
+
const { brand = {} } = config || {};
|
|
1995
|
+
const themeConfig = _chunkDHEVW7CRjs.getDefaultThemeConfig.call(void 0, brand.theme || _chunkDHEVW7CRjs.DEFAULT_THEME);
|
|
1996
|
+
return {
|
|
1997
|
+
logo: _nullishCoalesce(brand.logo, () => ( themeConfig.logo)),
|
|
1998
|
+
theme: _nullishCoalesce(brand.theme, () => ( themeConfig.theme)),
|
|
1999
|
+
primaryColor: _nullishCoalesce(brand.primaryColor, () => ( themeConfig.primaryColor)),
|
|
2000
|
+
borderRadius: _nullishCoalesce(brand.borderRadius, () => ( themeConfig.borderRadius)),
|
|
2001
|
+
modalZIndex: typeof brand.modalZIndex === "number" ? brand.modalZIndex : themeConfig.modalZIndex,
|
|
2002
|
+
appName: _nullishCoalesce(brand.appName, () => ( themeConfig.appName)),
|
|
2003
|
+
hideFooter: _nullishCoalesce(brand.hideFooter, () => ( themeConfig.hideFooter)),
|
|
2004
|
+
font: _nullishCoalesce(brand.font, () => ( themeConfig.font)),
|
|
2005
|
+
walletLayout: _nullishCoalesce(brand.walletLayout, () => ( themeConfig.walletLayout))
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
async tryRestoreConnection() {
|
|
2009
|
+
try {
|
|
2010
|
+
await _chunkDHEVW7CRjs.waitForStoreHydration.call(void 0, );
|
|
2011
|
+
const store = _chunkDHEVW7CRjs.useAurumStore.getState();
|
|
2012
|
+
if (!store.isConnected || !store.walletId || !store.address || !store.walletName) {
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2015
|
+
const persistedAdapter = this.wallets.find((w) => w.id === store.walletId) || null;
|
|
2016
|
+
if (!persistedAdapter || !persistedAdapter.isInstalled()) {
|
|
2017
|
+
store.clearConnection();
|
|
2018
|
+
return;
|
|
2019
|
+
}
|
|
2020
|
+
const connectionResult = await persistedAdapter.tryRestoreConnection();
|
|
2021
|
+
if (!connectionResult || connectionResult.address.toLowerCase() !== store.address.toLowerCase()) {
|
|
2022
|
+
store.clearConnection();
|
|
2023
|
+
return;
|
|
2024
|
+
}
|
|
2025
|
+
this.connectedWalletAdapter = persistedAdapter;
|
|
2026
|
+
this.updateProvider(connectionResult.provider);
|
|
2027
|
+
this.userInfo = {
|
|
2028
|
+
publicAddress: _viem.checksumAddress.call(void 0, connectionResult.address),
|
|
2029
|
+
walletName: store.walletName,
|
|
2030
|
+
walletId: persistedAdapter.id,
|
|
2031
|
+
email: _nullishCoalesce(store.email, () => ( void 0))
|
|
2032
|
+
};
|
|
2033
|
+
this.setInternalAccountChangeListener(persistedAdapter);
|
|
2034
|
+
} catch (e22) {
|
|
2035
|
+
this.resetConnectionState();
|
|
2036
|
+
} finally {
|
|
2037
|
+
this.ready = true;
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
persistConnectionState(adapter, address, email) {
|
|
2041
|
+
_chunkDHEVW7CRjs.useAurumStore.getState().setConnection(adapter.id, _viem.checksumAddress.call(void 0, address), adapter.name, email);
|
|
2042
|
+
}
|
|
2043
|
+
/* INTERNAL LISTENER METHODS */
|
|
2044
|
+
setInternalAccountChangeListener(adapter) {
|
|
2045
|
+
adapter.onAccountsChanged(async (accounts) => {
|
|
2046
|
+
if (accounts.length === 0) {
|
|
2047
|
+
await this.disconnect();
|
|
2048
|
+
return;
|
|
2049
|
+
}
|
|
2050
|
+
this.syncStateFromAccountsChanged(accounts);
|
|
2051
|
+
});
|
|
2052
|
+
}
|
|
2053
|
+
async syncStateFromAccountsChanged(accounts) {
|
|
2054
|
+
if (!accounts.length || !accounts[0]) return;
|
|
2055
|
+
const prevAccount = _optionalChain([this, 'access', _152 => _152.userInfo, 'optionalAccess', _153 => _153.publicAddress]);
|
|
2056
|
+
const newAccount = _viem.checksumAddress.call(void 0, accounts[0]);
|
|
2057
|
+
if (newAccount !== prevAccount) {
|
|
2058
|
+
this.userInfo = {
|
|
2059
|
+
publicAddress: newAccount,
|
|
2060
|
+
walletName: _optionalChain([this, 'access', _154 => _154.userInfo, 'optionalAccess', _155 => _155.walletName]),
|
|
2061
|
+
walletId: _optionalChain([this, 'access', _156 => _156.userInfo, 'optionalAccess', _157 => _157.walletId]),
|
|
2062
|
+
email: _optionalChain([this, 'access', _158 => _158.userInfo, 'optionalAccess', _159 => _159.email])
|
|
2063
|
+
};
|
|
2064
|
+
if (this.connectedWalletAdapter) {
|
|
2065
|
+
this.persistConnectionState(this.connectedWalletAdapter, newAccount, this.userInfo.email);
|
|
2066
|
+
}
|
|
2067
|
+
this.emitAccountsChanged([newAccount]);
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
/**
|
|
2071
|
+
* Emit accountsChanged to listeners registered via rpcProvider.on('accountsChanged', cb)
|
|
2072
|
+
* This is the single source of truth - we don't forward to underlying providers to prevent duplicates
|
|
2073
|
+
*/
|
|
2074
|
+
emitAccountsChanged(accounts) {
|
|
2075
|
+
const listeners = this.eventListeners.get("accountsChanged");
|
|
2076
|
+
if (listeners) {
|
|
2077
|
+
listeners.forEach((callback) => callback(accounts));
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
/**
|
|
2081
|
+
* Emit connect event per EIP-1193 when provider becomes connected
|
|
2082
|
+
* @param chainId - The chain ID in hex format (e.g., "0x1")
|
|
2083
|
+
*/
|
|
2084
|
+
emitConnect(chainId) {
|
|
2085
|
+
const listeners = this.eventListeners.get("connect");
|
|
2086
|
+
if (listeners) {
|
|
2087
|
+
listeners.forEach((callback) => callback({ chainId }));
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
/**
|
|
2091
|
+
* Emit disconnect event per EIP-1193 when provider becomes disconnected
|
|
2092
|
+
* @param error - Optional error that caused the disconnection
|
|
2093
|
+
*/
|
|
2094
|
+
emitDisconnect(error) {
|
|
2095
|
+
const listeners = this.eventListeners.get("disconnect");
|
|
2096
|
+
if (listeners) {
|
|
2097
|
+
const disconnectError = error || { code: 4900, message: "Disconnected" };
|
|
2098
|
+
listeners.forEach((callback) => callback(disconnectError));
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
/* SWITCH CHAIN METHODS */
|
|
2102
|
+
async attemptSwitchChain(hexChainId) {
|
|
2103
|
+
await this.rpcProvider.request({
|
|
2104
|
+
method: "wallet_switchEthereumChain",
|
|
2105
|
+
params: [{ chainId: hexChainId }]
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
async handleMissingChain(hexChainId, chain) {
|
|
2109
|
+
try {
|
|
2110
|
+
await this.addChain(chain);
|
|
2111
|
+
await this.attemptSwitchChain(hexChainId);
|
|
2112
|
+
} catch (addError) {
|
|
2113
|
+
if (isChainExistsError(addError)) {
|
|
2114
|
+
await this.attemptSwitchChain(hexChainId);
|
|
2115
|
+
} else {
|
|
2116
|
+
throw addError;
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
async addChain(chain) {
|
|
2121
|
+
if (!_optionalChain([chain, 'optionalAccess', _160 => _160.id]) || !_optionalChain([chain, 'optionalAccess', _161 => _161.name]) || !_optionalChain([chain, 'optionalAccess', _162 => _162.nativeCurrency]) || !_optionalChain([chain, 'optionalAccess', _163 => _163.rpcUrls, 'optionalAccess', _164 => _164.default, 'optionalAccess', _165 => _165.http])) {
|
|
2122
|
+
throw new Error("Invalid chain configuration: missing required properties");
|
|
2123
|
+
}
|
|
2124
|
+
await this.rpcProvider.request({
|
|
2125
|
+
method: "wallet_addEthereumChain",
|
|
2126
|
+
params: [
|
|
2127
|
+
{
|
|
2128
|
+
chainId: `0x${chain.id.toString(16)}`,
|
|
2129
|
+
chainName: chain.name,
|
|
2130
|
+
nativeCurrency: chain.nativeCurrency,
|
|
2131
|
+
rpcUrls: chain.rpcUrls.default.http,
|
|
2132
|
+
blockExplorerUrls: chain.blockExplorers ? [chain.blockExplorers.default.url] : void 0
|
|
2133
|
+
}
|
|
2134
|
+
]
|
|
2135
|
+
});
|
|
2136
|
+
}
|
|
2137
|
+
/* REST */
|
|
2138
|
+
resetConnectionState() {
|
|
2139
|
+
_chunkDHEVW7CRjs.useAurumStore.getState().clearConnection();
|
|
2140
|
+
this.connectedWalletAdapter = null;
|
|
2141
|
+
this.updateProvider(this.skeletonProvider);
|
|
2142
|
+
this.userInfo = void 0;
|
|
2143
|
+
}
|
|
2144
|
+
};
|
|
2145
|
+
// Singleton instance
|
|
2146
|
+
_AurumCore.instance = null;
|
|
2147
|
+
// Events managed by AurumCore (not forwarded to underlying provider)
|
|
2148
|
+
_AurumCore.MANAGED_EVENTS = ["accountsChanged", "connect", "disconnect"];
|
|
2149
|
+
var AurumCore = _AurumCore;
|
|
2150
|
+
|
|
2151
|
+
// src/Aurum.ts
|
|
2152
|
+
var Aurum = class {
|
|
2153
|
+
/**
|
|
2154
|
+
* Creates a new Aurum instance.
|
|
2155
|
+
*
|
|
2156
|
+
* @param config - Configuration for branding and wallets
|
|
2157
|
+
*
|
|
2158
|
+
* @example
|
|
2159
|
+
* ```typescript
|
|
2160
|
+
* const aurum = new Aurum({
|
|
2161
|
+
* brand: { appName: 'Your App Name' },
|
|
2162
|
+
* wallets: {
|
|
2163
|
+
* email: { projectId: 'cdp-project-id' },
|
|
2164
|
+
* walletConnect: { projectId: 'reown-project-id' },
|
|
2165
|
+
* },
|
|
2166
|
+
* });
|
|
2167
|
+
* ```
|
|
2168
|
+
*/
|
|
2169
|
+
constructor(config) {
|
|
2170
|
+
this.core = new AurumCore(config);
|
|
2171
|
+
}
|
|
2172
|
+
/**
|
|
2173
|
+
* EIP1193 compatible RPC provider that can be used to interact with the connected wallet.
|
|
2174
|
+
* Compatible with viem, ethers.js, and other web3 libraries.
|
|
2175
|
+
*
|
|
2176
|
+
* @example
|
|
2177
|
+
* ```typescript
|
|
2178
|
+
* const balance = await aurum.rpcProvider.request({
|
|
2179
|
+
* method: 'eth_getBalance',
|
|
2180
|
+
* params: [address, 'latest']
|
|
2181
|
+
* });
|
|
2182
|
+
* ```
|
|
2183
|
+
*/
|
|
2184
|
+
get rpcProvider() {
|
|
2185
|
+
return this.core.rpcProvider;
|
|
2186
|
+
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Indicates whether the SDK is finished initializing.
|
|
2189
|
+
*/
|
|
2190
|
+
get ready() {
|
|
2191
|
+
return this.core.ready;
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* Returns the resolved brand configuration.
|
|
2195
|
+
* @internal Used by widget components (i.e. ConnectWidget)
|
|
2196
|
+
*/
|
|
2197
|
+
get brandConfig() {
|
|
2198
|
+
return this.core.resolvedBrandConfig;
|
|
2199
|
+
}
|
|
2200
|
+
/**
|
|
2201
|
+
* Returns the wallet adapters configured for this instance.
|
|
2202
|
+
* @internal Used by widget components (i.e. ConnectWidget)
|
|
2203
|
+
*/
|
|
2204
|
+
get walletAdapters() {
|
|
2205
|
+
return this.core.walletAdapters;
|
|
2206
|
+
}
|
|
2207
|
+
/**
|
|
2208
|
+
* Returns the set of excluded wallet IDs.
|
|
2209
|
+
* @internal Used by widget components (i.e. ConnectWidget)
|
|
2210
|
+
*/
|
|
2211
|
+
get excludedWalletIds() {
|
|
2212
|
+
return this.core.excludedWalletIds;
|
|
2213
|
+
}
|
|
2214
|
+
/**
|
|
2215
|
+
* Waits for the SDK to finish initializing.
|
|
2216
|
+
* This should be called before calling methods with the provider to ensure provider is set (such as after a page refresh).
|
|
2217
|
+
*
|
|
2218
|
+
* @example
|
|
2219
|
+
* ```typescript
|
|
2220
|
+
* await aurum.whenReady();
|
|
2221
|
+
* const balance = await aurum.rpcProvider.request({
|
|
2222
|
+
* method: 'eth_getBalance',
|
|
2223
|
+
* params: [address, 'latest']
|
|
2224
|
+
* });
|
|
2225
|
+
* ```
|
|
2226
|
+
*/
|
|
2227
|
+
async whenReady() {
|
|
2228
|
+
return this.core.whenReady();
|
|
2229
|
+
}
|
|
2230
|
+
/**
|
|
2231
|
+
* Opens the wallet connection modal or connects directly to a specific wallet.
|
|
2232
|
+
*
|
|
2233
|
+
* @param walletId - Optional wallet ID for direct connection (bypasses modal).
|
|
2234
|
+
* Cannot be 'email' or 'walletconnect' (use their dedicated methods).
|
|
2235
|
+
* @returns The connected wallet address
|
|
2236
|
+
* @throws Error if user closes the modal without connecting a wallet
|
|
2237
|
+
*
|
|
2238
|
+
* @example
|
|
2239
|
+
* ```typescript
|
|
2240
|
+
* // Open modal for user to choose
|
|
2241
|
+
* const address = await aurum.connect();
|
|
2242
|
+
*
|
|
2243
|
+
* // Or connect directly to a specific wallet
|
|
2244
|
+
* import { WalletId } from '@aurum-sdk/types';
|
|
2245
|
+
* const address = await aurum.connect(WalletId.MetaMask);
|
|
2246
|
+
* ```
|
|
2247
|
+
*/
|
|
2248
|
+
async connect(walletId) {
|
|
2249
|
+
return this.core.connect(walletId);
|
|
2250
|
+
}
|
|
2251
|
+
/**
|
|
2252
|
+
* Disconnects the currently connected wallet and clears the connection state.
|
|
2253
|
+
*
|
|
2254
|
+
* @example
|
|
2255
|
+
* ```typescript
|
|
2256
|
+
* await aurum.disconnect();
|
|
2257
|
+
* ```
|
|
2258
|
+
*/
|
|
2259
|
+
async disconnect() {
|
|
2260
|
+
return this.core.disconnect();
|
|
2261
|
+
}
|
|
2262
|
+
/**
|
|
2263
|
+
* Gets information about the currently connected user.
|
|
2264
|
+
*
|
|
2265
|
+
* @returns User information including wallet address and wallet name, or undefined if no wallet is connected
|
|
2266
|
+
*
|
|
2267
|
+
* @example
|
|
2268
|
+
* ```typescript
|
|
2269
|
+
* const userInfo = await aurum.getUserInfo();
|
|
2270
|
+
* if (userInfo) {
|
|
2271
|
+
* console.log(`Connected to ${userInfo.walletName}: ${userInfo.publicAddress}`);
|
|
2272
|
+
* } else {
|
|
2273
|
+
* console.log('No wallet connected');
|
|
2274
|
+
* }
|
|
2275
|
+
* ```
|
|
2276
|
+
*/
|
|
2277
|
+
async getUserInfo() {
|
|
2278
|
+
return this.core.getUserInfo();
|
|
2279
|
+
}
|
|
2280
|
+
/**
|
|
2281
|
+
* Checks if a wallet is currently connected.
|
|
2282
|
+
*
|
|
2283
|
+
* @returns `true` if a wallet is connected, `false` otherwise
|
|
2284
|
+
*
|
|
2285
|
+
* @example
|
|
2286
|
+
* ```typescript
|
|
2287
|
+
* const isConnected = await aurum.isConnected();
|
|
2288
|
+
* console.log('Is user connected:', isConnected);
|
|
2289
|
+
* ```
|
|
2290
|
+
*/
|
|
2291
|
+
async isConnected() {
|
|
2292
|
+
return this.core.isConnected();
|
|
2293
|
+
}
|
|
2294
|
+
/**
|
|
2295
|
+
* Gets the current chain ID of the connected wallet.
|
|
2296
|
+
*
|
|
2297
|
+
* @returns The current chain ID as a number
|
|
2298
|
+
*
|
|
2299
|
+
* @example
|
|
2300
|
+
* ```typescript
|
|
2301
|
+
* const chainId = await aurum.getChainId();
|
|
2302
|
+
* console.log('Connected to chain:', chainId);
|
|
2303
|
+
* ```
|
|
2304
|
+
*/
|
|
2305
|
+
async getChainId() {
|
|
2306
|
+
return this.core.getChainId();
|
|
2307
|
+
}
|
|
2308
|
+
/**
|
|
2309
|
+
* Switches the connected wallet to a different blockchain network.
|
|
2310
|
+
* If the chain is not added to the wallet, it will attempt to add it using the provided chain config.
|
|
2311
|
+
*
|
|
2312
|
+
* @param chainId - The chain ID to switch to (can be hex string, decimal string, or number)
|
|
2313
|
+
* @param chain - Optional viem Chain object with chain configuration (required if chain needs to be added)
|
|
2314
|
+
* @throws Error if the switch fails or the user rejects the request
|
|
2315
|
+
*
|
|
2316
|
+
* @example
|
|
2317
|
+
* ```typescript
|
|
2318
|
+
* import { sepolia } from 'viem/chains';
|
|
2319
|
+
*
|
|
2320
|
+
* await aurum.switchChain(sepolia.id, sepolia);
|
|
2321
|
+
* ```
|
|
2322
|
+
*/
|
|
2323
|
+
async switchChain(chainId, chain) {
|
|
2324
|
+
return this.core.switchChain(chainId, chain);
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Updates the brand configuration at runtime.
|
|
2328
|
+
* Changes will be reflected the next time the connect modal is opened.
|
|
2329
|
+
*
|
|
2330
|
+
* @param newConfig - Partial brand config to merge with existing config
|
|
2331
|
+
*
|
|
2332
|
+
* @example
|
|
2333
|
+
* ```typescript
|
|
2334
|
+
* aurum.updateBrandConfig({
|
|
2335
|
+
* theme: 'light',
|
|
2336
|
+
* });
|
|
2337
|
+
* ```
|
|
2338
|
+
*/
|
|
2339
|
+
updateBrandConfig(newConfig) {
|
|
2340
|
+
this.core.updateBrandConfig(newConfig);
|
|
2341
|
+
}
|
|
2342
|
+
/**
|
|
2343
|
+
* Updates the wallets configuration at runtime.
|
|
2344
|
+
* Changes will be reflected the next time the connect modal is opened.
|
|
2345
|
+
*
|
|
2346
|
+
* @param newConfig - Partial wallets config to update (currently supports `exclude`)
|
|
2347
|
+
*
|
|
2348
|
+
* @example
|
|
2349
|
+
* ```typescript
|
|
2350
|
+
* import { WalletId } from '@aurum-sdk/types';
|
|
2351
|
+
*
|
|
2352
|
+
* aurum.updateWalletsConfig({
|
|
2353
|
+
* exclude: [WalletId.Email, WalletId.AppKit],
|
|
2354
|
+
* });
|
|
2355
|
+
* ```
|
|
2356
|
+
*/
|
|
2357
|
+
updateWalletsConfig(newConfig) {
|
|
2358
|
+
this.core.updateWalletsConfig(newConfig);
|
|
2359
|
+
}
|
|
2360
|
+
/**
|
|
2361
|
+
* Notifies the SDK of a widget-initiated connection.
|
|
2362
|
+
* Updates internal state so getUserInfo(), isConnected(), etc. work correctly.
|
|
2363
|
+
* @internal Used by ConnectWidget - not intended for direct use
|
|
2364
|
+
*/
|
|
2365
|
+
async handleWidgetConnection(result) {
|
|
2366
|
+
return this.core.handleWidgetConnection(result);
|
|
2367
|
+
}
|
|
2368
|
+
/* ===== HEADLESS / WHITELABEL API ===== */
|
|
2369
|
+
/**
|
|
2370
|
+
* Starts the email authentication flow by sending an OTP to the provided email.
|
|
2371
|
+
* Use with `emailAuthVerify()` to complete the connection.
|
|
2372
|
+
*
|
|
2373
|
+
* @param email - The email address to send the OTP to
|
|
2374
|
+
* @returns Object containing flowId to use with emailAuthVerify
|
|
2375
|
+
* @throws Error if email wallet is not configured
|
|
2376
|
+
*
|
|
2377
|
+
* @example
|
|
2378
|
+
* ```typescript
|
|
2379
|
+
* const { flowId } = await aurum.emailAuthStart('user@example.com');
|
|
2380
|
+
* // User receives OTP email, then verify:
|
|
2381
|
+
* const { address, email, isNewUser } = await aurum.emailAuthVerify(flowId, '123456');
|
|
2382
|
+
* ```
|
|
2383
|
+
*/
|
|
2384
|
+
async emailAuthStart(email) {
|
|
2385
|
+
return this.core.emailAuthStart(email);
|
|
2386
|
+
}
|
|
2387
|
+
/**
|
|
2388
|
+
* Verifies the email OTP and completes the wallet connection.
|
|
2389
|
+
*
|
|
2390
|
+
* @param flowId - The flowId returned from emailAuthStart
|
|
2391
|
+
* @param otp - The OTP code the user received via email
|
|
2392
|
+
* @returns Object containing the connected address and email
|
|
2393
|
+
* @throws Error if verification fails
|
|
2394
|
+
*
|
|
2395
|
+
* @example
|
|
2396
|
+
* ```typescript
|
|
2397
|
+
* const { flowId } = await aurum.emailAuthStart('user@example.com');
|
|
2398
|
+
* // User receives OTP...
|
|
2399
|
+
* const { address, email, isNewUser } = await aurum.emailAuthVerify(flowId, '123456');
|
|
2400
|
+
* console.log(`Connected: ${address} (${email})`);
|
|
2401
|
+
* ```
|
|
2402
|
+
*/
|
|
2403
|
+
async emailAuthVerify(flowId, otp) {
|
|
2404
|
+
return this.core.emailAuthVerify(flowId, otp);
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Initiates a WalletConnect session and returns the URI for displaying a custom QR code.
|
|
2408
|
+
* Use this for building custom QR code UIs instead of using the built-in modal.
|
|
2409
|
+
*
|
|
2410
|
+
* @returns Object containing the URI and a function to wait for the connection
|
|
2411
|
+
* @throws Error if WalletConnect is not configured
|
|
2412
|
+
*
|
|
2413
|
+
* @example
|
|
2414
|
+
* ```typescript
|
|
2415
|
+
* // Get the WalletConnect URI
|
|
2416
|
+
* const { uri, waitForConnection } = await aurum.getWalletConnectSession();
|
|
2417
|
+
*
|
|
2418
|
+
* // Display your custom QR code with the URI
|
|
2419
|
+
* myQRCodeComponent.render(uri);
|
|
2420
|
+
*
|
|
2421
|
+
* // Wait for user to scan and approve
|
|
2422
|
+
* const address = await waitForConnection();
|
|
2423
|
+
* console.log('Connected:', address);
|
|
2424
|
+
* ```
|
|
2425
|
+
*/
|
|
2426
|
+
async getWalletConnectSession() {
|
|
2427
|
+
return this.core.getWalletConnectSession();
|
|
2428
|
+
}
|
|
2429
|
+
};
|
|
2430
|
+
|
|
2431
|
+
|
|
2432
|
+
exports.Aurum = Aurum;
|
|
2433
|
+
//# sourceMappingURL=index.js.map
|