@mysten-incubation/dev-wallet 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +7 -4
  3. package/dist/client/connected-apps.d.mts +35 -0
  4. package/dist/client/connected-apps.d.mts.map +1 -0
  5. package/dist/client/connected-apps.mjs +50 -0
  6. package/dist/client/connected-apps.mjs.map +1 -0
  7. package/dist/client/dev-wallet-client.mjs +1 -1
  8. package/dist/client/dev-wallet-client.mjs.map +1 -1
  9. package/dist/client/index.d.mts +2 -1
  10. package/dist/client/index.mjs +2 -1
  11. package/dist/client/request-handler.d.mts +7 -0
  12. package/dist/client/request-handler.d.mts.map +1 -1
  13. package/dist/client/request-handler.mjs +17 -2
  14. package/dist/client/request-handler.mjs.map +1 -1
  15. package/dist/standalone/assets/{in-memory-adapter-Ban2kRYS.js → in-memory-adapter-uuWG4K4k.js} +1 -1
  16. package/dist/standalone/assets/main-CKYv0eR6.js +7 -0
  17. package/dist/standalone/assets/{webcrypto-adapter-Ddqn-RAu.js → webcrypto-adapter-5ShaPc_M.js} +1 -1
  18. package/dist/standalone/bookmarklet.js +1 -1
  19. package/dist/standalone/index.html +1 -1
  20. package/dist/ui/dev-wallet-balances.d.mts.map +1 -1
  21. package/dist/ui/dev-wallet-balances.mjs +20 -13
  22. package/dist/ui/dev-wallet-balances.mjs.map +1 -1
  23. package/dist/ui/dev-wallet-connect-guide.d.mts +29 -0
  24. package/dist/ui/dev-wallet-connect-guide.d.mts.map +1 -0
  25. package/dist/ui/dev-wallet-connect-guide.mjs +386 -0
  26. package/dist/ui/dev-wallet-connect-guide.mjs.map +1 -0
  27. package/dist/ui/dev-wallet-connected-apps.d.mts +27 -0
  28. package/dist/ui/dev-wallet-connected-apps.d.mts.map +1 -0
  29. package/dist/ui/dev-wallet-connected-apps.mjs +164 -0
  30. package/dist/ui/dev-wallet-connected-apps.mjs.map +1 -0
  31. package/dist/ui/dev-wallet-panel.d.mts.map +1 -1
  32. package/dist/ui/dev-wallet-panel.mjs +0 -9
  33. package/dist/ui/dev-wallet-panel.mjs.map +1 -1
  34. package/dist/ui/dev-wallet-settings.d.mts +8 -2
  35. package/dist/ui/dev-wallet-settings.d.mts.map +1 -1
  36. package/dist/ui/dev-wallet-settings.mjs +86 -171
  37. package/dist/ui/dev-wallet-settings.mjs.map +1 -1
  38. package/dist/ui/dev-wallet-standalone.d.mts +7 -2
  39. package/dist/ui/dev-wallet-standalone.d.mts.map +1 -1
  40. package/dist/ui/dev-wallet-standalone.mjs +68 -222
  41. package/dist/ui/dev-wallet-standalone.mjs.map +1 -1
  42. package/dist/ui/index.d.mts +3 -1
  43. package/dist/ui/index.mjs +3 -1
  44. package/dist/ui/wallet-controller.mjs +15 -3
  45. package/dist/ui/wallet-controller.mjs.map +1 -1
  46. package/dist/wallet/dev-wallet.d.mts +15 -3
  47. package/dist/wallet/dev-wallet.d.mts.map +1 -1
  48. package/dist/wallet/dev-wallet.mjs +94 -30
  49. package/dist/wallet/dev-wallet.mjs.map +1 -1
  50. package/dist/wallet/persisted.mjs +20 -0
  51. package/dist/wallet/persisted.mjs.map +1 -0
  52. package/package.json +6 -6
  53. package/src/app/main.ts +6 -2
  54. package/src/client/connected-apps.ts +79 -0
  55. package/src/client/dev-wallet-client.ts +2 -1
  56. package/src/client/index.ts +2 -0
  57. package/src/client/request-handler.ts +24 -1
  58. package/src/ui/dev-wallet-balances.ts +25 -13
  59. package/src/ui/dev-wallet-connect-guide.ts +428 -0
  60. package/src/ui/dev-wallet-connected-apps.ts +191 -0
  61. package/src/ui/dev-wallet-panel.ts +0 -9
  62. package/src/ui/dev-wallet-settings.ts +101 -179
  63. package/src/ui/dev-wallet-standalone.ts +80 -231
  64. package/src/ui/index.ts +2 -0
  65. package/src/ui/wallet-controller.ts +23 -3
  66. package/src/wallet/dev-wallet.ts +130 -39
  67. package/src/wallet/persisted.ts +24 -0
  68. package/dist/standalone/assets/main-xfzarPod.js +0 -7
