@phantom/browser-injected-sdk 1.0.0-beta.9 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
- import { P as Plugin } from '../index-3a750f13.js';
1
+ import { P as Plugin } from '../index-673af1e4.js';
2
2
  import { NetworkId } from '@phantom/constants';
3
+ import '@phantom/chain-interfaces';
3
4
 
4
5
  type AutoConfirmEnableParams = {
5
6
  chains?: NetworkId[];
@@ -3,6 +3,129 @@ import {
3
3
  __privateMethod
4
4
  } from "./chunk-GV6AIHPN.mjs";
5
5
 
6
+ // src/ethereum/siwe.ts
7
+ var ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
8
+ var DOMAIN_REGEX = /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(:[0-9]{1,5})?$/;
9
+ var IP_REGEX = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(:[0-9]{1,5})?$/;
10
+ var LOCALHOST_REGEX = /^localhost(:[0-9]{1,5})?$/;
11
+ var NONCE_REGEX = /^[a-zA-Z0-9]{8,}$/;
12
+ var SCHEME_REGEX = /^([a-zA-Z][a-zA-Z0-9+-.]*)$/;
13
+ function createSiweMessage({
14
+ address,
15
+ chainId,
16
+ domain,
17
+ nonce,
18
+ uri,
19
+ version,
20
+ scheme,
21
+ statement: _statement,
22
+ requestId,
23
+ resources,
24
+ issuedAt = /* @__PURE__ */ new Date(),
25
+ expirationTime,
26
+ notBefore
27
+ }) {
28
+ if (!ADDRESS_REGEX.test(address)) {
29
+ throw new Error("address must be a hex value of 20 bytes (40 hex characters).");
30
+ }
31
+ if (chainId !== Math.floor(chainId)) {
32
+ throw new Error("chainId must be a EIP-155 chain ID.");
33
+ }
34
+ if (!(DOMAIN_REGEX.test(domain) || IP_REGEX.test(domain) || LOCALHOST_REGEX.test(domain))) {
35
+ throw new Error("domain must be an RFC 3986 authority.");
36
+ }
37
+ if (!NONCE_REGEX.test(nonce)) {
38
+ throw new Error("nonce must be at least 8 characters.");
39
+ }
40
+ if (!_isUri(uri)) {
41
+ throw new Error("uri must be a RFC 3986 URI referring to the resource that is the subject of the signing.");
42
+ }
43
+ if (version !== "1") {
44
+ throw new Error("version must be '1'.");
45
+ }
46
+ if (scheme && !SCHEME_REGEX.test(scheme)) {
47
+ throw new Error("scheme must be an RFC 3986 URI scheme.");
48
+ }
49
+ if (_statement?.includes("\n")) {
50
+ throw new Error("statement must not include '\\n'.");
51
+ }
52
+ const origin = scheme ? `${scheme}://${domain}` : domain;
53
+ const statement = _statement ? `${_statement}
54
+ ` : "";
55
+ const prefix = `${origin} wants you to sign in with your Ethereum account:
56
+ ${address}
57
+
58
+ ${statement}`;
59
+ let suffix = `URI: ${uri}
60
+ Version: ${version}
61
+ Chain ID: ${chainId}
62
+ Nonce: ${nonce}
63
+ Issued At: ${issuedAt.toISOString()}`;
64
+ if (expirationTime) {
65
+ suffix += `
66
+ Expiration Time: ${expirationTime.toISOString()}`;
67
+ }
68
+ if (notBefore) {
69
+ suffix += `
70
+ Not Before: ${notBefore.toISOString()}`;
71
+ }
72
+ if (requestId) {
73
+ suffix += `
74
+ Request ID: ${requestId}`;
75
+ }
76
+ if (resources) {
77
+ let content = "\nResources:";
78
+ for (const resource of resources) {
79
+ if (!_isUri(resource)) {
80
+ throw new Error("resources must be RFC 3986 URIs.");
81
+ }
82
+ content += `
83
+ - ${resource}`;
84
+ }
85
+ suffix += content;
86
+ }
87
+ return `${prefix}
88
+ ${suffix}`;
89
+ }
90
+ function _isUri(value) {
91
+ if (/[^a-z0-9:/?#[\]@!$&'()*+,;=.\-_~%]/i.test(value))
92
+ return false;
93
+ if (/%[^0-9a-f]/i.test(value))
94
+ return false;
95
+ if (/%[0-9a-f](:?[^0-9a-f]|$)/i.test(value))
96
+ return false;
97
+ const splitted = splitUri(value);
98
+ const scheme = splitted[1];
99
+ const authority = splitted[2];
100
+ const path = splitted[3];
101
+ const query = splitted[4];
102
+ const fragment = splitted[5];
103
+ if (!(scheme?.length && path.length >= 0))
104
+ return false;
105
+ if (authority?.length) {
106
+ if (!(path.length === 0 || /^\//.test(path)))
107
+ return false;
108
+ } else {
109
+ if (/^\/\//.test(path))
110
+ return false;
111
+ }
112
+ if (!/^[a-z][a-z0-9+\-.]*$/.test(scheme.toLowerCase()))
113
+ return false;
114
+ let out = "";
115
+ out += `${scheme}:`;
116
+ if (authority?.length)
117
+ out += `//${authority}`;
118
+ out += path;
119
+ if (query?.length)
120
+ out += `?${query}`;
121
+ if (fragment?.length)
122
+ out += `#${fragment}`;
123
+ return out;
124
+ }
125
+ function splitUri(value) {
126
+ return value.match(/(?:([^:/?#]+):)?(?:\/\/([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);
127
+ }
128
+
6
129
  // src/ethereum/strategies/injected.ts
7
130
  var MAX_RETRIES = 4;
8
131
  var BASE_DELAY = 100;
@@ -119,7 +242,7 @@ var InjectedEthereumStrategy = class {
119
242
  if (!provider) {
120
243
  throw new Error("Provider not found.");
121
244
  }
122
- const message = `Sign in to ${signInData.domain || "this application"}`;
245
+ const message = createSiweMessage(signInData);
123
246
  const address = provider.selectedAddress;
124
247
  if (!address) {
125
248
  throw new Error("No address available.");
@@ -215,7 +338,7 @@ function addEventListener(event, callback) {
215
338
  eventListeners.set(event, /* @__PURE__ */ new Set());
216
339
  }
217
340
  const listeners = eventListeners.get(event);
218
- listeners.add(callback);
341
+ listeners?.add(callback);
219
342
  return () => removeEventListener(event, callback);
220
343
  }
221
344
  function removeEventListener(event, callback) {
@@ -289,16 +412,6 @@ async function getAccounts() {
289
412
  }
290
413
 
291
414
  // src/ethereum/signMessage.ts
292
- async function signMessage(message, address) {
293
- const provider = await getProvider();
294
- if (!provider) {
295
- throw new Error("Provider not found.");
296
- }
297
- if (!provider.isConnected) {
298
- await provider.connect({ onlyIfTrusted: false });
299
- }
300
- return provider.signMessage(message, address);
301
- }
302
415
  async function signPersonalMessage(message, address) {
303
416
  const provider = await getProvider();
304
417
  if (!provider) {
@@ -320,18 +433,6 @@ async function signTypedData(typedData, address) {
320
433
  return provider.signTypedData(typedData, address);
321
434
  }
322
435
 
323
- // src/ethereum/signIn.ts
324
- async function signIn(signInData) {
325
- const provider = await getProvider();
326
- if (!provider) {
327
- throw new Error("Provider not found.");
328
- }
329
- if (!provider.isConnected) {
330
- await provider.connect({ onlyIfTrusted: false });
331
- }
332
- return provider.signIn(signInData);
333
- }
334
-
335
436
  // src/ethereum/sendTransaction.ts
336
437
  async function sendTransaction(transaction) {
337
438
  const provider = await getProvider();
@@ -371,51 +472,127 @@ async function switchChain(chainId) {
371
472
  }
372
473
 
373
474
  // src/ethereum/plugin.ts
374
- var ethereum = {
375
- connect,
376
- disconnect,
377
- getAccounts,
378
- signMessage,
379
- signPersonalMessage,
380
- signTypedData,
381
- signIn,
382
- sendTransaction,
383
- signTransaction,
384
- getChainId,
385
- switchChain,
386
- getProvider,
387
- addEventListener,
388
- removeEventListener
389
- };
390
- async function bindProviderEvents() {
391
- try {
392
- const strategy = await getProvider();
393
- const provider = strategy.getProvider();
394
- if (provider) {
395
- provider.on("connect", () => {
396
- provider.request({ method: "eth_accounts" }).then((accounts) => {
397
- if (accounts?.length > 0)
475
+ var Ethereum = class {
476
+ constructor() {
477
+ this._chainId = "0x1";
478
+ this._accounts = [];
479
+ this.bindProviderEvents();
480
+ }
481
+ get connected() {
482
+ return this._accounts.length > 0;
483
+ }
484
+ get chainId() {
485
+ return this._chainId;
486
+ }
487
+ get accounts() {
488
+ return this._accounts;
489
+ }
490
+ async request(args) {
491
+ const provider = await getProvider();
492
+ if (!provider) {
493
+ throw new Error("Provider not found.");
494
+ }
495
+ const providerInstance = provider.getProvider();
496
+ if (!providerInstance) {
497
+ throw new Error("Provider instance not found.");
498
+ }
499
+ return providerInstance.request(args);
500
+ }
501
+ async connect() {
502
+ const accounts = await connect();
503
+ this._accounts = accounts;
504
+ return accounts;
505
+ }
506
+ async disconnect() {
507
+ await disconnect();
508
+ this._accounts = [];
509
+ }
510
+ signPersonalMessage(message, address) {
511
+ return signPersonalMessage(message, address);
512
+ }
513
+ signTypedData(data, address) {
514
+ return signTypedData(data, address);
515
+ }
516
+ signTransaction(transaction) {
517
+ return signTransaction(transaction);
518
+ }
519
+ sendTransaction(transaction) {
520
+ return sendTransaction(transaction);
521
+ }
522
+ async switchChain(chainId) {
523
+ const hexChainId = typeof chainId === "string" ? chainId.toLowerCase().startsWith("0x") ? chainId.toLowerCase() : `0x${parseInt(chainId, 10).toString(16)}` : `0x${chainId.toString(16)}`;
524
+ await switchChain(hexChainId);
525
+ this._chainId = hexChainId;
526
+ }
527
+ async getChainId() {
528
+ const chainId = await getChainId();
529
+ const parsed = parseInt(chainId, 16);
530
+ this._chainId = chainId;
531
+ return parsed;
532
+ }
533
+ async getAccounts() {
534
+ const accounts = await getAccounts();
535
+ this._accounts = accounts;
536
+ return accounts;
537
+ }
538
+ isConnected() {
539
+ return this._accounts.length > 0;
540
+ }
541
+ on(event, listener) {
542
+ addEventListener(event, listener);
543
+ }
544
+ off(event, listener) {
545
+ removeEventListener(event, listener);
546
+ }
547
+ async bindProviderEvents() {
548
+ try {
549
+ const strategy = await getProvider();
550
+ const provider = strategy.getProvider();
551
+ if (provider) {
552
+ provider.on("connect", async () => {
553
+ try {
554
+ const accounts = await provider.request({ method: "eth_accounts" });
555
+ if (accounts?.length > 0) {
556
+ this._accounts = accounts;
557
+ triggerEvent("connect", accounts);
558
+ }
559
+ } catch {
560
+ }
561
+ });
562
+ provider.on("disconnect", () => {
563
+ this._accounts = [];
564
+ const error = {
565
+ code: 4900,
566
+ message: "Provider disconnected"
567
+ };
568
+ triggerEvent("disconnect", error);
569
+ });
570
+ provider.on("accountsChanged", (accounts) => {
571
+ this._accounts = accounts;
572
+ triggerEvent("accountsChanged", accounts);
573
+ if (accounts && accounts.length > 0) {
398
574
  triggerEvent("connect", accounts);
399
- }).catch(() => {
575
+ }
400
576
  });
401
- });
402
- provider.on("disconnect", () => triggerEvent("disconnect", []));
403
- provider.on("accountsChanged", (accounts) => triggerEvent("accountsChanged", accounts));
404
- provider.on("chainChanged", (chainId) => triggerEvent("chainChanged", chainId));
577
+ provider.on("chainChanged", (chainId) => {
578
+ this._chainId = chainId;
579
+ triggerEvent("chainChanged", chainId);
580
+ });
581
+ }
582
+ } catch (error) {
405
583
  }
406
- } catch (error) {
407
584
  }
408
- }
585
+ };
409
586
  function createEthereumPlugin() {
410
587
  return {
411
588
  name: "ethereum",
412
589
  create: () => {
413
- bindProviderEvents();
414
- return ethereum;
590
+ return new Ethereum();
415
591
  }
416
592
  };
417
593
  }
418
594
 
419
595
  export {
596
+ createSiweMessage,
420
597
  createEthereumPlugin
421
598
  };
@@ -1 +1,2 @@
1
- export { E as Ethereum, e as EthereumEventType, d as EthereumSignInData, b as EthereumTransaction, a as PhantomEthereumProvider, c as createEthereumPlugin } from '../index-3a750f13.js';
1
+ export { e as EthereumEventType, d as EthereumSignInData, E as EthereumTransaction, b as PhantomEthereumProvider, c as createEthereumPlugin, a as createSiweMessage } from '../index-673af1e4.js';
2
+ import '@phantom/chain-interfaces';