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