@@ -5,6 +5,7 @@ import type { ReadonlyWalletAccount } from '@mysten/wallet-standard';
5
5
  import { css, html, LitElement, nothing } from 'lit';
6
6
  import { customElement, property, state } from 'lit/decorators.js';
7
7
 
8
+ import type { ConnectedAppsStore } from '../client/connected-apps.js';
8
9
  import type { DevWallet } from '../wallet/dev-wallet.js';
9
10
  import type { SignerAdapter } from '../types.js';
10
11
  import {
@@ -20,6 +21,8 @@ import {
20
21
  } from './styles.js';
21
22
  import { emitEvent, formatAddress, getErrorMessage, NETWORK_COLORS } from './utils.js';
22
23
  import './dev-wallet-accounts.js';
24
+ import './dev-wallet-connect-guide.js';
25
+ import './dev-wallet-connected-apps.js';
23
26
 
24
27
  @customElement('dev-wallet-settings')
25
28
  export class DevWalletSettings extends LitElement {
@@ -105,6 +108,9 @@ export class DevWalletSettings extends LitElement {
105
108
  .network-info {
106
109
  flex: 1;
107
110
  min-width: 0;
111
+ display: flex;
112
+ flex-direction: column;
113
+ gap: 3px;
108
114
  }
109
115
 
110
116
  .network-url {
@@ -118,6 +124,8 @@ export class DevWalletSettings extends LitElement {
118
124
  background: var(--dev-wallet-background);
119
125
  font-size: 10px;
120
126
  font-family: var(--dev-wallet-font-mono);
127
+ width: 100%;
128
+ box-sizing: border-box;
121
129
  }
122
130
 
123
131
  .network-actions {
@@ -252,103 +260,12 @@ export class DevWalletSettings extends LitElement {
252
260
  margin-top: 4px;
253
261
  }
254
262
 
255
- .bookmarklet-link-wrapper {
256
- margin-top: 8px;
257
- }
258
-
259
- .bookmarklet-link {
260
- display: inline-flex;
261
- align-items: center;
262
- gap: 6px;
263
- padding: 8px 14px;
264
- border-radius: var(--dev-wallet-radius-sm);
265
- background: var(--dev-wallet-primary);
266
- color: var(--dev-wallet-primary-foreground);
267
- font-size: 13px;
268
- font-weight: var(--dev-wallet-font-weight-semibold);
269
- text-decoration: none;
270
- cursor: grab;
271
- user-select: none;
272
- }
273
-
274
- .bookmarklet-link:hover {
275
- opacity: 0.9;
276
- }
277
-
278
- .bookmarklet-link:active {
279
- cursor: grabbing;
280
- }
281
-
282
- .bookmarklet-url {
283
- font-family: var(--dev-wallet-font-mono);
284
- font-size: 10px;
285
- color: var(--dev-wallet-muted-foreground);
286
- word-break: break-all;
287
- user-select: all;
288
- }
289
-
290
- .console-snippet {
291
- margin-top: 8px;
292
- border-radius: var(--dev-wallet-radius);
293
- background: var(--dev-wallet-bg-0);
294
- border: 1px solid var(--dev-wallet-border);
295
- overflow: hidden;
296
- }
297
-
298
- .console-snippet-header {
299
- display: flex;
300
- align-items: center;
301
- justify-content: space-between;
302
- gap: 8px;
303
- padding: 7px 8px 7px 10px;
304
- border-bottom: 1px solid var(--dev-wallet-border);
305
- background: color-mix(in srgb, var(--dev-wallet-bg-1) 72%, transparent);
306
- }
307
-
308
- .console-snippet-label {
309
- font-family: var(--dev-wallet-font-mono);
310
- font-size: 9.5px;
311
- font-weight: var(--dev-wallet-font-weight-medium);
312
- letter-spacing: 0.12em;
313
- text-transform: uppercase;
314
- color: var(--dev-wallet-text-3);
315
- }
316
-
317
- .console-snippet-code {
318
- margin: 0;
319
- max-width: 100%;
320
- padding: 10px 12px 12px;
321
- overflow-x: auto;
322
- font-family: var(--dev-wallet-font-mono);
323
- font-size: 11px;
324
- color: var(--dev-wallet-foreground);
325
- line-height: 1.5;
326
- white-space: pre-wrap;
327
- overflow-wrap: anywhere;
328
- user-select: all;
329
- }
330
-
331
- .btn-copy {
332
- display: inline-flex;
333
- align-items: center;
334
- justify-content: center;
335
- min-width: 54px;
336
- height: 24px;
337
- padding: 0 8px;
338
- border-radius: var(--dev-wallet-radius-xs);
339
- border: 1px solid var(--dev-wallet-border);
340
- background: var(--dev-wallet-bg-2);
341
- color: var(--dev-wallet-foreground);
342
- font-size: 10px;
343
- font-weight: var(--dev-wallet-font-weight-medium);
344
- cursor: pointer;
345
- white-space: nowrap;
346
- }
347
-
348
- .btn-copy:hover {
349
- background: var(--dev-wallet-bg-hover);
350
- border-color: var(--dev-wallet-border-strong);
351
- color: var(--dev-wallet-foreground);
263
+ /* The standalone page shows these in side rails above 1240px
264
+ (see dev-wallet-standalone.ts); only repeat them here below that. */
265
+ @media (min-width: 1241px) {
266
+ .rail-mirror {
267
+ display: none;
268
+ }
352
269
  }
353
270
 
354
271
  @media (max-width: 420px) {
@@ -371,8 +288,14 @@ export class DevWalletSettings extends LitElement {
371
288
  @property({ type: String })
372
289
  activeAddress = '';
373
290
 
291
+ /** Origin of a standalone/hosted wallet. When set, Settings leads with the
292
+ * connect guide so it's reachable when the standalone aside is hidden. */
374
293
  @property({ type: String })
375
- bookmarkletOrigin = '';
294
+ walletOrigin = '';
295
+
296
+ /** Connected-dApps store of a standalone wallet; listed below the guide. */
297
+ @property({ attribute: false })
298
+ connectedApps: ConnectedAppsStore | null = null;
376
299
 
377
300
  @state()
378
301
  private _showAddNetwork = false;
@@ -383,6 +306,9 @@ export class DevWalletSettings extends LitElement {
383
306
  @state()
384
307
  private _networkUrl = '';
385
308
 
309
+ @state()
310
+ private _networkFaucet = '';
311
+
386
312
  @state()
387
313
  private _error: string | null = null;
388
314
 
@@ -393,19 +319,26 @@ export class DevWalletSettings extends LitElement {
393
319
  private _editingUrl = '';
394
320
 
395
321
  @state()
396
- private _copied = false;
322
+ private _editingFaucet = '';
397
323
 
398
324
  override render() {
399
325
  return html`
326
+ ${this.walletOrigin
327
+ ? html`<div class="section rail-mirror">
328
+ <dev-wallet-connect-guide .origin=${this.walletOrigin}></dev-wallet-connect-guide>
329
+ </div>`
330
+ : nothing}
331
+ ${this.connectedApps
332
+ ? html`<div class="section rail-mirror">
333
+ <dev-wallet-connected-apps .store=${this.connectedApps}></dev-wallet-connected-apps>
334
+ </div>`
335
+ : nothing}
400
336
  <div class="section">${this.#renderSummary()}</div>
401
337
  <div class="section">${this.#renderNetworks()}</div>
402
338
  ${this.#hasCliAdapter()
403
339
  ? html`<div class="section">${this.#renderCliSigner()}</div>`
404
340
  : nothing}
405
341
  <div class="section">${this.#renderAccounts()}</div>
406
- ${this.bookmarkletOrigin
407
- ? html`<div class="section">${this.#renderBookmarklet()}</div>`
408
- : nothing}
409
342
  `;
410
343
  }
411
344
 
@@ -436,6 +369,7 @@ export class DevWalletSettings extends LitElement {
436
369
  const networks = this.wallet.availableNetworks;
437
370
  const activeNetwork = this.wallet.activeNetwork;
438
371
  const urls = this.wallet.networkUrls;
372
+ const faucets = this.wallet.faucetUrls;
439
373
 
440
374
  return html`
441
375
  <h3 class="section-header">Networks</h3>
@@ -451,20 +385,34 @@ export class DevWalletSettings extends LitElement {
451
385
  <span class="network-name">${name}</span>
452
386
  ${isEditing
453
387
  ? html`<input
454
- class="network-url-input"
455
- type="text"
456
- .value=${this._editingUrl}
457
- @input=${(e: InputEvent) => {
458
- this._editingUrl = (e.target as HTMLInputElement).value;
459
- }}
460
- @keydown=${(e: KeyboardEvent) => {
461
- if (e.key === 'Enter') this.#saveNetworkUrl(name);
462
- if (e.key === 'Escape') this.#cancelEditNetwork();
463
- }}
464
- />`
388
+ class="network-url-input"
389
+ type="text"
390
+ aria-label="gRPC URL"
391
+ .value=${this._editingUrl}
392
+ @input=${(e: InputEvent) => {
393
+ this._editingUrl = (e.target as HTMLInputElement).value;
394
+ }}
395
+ @keydown=${this.#onEditKeydown(name)}
396
+ />
397
+ <input
398
+ class="network-url-input"
399
+ type="text"
400
+ aria-label="Faucet URL"
401
+ placeholder="Faucet URL (optional)"
402
+ .value=${this._editingFaucet}
403
+ @input=${(e: InputEvent) => {
404
+ this._editingFaucet = (e.target as HTMLInputElement).value;
405
+ }}
406
+ @keydown=${this.#onEditKeydown(name)}
407
+ />
408
+ ${this._error ? html`<div class="error">${this._error}</div>` : nothing}`
465
409
  : html`<span class="network-url" title=${urls[name] ?? ''}
466
- >${urls[name] ?? ''}</span
467
- >`}
410
+ >${urls[name] ?? ''}</span
411
+ >${faucets[name]
412
+ ? html`<span class="network-url" title=${faucets[name]}
413
+ >faucet: ${faucets[name]}</span
414
+ >`
415
+ : nothing}`}
468
416
  </div>
469
417
  <div class="network-actions">
470
418
  ${isEditing
@@ -472,7 +420,7 @@ export class DevWalletSettings extends LitElement {
472
420
  <button
473
421
  class="btn-icon"
474
422
  title="Save"
475
- aria-label="Save URL"
423
+ aria-label="Save network"
476
424
  @click=${() => this.#saveNetworkUrl(name)}
477
425
  >
478
426
  &#10003;
@@ -489,9 +437,10 @@ export class DevWalletSettings extends LitElement {
489
437
  : html`
490
438
  <button
491
439
  class="btn-icon"
492
- title="Edit URL"
493
- aria-label="Edit network URL"
494
- @click=${() => this.#startEditNetwork(name, urls[name] ?? '')}
440
+ title="Edit"
441
+ aria-label="Edit network"
442
+ @click=${() =>
443
+ this.#startEditNetwork(name, urls[name] ?? '', faucets[name] ?? '')}
495
444
  >
496
445
  &#9998;
497
446
  </button>
@@ -549,10 +498,18 @@ export class DevWalletSettings extends LitElement {
549
498
  this._networkUrl = (e.target as HTMLInputElement).value;
550
499
  this._error = null;
551
500
  }}
552
- @keydown=${(e: KeyboardEvent) => {
553
- if (e.key === 'Enter') this.#addNetwork();
554
- if (e.key === 'Escape') this.#cancelAddNetwork();
501
+ @keydown=${this.#onAddKeydown}
502
+ />
503
+ <input
504
+ class="form-input"
505
+ type="text"
506
+ placeholder="Faucet URL (optional, e.g. http://localhost:9123)"
507
+ .value=${this._networkFaucet}
508
+ @input=${(e: InputEvent) => {
509
+ this._networkFaucet = (e.target as HTMLInputElement).value;
510
+ this._error = null;
555
511
  }}
512
+ @keydown=${this.#onAddKeydown}
556
513
  />
557
514
  ${this._error ? html`<div class="error">${this._error}</div>` : nothing}
558
515
  <div class="form-actions">
@@ -634,65 +591,12 @@ export class DevWalletSettings extends LitElement {
634
591
  `;
635
592
  }
636
593
 
637
- #renderBookmarklet() {
638
- if (!this.bookmarkletOrigin) return nothing;
639
- const origin = this.bookmarkletOrigin;
640
-
641
- const bookmarkletJs = `${origin}/bookmarklet.js`;
642
- const bookmarkletHref = `javascript:void(document.head.appendChild(Object.assign(document.createElement('script'),{src:'${bookmarkletJs}'})))`;
643
- const consoleSnippet = `var s=document.createElement('script');s.src='${bookmarkletJs}';document.head.appendChild(s);`;
644
-
645
- return html`
646
- <h3 class="section-header">Bookmarklet</h3>
647
- <div class="about">
648
- Drag this link to your bookmarks bar, then click it on any dApp to inject the wallet:
649
- </div>
650
- <div class="bookmarklet-link-wrapper">
651
- <a
652
- class="bookmarklet-link"
653
- href=${bookmarkletHref}
654
- title="Drag to bookmarks bar"
655
- @click=${(e: MouseEvent) => e.preventDefault()}
656
- >
657
- Dev Wallet
658
- </a>
659
- </div>
660
- <div class="about" style="margin-top: 12px">Or paste this in the browser console:</div>
661
- <div class="console-snippet">
662
- <div class="console-snippet-header">
663
- <span class="console-snippet-label">Console</span>
664
- <button
665
- class="btn-copy"
666
- type="button"
667
- aria-label="Copy console snippet"
668
- @click=${() => this.#copySnippet(consoleSnippet)}
669
- >
670
- ${this._copied ? 'Copied' : 'Copy'}
671
- </button>
672
- </div>
673
- <pre class="console-snippet-code"><code>${consoleSnippet}</code></pre>
674
- </div>
675
- <div class="about" style="margin-top: 8px">
676
- Or add this script to your page:<br />
677
- <code class="bookmarklet-url">${bookmarkletJs}</code>
678
- </div>
679
- `;
680
- }
681
-
682
- #copySnippet(text: string) {
683
- navigator.clipboard.writeText(text).then(() => {
684
- this._copied = true;
685
- setTimeout(() => {
686
- this._copied = false;
687
- }, 2000);
688
- });
689
- }
690
-
691
594
  #addNetwork() {
692
595
  if (!this.wallet) return;
693
596
 
694
597
  const name = this._networkName.trim();
695
598
  const url = this._networkUrl.trim();
599
+ const faucet = this._networkFaucet.trim();
696
600
 
697
601
  if (!name || !url) return;
698
602
 
@@ -702,9 +606,10 @@ export class DevWalletSettings extends LitElement {
702
606
  }
703
607
 
704
608
  try {
705
- this.wallet.addNetwork(name, url);
609
+ this.wallet.addNetwork(name, url, faucet || undefined);
706
610
  this._networkName = '';
707
611
  this._networkUrl = '';
612
+ this._networkFaucet = '';
708
613
  this._showAddNetwork = false;
709
614
  this._error = null;
710
615
  emitEvent(this, 'network-added', { name, url });
@@ -717,23 +622,39 @@ export class DevWalletSettings extends LitElement {
717
622
  this._showAddNetwork = false;
718
623
  this._networkName = '';
719
624
  this._networkUrl = '';
625
+ this._networkFaucet = '';
720
626
  this._error = null;
721
627
  }
722
628
 
723
- #startEditNetwork(name: string, url: string) {
629
+ #onAddKeydown = (e: KeyboardEvent) => {
630
+ if (e.key === 'Enter') this.#addNetwork();
631
+ if (e.key === 'Escape') this.#cancelAddNetwork();
632
+ };
633
+
634
+ #onEditKeydown(name: string) {
635
+ return (e: KeyboardEvent) => {
636
+ if (e.key === 'Enter') this.#saveNetworkUrl(name);
637
+ if (e.key === 'Escape') this.#cancelEditNetwork();
638
+ };
639
+ }
640
+
641
+ #startEditNetwork(name: string, url: string, faucet: string) {
724
642
  this._editingNetwork = name;
725
643
  this._editingUrl = url;
644
+ this._editingFaucet = faucet;
726
645
  }
727
646
 
728
647
  #saveNetworkUrl(name: string) {
729
648
  if (!this.wallet) return;
730
649
  const url = this._editingUrl.trim();
650
+ const faucet = this._editingFaucet.trim();
731
651
  if (!url) return;
732
652
 
733
653
  try {
734
- this.wallet.addNetwork(name, url);
654
+ this.wallet.addNetwork(name, url, faucet || null);
735
655
  this._editingNetwork = null;
736
656
  this._editingUrl = '';
657
+ this._editingFaucet = '';
737
658
  } catch (error) {
738
659
  this._error = error instanceof Error ? error.message : 'Invalid URL';
739
660
  }
@@ -742,6 +663,7 @@ export class DevWalletSettings extends LitElement {
742
663
  #cancelEditNetwork() {
743
664
  this._editingNetwork = null;
744
665
  this._editingUrl = '';
666
+ this._editingFaucet = '';
745
667
  }
746
668
 
747
669
  #removeNetwork(name: string) {