@tomo-inc/inject-providers 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,1995 @@
1
+ 'use strict';
2
+
3
+ var ethRpcErrors = require('eth-rpc-errors');
4
+ var events = require('events');
5
+ var jsonRpcEngine = require('json-rpc-engine');
6
+ var jsonRpcMiddlewareStream = require('json-rpc-middleware-stream');
7
+ var viem = require('viem');
8
+ var web3_js = require('@solana/web3.js');
9
+ var bs58 = require('bs58');
10
+ var tronweb = require('tronweb');
11
+
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var bs58__default = /*#__PURE__*/_interopDefault(bs58);
15
+
16
+ var __defProp = Object.defineProperty;
17
+ var __defProps = Object.defineProperties;
18
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
19
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
20
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
21
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
22
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
23
+ var __spreadValues = (a, b) => {
24
+ for (var prop in b || (b = {}))
25
+ if (__hasOwnProp.call(b, prop))
26
+ __defNormalProp(a, prop, b[prop]);
27
+ if (__getOwnPropSymbols)
28
+ for (var prop of __getOwnPropSymbols(b)) {
29
+ if (__propIsEnum.call(b, prop))
30
+ __defNormalProp(a, prop, b[prop]);
31
+ }
32
+ return a;
33
+ };
34
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
35
+
36
+ // src/utils/dapp-info.ts
37
+ var $ = document.querySelector.bind(document);
38
+ async function getDappInfo() {
39
+ var _a;
40
+ return {
41
+ origin: (_a = window.top) == null ? void 0 : _a.location.origin,
42
+ // host: window.location.hostname,
43
+ favicon: await getSiteIcon(),
44
+ title: getSiteName(window),
45
+ desc: getSiteDesc(window)
46
+ };
47
+ }
48
+ function getSiteName(windowObject) {
49
+ const { document: document2 } = windowObject;
50
+ const siteName = document2.querySelector('head > meta[property="og:site_name"]');
51
+ if (siteName) {
52
+ return siteName.content;
53
+ }
54
+ const metaTitle = document2.querySelector('head > meta[name="title"]');
55
+ if (metaTitle) {
56
+ return metaTitle.content;
57
+ }
58
+ if (document2.title && document2.title.length > 0) {
59
+ return document2.title;
60
+ }
61
+ return window.location.hostname;
62
+ }
63
+ function getSiteDesc(windowObject) {
64
+ const { document: document2 } = windowObject;
65
+ const siteName = document2.querySelector('head > meta[property="og:description"]');
66
+ if (siteName) {
67
+ return siteName.content;
68
+ }
69
+ const siteNameX = document2.querySelector('head > meta[property="twitter:description"]');
70
+ if (siteNameX) {
71
+ return siteNameX.content;
72
+ }
73
+ const metaTitle = document2.querySelector('head > meta[name="description"]');
74
+ if (metaTitle) {
75
+ return metaTitle.content;
76
+ }
77
+ if (document2.title && document2.title.length > 0) {
78
+ return document2.title;
79
+ }
80
+ return document2.body.innerText.split("\n")[0] || "";
81
+ }
82
+ async function getSiteIcon(windowObject) {
83
+ var _a, _b;
84
+ const icon = ((_a = $('head > link[rel~="icon"]')) == null ? void 0 : _a.href) || ((_b = $('head > meta[itemprop="image"]')) == null ? void 0 : _b.content);
85
+ if (!icon) {
86
+ return "";
87
+ }
88
+ const isOK = await imgExists(icon);
89
+ if (isOK) {
90
+ return icon;
91
+ }
92
+ return "";
93
+ }
94
+ function imgExists(url) {
95
+ return new Promise((resolve, reject) => {
96
+ try {
97
+ const img = document.createElement("img");
98
+ img.onload = () => resolve(true);
99
+ img.onerror = () => resolve(false);
100
+ img.src = url;
101
+ } catch (e) {
102
+ reject(e);
103
+ }
104
+ });
105
+ }
106
+
107
+ // src/utils/dom.ts
108
+ var domReadyCall = (callback) => {
109
+ if (document.readyState === "complete") {
110
+ callback();
111
+ } else {
112
+ const domContentLoadedHandler = (e) => {
113
+ callback();
114
+ document.removeEventListener("DOMContentLoaded", domContentLoadedHandler);
115
+ };
116
+ document.addEventListener("DOMContentLoaded", domContentLoadedHandler);
117
+ }
118
+ };
119
+
120
+ // src/utils/ready-promise.ts
121
+ var ReadyPromise = class {
122
+ constructor(count) {
123
+ this._allCheck = [];
124
+ this._tasks = [];
125
+ this.check = (index) => {
126
+ this._allCheck[index - 1] = true;
127
+ this._proceed();
128
+ };
129
+ this.uncheck = (index) => {
130
+ this._allCheck[index - 1] = false;
131
+ };
132
+ this._proceed = () => {
133
+ if (this._allCheck.some((_) => !_)) {
134
+ return;
135
+ }
136
+ while (this._tasks.length) {
137
+ const { resolve, fn } = this._tasks.shift();
138
+ resolve(fn());
139
+ }
140
+ };
141
+ this.call = (fn) => {
142
+ return new Promise((resolve) => {
143
+ this._tasks.push({
144
+ fn,
145
+ resolve
146
+ });
147
+ this._proceed();
148
+ });
149
+ };
150
+ this._allCheck = [...Array(count)];
151
+ }
152
+ };
153
+
154
+ // src/utils/utils.ts
155
+ function hexToUint8Array(hexString) {
156
+ const cleanHex = hexString.startsWith("0x") ? hexString.slice(2) : hexString;
157
+ if (cleanHex.length !== 128) {
158
+ throw new Error("Invalid signature length");
159
+ }
160
+ const bytes = new Uint8Array(64);
161
+ for (let i = 0; i < 64; i++) {
162
+ bytes[i] = parseInt(cleanHex.slice(i * 2, i * 2 + 2), 16);
163
+ }
164
+ return bytes;
165
+ }
166
+ function isHexString(str) {
167
+ const hexRegex = /^(0x)?[0-9a-fA-F]+$/;
168
+ return hexRegex.test(str);
169
+ }
170
+
171
+ // src/btc/unisat.ts
172
+ var chainType = "btc" /* BTC */;
173
+ var BtcProvider = class extends events.EventEmitter {
174
+ constructor(productInfo, { sendRequest, onResponse }) {
175
+ super();
176
+ this._selectedAddress = null;
177
+ this._isConnected = false;
178
+ this._initialized = false;
179
+ this._isUnlocked = false;
180
+ this.rdns = "";
181
+ this.name = "";
182
+ this.chainId = "BITCOIN_MAINNET";
183
+ this._state = {
184
+ accounts: null,
185
+ isConnected: false,
186
+ isUnlocked: false,
187
+ initialized: false,
188
+ isPermanentlyDisconnected: false
189
+ };
190
+ this._requestPromise = new ReadyPromise(0);
191
+ this.initialize = async () => {
192
+ document.addEventListener("visibilitychange", async () => {
193
+ if (document.visibilityState === "visible") {
194
+ this._request({
195
+ method: "wallet_sendDomainMetadata",
196
+ params: await getDappInfo()
197
+ });
198
+ }
199
+ });
200
+ domReadyCall(async () => {
201
+ this._request({
202
+ method: "wallet_sendDomainMetadata",
203
+ params: await getDappInfo()
204
+ });
205
+ });
206
+ window.addEventListener("message", (event) => {
207
+ const { data, type, method } = event.data;
208
+ if (type === "subscribeWalletEvents" && method) {
209
+ this.subscribeWalletEventsCallback({ data, method });
210
+ }
211
+ });
212
+ this._state.initialized = true;
213
+ this._state.isConnected = true;
214
+ this.keepAlive();
215
+ };
216
+ this.subscribeWalletEventsCallback = ({ method, data }) => {
217
+ if (method === "accountsChanged") {
218
+ const addresses = (data == null ? void 0 : data[chainType]) || [];
219
+ const accounts = addresses.map(({ address }) => address);
220
+ this._handleAccountsChanged(accounts);
221
+ }
222
+ if (method === "chainChanged") {
223
+ const { chainId, type } = data;
224
+ if (type.indexOf(`${chainType}:`) === 0) {
225
+ this._handleChainChanged({ chainId, isConnected: true });
226
+ }
227
+ }
228
+ };
229
+ /**
230
+ * Sending a message to the extension to receive will keep the service worker alive.
231
+ */
232
+ this.keepAlive = () => {
233
+ this._request({
234
+ method: "keepAlive",
235
+ params: {}
236
+ }).then((v) => {
237
+ setTimeout(() => {
238
+ this.keepAlive();
239
+ }, 1e3);
240
+ });
241
+ };
242
+ //adapter data by reuqest function
243
+ this._request = async ({ method, params }, adapter) => {
244
+ if (!method) {
245
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest();
246
+ }
247
+ const dappInfo = await getDappInfo();
248
+ this.sendRequest(chainType, { method, params, dappInfo });
249
+ const connectFuns = {
250
+ getAccounts: true,
251
+ requestAccounts: true
252
+ };
253
+ return this.onResponse({ method }).then((res) => {
254
+ const { data } = res || {};
255
+ if (method === "wallet_switchEthereumChain") {
256
+ this._handleChainChanged({ chainId: data, isConnected: true });
257
+ }
258
+ if (method === "connect" && (data == null ? void 0 : data.address)) {
259
+ this._handleAccountsChanged([data == null ? void 0 : data.address]);
260
+ }
261
+ if (method in connectFuns && connectFuns[method]) {
262
+ this._handleAccountsChanged(data || []);
263
+ }
264
+ return adapter ? adapter(data) : data;
265
+ });
266
+ };
267
+ this.request = async ({ method, params }) => {
268
+ if (!method) {
269
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest();
270
+ }
271
+ return this._request({
272
+ method,
273
+ params
274
+ });
275
+ };
276
+ //res = { address, approved, balance, publicKey }
277
+ this.connect = async () => {
278
+ return this._request({
279
+ method: "connect"
280
+ });
281
+ };
282
+ //res = { disconnected }
283
+ this.disconnect = async () => {
284
+ return this._request({
285
+ method: "disconnect"
286
+ });
287
+ };
288
+ //unisat public methods
289
+ this.requestAccounts = async () => {
290
+ return this._request({
291
+ method: "requestAccounts"
292
+ });
293
+ };
294
+ this.getAccounts = async () => {
295
+ return this._request({
296
+ method: "getAccounts"
297
+ });
298
+ };
299
+ this.getPublicKey = async () => {
300
+ return this._request({
301
+ method: "getPublicKey"
302
+ });
303
+ };
304
+ //res = { address, balance }
305
+ this.getBalance = async () => {
306
+ return this._request({
307
+ method: "getBalance"
308
+ });
309
+ };
310
+ //res = {status === 'confirmed', confirmations > 1}
311
+ this.getTransactionStatus = async ({ txId }) => {
312
+ return this._request({
313
+ method: "getTransactionStatus",
314
+ params: { txId }
315
+ });
316
+ };
317
+ this.signMessage = async (text, type) => {
318
+ return this._request({
319
+ method: "signMessage",
320
+ params: {
321
+ text,
322
+ type
323
+ }
324
+ });
325
+ };
326
+ this.getNetwork = async () => {
327
+ return this._request({
328
+ method: "getNetwork"
329
+ });
330
+ };
331
+ this.switchNetwork = async (network) => {
332
+ return this._request({
333
+ method: "switchNetwork",
334
+ params: {
335
+ network
336
+ }
337
+ });
338
+ };
339
+ this.getChain = async () => {
340
+ return this._request({
341
+ method: "getChain"
342
+ });
343
+ };
344
+ this.switchChain = async (chainId) => {
345
+ return this._request({
346
+ method: "switchChain",
347
+ params: {
348
+ chainId
349
+ }
350
+ });
351
+ };
352
+ this.signPsbt = async (psbtHex, options) => {
353
+ return this._request({
354
+ method: "signPsbt",
355
+ params: {
356
+ psbtHex,
357
+ options: {
358
+ autoFinalized: options == null ? void 0 : options.autoFinalized
359
+ }
360
+ }
361
+ });
362
+ };
363
+ this.signPsbts = async (psbtHexs, options) => {
364
+ return this._request({
365
+ method: "signPsbts",
366
+ params: {
367
+ psbtHexs,
368
+ options
369
+ }
370
+ });
371
+ };
372
+ this.pushPsbt = async (psbtHex) => {
373
+ return this._request({
374
+ method: "pushPsbt",
375
+ params: {
376
+ psbtHex
377
+ }
378
+ });
379
+ };
380
+ this.sendBitcoin = async (toAddress, satoshis, options) => {
381
+ return this._request({
382
+ method: "sendBitcoin",
383
+ params: {
384
+ to: toAddress,
385
+ amount: satoshis,
386
+ feeRate: options == null ? void 0 : options.feeRate
387
+ }
388
+ });
389
+ };
390
+ this.signTx = async (rawtx) => {
391
+ return this._request({
392
+ method: "signTx",
393
+ params: {
394
+ rawtx
395
+ }
396
+ });
397
+ };
398
+ this.pushTx = async (rawtx) => {
399
+ return this._request({
400
+ method: "pushTx",
401
+ params: {
402
+ rawtx
403
+ }
404
+ });
405
+ };
406
+ this.name = productInfo.name;
407
+ this.rdns = productInfo.rdns;
408
+ this._handleAccountsChanged = this._handleAccountsChanged.bind(this);
409
+ this.setMaxListeners(100);
410
+ this.sendRequest = sendRequest;
411
+ this.onResponse = onResponse;
412
+ this.initialize();
413
+ }
414
+ _handleChainChanged({ chainId, isConnected } = {}) {
415
+ if (!chainId || typeof chainId !== "string" || !chainId.startsWith("0x")) {
416
+ return;
417
+ }
418
+ if (!isConnected || chainId === this.chainId || !this._state.initialized) {
419
+ return;
420
+ }
421
+ this.chainId = chainId;
422
+ this.emit("chainChanged", this.chainId);
423
+ }
424
+ _handleAccountsChanged(accounts) {
425
+ let _accounts = accounts;
426
+ if (!Array.isArray(accounts)) {
427
+ console.error("BTC: Received invalid accounts parameter.", accounts);
428
+ _accounts = [];
429
+ }
430
+ if (this._state.accounts !== _accounts) {
431
+ this._state.accounts = _accounts;
432
+ this._selectedAddress = _accounts[0];
433
+ if (this._state.initialized) {
434
+ this.emit("accountsChanged", accounts);
435
+ }
436
+ }
437
+ }
438
+ };
439
+ var chainType2 = "doge" /* DOGE */;
440
+ var DogecoinProvider = class extends events.EventEmitter {
441
+ constructor(productInfo, { sendRequest, onResponse }) {
442
+ super();
443
+ this._selectedAddress = null;
444
+ this._network = null;
445
+ this._isConnected = false;
446
+ this._initialized = false;
447
+ this._isUnlocked = false;
448
+ this.rdns = "";
449
+ this.name = "";
450
+ this._state = {
451
+ accounts: null,
452
+ isConnected: false,
453
+ isUnlocked: false,
454
+ initialized: false,
455
+ isPermanentlyDisconnected: false
456
+ };
457
+ this._requestPromise = new ReadyPromise(0);
458
+ this.initialize = async () => {
459
+ document.addEventListener("visibilitychange", async () => {
460
+ if (document.visibilityState === "visible") {
461
+ this._request({
462
+ method: "wallet_sendDomainMetadata",
463
+ params: await getDappInfo()
464
+ });
465
+ }
466
+ });
467
+ domReadyCall(async () => {
468
+ this._request({
469
+ method: "wallet_sendDomainMetadata",
470
+ params: await getDappInfo()
471
+ });
472
+ });
473
+ this._state.initialized = true;
474
+ this._state.isConnected = true;
475
+ this.keepAlive();
476
+ };
477
+ /**
478
+ * Sending a message to the extension to receive will keep the service worker alive.
479
+ */
480
+ this.keepAlive = () => {
481
+ this._request({
482
+ method: "keepAlive",
483
+ params: {}
484
+ }).then((v) => {
485
+ setTimeout(() => {
486
+ this.keepAlive();
487
+ }, 1e3);
488
+ });
489
+ };
490
+ //adapter data by reuqest function
491
+ this._request = async ({ method, params }, adapter) => {
492
+ if (!method) {
493
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest();
494
+ }
495
+ const dappInfo = await getDappInfo();
496
+ this.sendRequest(chainType2, { method, params, dappInfo });
497
+ return this.onResponse({ method }).then((res) => {
498
+ const { data } = res || {};
499
+ return adapter ? adapter(data) : data;
500
+ });
501
+ };
502
+ this.request = async ({ method, params }) => {
503
+ if (!method) {
504
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest();
505
+ }
506
+ return this._request({
507
+ method,
508
+ params
509
+ });
510
+ };
511
+ //res = { address, approved, balance, publicKey }
512
+ this.connect = async () => {
513
+ return this._request({
514
+ method: "connect",
515
+ params: {}
516
+ });
517
+ };
518
+ //res = { address, balance }
519
+ this.getBalance = async () => {
520
+ return this._request({
521
+ method: "getBalance"
522
+ });
523
+ };
524
+ //res = { disconnected }
525
+ this.disconnect = async () => {
526
+ return this._request({
527
+ method: "disconnect",
528
+ params: {}
529
+ });
530
+ };
531
+ //res = { "connected, address, selectedWalletAddress }
532
+ this.getConnectionStatus = async () => {
533
+ return this._request({
534
+ method: "getConnectionStatus",
535
+ params: {}
536
+ });
537
+ };
538
+ //res = { txId }
539
+ this.requestTransaction = async ({ recipientAddress, dogeAmount }) => {
540
+ return this._request({
541
+ method: "requestTransaction",
542
+ params: {
543
+ to: recipientAddress,
544
+ amount: dogeAmount,
545
+ type: 3 /* SEND_DOGECOIN */
546
+ }
547
+ });
548
+ };
549
+ //res = {status === 'confirmed', confirmations > 1}
550
+ this.getTransactionStatus = async ({ txId }) => {
551
+ return this._request({
552
+ method: "getTransactionStatus",
553
+ params: { txId }
554
+ });
555
+ };
556
+ //res = { signedMessage }
557
+ this.requestSignedMessage = async ({ message, type = "" }) => {
558
+ return this._request({
559
+ method: "requestSignedMessage",
560
+ params: {
561
+ text: message,
562
+ type
563
+ }
564
+ });
565
+ };
566
+ //res = { decryptedMessage }
567
+ this.requestDecryptedMessage = async ({ message }) => {
568
+ return this._request({
569
+ method: "requestDecryptedMessage",
570
+ params: {
571
+ message
572
+ }
573
+ });
574
+ };
575
+ //res = { signedMessage }
576
+ this.getDRC20Balances = async (address, ticker) => {
577
+ return this._request({
578
+ method: "getDRC20Balances",
579
+ params: {
580
+ address,
581
+ ticker
582
+ }
583
+ });
584
+ };
585
+ //res = { availableBalance, transferableBalance, ticker, address }
586
+ this.getDRC20Balance = async ({ ticker }) => {
587
+ return this._request({
588
+ method: "getDRC20Balance",
589
+ params: {
590
+ ticker
591
+ }
592
+ });
593
+ };
594
+ //res = { inscriptions, ticker, address }
595
+ this.getTransferableDRC20 = async ({ ticker }) => {
596
+ return this._request({
597
+ method: "getTransferableDRC20",
598
+ params: {
599
+ ticker
600
+ }
601
+ });
602
+ };
603
+ //res = { txId, ticker, amount }
604
+ this.requestAvailableDRC20Transaction = async ({ ticker, amount }) => {
605
+ return this._request({
606
+ method: "requestAvailableDRC20Transaction",
607
+ params: {
608
+ ticker,
609
+ amount
610
+ }
611
+ });
612
+ };
613
+ //res = { txId }
614
+ this.requestInscriptionTransaction = async ({
615
+ location,
616
+ recipientAddress
617
+ }) => {
618
+ return this._request({
619
+ method: "requestInscriptionTransaction",
620
+ params: {
621
+ location,
622
+ recipientAddress
623
+ }
624
+ });
625
+ };
626
+ //res = { ?signedRawTx, ?txId }
627
+ this.requestPsbt = async ({
628
+ rawTx,
629
+ indexes,
630
+ feeOnly,
631
+ signOnly,
632
+ partial,
633
+ sighashType
634
+ }) => {
635
+ return this._request({
636
+ method: "requestPsbt",
637
+ params: {
638
+ rawTx,
639
+ indexes,
640
+ feeOnly,
641
+ signOnly,
642
+ partial,
643
+ sighashType
644
+ }
645
+ });
646
+ };
647
+ //---------//dunes
648
+ this.getDunesBalance = async (params) => {
649
+ return this._request({
650
+ method: "getDunesBalance",
651
+ params
652
+ });
653
+ };
654
+ this.requestDunesTransaction = async ({
655
+ ticker,
656
+ amount,
657
+ recipientAddress
658
+ }) => {
659
+ return this._request({
660
+ method: "requestDunesTransaction",
661
+ params: {
662
+ ticker,
663
+ amount,
664
+ recipientAddress
665
+ }
666
+ });
667
+ };
668
+ this.name = productInfo.name;
669
+ this.rdns = productInfo.rdns;
670
+ this.setMaxListeners(100);
671
+ this.sendRequest = sendRequest;
672
+ this.onResponse = onResponse;
673
+ this.initialize();
674
+ }
675
+ };
676
+
677
+ // src/evm/messages.ts
678
+ var ProductInfo = { name: "ethereum.provider" };
679
+ var messages = {
680
+ errors: {
681
+ disconnected: () => `${ProductInfo.name}: Disconnected from chain. Attempting to connect.`,
682
+ permanentlyDisconnected: () => `${ProductInfo.name}: Disconnected from ${ProductInfo.name} background. Page reload required.`,
683
+ sendSiteMetadata: () => `${ProductInfo.name}: Failed to send site metadata. This is an internal error, please report this bug.`,
684
+ unsupportedSync: (method) => `${ProductInfo.name}: The ${ProductInfo.name} Ethereum provider does not support synchronous methods like ${method} without a callback parameter.`,
685
+ invalidDuplexStream: () => "Must provide a Node.js-style duplex stream.",
686
+ invalidOptions: (maxEventListeners, shouldSendMetadata) => `Invalid options. Received: { maxEventListeners: ${maxEventListeners}, shouldSendMetadata: ${shouldSendMetadata} }`,
687
+ invalidRequestArgs: () => `Expected a single, non-array, object argument.`,
688
+ invalidRequestMethod: () => `'args.method' must be a non-empty string.`,
689
+ invalidRequestParams: () => `'args.params' must be an object or array if provided.`,
690
+ invalidLoggerObject: () => `'args.logger' must be an object if provided.`,
691
+ invalidLoggerMethod: (method) => `'args.logger' must include required method '${method}'.`
692
+ },
693
+ warnings: {
694
+ // deprecated methods
695
+ enableDeprecation: `${ProductInfo.name}: 'ethereum.enable()' is deprecated and may be removed in the future. Please use the 'eth_requestAccounts' RPC method instead.
696
+ For more information, see: https://eips.ethereum.org/EIPS/eip-1102`,
697
+ sendDeprecation: `${ProductInfo.name}: 'ethereum.send(...)' is deprecated and may be removed in the future. Please use 'ethereum.sendAsync(...)' or 'ethereum.request(...)' instead.
698
+ For more information, see: https://eips.ethereum.org/EIPS/eip-1193`,
699
+ // deprecated events
700
+ events: {
701
+ close: `${ProductInfo.name}: The event 'close' is deprecated and may be removed in the future. Please use 'disconnect' instead.
702
+ For more information, see: https://eips.ethereum.org/EIPS/eip-1193#disconnect`,
703
+ data: `${ProductInfo.name}: The event 'data' is deprecated and will be removed in the future. Use 'message' instead.
704
+ For more information, see: https://eips.ethereum.org/EIPS/eip-1193#message`,
705
+ networkChanged: `${ProductInfo.name}: The event 'networkChanged' is deprecated and may be removed in the future. Use 'chainChanged' instead.
706
+ For more information, see: https://eips.ethereum.org/EIPS/eip-1193#chainchanged`,
707
+ notification: `${ProductInfo.name}: The event 'notification' is deprecated and may be removed in the future. Use 'message' instead.
708
+ For more information, see: https://eips.ethereum.org/EIPS/eip-1193#message`
709
+ }}
710
+ };
711
+ var messages_default = messages;
712
+ function createErrorMiddleware(log) {
713
+ return (req, res, next) => {
714
+ if (typeof req.method !== "string" || !req.method) {
715
+ res.error = ethRpcErrors.ethErrors.rpc.invalidRequest({
716
+ message: `The request 'method' must be a non-empty string.`,
717
+ data: req
718
+ });
719
+ }
720
+ next((done) => {
721
+ const { error } = res;
722
+ if (!error) {
723
+ return done();
724
+ }
725
+ log.error(`RPC Error: ${error.message}`, error);
726
+ return done();
727
+ });
728
+ };
729
+ }
730
+ var getRpcPromiseCallback = (resolve, reject, unwrapResult = true) => (error, response) => {
731
+ if (error || response.error) {
732
+ reject(error || response.error);
733
+ } else {
734
+ !unwrapResult || Array.isArray(response) ? resolve(response) : resolve(response.result);
735
+ }
736
+ };
737
+ function logStreamDisconnectWarning(log, remoteLabel, error, emitter) {
738
+ let warningMsg = `Lost connection to "${remoteLabel}".`;
739
+ if (error == null ? void 0 : error.stack) {
740
+ warningMsg += `
741
+ ${error.stack}`;
742
+ }
743
+ log.warn(warningMsg);
744
+ if (emitter && emitter.listenerCount("error") > 0) {
745
+ emitter.emit("error", warningMsg);
746
+ }
747
+ }
748
+ var NOOP = () => void 0;
749
+ var EMITTED_NOTIFICATIONS = [
750
+ "eth_subscription"
751
+ // per eth-json-rpc-filters/subscriptionManager
752
+ ];
753
+
754
+ // src/evm/metamask.ts
755
+ var chainType3 = "evm" /* EVM */;
756
+ var EvmProvider = class extends events.EventEmitter {
757
+ /**
758
+ * @param connectionStream - A Node.js duplex stream
759
+ * @param options - An options bag
760
+ * @param options.jsonRpcStreamName - The name of the internal JSON-RPC stream.
761
+ * @param options.logger - The logging API to use. Default: console
762
+ * @param options.maxEventListeners - The maximum number of event
763
+ * listeners. Default: 100
764
+ * @param options.shouldSendMetadata - Whether the provider should
765
+ * send page metadata. Default: true
766
+ */
767
+ constructor(productInfo, {
768
+ logger = console,
769
+ maxEventListeners = 100,
770
+ shouldSendMetadata = true,
771
+ sendRequest,
772
+ onResponse
773
+ }) {
774
+ if (typeof maxEventListeners !== "number" || typeof shouldSendMetadata !== "boolean") {
775
+ throw new Error(messages_default.errors.invalidOptions(maxEventListeners, shouldSendMetadata));
776
+ }
777
+ validateLoggerObject(logger);
778
+ super();
779
+ this.subscribeWalletEventsCallback = ({ method, data }) => {
780
+ if (method === "accountsChanged") {
781
+ const addresses = (data == null ? void 0 : data[chainType3]) || [];
782
+ const accounts = addresses.map(({ address }) => address);
783
+ this._handleAccountsChanged(accounts, true);
784
+ }
785
+ if (method === "chainChanged") {
786
+ const { chainId, type } = data;
787
+ if (type.indexOf(`${chainType3}:`) === 0) {
788
+ const chainIdHex = viem.toHex(parseInt(chainId));
789
+ this._handleChainChanged({ chainId: chainIdHex, isConnected: true });
790
+ }
791
+ }
792
+ };
793
+ this.keepAlive = () => {
794
+ this.request({
795
+ method: "keepAlive",
796
+ params: {}
797
+ }).then(() => {
798
+ setTimeout(() => {
799
+ this.keepAlive();
800
+ }, 1e3);
801
+ });
802
+ };
803
+ this._log = logger;
804
+ this.name = productInfo.name;
805
+ this.icon = productInfo.icon;
806
+ this.sendRequest = sendRequest;
807
+ this.onResponse = onResponse;
808
+ this.setMaxListeners(maxEventListeners);
809
+ this._state = {
810
+ sentWarnings: {
811
+ // methods
812
+ enable: false,
813
+ experimentalMethods: false,
814
+ send: false,
815
+ // events
816
+ events: {
817
+ close: false,
818
+ data: false,
819
+ networkChanged: false,
820
+ notification: false
821
+ }
822
+ },
823
+ accounts: null,
824
+ isConnected: false,
825
+ isUnlocked: false,
826
+ initialized: true,
827
+ isPermanentlyDisconnected: false
828
+ };
829
+ this.selectedAddress = null;
830
+ this.networkVersion = null;
831
+ this.chainId = null;
832
+ this._handleAccountsChanged = this._handleAccountsChanged.bind(this);
833
+ this._handleConnect = this._handleConnect.bind(this);
834
+ this._handleChainChanged = this._handleChainChanged.bind(this);
835
+ this._handleDisconnect = this._handleDisconnect.bind(this);
836
+ this._handleStreamDisconnect = this._handleStreamDisconnect.bind(this);
837
+ this._handleUnlockStateChanged = this._handleUnlockStateChanged.bind(this);
838
+ this._sendSync = this._sendSync.bind(this);
839
+ this._rpcRequest = this._rpcRequest.bind(this);
840
+ this._warnOfDeprecation = this._warnOfDeprecation.bind(this);
841
+ this.enable = this.enable.bind(this);
842
+ this.connect = this.connect.bind(this);
843
+ this.disconnect = this.disconnect.bind(this);
844
+ this.request = this.request.bind(this);
845
+ this.send = this.send.bind(this);
846
+ this.sendAsync = this.sendAsync.bind(this);
847
+ this.on("connect", () => {
848
+ this._state.isConnected = true;
849
+ });
850
+ const jsonRpcConnection = jsonRpcMiddlewareStream.createStreamMiddleware();
851
+ const rpcEngine = new jsonRpcEngine.JsonRpcEngine();
852
+ rpcEngine.push(jsonRpcEngine.createIdRemapMiddleware());
853
+ rpcEngine.push(createErrorMiddleware(this._log));
854
+ rpcEngine.push(jsonRpcConnection.middleware);
855
+ this._rpcEngine = rpcEngine;
856
+ this._initializeState();
857
+ jsonRpcConnection.events.on("notification", (payload) => {
858
+ const { method, params } = payload;
859
+ if (method === "wallet_accountsChanged") {
860
+ this._handleAccountsChanged(params);
861
+ } else if (method === "wallet_unlockStateChanged") {
862
+ this._handleUnlockStateChanged(params);
863
+ } else if (method === "wallet_chainChanged") {
864
+ this._handleChainChanged(params);
865
+ } else if (EMITTED_NOTIFICATIONS.includes(method)) {
866
+ this.emit("data", payload);
867
+ this.emit("message", {
868
+ type: method,
869
+ data: params
870
+ });
871
+ this.emit("notification", payload.params.result);
872
+ } else if (method === "WALLET_STREAM_FAILURE") {
873
+ console.error(messages_default.errors.permanentlyDisconnected());
874
+ }
875
+ });
876
+ }
877
+ //====================
878
+ // Public Methods
879
+ //====================
880
+ /**
881
+ * Returns whether the provider can process RPC requests.
882
+ */
883
+ isConnected() {
884
+ return this._state.isConnected;
885
+ }
886
+ /**
887
+ * Submits an RPC request for the given method, with the given params.
888
+ * Resolves with the result of the method call, or rejects on error.
889
+ *
890
+ * @param args - The RPC request arguments.
891
+ * @param args.method - The RPC method name.
892
+ * @param args.params - The parameters for the RPC method.
893
+ * @returns A Promise that resolves with the result of the RPC method,
894
+ * or rejects if an error is encountered.
895
+ */
896
+ async request(args) {
897
+ if (!args || typeof args !== "object" || Array.isArray(args)) {
898
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest({
899
+ message: messages_default.errors.invalidRequestArgs(),
900
+ data: args
901
+ });
902
+ }
903
+ const { method, params } = args;
904
+ if (typeof method !== "string" || method.length === 0) {
905
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest({
906
+ message: messages_default.errors.invalidRequestMethod(),
907
+ data: args
908
+ });
909
+ }
910
+ if (method === "wallet_addEthereumChain") {
911
+ if (!Array.isArray(params) || params.length === 0) {
912
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest({
913
+ message: messages_default.errors.invalidRequestParams(),
914
+ data: args
915
+ });
916
+ }
917
+ const network = params[0];
918
+ if (!network || !network.chainName || !network.rpcUrls || !network.chainId || !network.nativeCurrency) {
919
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest({
920
+ message: messages_default.errors.invalidRequestParams(),
921
+ data: args
922
+ });
923
+ }
924
+ }
925
+ if (method === "personal_sign") {
926
+ if (!Array.isArray(params) || params.length !== 2 || !params[0] || !params[1]) {
927
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest({
928
+ message: messages_default.errors.invalidRequestParams(),
929
+ data: args
930
+ });
931
+ }
932
+ }
933
+ if (method === "wallet_watchAsset") {
934
+ const { type, options } = params;
935
+ const isNotCompelete = !options || !options.address || !options.symbol || !options.decimals;
936
+ if (!type || isNotCompelete) {
937
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest({
938
+ message: messages_default.errors.invalidRequestParams(),
939
+ data: args
940
+ });
941
+ }
942
+ }
943
+ if (params !== void 0 && !Array.isArray(params) && (typeof params !== "object" || params === null)) {
944
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest({
945
+ message: messages_default.errors.invalidRequestParams(),
946
+ data: args
947
+ });
948
+ }
949
+ const connectFuns = {
950
+ enable: true,
951
+ connect: true,
952
+ eth_accounts: true,
953
+ eth_requestAccounts: true
954
+ };
955
+ const dappInfo = await getDappInfo();
956
+ args = __spreadValues(__spreadValues({}, args), { dappInfo });
957
+ this.sendRequest(chainType3, args);
958
+ return this.onResponse(args).then((res) => {
959
+ const { data, method: method2 } = res || {};
960
+ if (method2 === "_wallet_getProviderState") {
961
+ this._handleAccountsChanged((data == null ? void 0 : data.accounts) || [], true);
962
+ }
963
+ if (method2 === "wallet_revokePermissions") {
964
+ this._handleAccountsChanged([], true);
965
+ }
966
+ if (method2 in connectFuns && connectFuns[method2]) {
967
+ this._handleAccountsChanged(data || [], true);
968
+ }
969
+ if (method2 === "wallet_switchEthereumChain" || method2 === "eth_chainId") {
970
+ this._handleChainChanged({ chainId: data, isConnected: true });
971
+ }
972
+ return data;
973
+ });
974
+ }
975
+ /**
976
+ * Submits an RPC request per the given JSON-RPC request object.
977
+ *
978
+ * @param payload - The RPC request object.
979
+ * @param cb - The callback function.
980
+ */
981
+ sendAsync(payload, callback) {
982
+ this._rpcRequest(payload, callback);
983
+ }
984
+ /**
985
+ * We override the following event methods so that we can warn consumers
986
+ * about deprecated events:
987
+ * addListener, on, once, prependListener, prependOnceListener
988
+ */
989
+ addListener(eventName, listener) {
990
+ this._warnOfDeprecation(eventName);
991
+ return super.addListener(eventName, listener);
992
+ }
993
+ on(eventName, listener) {
994
+ this._warnOfDeprecation(eventName);
995
+ return super.on(eventName, listener);
996
+ }
997
+ once(eventName, listener) {
998
+ this._warnOfDeprecation(eventName);
999
+ return super.once(eventName, listener);
1000
+ }
1001
+ prependListener(eventName, listener) {
1002
+ this._warnOfDeprecation(eventName);
1003
+ return super.prependListener(eventName, listener);
1004
+ }
1005
+ prependOnceListener(eventName, listener) {
1006
+ this._warnOfDeprecation(eventName);
1007
+ return super.prependOnceListener(eventName, listener);
1008
+ }
1009
+ //====================
1010
+ // Private Methods
1011
+ //====================
1012
+ /**
1013
+ * Constructor helper.
1014
+ * Populates initial state by calling 'getProviderState' and emits
1015
+ * necessary events.
1016
+ */
1017
+ async _initializeState() {
1018
+ try {
1019
+ const {
1020
+ accounts = [],
1021
+ chainId = "0x01",
1022
+ isUnlocked = false,
1023
+ isConnected = false
1024
+ } = await this.request({
1025
+ method: "wallet_getProviderState"
1026
+ });
1027
+ this.emit("connect", { chainId });
1028
+ this._handleChainChanged({ chainId, isConnected });
1029
+ this._handleUnlockStateChanged({ accounts, isUnlocked });
1030
+ this._handleAccountsChanged(accounts);
1031
+ window.addEventListener("message", (event) => {
1032
+ const { data, type, method } = event.data;
1033
+ if (type === "subscribeWalletEvents" && method) {
1034
+ this.subscribeWalletEventsCallback({ data, method });
1035
+ }
1036
+ });
1037
+ } catch (error) {
1038
+ this._log.error(`${this.name}: Failed to get initial state.`, error);
1039
+ } finally {
1040
+ this._state.initialized = true;
1041
+ this.emit("_initialized");
1042
+ }
1043
+ this.keepAlive();
1044
+ }
1045
+ /**
1046
+ * Internal RPC method. Forwards requests to background via the RPC engine.
1047
+ * Also remap ids inbound and outbound.
1048
+ *
1049
+ * @param payload - The RPC request object.
1050
+ * @param callback - The consumer's callback.
1051
+ */
1052
+ _rpcRequest(payload, callback) {
1053
+ let cb = callback;
1054
+ if (!Array.isArray(payload)) {
1055
+ if (!payload.jsonrpc) {
1056
+ payload.jsonrpc = "2.0";
1057
+ }
1058
+ if (payload.method === "eth_accounts" || payload.method === "eth_requestAccounts") {
1059
+ cb = (err, res) => {
1060
+ this._handleAccountsChanged(res.result || [], payload.method === "eth_accounts");
1061
+ callback(err, res);
1062
+ };
1063
+ }
1064
+ return this._rpcEngine.handle(payload, cb);
1065
+ }
1066
+ return this._rpcEngine.handle(payload, cb);
1067
+ }
1068
+ /**
1069
+ * When the provider becomes connected, updates internal state and emits
1070
+ * required events. Idempotent.
1071
+ *
1072
+ * @param chainId - The ID of the newly connected chain.
1073
+ * @emits InpageProvider#connect
1074
+ */
1075
+ _handleConnect(chainId) {
1076
+ if (!this._state.isConnected) {
1077
+ this._state.isConnected = true;
1078
+ this.emit("connect", { chainId });
1079
+ }
1080
+ }
1081
+ /**
1082
+ * When the provider becomes disconnected, updates internal state and emits
1083
+ * required events. Idempotent with respect to the isRecoverable parameter.
1084
+ *
1085
+ * Error codes per the CloseEvent status codes as required by EIP-1193:
1086
+ * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
1087
+ *
1088
+ * @param isRecoverable - Whether the disconnection is recoverable.
1089
+ * @param errorMessage - A custom error message.
1090
+ * @emits InpageProvider#disconnect
1091
+ */
1092
+ _handleDisconnect(isRecoverable, errorMessage) {
1093
+ if (this._state.isConnected || !this._state.isPermanentlyDisconnected && !isRecoverable) {
1094
+ this._state.isConnected = false;
1095
+ let error;
1096
+ if (isRecoverable) {
1097
+ error = new ethRpcErrors.EthereumRpcError(
1098
+ 1013,
1099
+ // Try again later
1100
+ errorMessage || messages_default.errors.disconnected()
1101
+ );
1102
+ } else {
1103
+ error = new ethRpcErrors.EthereumRpcError(
1104
+ 1011,
1105
+ // Internal error
1106
+ errorMessage || messages_default.errors.permanentlyDisconnected()
1107
+ );
1108
+ this.chainId = null;
1109
+ this.networkVersion = null;
1110
+ this._state.accounts = null;
1111
+ this.selectedAddress = null;
1112
+ this._state.isUnlocked = false;
1113
+ this._state.isPermanentlyDisconnected = true;
1114
+ }
1115
+ this.emit("disconnect", error);
1116
+ this.emit("close", error);
1117
+ }
1118
+ }
1119
+ /**
1120
+ * Called when connection is lost to critical streams.
1121
+ *
1122
+ * @emits InpageProvider#disconnect
1123
+ */
1124
+ _handleStreamDisconnect(streamName, error) {
1125
+ logStreamDisconnectWarning(this._log, streamName, error, this);
1126
+ this._handleDisconnect(false, error ? error == null ? void 0 : error.message : void 0);
1127
+ }
1128
+ /**
1129
+ * Upon receipt of a new chainId and networkVersion, emits corresponding
1130
+ * events and sets relevant public state.
1131
+ * Does nothing if neither the chainId nor the networkVersion are different
1132
+ * from existing values.
1133
+ *
1134
+ * @emits InpageProvider#chainChanged
1135
+ * @param networkInfo - An object with network info.
1136
+ * @param networkInfo.chainId - The latest chain ID.
1137
+ * @param networkInfo.networkVersion - The latest network ID.
1138
+ */
1139
+ _handleChainChanged({ chainId, isConnected } = {}) {
1140
+ if (!chainId || typeof chainId !== "string" || !chainId.startsWith("0x")) {
1141
+ return;
1142
+ }
1143
+ if (!isConnected) {
1144
+ this._handleDisconnect(true);
1145
+ } else {
1146
+ this._handleConnect(chainId);
1147
+ if (chainId !== this.chainId) {
1148
+ this.chainId = chainId;
1149
+ if (this._state.initialized) {
1150
+ this.emit("chainChanged", this.chainId);
1151
+ }
1152
+ }
1153
+ }
1154
+ }
1155
+ /**
1156
+ * Called when accounts may have changed. Diffs the new accounts value with
1157
+ * the current one, updates all state as necessary, and emits the
1158
+ * accountsChanged event.
1159
+ *
1160
+ * @param accounts - The new accounts value.
1161
+ * @param isEthAccounts - Whether the accounts value was returned by
1162
+ * a call to eth_accounts.
1163
+ */
1164
+ _handleAccountsChanged(accounts, isEthAccounts = false) {
1165
+ let _accounts = accounts;
1166
+ if (!Array.isArray(accounts)) {
1167
+ this._log.error(`${this.name}: Received invalid accounts parameter.`, accounts);
1168
+ _accounts = [];
1169
+ }
1170
+ for (const account of accounts) {
1171
+ if (typeof account !== "string") {
1172
+ this._log.error(`${this.name}: Received non-string account.`, accounts);
1173
+ _accounts = [];
1174
+ break;
1175
+ }
1176
+ }
1177
+ if (this._state.accounts !== _accounts) {
1178
+ if (isEthAccounts && this._state.accounts !== null) ;
1179
+ this._state.accounts = _accounts;
1180
+ if (this.selectedAddress !== _accounts[0]) {
1181
+ this.selectedAddress = _accounts[0] || null;
1182
+ }
1183
+ if (this._state.initialized) {
1184
+ this.emit("accountsChanged", _accounts);
1185
+ }
1186
+ }
1187
+ }
1188
+ /**
1189
+ * Upon receipt of a new isUnlocked state, sets relevant public state.
1190
+ * Calls the accounts changed handler with the received accounts, or an empty
1191
+ * array.
1192
+ *
1193
+ * Does nothing if the received value is equal to the existing value.
1194
+ * There are no lock/unlock events.
1195
+ *
1196
+ * @param opts - Options bag.
1197
+ * @param opts.accounts - The exposed accounts, if any.
1198
+ * @param opts.isUnlocked - The latest isUnlocked value.
1199
+ */
1200
+ _handleUnlockStateChanged({ accounts, isUnlocked } = {}) {
1201
+ if (typeof isUnlocked !== "boolean") {
1202
+ this._log.error(`${this.name}: Received invalid isUnlocked parameter.`);
1203
+ return;
1204
+ }
1205
+ if (isUnlocked !== this._state.isUnlocked) {
1206
+ this._state.isUnlocked = isUnlocked;
1207
+ this._handleAccountsChanged(accounts || []);
1208
+ }
1209
+ }
1210
+ /**
1211
+ * Warns of deprecation for the given event, if applicable.
1212
+ */
1213
+ _warnOfDeprecation(eventName) {
1214
+ const events = this._state.sentWarnings.events;
1215
+ if (events[eventName] === false) {
1216
+ this._log.warn(messages_default.warnings.events[eventName]);
1217
+ events[eventName] = true;
1218
+ }
1219
+ }
1220
+ //====================
1221
+ // Deprecated Methods
1222
+ //====================
1223
+ /**
1224
+ * Equivalent to: ethereum.request('eth_requestAccounts')
1225
+ *
1226
+ * @deprecated Use request({ method: 'eth_requestAccounts' }) instead.
1227
+ * @returns A promise that resolves to an array of addresses.
1228
+ */
1229
+ enable() {
1230
+ return this.connect();
1231
+ }
1232
+ setConnectedStatus({ connected, address }) {
1233
+ this._state.isConnected = connected;
1234
+ this._state.accounts = address;
1235
+ }
1236
+ connect() {
1237
+ if (!this._state.sentWarnings.enable) {
1238
+ this._log.warn(messages_default.warnings.enableDeprecation);
1239
+ this._state.sentWarnings.enable = true;
1240
+ }
1241
+ return new Promise((resolve, reject) => {
1242
+ if (this._state.isConnected) {
1243
+ resolve(this._state.accounts);
1244
+ }
1245
+ try {
1246
+ this.request({
1247
+ method: "eth_requestAccounts"
1248
+ }).then((accounts) => {
1249
+ if (accounts) {
1250
+ this.emit("connect", {});
1251
+ resolve(accounts);
1252
+ } else {
1253
+ reject(new Error("No accounts returned"));
1254
+ }
1255
+ });
1256
+ } catch (error) {
1257
+ reject(error);
1258
+ }
1259
+ });
1260
+ }
1261
+ disconnect() {
1262
+ return new Promise((resolve, reject) => {
1263
+ try {
1264
+ (async () => {
1265
+ const { isConnected } = await this.request({
1266
+ method: "wallet_revokePermissions"
1267
+ });
1268
+ if (!isConnected) {
1269
+ this._handleDisconnect(true);
1270
+ this.emit("disconnect", null);
1271
+ }
1272
+ resolve(!isConnected);
1273
+ })();
1274
+ } catch (error) {
1275
+ reject(error);
1276
+ }
1277
+ });
1278
+ }
1279
+ send(methodOrPayload, callbackOrArgs) {
1280
+ if (!this._state.sentWarnings.send) {
1281
+ this._log.warn(messages_default.warnings.sendDeprecation);
1282
+ this._state.sentWarnings.send = true;
1283
+ }
1284
+ if (typeof methodOrPayload === "string" && (!callbackOrArgs || Array.isArray(callbackOrArgs))) {
1285
+ return new Promise((resolve, reject) => {
1286
+ try {
1287
+ this._rpcRequest(
1288
+ { method: methodOrPayload, params: callbackOrArgs },
1289
+ getRpcPromiseCallback(resolve, reject, false)
1290
+ );
1291
+ } catch (error) {
1292
+ reject(error);
1293
+ }
1294
+ });
1295
+ } else if (methodOrPayload && typeof methodOrPayload === "object" && typeof callbackOrArgs === "function") {
1296
+ return this._rpcRequest(
1297
+ methodOrPayload,
1298
+ callbackOrArgs
1299
+ );
1300
+ }
1301
+ return this._sendSync(methodOrPayload);
1302
+ }
1303
+ /**
1304
+ * Internal backwards compatibility method, used in send.
1305
+ *
1306
+ * @deprecated
1307
+ */
1308
+ _sendSync(payload) {
1309
+ let result;
1310
+ switch (payload.method) {
1311
+ case "eth_accounts":
1312
+ result = this.selectedAddress ? [this.selectedAddress] : [];
1313
+ break;
1314
+ case "eth_coinbase":
1315
+ result = this.selectedAddress || null;
1316
+ break;
1317
+ case "eth_uninstallFilter":
1318
+ this._rpcRequest(payload, NOOP);
1319
+ result = true;
1320
+ break;
1321
+ case "net_version":
1322
+ result = this.networkVersion || null;
1323
+ break;
1324
+ default:
1325
+ throw new Error(messages_default.errors.unsupportedSync(payload.method));
1326
+ }
1327
+ return {
1328
+ id: payload.id,
1329
+ jsonrpc: payload.jsonrpc,
1330
+ result
1331
+ };
1332
+ }
1333
+ };
1334
+ function validateLoggerObject(logger) {
1335
+ if (logger !== console) {
1336
+ if (typeof logger === "object") {
1337
+ const methodKeys = ["log", "warn", "error", "debug", "info", "trace"];
1338
+ for (const key of methodKeys) {
1339
+ if (typeof logger[key] !== "function") {
1340
+ throw new Error(messages_default.errors.invalidLoggerMethod(key));
1341
+ }
1342
+ }
1343
+ return;
1344
+ }
1345
+ throw new Error(messages_default.errors.invalidLoggerObject());
1346
+ }
1347
+ }
1348
+ var txToHex = (tx) => {
1349
+ if (typeof tx === "string") {
1350
+ return tx;
1351
+ }
1352
+ if ((tx == null ? void 0 : tx.message) && (tx == null ? void 0 : tx.signatures.length) > 0) {
1353
+ return Buffer.from(tx.serialize()).toString("hex");
1354
+ }
1355
+ return Buffer.from(
1356
+ tx.serialize({
1357
+ requireAllSignatures: false,
1358
+ verifySignatures: false
1359
+ })
1360
+ ).toString("hex");
1361
+ };
1362
+ var hexToTx = (hexString) => {
1363
+ try {
1364
+ const buffer = Buffer.from(hexString, "hex");
1365
+ try {
1366
+ return web3_js.VersionedTransaction.deserialize(buffer);
1367
+ } catch (e) {
1368
+ return web3_js.Transaction.from(buffer);
1369
+ }
1370
+ } catch (error) {
1371
+ throw new Error(`Failed to deserialize transaction: ${error}`);
1372
+ }
1373
+ };
1374
+
1375
+ // src/solana/phantom.ts
1376
+ var chainType4 = "sol" /* SOL */;
1377
+ var PhantomProvider = class extends events.EventEmitter {
1378
+ constructor(productInfo, { sendRequest, onResponse }) {
1379
+ super();
1380
+ this._isUnlocked = false;
1381
+ this.name = "";
1382
+ this.icon = "";
1383
+ this.publicKey = null;
1384
+ this.events = {
1385
+ connect: true,
1386
+ disconnect: true,
1387
+ accountChanged: true
1388
+ };
1389
+ this._state = {
1390
+ accounts: null,
1391
+ isConnected: false,
1392
+ isUnlocked: false,
1393
+ initialized: false,
1394
+ isPermanentlyDisconnected: false
1395
+ };
1396
+ // private _pushEventHandlers: PushEventHandlers;
1397
+ this._requestPromise = new ReadyPromise(0);
1398
+ this.initialize = async () => {
1399
+ document.addEventListener("visibilitychange", async () => {
1400
+ if (document.visibilityState === "visible") {
1401
+ this._request({
1402
+ method: "wallet_sendDomainMetadata",
1403
+ params: await getDappInfo()
1404
+ });
1405
+ }
1406
+ });
1407
+ domReadyCall(async () => {
1408
+ this._request({
1409
+ method: "wallet_sendDomainMetadata",
1410
+ params: await getDappInfo()
1411
+ });
1412
+ });
1413
+ window.addEventListener("message", (event) => {
1414
+ const { data, type, method } = event.data;
1415
+ if (type === "subscribeWalletEvents" && method) {
1416
+ this.subscribeWalletEventsCallback({ data, method });
1417
+ }
1418
+ });
1419
+ this.keepAlive();
1420
+ this._state.initialized = true;
1421
+ };
1422
+ this.subscribeWalletEventsCallback = ({ method, data }) => {
1423
+ if (method === "accountsChanged") {
1424
+ const accounts = data == null ? void 0 : data[chainType4];
1425
+ this._handleAccountsChanged(accounts);
1426
+ }
1427
+ };
1428
+ /**
1429
+ * Sending a message to the extension to receive will keep the service worker alive.
1430
+ */
1431
+ this.keepAlive = () => {
1432
+ this._request({
1433
+ method: "keepAlive",
1434
+ params: {}
1435
+ }).then(() => {
1436
+ setTimeout(() => {
1437
+ this.keepAlive();
1438
+ }, 1e3);
1439
+ });
1440
+ };
1441
+ this._request = async (data, responseAdaptor) => {
1442
+ if (!data || !data.method) {
1443
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest();
1444
+ }
1445
+ const dappInfo = await getDappInfo();
1446
+ this.sendRequest(chainType4, __spreadProps(__spreadValues({}, data), { dappInfo }));
1447
+ return this.onResponse(data).then((res) => {
1448
+ let { data: data2 } = res || {};
1449
+ if (data2 && data2.publicKey) {
1450
+ data2 = __spreadValues(__spreadValues({}, data2), { publicKey: new web3_js.PublicKey(data2.publicKey) });
1451
+ }
1452
+ if (data2 && data2.address && !data2.publicKey) {
1453
+ data2 = __spreadValues(__spreadValues({}, data2), { address: new web3_js.PublicKey(data2.address) });
1454
+ }
1455
+ if (responseAdaptor) {
1456
+ return responseAdaptor(data2);
1457
+ }
1458
+ return data2;
1459
+ });
1460
+ };
1461
+ this.request = async ({ method, params }, responseAdaptor) => {
1462
+ if (method === "signMessage") {
1463
+ const { message, display = "utf8" } = params;
1464
+ params = __spreadValues(__spreadValues({}, params), {
1465
+ message: new TextDecoder().decode(message),
1466
+ display
1467
+ });
1468
+ }
1469
+ const dappInfo = await getDappInfo();
1470
+ return this._request(
1471
+ {
1472
+ method,
1473
+ params: __spreadValues(__spreadValues({}, dappInfo), params || {})
1474
+ },
1475
+ responseAdaptor
1476
+ );
1477
+ };
1478
+ //phantom api
1479
+ this.connect = async (params) => {
1480
+ const dappInfo = await getDappInfo();
1481
+ return this._request(
1482
+ {
1483
+ method: "connect",
1484
+ params: __spreadValues(__spreadValues({}, dappInfo), params || {})
1485
+ },
1486
+ (data) => {
1487
+ this.emit("connect", true);
1488
+ this.publicKey = data == null ? void 0 : data.publicKey;
1489
+ return data;
1490
+ }
1491
+ );
1492
+ };
1493
+ this.disconnect = async () => {
1494
+ return this._request(
1495
+ {
1496
+ method: "disconnect",
1497
+ params: await getDappInfo()
1498
+ },
1499
+ (data) => {
1500
+ this.emit("disconnect", true);
1501
+ this.publicKey = null;
1502
+ return data;
1503
+ }
1504
+ );
1505
+ };
1506
+ this.getAccount = async () => {
1507
+ return this._request({
1508
+ method: "getAccount",
1509
+ params: {}
1510
+ });
1511
+ };
1512
+ this.signMessage = async (message, display) => {
1513
+ return this._request(
1514
+ {
1515
+ method: "signMessage",
1516
+ params: {
1517
+ message: new TextDecoder().decode(message),
1518
+ display
1519
+ }
1520
+ },
1521
+ (data) => {
1522
+ if (data && data.signedMessage) {
1523
+ data = __spreadValues(__spreadValues({}, data), { signedMessage: new TextEncoder().encode(data.signedMessage) });
1524
+ }
1525
+ if (data && data.signature) {
1526
+ const signature = hexToUint8Array(data.signature);
1527
+ data = __spreadValues(__spreadValues({}, data), { signature });
1528
+ }
1529
+ return data;
1530
+ }
1531
+ );
1532
+ };
1533
+ //doc: https://github.com/phantom/sign-in-with-solana
1534
+ this.signIn = async (params) => {
1535
+ const { domain = window.location.host, statement, nonce, version, issuedAt, resources = [] } = params || {};
1536
+ const address = this.publicKey ? this.publicKey.toString() : "";
1537
+ let message = `${domain} wants you to sign in with your Solana account:
1538
+ ${address}`;
1539
+ if (statement) {
1540
+ message += `
1541
+
1542
+ ${statement}`;
1543
+ }
1544
+ if (version) {
1545
+ message += `
1546
+
1547
+ Version:${version}`;
1548
+ }
1549
+ if (nonce) {
1550
+ message += `
1551
+ Nonce:${nonce}`;
1552
+ }
1553
+ if (issuedAt) {
1554
+ message += `
1555
+ Issued At:${issuedAt}`;
1556
+ }
1557
+ if (resources.length > 0) {
1558
+ message += `
1559
+ Resources:`;
1560
+ resources.forEach((resource) => {
1561
+ message += `
1562
+ - ${resource}`;
1563
+ });
1564
+ }
1565
+ return this._request(
1566
+ {
1567
+ method: "signIn",
1568
+ params: {
1569
+ message
1570
+ }
1571
+ },
1572
+ (data) => {
1573
+ if (data && data.signedMessage) {
1574
+ data = __spreadValues(__spreadValues({}, data), { signedMessage: new TextEncoder().encode(data.signedMessage) });
1575
+ }
1576
+ if (data && data.signature) {
1577
+ const signature = hexToUint8Array(data.signature);
1578
+ data = __spreadValues(__spreadValues({}, data), { signature });
1579
+ }
1580
+ return data;
1581
+ }
1582
+ );
1583
+ };
1584
+ this.signTransaction = async (tx) => {
1585
+ return this._request(
1586
+ {
1587
+ method: "signTransaction",
1588
+ params: {
1589
+ rawTransaction: txToHex(tx)
1590
+ }
1591
+ },
1592
+ (data) => {
1593
+ return hexToTx(data.signature);
1594
+ }
1595
+ );
1596
+ };
1597
+ this.signAllTransactions = async (txs) => {
1598
+ const rawTransactions = [];
1599
+ for (const tx of txs) {
1600
+ rawTransactions.push(txToHex(tx));
1601
+ }
1602
+ return this._request(
1603
+ {
1604
+ method: "signAllTransactions",
1605
+ params: {
1606
+ rawTransactions
1607
+ }
1608
+ },
1609
+ (data) => {
1610
+ return data;
1611
+ }
1612
+ );
1613
+ };
1614
+ this.signAndSendTransaction = async (tx) => {
1615
+ return this._request(
1616
+ {
1617
+ method: "signAndSendTransaction",
1618
+ params: {
1619
+ rawTransaction: txToHex(tx)
1620
+ }
1621
+ },
1622
+ (data) => {
1623
+ if (data && data.signature) {
1624
+ const signature = bs58__default.default.decode(data.signature);
1625
+ data = __spreadValues(__spreadValues({}, data), { signature });
1626
+ }
1627
+ return data;
1628
+ }
1629
+ );
1630
+ };
1631
+ this.signAndSendAllTransactions = async (txs) => {
1632
+ const rawTransactions = [];
1633
+ for (const tx of txs) {
1634
+ rawTransactions.push(txToHex(tx));
1635
+ }
1636
+ return this._request({
1637
+ method: "signAndSendAllTransactions",
1638
+ params: {
1639
+ rawTransactions
1640
+ }
1641
+ });
1642
+ };
1643
+ this.sendSolana = async (tx) => {
1644
+ return this._request(
1645
+ {
1646
+ method: "sendSolana",
1647
+ intent: true,
1648
+ params: tx
1649
+ },
1650
+ (data) => {
1651
+ if (data && data.signature) {
1652
+ const signature = isHexString(data.signature) ? hexToUint8Array(data.signature) : bs58__default.default.decode(data.signature);
1653
+ data = __spreadValues(__spreadValues({}, data), { signature });
1654
+ }
1655
+ return data;
1656
+ }
1657
+ );
1658
+ };
1659
+ this.sendToken = async (tx) => {
1660
+ return this._request(
1661
+ {
1662
+ method: "sendToken",
1663
+ intent: true,
1664
+ params: tx
1665
+ },
1666
+ (data) => {
1667
+ if (data && data.signature) {
1668
+ const signature = isHexString(data.signature) ? hexToUint8Array(data.signature) : bs58__default.default.decode(data.signature);
1669
+ data = __spreadValues(__spreadValues({}, data), { signature });
1670
+ }
1671
+ return data;
1672
+ }
1673
+ );
1674
+ };
1675
+ this.setMaxListeners(100);
1676
+ this.name = productInfo.name;
1677
+ this.icon = productInfo.icon;
1678
+ this.sendRequest = sendRequest;
1679
+ this.onResponse = onResponse;
1680
+ this.initialize();
1681
+ this._handleAccountsChanged = this._handleAccountsChanged.bind(this);
1682
+ this.on("connect", () => {
1683
+ this._state.isConnected = true;
1684
+ });
1685
+ }
1686
+ on(eventName, listener) {
1687
+ if (!this.events[eventName]) {
1688
+ throw Error("${eventName} no supported.");
1689
+ }
1690
+ return super.on(eventName, listener);
1691
+ }
1692
+ _handleAccountsChanged(accounts) {
1693
+ let _accounts = accounts;
1694
+ if (!Array.isArray(accounts)) {
1695
+ console.error(`${this.name}: Received invalid accounts parameter.`, accounts);
1696
+ _accounts = [];
1697
+ }
1698
+ if (this._state.accounts !== _accounts) {
1699
+ this._state.accounts = _accounts;
1700
+ const { publicKey, address } = _accounts[0] || {};
1701
+ const currentPublicKey = publicKey || address;
1702
+ if (currentPublicKey) {
1703
+ this.publicKey = new web3_js.PublicKey(currentPublicKey);
1704
+ }
1705
+ if (this._state.initialized) {
1706
+ this.emit("accountChanged", this.publicKey);
1707
+ }
1708
+ }
1709
+ }
1710
+ };
1711
+ var chainType5 = "tron" /* TRON */;
1712
+ var TomoTronProvider = class extends events.EventEmitter {
1713
+ constructor(productInfo, { sendRequest, onResponse }) {
1714
+ super();
1715
+ this._isUnlocked = false;
1716
+ this.name = "";
1717
+ this.icon = "";
1718
+ this.ready = false;
1719
+ this.tronWeb = null;
1720
+ this.events = {
1721
+ connect: true,
1722
+ disconnect: true,
1723
+ accountChanged: true
1724
+ };
1725
+ this._state = {
1726
+ accounts: null,
1727
+ isConnected: false,
1728
+ isUnlocked: false,
1729
+ initialized: false,
1730
+ isPermanentlyDisconnected: false
1731
+ };
1732
+ // private _pushEventHandlers: PushEventHandlers;
1733
+ this._requestPromise = new ReadyPromise(0);
1734
+ this._initTronWeb = async (res) => {
1735
+ const { fullHost = "https://api.trongrid.io", address } = res || {};
1736
+ this.tronWeb = new tronweb.TronWeb({
1737
+ fullHost
1738
+ });
1739
+ this.tronWeb.defaultAddress.base58 = address;
1740
+ this.tronWeb.defaultAddress.hex = tronweb.TronWeb.address.toHex(address);
1741
+ this.tronWeb["request"] = async ({ method, params }) => {
1742
+ return await this.request({ method, params });
1743
+ };
1744
+ const trx = this.tronWeb.trx;
1745
+ this.tronWeb.trx = new Proxy(trx, {
1746
+ get: (target, prop) => {
1747
+ switch (prop) {
1748
+ case "sign":
1749
+ case "signMessage":
1750
+ throw new Error("Not supported");
1751
+ case "signMessageV2":
1752
+ return async (message, privateKey) => {
1753
+ return await this.signMessage(message);
1754
+ };
1755
+ case "multiSign":
1756
+ return async (transaction, privateKey) => {
1757
+ const signedTransaction = await this.signTransaction(transaction);
1758
+ return signedTransaction;
1759
+ };
1760
+ case "sendTransaction":
1761
+ return async (to, amount) => {
1762
+ const signedTransaction = await this.sendTransaction({ from: address, to, amount });
1763
+ return signedTransaction;
1764
+ };
1765
+ case "sendToken":
1766
+ return async (to, amount, tokenId) => {
1767
+ const signedTransaction = await this.sendToken({ from: address, to, amount, tokenAddress: tokenId });
1768
+ return signedTransaction;
1769
+ };
1770
+ // case "sendRawTransaction":
1771
+ // return async (transaction: Transaction, privateKey?: string) => {
1772
+ // const res = await this.sendRawTransaction(transaction);
1773
+ // return res;
1774
+ // };
1775
+ default:
1776
+ return Reflect.get(target, prop);
1777
+ }
1778
+ }
1779
+ });
1780
+ };
1781
+ this.initialize = async () => {
1782
+ document.addEventListener("visibilitychange", async () => {
1783
+ if (document.visibilityState === "visible") {
1784
+ this._request({
1785
+ method: "wallet_sendDomainMetadata",
1786
+ params: await getDappInfo()
1787
+ });
1788
+ }
1789
+ });
1790
+ domReadyCall(async () => {
1791
+ this._request({
1792
+ method: "wallet_sendDomainMetadata",
1793
+ params: await getDappInfo()
1794
+ });
1795
+ });
1796
+ window.addEventListener("message", (event) => {
1797
+ const { data, type, method } = event.data;
1798
+ if (type === "subscribeWalletEvents" && method) {
1799
+ this.subscribeWalletEventsCallback({ data, method });
1800
+ }
1801
+ });
1802
+ this._state.initialized = true;
1803
+ };
1804
+ this.subscribeWalletEventsCallback = ({ method, data }) => {
1805
+ if (method === "accountsChanged") {
1806
+ const accounts = data == null ? void 0 : data[chainType5];
1807
+ this._handleAccountsChanged(accounts);
1808
+ }
1809
+ };
1810
+ this._request = async (data, responseAdaptor) => {
1811
+ if (!data || !data.method) {
1812
+ throw ethRpcErrors.ethErrors.rpc.invalidRequest();
1813
+ }
1814
+ const dappInfo = await getDappInfo();
1815
+ this.sendRequest(chainType5, __spreadProps(__spreadValues({}, data), { dappInfo }));
1816
+ return this.onResponse(data).then((res) => {
1817
+ const { data: data2, method } = res || {};
1818
+ if (method === "tron_requestAccounts") {
1819
+ this.emit("connect", data2);
1820
+ }
1821
+ if (responseAdaptor) {
1822
+ return responseAdaptor(data2);
1823
+ }
1824
+ return data2;
1825
+ });
1826
+ };
1827
+ this.request = async ({ method, params }, responseAdaptor) => {
1828
+ return this._request(
1829
+ {
1830
+ method,
1831
+ params
1832
+ },
1833
+ responseAdaptor
1834
+ );
1835
+ };
1836
+ //tronLink api
1837
+ this.connect = async () => {
1838
+ return this._request(
1839
+ {
1840
+ method: "connect"
1841
+ },
1842
+ (data) => {
1843
+ this.emit("connect", data);
1844
+ this.ready = true;
1845
+ return data;
1846
+ }
1847
+ );
1848
+ };
1849
+ this.disconnect = async () => {
1850
+ return this._request(
1851
+ {
1852
+ method: "disconnect"
1853
+ },
1854
+ (data) => {
1855
+ this.emit("disconnect", true);
1856
+ this.ready = false;
1857
+ return data;
1858
+ }
1859
+ );
1860
+ };
1861
+ this.signMessage = async (message) => {
1862
+ return this._request(
1863
+ {
1864
+ method: "signMessage",
1865
+ params: {
1866
+ message
1867
+ }
1868
+ },
1869
+ (data) => {
1870
+ return data;
1871
+ }
1872
+ );
1873
+ };
1874
+ this.signTransaction = async (transaction) => {
1875
+ return this._request(
1876
+ {
1877
+ method: "signTransaction",
1878
+ params: {
1879
+ transaction
1880
+ }
1881
+ },
1882
+ (data) => {
1883
+ return data;
1884
+ }
1885
+ );
1886
+ };
1887
+ this.sendRawTransaction = async (transaction) => {
1888
+ return this._request(
1889
+ {
1890
+ method: "sendRawTransaction",
1891
+ params: {
1892
+ transaction
1893
+ }
1894
+ },
1895
+ (data) => {
1896
+ return data;
1897
+ }
1898
+ );
1899
+ };
1900
+ this.sendTransaction = async (params) => {
1901
+ return this._request(
1902
+ {
1903
+ method: "sendTransaction",
1904
+ params
1905
+ },
1906
+ (data) => {
1907
+ return data;
1908
+ }
1909
+ );
1910
+ };
1911
+ this.sendToken = async (params) => {
1912
+ return this._request(
1913
+ {
1914
+ method: "sendToken",
1915
+ params
1916
+ },
1917
+ (data) => {
1918
+ return data;
1919
+ }
1920
+ );
1921
+ };
1922
+ this.setMaxListeners(100);
1923
+ this.name = productInfo.name;
1924
+ this.icon = productInfo.icon;
1925
+ this.sendRequest = sendRequest;
1926
+ this.onResponse = onResponse;
1927
+ this.initialize();
1928
+ this._handleAccountsChanged = this._handleAccountsChanged.bind(this);
1929
+ this.on("connect", (res) => {
1930
+ this._state.isConnected = true;
1931
+ this._initTronWeb(res);
1932
+ window.postMessage(
1933
+ {
1934
+ message: {
1935
+ action: "connect",
1936
+ data: res
1937
+ }
1938
+ },
1939
+ window.location.origin
1940
+ );
1941
+ });
1942
+ this.on("disconnect", (result) => {
1943
+ this._state.isConnected = false;
1944
+ this.tronWeb = null;
1945
+ window.postMessage(
1946
+ {
1947
+ message: {
1948
+ action: "disconnect",
1949
+ data: result
1950
+ }
1951
+ },
1952
+ window.location.origin
1953
+ );
1954
+ });
1955
+ this.on("accountChanged", (address) => {
1956
+ window.postMessage(
1957
+ {
1958
+ message: {
1959
+ action: "accountChanged",
1960
+ data: {
1961
+ address
1962
+ }
1963
+ }
1964
+ },
1965
+ window.location.origin
1966
+ );
1967
+ });
1968
+ }
1969
+ on(eventName, listener) {
1970
+ if (!this.events[eventName]) {
1971
+ throw Error("${eventName} no supported.");
1972
+ }
1973
+ return super.on(eventName, listener);
1974
+ }
1975
+ _handleAccountsChanged(accounts) {
1976
+ let _accounts = accounts;
1977
+ if (!Array.isArray(accounts)) {
1978
+ console.error(`${this.name}: Received invalid accounts parameter.`, accounts);
1979
+ _accounts = [];
1980
+ }
1981
+ if (this._state.accounts !== _accounts) {
1982
+ this._state.accounts = _accounts;
1983
+ const { address } = _accounts[0] || {};
1984
+ if (this._state.initialized) {
1985
+ this.emit("accountChanged", address);
1986
+ }
1987
+ }
1988
+ }
1989
+ };
1990
+
1991
+ exports.BtcProvider = BtcProvider;
1992
+ exports.DogecoinProvider = DogecoinProvider;
1993
+ exports.EvmProvider = EvmProvider;
1994
+ exports.SolanaProvider = PhantomProvider;
1995
+ exports.TronProvider = TomoTronProvider;