@mysten-incubation/dev-wallet 0.3.0 → 0.4.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 (147) hide show
  1. package/CHANGELOG.md +55 -2
  2. package/dist/_virtual/{_@oxc-project_runtime@0.127.0/helpers → _@oxc-project_runtime@0.135.0/helpers/esm}/decorate.mjs +1 -1
  3. package/dist/adapters/base-adapter.d.mts.map +1 -1
  4. package/dist/adapters/base-adapter.mjs.map +1 -1
  5. package/dist/adapters/build-managed-account.mjs.map +1 -1
  6. package/dist/adapters/devstack-adapter.d.mts.map +1 -1
  7. package/dist/adapters/devstack-adapter.mjs.map +1 -1
  8. package/dist/adapters/devstack-paths.d.mts.map +1 -1
  9. package/dist/adapters/devstack-paths.mjs.map +1 -1
  10. package/dist/adapters/fork-relay.d.mts.map +1 -1
  11. package/dist/adapters/fork-relay.mjs.map +1 -1
  12. package/dist/adapters/idb-store.mjs.map +1 -1
  13. package/dist/adapters/in-memory-adapter.d.mts.map +1 -1
  14. package/dist/adapters/in-memory-adapter.mjs.map +1 -1
  15. package/dist/adapters/passkey-adapter.d.mts.map +1 -1
  16. package/dist/adapters/passkey-adapter.mjs.map +1 -1
  17. package/dist/adapters/remote-cli-adapter.d.mts.map +1 -1
  18. package/dist/adapters/remote-cli-adapter.mjs.map +1 -1
  19. package/dist/adapters/webcrypto-adapter.d.mts.map +1 -1
  20. package/dist/adapters/webcrypto-adapter.mjs.map +1 -1
  21. package/dist/bin/cli.mjs.map +1 -1
  22. package/dist/client/dev-wallet-client.d.mts.map +1 -1
  23. package/dist/client/dev-wallet-client.mjs.map +1 -1
  24. package/dist/client/request-handler.d.mts.map +1 -1
  25. package/dist/client/request-handler.mjs.map +1 -1
  26. package/dist/index.d.mts +2 -1
  27. package/dist/index.mjs +2 -1
  28. package/dist/inject/index.d.mts +61 -0
  29. package/dist/inject/index.d.mts.map +1 -0
  30. package/dist/inject/index.mjs +61 -0
  31. package/dist/inject/index.mjs.map +1 -0
  32. package/dist/react/components.d.mts +6 -8
  33. package/dist/react/components.d.mts.map +1 -1
  34. package/dist/react/components.mjs.map +1 -1
  35. package/dist/react/context.d.mts +2 -3
  36. package/dist/react/context.d.mts.map +1 -1
  37. package/dist/react/context.mjs.map +1 -1
  38. package/dist/react/useDevWallet.d.mts +3 -11
  39. package/dist/react/useDevWallet.d.mts.map +1 -1
  40. package/dist/react/useDevWallet.mjs +14 -36
  41. package/dist/react/useDevWallet.mjs.map +1 -1
  42. package/dist/server/cli-signing-middleware.d.mts.map +1 -1
  43. package/dist/server/cli-signing-middleware.mjs.map +1 -1
  44. package/dist/standalone/assets/base-adapter-DET6CP7z.js +1 -0
  45. package/dist/standalone/assets/in-memory-adapter-CX7xym4e.js +1 -0
  46. package/dist/standalone/assets/main-CuOnBmaa.js +7 -0
  47. package/dist/standalone/assets/webcrypto-adapter-CUQmbHDy.js +1 -0
  48. package/dist/standalone/bookmarklet.js +5 -5
  49. package/dist/standalone/index.html +2 -1
  50. package/dist/types.d.mts.map +1 -1
  51. package/dist/ui/copy-controller.mjs.map +1 -1
  52. package/dist/ui/dev-wallet-account-selector.d.mts +2 -3
  53. package/dist/ui/dev-wallet-account-selector.d.mts.map +1 -1
  54. package/dist/ui/dev-wallet-account-selector.mjs +1 -1
  55. package/dist/ui/dev-wallet-account-selector.mjs.map +1 -1
  56. package/dist/ui/dev-wallet-accounts.d.mts +2 -3
  57. package/dist/ui/dev-wallet-accounts.d.mts.map +1 -1
  58. package/dist/ui/dev-wallet-accounts.mjs +1 -1
  59. package/dist/ui/dev-wallet-accounts.mjs.map +1 -1
  60. package/dist/ui/dev-wallet-balances.d.mts +2 -3
  61. package/dist/ui/dev-wallet-balances.d.mts.map +1 -1
  62. package/dist/ui/dev-wallet-balances.mjs +1 -1
  63. package/dist/ui/dev-wallet-balances.mjs.map +1 -1
  64. package/dist/ui/dev-wallet-connect.d.mts +2 -3
  65. package/dist/ui/dev-wallet-connect.d.mts.map +1 -1
  66. package/dist/ui/dev-wallet-connect.mjs +1 -1
  67. package/dist/ui/dev-wallet-connect.mjs.map +1 -1
  68. package/dist/ui/dev-wallet-dropdown.d.mts +2 -3
  69. package/dist/ui/dev-wallet-dropdown.d.mts.map +1 -1
  70. package/dist/ui/dev-wallet-dropdown.mjs +1 -1
  71. package/dist/ui/dev-wallet-dropdown.mjs.map +1 -1
  72. package/dist/ui/dev-wallet-fork-panel.d.mts +2 -3
  73. package/dist/ui/dev-wallet-fork-panel.d.mts.map +1 -1
  74. package/dist/ui/dev-wallet-fork-panel.mjs +1 -1
  75. package/dist/ui/dev-wallet-fork-panel.mjs.map +1 -1
  76. package/dist/ui/dev-wallet-network-badge.d.mts +2 -3
  77. package/dist/ui/dev-wallet-network-badge.d.mts.map +1 -1
  78. package/dist/ui/dev-wallet-network-badge.mjs +1 -1
  79. package/dist/ui/dev-wallet-network-badge.mjs.map +1 -1
  80. package/dist/ui/dev-wallet-new-account.d.mts +2 -3
  81. package/dist/ui/dev-wallet-new-account.d.mts.map +1 -1
  82. package/dist/ui/dev-wallet-new-account.mjs +1 -1
  83. package/dist/ui/dev-wallet-new-account.mjs.map +1 -1
  84. package/dist/ui/dev-wallet-objects.d.mts +2 -3
  85. package/dist/ui/dev-wallet-objects.d.mts.map +1 -1
  86. package/dist/ui/dev-wallet-objects.mjs +1 -1
  87. package/dist/ui/dev-wallet-objects.mjs.map +1 -1
  88. package/dist/ui/dev-wallet-panel.d.mts +2 -3
  89. package/dist/ui/dev-wallet-panel.d.mts.map +1 -1
  90. package/dist/ui/dev-wallet-panel.mjs +1 -1
  91. package/dist/ui/dev-wallet-panel.mjs.map +1 -1
  92. package/dist/ui/dev-wallet-popup.d.mts +2 -3
  93. package/dist/ui/dev-wallet-popup.d.mts.map +1 -1
  94. package/dist/ui/dev-wallet-popup.mjs +1 -1
  95. package/dist/ui/dev-wallet-popup.mjs.map +1 -1
  96. package/dist/ui/dev-wallet-settings.d.mts +2 -3
  97. package/dist/ui/dev-wallet-settings.d.mts.map +1 -1
  98. package/dist/ui/dev-wallet-settings.mjs +1 -1
  99. package/dist/ui/dev-wallet-settings.mjs.map +1 -1
  100. package/dist/ui/dev-wallet-signing-modal.d.mts +2 -3
  101. package/dist/ui/dev-wallet-signing-modal.d.mts.map +1 -1
  102. package/dist/ui/dev-wallet-signing-modal.mjs +1 -1
  103. package/dist/ui/dev-wallet-signing-modal.mjs.map +1 -1
  104. package/dist/ui/dev-wallet-signing.d.mts +2 -3
  105. package/dist/ui/dev-wallet-signing.d.mts.map +1 -1
  106. package/dist/ui/dev-wallet-signing.mjs +2 -1
  107. package/dist/ui/dev-wallet-signing.mjs.map +1 -1
  108. package/dist/ui/dev-wallet-standalone.d.mts +2 -3
  109. package/dist/ui/dev-wallet-standalone.d.mts.map +1 -1
  110. package/dist/ui/dev-wallet-standalone.mjs +1 -1
  111. package/dist/ui/dev-wallet-standalone.mjs.map +1 -1
  112. package/dist/ui/dev-wallet-tab-bar.d.mts +1 -2
  113. package/dist/ui/dev-wallet-tab-bar.d.mts.map +1 -1
  114. package/dist/ui/dev-wallet-tab-bar.mjs +1 -1
  115. package/dist/ui/dev-wallet-tab-bar.mjs.map +1 -1
  116. package/dist/ui/mount.mjs.map +1 -1
  117. package/dist/ui/styles.mjs.map +1 -1
  118. package/dist/ui/transaction-analyzer.mjs.map +1 -1
  119. package/dist/ui/utils.d.mts.map +1 -1
  120. package/dist/ui/utils.mjs.map +1 -1
  121. package/dist/ui/wallet-controller.mjs.map +1 -1
  122. package/dist/wallet/constants.d.mts.map +1 -1
  123. package/dist/wallet/constants.mjs.map +1 -1
  124. package/dist/wallet/dev-wallet.d.mts +19 -0
  125. package/dist/wallet/dev-wallet.d.mts.map +1 -1
  126. package/dist/wallet/dev-wallet.mjs +58 -2
  127. package/dist/wallet/dev-wallet.mjs.map +1 -1
  128. package/dist/wallet/initializer.d.mts.map +1 -1
  129. package/dist/wallet/initializer.mjs +10 -26
  130. package/dist/wallet/initializer.mjs.map +1 -1
  131. package/dist/wallet/mount-and-register.d.mts +44 -0
  132. package/dist/wallet/mount-and-register.d.mts.map +1 -0
  133. package/dist/wallet/mount-and-register.mjs +46 -0
  134. package/dist/wallet/mount-and-register.mjs.map +1 -0
  135. package/dist/wallet/signing.d.mts.map +1 -1
  136. package/dist/wallet/signing.mjs.map +1 -1
  137. package/package.json +26 -22
  138. package/src/index.ts +5 -0
  139. package/src/inject/index.ts +183 -0
  140. package/src/react/useDevWallet.ts +26 -71
  141. package/src/ui/dev-wallet-signing.ts +2 -0
  142. package/src/wallet/dev-wallet.ts +75 -2
  143. package/src/wallet/initializer.ts +16 -42
  144. package/src/wallet/mount-and-register.ts +93 -0
  145. package/dist/standalone/assets/in-memory-adapter-qRkNfj9O.js +0 -1
  146. package/dist/standalone/assets/main-DDltQnzR.js +0 -3954
  147. package/dist/standalone/assets/webcrypto-adapter-FejcrL9x.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"wallet-controller.mjs","names":["#wallet","#unsubscribe","#subscribe","#isForkMode","#resolveUpstreamLabel","#unsubscribeEvents","#unsubscribeRequests","#unsubscribeConnect"],"sources":["../../src/ui/wallet-controller.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport type { ReadonlyWalletAccount } from '@mysten/wallet-standard';\nimport { html, nothing } from 'lit';\nimport type { ReactiveController, ReactiveControllerHost } from 'lit';\n\nimport type { ForkRelay } from '../adapters/fork-relay.js';\nimport { getNetworkFromChain } from '../wallet/constants.js';\nimport type {\n\tDevWallet,\n\tPendingConnectRequest,\n\tPendingSigningRequest,\n} from '../wallet/dev-wallet.js';\nimport './dev-wallet-account-selector.js';\nimport './dev-wallet-balances.js';\nimport './dev-wallet-connect.js';\nimport './dev-wallet-fork-panel.js';\nimport './dev-wallet-network-badge.js';\nimport './dev-wallet-objects.js';\nimport './dev-wallet-settings.js';\nimport './dev-wallet-signing-modal.js';\nimport type { TabId } from './dev-wallet-tab-bar.js';\nimport './dev-wallet-tab-bar.js';\nimport type { CoinRecord } from './utils.js';\nimport { isForkNetwork } from './utils.js';\n\n/**\n * Lit Reactive Controller that encapsulates all shared wallet management logic\n * between `dev-wallet-panel` and `dev-wallet-standalone`.\n *\n * Both components delegate state management, event subscription, and shared\n * render fragments to this controller, keeping only layout-specific code.\n */\nexport class WalletController implements ReactiveController {\n\thost: ReactiveControllerHost;\n\n\tactiveTab: TabId = 'assets';\n\taccounts: ReadonlyWalletAccount[] = [];\n\tactiveAccountIndex = 0;\n\tpendingRequest: PendingSigningRequest | null = null;\n\tpendingConnect: PendingConnectRequest | null = null;\n\tbookmarkletOrigin = '';\n\t/** Pre-seeded coin metadata (typically the generated `coins` constant from\n\t * devstack codegen). Forwarded to `<dev-wallet-balances>` and the\n\t * signing modal so they can skip per-coin RPC waterfalls. */\n\tcoins: CoinRecord | null = null;\n\t/** Phase 5 Subtopic 6 — when set, the controller surfaces a Fork\n\t * tab and binds it to this relay. The hosting custom element\n\t * (`dev-wallet-panel`) constructs the relay from the manifest's\n\t * wallet endpoint and pipes it through as a property. */\n\tforkRelay: ForkRelay | null = null;\n\t/** Upstream label (`'mainnet'`, etc.) sourced from the manifest. Used\n\t * by the fork panel banner and by `renderTabBar` to decide whether\n\t * to render the Fork tab. Falls back to inferring from the active\n\t * network literal (`'*-fork'`) when not provided. */\n\tforkUpstream = '';\n\n\t#wallet: DevWallet | null = null;\n\t#unsubscribeEvents: (() => void) | null = null;\n\t#unsubscribeRequests: (() => void) | null = null;\n\t#unsubscribeConnect: (() => void) | null = null;\n\n\tconstructor(host: ReactiveControllerHost) {\n\t\tthis.host = host;\n\t\thost.addController(this);\n\t}\n\n\tget wallet(): DevWallet | null {\n\t\treturn this.#wallet;\n\t}\n\n\tget activeAddress(): string {\n\t\treturn this.accounts[this.activeAccountIndex]?.address ?? '';\n\t}\n\n\tset wallet(value: DevWallet | null) {\n\t\tif (value === this.#wallet) return;\n\t\tthis.#unsubscribe();\n\t\tthis.#wallet = value;\n\t\tthis.#subscribe();\n\t\tthis.syncState();\n\t}\n\n\thostConnected(): void {\n\t\tthis.#subscribe();\n\t\tthis.syncState();\n\t}\n\n\thostDisconnected(): void {\n\t\tthis.#unsubscribe();\n\t}\n\n\t// ── State sync ──────────────────────────────────────────────────────────\n\n\tsyncState(): void {\n\t\tif (!this.#wallet) return;\n\t\tconst newAccounts = this.#wallet.accounts;\n\t\tconst newPending = this.#wallet.pendingRequest;\n\n\t\tconst accountsChanged =\n\t\t\tnewAccounts.length !== this.accounts.length ||\n\t\t\tnewAccounts.some((a, i) => a.address !== this.accounts[i]?.address);\n\t\tconst pendingChanged = newPending !== this.pendingRequest;\n\n\t\tif (!accountsChanged && !pendingChanged) return;\n\n\t\tif (accountsChanged) {\n\t\t\tthis.accounts = [...newAccounts];\n\t\t\t// Clamp activeAccountIndex when accounts shrink\n\t\t\tif (this.activeAccountIndex >= newAccounts.length && newAccounts.length > 0) {\n\t\t\t\tthis.activeAccountIndex = newAccounts.length - 1;\n\t\t\t}\n\t\t}\n\t\tthis.pendingRequest = newPending;\n\t\tthis.host.requestUpdate();\n\t}\n\n\tsyncConnectState(): void {\n\t\tif (!this.#wallet) return;\n\t\tconst newConnect = this.#wallet.pendingConnect;\n\t\tif (newConnect === this.pendingConnect) return;\n\t\tthis.pendingConnect = newConnect;\n\t\tthis.host.requestUpdate();\n\t}\n\n\t// ── Client resolution ───────────────────────────────────────────────────\n\n\tgetActiveClient(): ClientWithCoreApi | null {\n\t\tif (!this.#wallet) return null;\n\n\t\tif (this.pendingRequest) {\n\t\t\tconst network = getNetworkFromChain(this.pendingRequest.chain);\n\t\t\tif (network) {\n\t\t\t\ttry {\n\t\t\t\t\treturn this.#wallet.getClient(network);\n\t\t\t\t} catch {\n\t\t\t\t\treturn this.#wallet.activeClient;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.#wallet.activeClient;\n\t}\n\n\t// ── Event handlers ──────────────────────────────────────────────────────\n\n\tasync handleApprove(): Promise<void> {\n\t\tif (!this.#wallet) return;\n\t\ttry {\n\t\t\tawait this.#wallet.approveRequest();\n\t\t} catch (error) {\n\t\t\tconsole.error('[dev-wallet] approve failed:', error);\n\t\t}\n\t}\n\n\thandleReject(): void {\n\t\tif (!this.#wallet) return;\n\t\ttry {\n\t\t\tthis.#wallet.rejectRequest();\n\t\t} catch (error) {\n\t\t\tconsole.error('[dev-wallet] reject failed:', error);\n\t\t}\n\t}\n\n\thandleTabChanged(e: CustomEvent<{ tab: TabId }>): void {\n\t\tthis.activeTab = e.detail.tab;\n\t\tthis.host.requestUpdate();\n\t}\n\n\thandleNetworkChanged(e: CustomEvent<{ network: string }>): void {\n\t\tthis.#wallet?.setActiveNetwork(e.detail.network);\n\t}\n\n\thandleAccountSelected(e: CustomEvent<{ account: ReadonlyWalletAccount }>): void {\n\t\tconst index = this.accounts.findIndex((a) => a.address === e.detail.account.address);\n\t\tif (index !== -1) {\n\t\t\tthis.activeAccountIndex = index;\n\t\t\tthis.host.requestUpdate();\n\t\t}\n\t}\n\n\thandleApproveConnect(e: CustomEvent<{ selectedAddresses: string[] }>): void {\n\t\te.stopPropagation();\n\t\tif (!this.#wallet) return;\n\t\ttry {\n\t\t\tthis.#wallet.approveConnect(e.detail.selectedAddresses);\n\t\t} catch (error) {\n\t\t\tconsole.error('[dev-wallet] connect approve failed:', error);\n\t\t}\n\t}\n\n\thandleRejectConnect(e?: Event): void {\n\t\te?.preventDefault();\n\t\tif (e instanceof CustomEvent) e.stopPropagation();\n\t\tif (!this.#wallet) return;\n\t\ttry {\n\t\t\tthis.#wallet.rejectConnect();\n\t\t} catch (error) {\n\t\t\tconsole.error('[dev-wallet] connect reject failed:', error);\n\t\t}\n\t}\n\n\t// ── Shared render fragments ─────────────────────────────────────────────\n\n\trenderAccountSelector() {\n\t\treturn html`\n\t\t\t<div class=\"section\">\n\t\t\t\t<dev-wallet-account-selector\n\t\t\t\t\texportparts=\"trigger: selector-trigger, copy-button: selector-copy-button, empty-state: selector-empty-state\"\n\t\t\t\t\t.accounts=${this.accounts}\n\t\t\t\t\t.adapters=${this.#wallet ? [...this.#wallet.adapters] : []}\n\t\t\t\t\t.activeAddress=${this.activeAddress}\n\t\t\t\t\t@account-selected=${(e: CustomEvent) => this.handleAccountSelected(e)}\n\t\t\t\t></dev-wallet-account-selector>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\trenderAssetsTab() {\n\t\treturn html`\n\t\t\t${this.renderAccountSelector()}\n\t\t\t${this.activeAddress && this.#wallet\n\t\t\t\t? html`\n\t\t\t\t\t\t<div class=\"section\">\n\t\t\t\t\t\t\t<dev-wallet-balances\n\t\t\t\t\t\t\t\texportparts=\"balance-list, loading: balances-loading, error-message: balances-error-message, empty-state: balances-empty-state\"\n\t\t\t\t\t\t\t\t.address=${this.activeAddress}\n\t\t\t\t\t\t\t\t.client=${this.getActiveClient()}\n\t\t\t\t\t\t\t\t.network=${this.#wallet.activeNetwork}\n\t\t\t\t\t\t\t\t.coins=${this.coins}\n\t\t\t\t\t\t\t></dev-wallet-balances>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`\n\t\t\t\t: nothing}\n\t\t`;\n\t}\n\n\trenderObjectsTab() {\n\t\treturn html`\n\t\t\t${this.renderAccountSelector()}\n\t\t\t${this.activeAddress && this.#wallet\n\t\t\t\t? html`\n\t\t\t\t\t\t<div class=\"section\">\n\t\t\t\t\t\t\t<dev-wallet-objects\n\t\t\t\t\t\t\t\texportparts=\"object-list, loading: objects-loading, error-message: objects-error-message, empty-state: objects-empty-state, load-more-button\"\n\t\t\t\t\t\t\t\t.address=${this.activeAddress}\n\t\t\t\t\t\t\t\t.client=${this.getActiveClient()}\n\t\t\t\t\t\t\t></dev-wallet-objects>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`\n\t\t\t\t: nothing}\n\t\t`;\n\t}\n\n\trenderSettingsTab() {\n\t\treturn html`\n\t\t\t<dev-wallet-settings\n\t\t\t\texportparts=\"accounts-account-list, accounts-add-button, accounts-empty-state\"\n\t\t\t\t.wallet=${this.#wallet}\n\t\t\t\t.accounts=${this.accounts}\n\t\t\t\t.adapters=${this.#wallet ? [...this.#wallet.adapters] : []}\n\t\t\t\t.activeAddress=${this.activeAddress}\n\t\t\t\t.bookmarkletOrigin=${this.bookmarkletOrigin}\n\t\t\t\t@account-selected=${(e: CustomEvent) => this.handleAccountSelected(e)}\n\t\t\t></dev-wallet-settings>\n\t\t`;\n\t}\n\n\trenderForkTab() {\n\t\t// Defence-in-depth: the tab itself is hidden unless `#isForkMode`\n\t\t// returns true, but render-time we re-check so direct\n\t\t// `activeTab = 'fork'` writes don't end up rendering the panel\n\t\t// against a bundled-mode stack.\n\t\tif (!this.#isForkMode()) return nothing;\n\t\treturn html`\n\t\t\t<dev-wallet-fork-panel\n\t\t\t\texportparts=\"\n\t\t\t\t\tfork-banner,\n\t\t\t\t\tstatus-grid,\n\t\t\t\t\tstatus-checkpoint,\n\t\t\t\t\tstatus-clock,\n\t\t\t\t\tstatus-clock-iso,\n\t\t\t\t\tstatus-auto-tick,\n\t\t\t\t\tstatus-loading,\n\t\t\t\t\tstatus-error,\n\t\t\t\t\tstatus-empty,\n\t\t\t\t\tadvance-clock-input,\n\t\t\t\t\tadvance-clock-button,\n\t\t\t\t\tadvance-checkpoint-input,\n\t\t\t\t\tadvance-checkpoint-button,\n\t\t\t\t\taction-error,\n\t\t\t\t\tslot-list,\n\t\t\t\t\tslot-item,\n\t\t\t\t\tslot-item-active,\n\t\t\t\t\tslot-toggle,\n\t\t\t\t\tslots-empty,\n\t\t\t\t\tslots-error,\n\t\t\t\t\tempty-state\n\t\t\t\t\"\n\t\t\t\t.relay=${this.forkRelay}\n\t\t\t\t.upstream=${this.#resolveUpstreamLabel()}\n\t\t\t\t@fork-impersonation-changed=${(e: CustomEvent) => this.handleForkImpersonationChanged(e)}\n\t\t\t></dev-wallet-fork-panel>\n\t\t`;\n\t}\n\n\trenderTabContent() {\n\t\tif (this.activeTab === 'assets') return this.renderAssetsTab();\n\t\tif (this.activeTab === 'objects') return this.renderObjectsTab();\n\t\tif (this.activeTab === 'fork') return this.renderForkTab();\n\t\tif (this.activeTab === 'settings') return this.renderSettingsTab();\n\t\treturn nothing;\n\t}\n\n\thandleForkImpersonationChanged(_e: CustomEvent): void {\n\t\t// Slot changes can affect the impersonation banner in the signing\n\t\t// modal (Phase 4 P4.19), so request a re-render. The actual flag\n\t\t// flip happens in the signing-modal's own derivation from\n\t\t// `account.source`, which the devstack adapter updates when the\n\t\t// server-side toggle resolves.\n\t\tthis.host.requestUpdate();\n\t}\n\n\trenderSigningModal() {\n\t\tif (!this.pendingRequest) return nothing;\n\n\t\treturn html`\n\t\t\t<dev-wallet-signing-modal\n\t\t\t\texportparts=\"signing-approve-button, signing-reject-button, signing-request-type, signing-empty-state, signing-error-message, signing-footer, dialog: signing-dialog\"\n\t\t\t\t.request=${this.pendingRequest}\n\t\t\t\t.client=${this.getActiveClient()}\n\t\t\t\t.coins=${this.coins}\n\t\t\t\t.walletName=${this.#wallet?.name ?? 'Dev Wallet'}\n\t\t\t\t@approve=${() => this.handleApprove()}\n\t\t\t\t@reject=${() => this.handleReject()}\n\t\t\t></dev-wallet-signing-modal>\n\t\t`;\n\t}\n\n\trenderConnectPicker() {\n\t\tif (!this.pendingConnect) return nothing;\n\n\t\tconst allAccounts = this.#wallet\n\t\t\t? this.#wallet.adapters.flatMap((a) =>\n\t\t\t\t\ta.getAccounts().map((acc) => ({\n\t\t\t\t\t\taddress: acc.address,\n\t\t\t\t\t\tlabel: acc.label,\n\t\t\t\t\t\tadapterName: a.name,\n\t\t\t\t\t})),\n\t\t\t\t)\n\t\t\t: [];\n\n\t\treturn html`\n\t\t\t<dialog class=\"connect-dialog\" @cancel=${(e: Event) => this.handleRejectConnect(e)}>\n\t\t\t\t<div class=\"connect-dialog-header\">\n\t\t\t\t\t<span class=\"connect-dialog-title\">${this.#wallet?.name ?? 'Dev Wallet'}</span>\n\t\t\t\t</div>\n\t\t\t\t<dev-wallet-connect\n\t\t\t\t\texportparts=\"approve-button: connect-approve-button, reject-button: connect-reject-button, account-list: connect-account-list, error-message: connect-error-message\"\n\t\t\t\t\t.accounts=${allAccounts}\n\t\t\t\t\t@approve=${(e: CustomEvent) => this.handleApproveConnect(e)}\n\t\t\t\t\t@reject=${(e: Event) => this.handleRejectConnect(e)}\n\t\t\t\t></dev-wallet-connect>\n\t\t\t</dialog>\n\t\t`;\n\t}\n\n\trenderNetworkBadge() {\n\t\tif (!this.#wallet) return nothing;\n\t\treturn html`\n\t\t\t<dev-wallet-network-badge\n\t\t\t\texportparts=\"trigger: network-trigger\"\n\t\t\t\t.active=${this.#wallet.activeNetwork}\n\t\t\t\t.networks=${this.#wallet.availableNetworks}\n\t\t\t\t@network-changed=${(e: CustomEvent) => this.handleNetworkChanged(e)}\n\t\t\t></dev-wallet-network-badge>\n\t\t`;\n\t}\n\n\trenderTabBar() {\n\t\treturn html`\n\t\t\t<dev-wallet-tab-bar\n\t\t\t\texportparts=\"tab-bar, tab\"\n\t\t\t\t.active=${this.activeTab}\n\t\t\t\t.showFork=${this.#isForkMode()}\n\t\t\t\t@tab-changed=${(e: CustomEvent) => this.handleTabChanged(e)}\n\t\t\t></dev-wallet-tab-bar>\n\t\t`;\n\t}\n\n\t/** Phase 5 Subtopic 6 (P5.8.5) — the Fork tab + panel render only\n\t * when the active stack is in fork mode. Two signals satisfy that:\n\t * 1. The host passed in a `ForkRelay` (built from the manifest's\n\t * wallet endpoint — devstack only constructs one when\n\t * `meta.runtime === 'forked'`).\n\t * 2. The active network literal ends in `-fork` (catch-all for\n\t * when the relay is wired but the user switched to a\n\t * non-fork network from the badge dropdown).\n\t * Both signals must agree — otherwise the tab is hidden. */\n\t#isForkMode(): boolean {\n\t\tif (this.forkRelay === null) return false;\n\t\tconst active = this.#wallet?.activeNetwork;\n\t\tif (!active) return false;\n\t\treturn isForkNetwork(active);\n\t}\n\n\t#resolveUpstreamLabel(): string {\n\t\tif (this.forkUpstream !== '') return this.forkUpstream;\n\t\tconst active = this.#wallet?.activeNetwork ?? '';\n\t\treturn active.endsWith('-fork') ? active.replace(/-fork$/, '') : '';\n\t}\n\n\t// ── Subscriptions ───────────────────────────────────────────────────────\n\n\t#subscribe(): void {\n\t\tif (!this.#wallet) return;\n\t\tthis.#unsubscribeEvents = this.#wallet.features['standard:events'].on('change', () => {\n\t\t\tthis.syncState();\n\t\t});\n\t\tthis.#unsubscribeRequests = this.#wallet.onRequestChange(() => {\n\t\t\tthis.syncState();\n\t\t});\n\t\tthis.#unsubscribeConnect = this.#wallet.onConnectChange(() => {\n\t\t\tthis.syncConnectState();\n\t\t});\n\t}\n\n\t#unsubscribe(): void {\n\t\tthis.#unsubscribeEvents?.();\n\t\tthis.#unsubscribeEvents = null;\n\t\tthis.#unsubscribeRequests?.();\n\t\tthis.#unsubscribeRequests = null;\n\t\tthis.#unsubscribeConnect?.();\n\t\tthis.#unsubscribeConnect = null;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"wallet-controller.mjs","names":["#wallet","#unsubscribe","#subscribe","#isForkMode","#resolveUpstreamLabel","#unsubscribeEvents","#unsubscribeRequests","#unsubscribeConnect"],"sources":["../../src/ui/wallet-controller.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport type { ReadonlyWalletAccount } from '@mysten/wallet-standard';\nimport { html, nothing } from 'lit';\nimport type { ReactiveController, ReactiveControllerHost } from 'lit';\n\nimport type { ForkRelay } from '../adapters/fork-relay.js';\nimport { getNetworkFromChain } from '../wallet/constants.js';\nimport type {\n\tDevWallet,\n\tPendingConnectRequest,\n\tPendingSigningRequest,\n} from '../wallet/dev-wallet.js';\nimport './dev-wallet-account-selector.js';\nimport './dev-wallet-balances.js';\nimport './dev-wallet-connect.js';\nimport './dev-wallet-fork-panel.js';\nimport './dev-wallet-network-badge.js';\nimport './dev-wallet-objects.js';\nimport './dev-wallet-settings.js';\nimport './dev-wallet-signing-modal.js';\nimport type { TabId } from './dev-wallet-tab-bar.js';\nimport './dev-wallet-tab-bar.js';\nimport type { CoinRecord } from './utils.js';\nimport { isForkNetwork } from './utils.js';\n\n/**\n * Lit Reactive Controller that encapsulates all shared wallet management logic\n * between `dev-wallet-panel` and `dev-wallet-standalone`.\n *\n * Both components delegate state management, event subscription, and shared\n * render fragments to this controller, keeping only layout-specific code.\n */\nexport class WalletController implements ReactiveController {\n\thost: ReactiveControllerHost;\n\n\tactiveTab: TabId = 'assets';\n\taccounts: ReadonlyWalletAccount[] = [];\n\tactiveAccountIndex = 0;\n\tpendingRequest: PendingSigningRequest | null = null;\n\tpendingConnect: PendingConnectRequest | null = null;\n\tbookmarkletOrigin = '';\n\t/** Pre-seeded coin metadata (typically the generated `coins` constant from\n\t * devstack codegen). Forwarded to `<dev-wallet-balances>` and the\n\t * signing modal so they can skip per-coin RPC waterfalls. */\n\tcoins: CoinRecord | null = null;\n\t/** Phase 5 Subtopic 6 — when set, the controller surfaces a Fork\n\t * tab and binds it to this relay. The hosting custom element\n\t * (`dev-wallet-panel`) constructs the relay from the manifest's\n\t * wallet endpoint and pipes it through as a property. */\n\tforkRelay: ForkRelay | null = null;\n\t/** Upstream label (`'mainnet'`, etc.) sourced from the manifest. Used\n\t * by the fork panel banner and by `renderTabBar` to decide whether\n\t * to render the Fork tab. Falls back to inferring from the active\n\t * network literal (`'*-fork'`) when not provided. */\n\tforkUpstream = '';\n\n\t#wallet: DevWallet | null = null;\n\t#unsubscribeEvents: (() => void) | null = null;\n\t#unsubscribeRequests: (() => void) | null = null;\n\t#unsubscribeConnect: (() => void) | null = null;\n\n\tconstructor(host: ReactiveControllerHost) {\n\t\tthis.host = host;\n\t\thost.addController(this);\n\t}\n\n\tget wallet(): DevWallet | null {\n\t\treturn this.#wallet;\n\t}\n\n\tget activeAddress(): string {\n\t\treturn this.accounts[this.activeAccountIndex]?.address ?? '';\n\t}\n\n\tset wallet(value: DevWallet | null) {\n\t\tif (value === this.#wallet) return;\n\t\tthis.#unsubscribe();\n\t\tthis.#wallet = value;\n\t\tthis.#subscribe();\n\t\tthis.syncState();\n\t}\n\n\thostConnected(): void {\n\t\tthis.#subscribe();\n\t\tthis.syncState();\n\t}\n\n\thostDisconnected(): void {\n\t\tthis.#unsubscribe();\n\t}\n\n\t// ── State sync ──────────────────────────────────────────────────────────\n\n\tsyncState(): void {\n\t\tif (!this.#wallet) return;\n\t\tconst newAccounts = this.#wallet.accounts;\n\t\tconst newPending = this.#wallet.pendingRequest;\n\n\t\tconst accountsChanged =\n\t\t\tnewAccounts.length !== this.accounts.length ||\n\t\t\tnewAccounts.some((a, i) => a.address !== this.accounts[i]?.address);\n\t\tconst pendingChanged = newPending !== this.pendingRequest;\n\n\t\tif (!accountsChanged && !pendingChanged) return;\n\n\t\tif (accountsChanged) {\n\t\t\tthis.accounts = [...newAccounts];\n\t\t\t// Clamp activeAccountIndex when accounts shrink\n\t\t\tif (this.activeAccountIndex >= newAccounts.length && newAccounts.length > 0) {\n\t\t\t\tthis.activeAccountIndex = newAccounts.length - 1;\n\t\t\t}\n\t\t}\n\t\tthis.pendingRequest = newPending;\n\t\tthis.host.requestUpdate();\n\t}\n\n\tsyncConnectState(): void {\n\t\tif (!this.#wallet) return;\n\t\tconst newConnect = this.#wallet.pendingConnect;\n\t\tif (newConnect === this.pendingConnect) return;\n\t\tthis.pendingConnect = newConnect;\n\t\tthis.host.requestUpdate();\n\t}\n\n\t// ── Client resolution ───────────────────────────────────────────────────\n\n\tgetActiveClient(): ClientWithCoreApi | null {\n\t\tif (!this.#wallet) return null;\n\n\t\tif (this.pendingRequest) {\n\t\t\tconst network = getNetworkFromChain(this.pendingRequest.chain);\n\t\t\tif (network) {\n\t\t\t\ttry {\n\t\t\t\t\treturn this.#wallet.getClient(network);\n\t\t\t\t} catch {\n\t\t\t\t\treturn this.#wallet.activeClient;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.#wallet.activeClient;\n\t}\n\n\t// ── Event handlers ──────────────────────────────────────────────────────\n\n\tasync handleApprove(): Promise<void> {\n\t\tif (!this.#wallet) return;\n\t\ttry {\n\t\t\tawait this.#wallet.approveRequest();\n\t\t} catch (error) {\n\t\t\tconsole.error('[dev-wallet] approve failed:', error);\n\t\t}\n\t}\n\n\thandleReject(): void {\n\t\tif (!this.#wallet) return;\n\t\ttry {\n\t\t\tthis.#wallet.rejectRequest();\n\t\t} catch (error) {\n\t\t\tconsole.error('[dev-wallet] reject failed:', error);\n\t\t}\n\t}\n\n\thandleTabChanged(e: CustomEvent<{ tab: TabId }>): void {\n\t\tthis.activeTab = e.detail.tab;\n\t\tthis.host.requestUpdate();\n\t}\n\n\thandleNetworkChanged(e: CustomEvent<{ network: string }>): void {\n\t\tthis.#wallet?.setActiveNetwork(e.detail.network);\n\t}\n\n\thandleAccountSelected(e: CustomEvent<{ account: ReadonlyWalletAccount }>): void {\n\t\tconst index = this.accounts.findIndex((a) => a.address === e.detail.account.address);\n\t\tif (index !== -1) {\n\t\t\tthis.activeAccountIndex = index;\n\t\t\tthis.host.requestUpdate();\n\t\t}\n\t}\n\n\thandleApproveConnect(e: CustomEvent<{ selectedAddresses: string[] }>): void {\n\t\te.stopPropagation();\n\t\tif (!this.#wallet) return;\n\t\ttry {\n\t\t\tthis.#wallet.approveConnect(e.detail.selectedAddresses);\n\t\t} catch (error) {\n\t\t\tconsole.error('[dev-wallet] connect approve failed:', error);\n\t\t}\n\t}\n\n\thandleRejectConnect(e?: Event): void {\n\t\te?.preventDefault();\n\t\tif (e instanceof CustomEvent) e.stopPropagation();\n\t\tif (!this.#wallet) return;\n\t\ttry {\n\t\t\tthis.#wallet.rejectConnect();\n\t\t} catch (error) {\n\t\t\tconsole.error('[dev-wallet] connect reject failed:', error);\n\t\t}\n\t}\n\n\t// ── Shared render fragments ─────────────────────────────────────────────\n\n\trenderAccountSelector() {\n\t\treturn html`\n\t\t\t<div class=\"section\">\n\t\t\t\t<dev-wallet-account-selector\n\t\t\t\t\texportparts=\"trigger: selector-trigger, copy-button: selector-copy-button, empty-state: selector-empty-state\"\n\t\t\t\t\t.accounts=${this.accounts}\n\t\t\t\t\t.adapters=${this.#wallet ? [...this.#wallet.adapters] : []}\n\t\t\t\t\t.activeAddress=${this.activeAddress}\n\t\t\t\t\t@account-selected=${(e: CustomEvent) => this.handleAccountSelected(e)}\n\t\t\t\t></dev-wallet-account-selector>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\trenderAssetsTab() {\n\t\treturn html`\n\t\t\t${this.renderAccountSelector()}\n\t\t\t${this.activeAddress && this.#wallet\n\t\t\t\t? html`\n\t\t\t\t\t\t<div class=\"section\">\n\t\t\t\t\t\t\t<dev-wallet-balances\n\t\t\t\t\t\t\t\texportparts=\"balance-list, loading: balances-loading, error-message: balances-error-message, empty-state: balances-empty-state\"\n\t\t\t\t\t\t\t\t.address=${this.activeAddress}\n\t\t\t\t\t\t\t\t.client=${this.getActiveClient()}\n\t\t\t\t\t\t\t\t.network=${this.#wallet.activeNetwork}\n\t\t\t\t\t\t\t\t.coins=${this.coins}\n\t\t\t\t\t\t\t></dev-wallet-balances>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`\n\t\t\t\t: nothing}\n\t\t`;\n\t}\n\n\trenderObjectsTab() {\n\t\treturn html`\n\t\t\t${this.renderAccountSelector()}\n\t\t\t${this.activeAddress && this.#wallet\n\t\t\t\t? html`\n\t\t\t\t\t\t<div class=\"section\">\n\t\t\t\t\t\t\t<dev-wallet-objects\n\t\t\t\t\t\t\t\texportparts=\"object-list, loading: objects-loading, error-message: objects-error-message, empty-state: objects-empty-state, load-more-button\"\n\t\t\t\t\t\t\t\t.address=${this.activeAddress}\n\t\t\t\t\t\t\t\t.client=${this.getActiveClient()}\n\t\t\t\t\t\t\t></dev-wallet-objects>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`\n\t\t\t\t: nothing}\n\t\t`;\n\t}\n\n\trenderSettingsTab() {\n\t\treturn html`\n\t\t\t<dev-wallet-settings\n\t\t\t\texportparts=\"accounts-account-list, accounts-add-button, accounts-empty-state\"\n\t\t\t\t.wallet=${this.#wallet}\n\t\t\t\t.accounts=${this.accounts}\n\t\t\t\t.adapters=${this.#wallet ? [...this.#wallet.adapters] : []}\n\t\t\t\t.activeAddress=${this.activeAddress}\n\t\t\t\t.bookmarkletOrigin=${this.bookmarkletOrigin}\n\t\t\t\t@account-selected=${(e: CustomEvent) => this.handleAccountSelected(e)}\n\t\t\t></dev-wallet-settings>\n\t\t`;\n\t}\n\n\trenderForkTab() {\n\t\t// Defence-in-depth: the tab itself is hidden unless `#isForkMode`\n\t\t// returns true, but render-time we re-check so direct\n\t\t// `activeTab = 'fork'` writes don't end up rendering the panel\n\t\t// against a bundled-mode stack.\n\t\tif (!this.#isForkMode()) return nothing;\n\t\treturn html`\n\t\t\t<dev-wallet-fork-panel\n\t\t\t\texportparts=\"\n\t\t\t\t\tfork-banner,\n\t\t\t\t\tstatus-grid,\n\t\t\t\t\tstatus-checkpoint,\n\t\t\t\t\tstatus-clock,\n\t\t\t\t\tstatus-clock-iso,\n\t\t\t\t\tstatus-auto-tick,\n\t\t\t\t\tstatus-loading,\n\t\t\t\t\tstatus-error,\n\t\t\t\t\tstatus-empty,\n\t\t\t\t\tadvance-clock-input,\n\t\t\t\t\tadvance-clock-button,\n\t\t\t\t\tadvance-checkpoint-input,\n\t\t\t\t\tadvance-checkpoint-button,\n\t\t\t\t\taction-error,\n\t\t\t\t\tslot-list,\n\t\t\t\t\tslot-item,\n\t\t\t\t\tslot-item-active,\n\t\t\t\t\tslot-toggle,\n\t\t\t\t\tslots-empty,\n\t\t\t\t\tslots-error,\n\t\t\t\t\tempty-state\n\t\t\t\t\"\n\t\t\t\t.relay=${this.forkRelay}\n\t\t\t\t.upstream=${this.#resolveUpstreamLabel()}\n\t\t\t\t@fork-impersonation-changed=${(e: CustomEvent) => this.handleForkImpersonationChanged(e)}\n\t\t\t></dev-wallet-fork-panel>\n\t\t`;\n\t}\n\n\trenderTabContent() {\n\t\tif (this.activeTab === 'assets') return this.renderAssetsTab();\n\t\tif (this.activeTab === 'objects') return this.renderObjectsTab();\n\t\tif (this.activeTab === 'fork') return this.renderForkTab();\n\t\tif (this.activeTab === 'settings') return this.renderSettingsTab();\n\t\treturn nothing;\n\t}\n\n\thandleForkImpersonationChanged(_e: CustomEvent): void {\n\t\t// Slot changes can affect the impersonation banner in the signing\n\t\t// modal (Phase 4 P4.19), so request a re-render. The actual flag\n\t\t// flip happens in the signing-modal's own derivation from\n\t\t// `account.source`, which the devstack adapter updates when the\n\t\t// server-side toggle resolves.\n\t\tthis.host.requestUpdate();\n\t}\n\n\trenderSigningModal() {\n\t\tif (!this.pendingRequest) return nothing;\n\n\t\treturn html`\n\t\t\t<dev-wallet-signing-modal\n\t\t\t\texportparts=\"signing-approve-button, signing-reject-button, signing-request-type, signing-empty-state, signing-error-message, signing-footer, dialog: signing-dialog\"\n\t\t\t\t.request=${this.pendingRequest}\n\t\t\t\t.client=${this.getActiveClient()}\n\t\t\t\t.coins=${this.coins}\n\t\t\t\t.walletName=${this.#wallet?.name ?? 'Dev Wallet'}\n\t\t\t\t@approve=${() => this.handleApprove()}\n\t\t\t\t@reject=${() => this.handleReject()}\n\t\t\t></dev-wallet-signing-modal>\n\t\t`;\n\t}\n\n\trenderConnectPicker() {\n\t\tif (!this.pendingConnect) return nothing;\n\n\t\tconst allAccounts = this.#wallet\n\t\t\t? this.#wallet.adapters.flatMap((a) =>\n\t\t\t\t\ta.getAccounts().map((acc) => ({\n\t\t\t\t\t\taddress: acc.address,\n\t\t\t\t\t\tlabel: acc.label,\n\t\t\t\t\t\tadapterName: a.name,\n\t\t\t\t\t})),\n\t\t\t\t)\n\t\t\t: [];\n\n\t\treturn html`\n\t\t\t<dialog class=\"connect-dialog\" @cancel=${(e: Event) => this.handleRejectConnect(e)}>\n\t\t\t\t<div class=\"connect-dialog-header\">\n\t\t\t\t\t<span class=\"connect-dialog-title\">${this.#wallet?.name ?? 'Dev Wallet'}</span>\n\t\t\t\t</div>\n\t\t\t\t<dev-wallet-connect\n\t\t\t\t\texportparts=\"approve-button: connect-approve-button, reject-button: connect-reject-button, account-list: connect-account-list, error-message: connect-error-message\"\n\t\t\t\t\t.accounts=${allAccounts}\n\t\t\t\t\t@approve=${(e: CustomEvent) => this.handleApproveConnect(e)}\n\t\t\t\t\t@reject=${(e: Event) => this.handleRejectConnect(e)}\n\t\t\t\t></dev-wallet-connect>\n\t\t\t</dialog>\n\t\t`;\n\t}\n\n\trenderNetworkBadge() {\n\t\tif (!this.#wallet) return nothing;\n\t\treturn html`\n\t\t\t<dev-wallet-network-badge\n\t\t\t\texportparts=\"trigger: network-trigger\"\n\t\t\t\t.active=${this.#wallet.activeNetwork}\n\t\t\t\t.networks=${this.#wallet.availableNetworks}\n\t\t\t\t@network-changed=${(e: CustomEvent) => this.handleNetworkChanged(e)}\n\t\t\t></dev-wallet-network-badge>\n\t\t`;\n\t}\n\n\trenderTabBar() {\n\t\treturn html`\n\t\t\t<dev-wallet-tab-bar\n\t\t\t\texportparts=\"tab-bar, tab\"\n\t\t\t\t.active=${this.activeTab}\n\t\t\t\t.showFork=${this.#isForkMode()}\n\t\t\t\t@tab-changed=${(e: CustomEvent) => this.handleTabChanged(e)}\n\t\t\t></dev-wallet-tab-bar>\n\t\t`;\n\t}\n\n\t/** Phase 5 Subtopic 6 (P5.8.5) — the Fork tab + panel render only\n\t * when the active stack is in fork mode. Two signals satisfy that:\n\t * 1. The host passed in a `ForkRelay` (built from the manifest's\n\t * wallet endpoint — devstack only constructs one when\n\t * `meta.runtime === 'forked'`).\n\t * 2. The active network literal ends in `-fork` (catch-all for\n\t * when the relay is wired but the user switched to a\n\t * non-fork network from the badge dropdown).\n\t * Both signals must agree — otherwise the tab is hidden. */\n\t#isForkMode(): boolean {\n\t\tif (this.forkRelay === null) return false;\n\t\tconst active = this.#wallet?.activeNetwork;\n\t\tif (!active) return false;\n\t\treturn isForkNetwork(active);\n\t}\n\n\t#resolveUpstreamLabel(): string {\n\t\tif (this.forkUpstream !== '') return this.forkUpstream;\n\t\tconst active = this.#wallet?.activeNetwork ?? '';\n\t\treturn active.endsWith('-fork') ? active.replace(/-fork$/, '') : '';\n\t}\n\n\t// ── Subscriptions ───────────────────────────────────────────────────────\n\n\t#subscribe(): void {\n\t\tif (!this.#wallet) return;\n\t\tthis.#unsubscribeEvents = this.#wallet.features['standard:events'].on('change', () => {\n\t\t\tthis.syncState();\n\t\t});\n\t\tthis.#unsubscribeRequests = this.#wallet.onRequestChange(() => {\n\t\t\tthis.syncState();\n\t\t});\n\t\tthis.#unsubscribeConnect = this.#wallet.onConnectChange(() => {\n\t\t\tthis.syncConnectState();\n\t\t});\n\t}\n\n\t#unsubscribe(): void {\n\t\tthis.#unsubscribeEvents?.();\n\t\tthis.#unsubscribeEvents = null;\n\t\tthis.#unsubscribeRequests?.();\n\t\tthis.#unsubscribeRequests = null;\n\t\tthis.#unsubscribeConnect?.();\n\t\tthis.#unsubscribeConnect = null;\n\t}\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.mts","names":[],"sources":["../../src/wallet/constants.ts"],"mappings":";;;KAKY,eAAA,iBACC,uBAAA,GAA0B,UAAA,CAAW,uBAAA,CAAwB,CAAA;;iBAI1D,mBAAA,CAAoB,KAAA;;cAKvB,mBAAA,EAAqB,UAAA"}
1
+ {"version":3,"file":"constants.d.mts","names":[],"sources":["../../src/wallet/constants.ts"],"mappings":";;;KAKY,eAAA,iBACC,uBAAA,GAA0B,UAAA,CAAW,uBAAA,CAAwB,CAAA;;iBAI1D,mBAAA,CAAoB,KAAa;;cAKpC,mBAAA,EAAqB,UACm7D"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","names":[],"sources":["../../src/wallet/constants.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { StandardEventsListeners, WalletIcon } from '@mysten/wallet-standard';\n\nexport type WalletEventsMap = {\n\t[E in keyof StandardEventsListeners]: Parameters<StandardEventsListeners[E]>[0];\n};\n\n/** Extract the network name from a chain identifier (e.g. 'sui:devnet' → 'devnet'). */\nexport function getNetworkFromChain(chain: string): string | undefined {\n\treturn chain.split(':')[1];\n}\n\n/** Default wallet icon shared between DevWallet and DevWalletClient. */\nexport const DEFAULT_WALLET_ICON: WalletIcon =\n\t'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCIgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0Ij4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0id2FsbGV0R3JhZCIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+CiAgICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiM2MzY2RjEiIC8+CiAgICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6IzI1NjNFQiIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImZsYXBHcmFkIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzgxOENGOCIgLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjojNEY0NkU1IiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICA8L2RlZnM+CiAgPCEtLSBTaGFkb3cgLS0+CiAgPHJlY3QgeD0iOSIgeT0iMjEiIHdpZHRoPSI1MCIgaGVpZ2h0PSIzNiIgcng9IjYiIHJ5PSI2IiBmaWxsPSIjMDAwIiBvcGFjaXR5PSIwLjEiIC8+CiAgPCEtLSBXYWxsZXQgYm9keSAtLT4KICA8cmVjdCB4PSI2IiB5PSIxOCIgd2lkdGg9IjUwIiBoZWlnaHQ9IjM2IiByeD0iNiIgcnk9IjYiIGZpbGw9InVybCgjd2FsbGV0R3JhZCkiIC8+CiAgPCEtLSBGbGFwIC0tPgogIDxwYXRoIGQ9Ik02IDI2IEw2IDIyIEM2IDE1IDggMTIgMTQgMTIgTDQ2IDEyIEM1MiAxMiA1NiAxNSA1NiAyMiBMNTYgMjYgWiIgZmlsbD0idXJsKCNmbGFwR3JhZCkiIC8+CiAgPCEtLSBDbGFzcCAtLT4KICA8cmVjdCB4PSI0MiIgeT0iMzAiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgcng9IjQiIHJ5PSI0IiBmaWxsPSIjNDMzOENBIiAvPgogIDwhLS0gR29sZCBjb2luIGluIGNsYXNwIC0tPgogIDxjaXJjbGUgY3g9IjQ4IiBjeT0iMzYiIHI9IjMuNSIgZmlsbD0iI0ZDRDM0RCIgLz4KICA8Y2lyY2xlIGN4PSI0OCIgY3k9IjM2IiByPSIyIiBmaWxsPSIjRjU5RTBCIiAvPgogIDwhLS0gRW1ib3NzZWQgRFcgdGV4dCAtLT4KICA8dGV4dCB4PSIyNiIgeT0iNDUiIGZvbnQtZmFtaWx5PSJBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0iOTAwIiBmb250LXNpemU9IjE4IiBmaWxsPSIjMzczMEEzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBkb21pbmFudC1iYXNlbGluZT0ibWlkZGxlIiBsZXR0ZXItc3BhY2luZz0iMiI+RFc8L3RleHQ+CiAgPHRleHQgeD0iMjYiIHk9IjQ0IiBmb250LWZhbWlseT0iQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZiIgZm9udC13ZWlnaHQ9IjkwMCIgZm9udC1zaXplPSIxOCIgZmlsbD0iI0M3RDJGRSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGxlIiBsZXR0ZXItc3BhY2luZz0iMiI+RFc8L3RleHQ+Cjwvc3ZnPgo=';\n"],"mappings":";;AAUA,SAAgB,oBAAoB,OAAmC;AACtE,QAAO,MAAM,MAAM,IAAI,CAAC;;;AAIzB,MAAa,sBACZ"}
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../../src/wallet/constants.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { StandardEventsListeners, WalletIcon } from '@mysten/wallet-standard';\n\nexport type WalletEventsMap = {\n\t[E in keyof StandardEventsListeners]: Parameters<StandardEventsListeners[E]>[0];\n};\n\n/** Extract the network name from a chain identifier (e.g. 'sui:devnet' → 'devnet'). */\nexport function getNetworkFromChain(chain: string): string | undefined {\n\treturn chain.split(':')[1];\n}\n\n/** Default wallet icon shared between DevWallet and DevWalletClient. */\nexport const DEFAULT_WALLET_ICON: WalletIcon =\n\t'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCIgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0Ij4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0id2FsbGV0R3JhZCIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+CiAgICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiM2MzY2RjEiIC8+CiAgICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6IzI1NjNFQiIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImZsYXBHcmFkIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzgxOENGOCIgLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjojNEY0NkU1IiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICA8L2RlZnM+CiAgPCEtLSBTaGFkb3cgLS0+CiAgPHJlY3QgeD0iOSIgeT0iMjEiIHdpZHRoPSI1MCIgaGVpZ2h0PSIzNiIgcng9IjYiIHJ5PSI2IiBmaWxsPSIjMDAwIiBvcGFjaXR5PSIwLjEiIC8+CiAgPCEtLSBXYWxsZXQgYm9keSAtLT4KICA8cmVjdCB4PSI2IiB5PSIxOCIgd2lkdGg9IjUwIiBoZWlnaHQ9IjM2IiByeD0iNiIgcnk9IjYiIGZpbGw9InVybCgjd2FsbGV0R3JhZCkiIC8+CiAgPCEtLSBGbGFwIC0tPgogIDxwYXRoIGQ9Ik02IDI2IEw2IDIyIEM2IDE1IDggMTIgMTQgMTIgTDQ2IDEyIEM1MiAxMiA1NiAxNSA1NiAyMiBMNTYgMjYgWiIgZmlsbD0idXJsKCNmbGFwR3JhZCkiIC8+CiAgPCEtLSBDbGFzcCAtLT4KICA8cmVjdCB4PSI0MiIgeT0iMzAiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgcng9IjQiIHJ5PSI0IiBmaWxsPSIjNDMzOENBIiAvPgogIDwhLS0gR29sZCBjb2luIGluIGNsYXNwIC0tPgogIDxjaXJjbGUgY3g9IjQ4IiBjeT0iMzYiIHI9IjMuNSIgZmlsbD0iI0ZDRDM0RCIgLz4KICA8Y2lyY2xlIGN4PSI0OCIgY3k9IjM2IiByPSIyIiBmaWxsPSIjRjU5RTBCIiAvPgogIDwhLS0gRW1ib3NzZWQgRFcgdGV4dCAtLT4KICA8dGV4dCB4PSIyNiIgeT0iNDUiIGZvbnQtZmFtaWx5PSJBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0iOTAwIiBmb250LXNpemU9IjE4IiBmaWxsPSIjMzczMEEzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBkb21pbmFudC1iYXNlbGluZT0ibWlkZGxlIiBsZXR0ZXItc3BhY2luZz0iMiI+RFc8L3RleHQ+CiAgPHRleHQgeD0iMjYiIHk9IjQ0IiBmb250LWZhbWlseT0iQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZiIgZm9udC13ZWlnaHQ9IjkwMCIgZm9udC1zaXplPSIxOCIgZmlsbD0iI0M3RDJGRSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGxlIiBsZXR0ZXItc3BhY2luZz0iMiI+RFc8L3RleHQ+Cjwvc3ZnPgo=';\n"],"mappings":";;AAUA,SAAgB,oBAAoB,OAAmC;CACtE,OAAO,MAAM,MAAM,GAAG,CAAC,CAAC;AACzB;;AAGA,MAAa,sBACZ"}
@@ -80,6 +80,18 @@ declare class DevWallet implements Wallet {
80
80
  get icon(): `data:image/svg+xml;base64,${string}` | `data:image/webp;base64,${string}` | `data:image/png;base64,${string}` | `data:image/gif;base64,${string}`;
81
81
  get chains(): readonly ["sui:devnet", "sui:testnet", "sui:localnet", "sui:mainnet"];
82
82
  get accounts(): readonly ReadonlyWalletAccount[];
83
+ /**
84
+ * Narrow the accounts this wallet exposes to dApps (via the
85
+ * wallet-standard `accounts` array + `change` events) to a single
86
+ * address, or pass `null` to expose all aggregated accounts again.
87
+ *
88
+ * Used by the devstack page-register entry to drive headless account
89
+ * selection: dApp Kit reflects the `change` event by switching its
90
+ * connected account to the now-single exposed account (or, if not yet
91
+ * connected, auto-connects to it). No reference to the app's dApp Kit
92
+ * instance is required — selection rides the wallet-standard protocol.
93
+ */
94
+ setSelectedAccount(address: string | null): void;
83
95
  get features(): StandardConnectFeature & StandardEventsFeature & StandardDisconnectFeature & SuiFeatures;
84
96
  /** The current pending signing request, or null if none. */
85
97
  get pendingRequest(): PendingSigningRequest | null;
@@ -112,6 +124,13 @@ declare class DevWallet implements Wallet {
112
124
  rejectConnect(reason?: string): void;
113
125
  /** Subscribe to pending connect request changes. Returns an unsubscribe function. */
114
126
  onConnectChange(callback: (request: PendingConnectRequest | null) => void): () => void;
127
+ /**
128
+ * Subscribe to the "a dApp invoked `standard:connect`" edge. Returns an
129
+ * unsubscribe function. Used by the page-register entry to gate its
130
+ * narrow→widen account-selection on an OBSERVED connect rather than a fixed
131
+ * timer (see `src/inject/index.ts`).
132
+ */
133
+ onDAppConnected(callback: () => void): () => void;
115
134
  }
116
135
  //#endregion
117
136
  export { AutoApprovePolicy, DEFAULT_NETWORK_URLS, DevWallet, DevWalletConfig, PendingConnectRequest, PendingSigningRequest };
@@ -1 +1 @@
1
- {"version":3,"file":"dev-wallet.d.mts","names":[],"sources":["../../src/wallet/dev-wallet.ts"],"mappings":";;;;;;;AAiCA;;cAAa,oBAAA;EAAA;;;;;UAOI,aAAA;EAChB,EAAA;EACA,IAAA;EACA,OAAA,EAAS,aAAA;EACT,KAAA;EAEe;EAAf,IAAA,WAAe,UAAA;EACf,OAAA,GAAU,MAAA,EAAQ,aAAA;EAClB,MAAA,GAAS,KAAA,EAAO,KAAA;AAAA;;KAIL,qBAAA,GAAwB,IAAA,CAAK,aAAA;AAAA,UAExB,cAAA;EAChB,EAAA;EACA,OAAA,GAAU,MAAA;IAAU,QAAA,WAAmB,aAAA;EAAA;EACvC,MAAA,GAAS,KAAA,EAAO,KAAA;AAAA;;KAIL,qBAAA,GAAwB,IAAA,CAAK,cAAA;;;;;KAM7B,iBAAA,eAEP,OAAA;EACF,IAAA,EAAM,aAAA;EACN,OAAA,EAAS,aAAA;EACT,KAAA;EACA,IAAA,WAAe,UAAA;AAAA;AAAA,UAGD,eAAA;EAChB,QAAA,EAAU,aAAA;EApBW;EAsBrB,QAAA,GAAW,MAAA;EAvBX;EAyBA,IAAA;EACA,IAAA,GAAO,UAAA;EA1BG;EA4BV,aAAA;EA3BgB;;;;EAgChB,WAAA,GAAc,iBAAA;EA5BkB;EA8BhC,WAAA;EA9BmC;EAgCnC,aAAA,IAAiB,OAAA,UAAiB,GAAA,aAAgB,iBAAA;EA1BvC;;;;EA+BX,eAAA;AAAA;;;;;cAOY,SAAA,YAAqB,MAAA;EAAA;cAoBrB,MAAA,EAAQ,eAAA;EAAA,IA0BhB,OAAA,CAAA;EAAA,IAIA,IAAA,CAAA;EAAA,IAIA,IAAA,CAAA;EAAA,IAIA,MAAA,CAAA;EAAA,IAIA,QAAA,CAAA,YAAqB,qBAAA;EAAA,IAIrB,QAAA,CAAA,GAAY,sBAAA,GACf,qBAAA,GACA,yBAAA,GACA,WAAA;EAlG8B;EAAA,IAgI3B,cAAA,CAAA,GAAkB,qBAAA;EAAA,IAIlB,QAAA,CAAA,YAAqB,aAAA;EAIzB,oBAAA,CAAqB,OAAA,WAAkB,aAAA;EAlIhC;EAAA,IAuIH,OAAA,CAAA,GAAW,MAAA,SAAe,iBAAA;EAO9B,SAAA,CAAU,OAAA,WAAkB,iBAAA;EAAA,IAIxB,WAAA,CAAA,GAAe,MAAA;EAAA,IAIf,aAAA,CAAA;EAAA,IAIA,YAAA,CAAA,GAAgB,iBAAA;EAAA,IAKhB,iBAAA,CAAA;EAlKJ;EAuKA,gBAAA,CAAiB,OAAA;EAUjB,UAAA,CAAW,IAAA,UAAc,GAAA;EAgBzB,aAAA,CAAc,IAAA;EA9LP;EAyMP,QAAA,CAAA;EAlMA;EA6MA,OAAA,CAAA;EA3MA;EAkOM,cAAA,CAAA,GAAkB,OAAA;EAuBxB,aAAA,CAAc,MAAA;EAvPoB;EAkQlC,eAAA,CAAgB,QAAA,GAAW,OAAA,EAAS,qBAAA;EA7PpC;EAAA,IAqQI,cAAA,CAAA,GAAkB,qBAAA;EArQP;EA0Qf,cAAA,CAAe,iBAAA;EAgBf,aAAA,CAAc,MAAA;;EAWd,eAAA,CAAgB,QAAA,GAAW,OAAA,EAAS,qBAAA;AAAA"}
1
+ {"version":3,"file":"dev-wallet.d.mts","names":[],"sources":["../../src/wallet/dev-wallet.ts"],"mappings":";;;;;;;AAiCA;;cAAa,oBAAA;EAAA;;;;;UAOI,aAAA;EAChB,EAAA;EACA,IAAA;EACA,OAAA,EAAS,aAAA;EACT,KAAA;EAEe;EAAf,IAAA,WAAe,UAAA;EACf,OAAA,GAAU,MAAA,EAAQ,aAAA;EAClB,MAAA,GAAS,KAAA,EAAO,KAAA;AAAA;;KAIL,qBAAA,GAAwB,IAAI,CAAC,aAAA;AAAA,UAExB,cAAA;EAChB,EAAA;EACA,OAAA,GAAU,MAAA;IAAU,QAAA,WAAmB,aAAA;EAAA;EACvC,MAAA,GAAS,KAAA,EAAO,KAAK;AAAA;;KAIV,qBAAA,GAAwB,IAAI,CAAC,cAAA;;;;AAbnB;KAmBV,iBAAA,eAEP,OAAA;EACF,IAAA,EAAM,aAAA;EACN,OAAA,EAAS,aAAA;EACT,KAAA;EACA,IAAA,WAAe,UAAA;AAAA;AAAA,UAGD,eAAA;EAChB,QAAA,EAAU,aAAA;EApBW;EAsBrB,QAAA,GAAW,MAAA;EAvBX;EAyBA,IAAA;EACA,IAAA,GAAO,UAAA;EA1BG;EA4BV,aAAA;EA3BgB;;;AAAK;EAgCrB,WAAA,GAAc,iBAAA;EA5BkB;EA8BhC,WAAA;EA9BmC;EAgCnC,aAAA,IAAiB,OAAA,UAAiB,GAAA,aAAgB,iBAAA;EA1BvC;;;;EA+BX,eAAA;AAAA;;;;;cAOY,SAAA,YAAqB,MAAA;EAAA;cA2BrB,MAAA,EAAQ,eAAA;EAAA,IA2BhB,OAAA;EAAA,IAIA,IAAA;EAAA,IAIA,IAAA;EAAA,IAIA,MAAA;EAAA,IAIA,QAAA,aAAqB,qBAAA;EAnGT;;;;;;;;;;;EAkHhB,kBAAA,CAAmB,OAAA;EAAA,IAwBf,QAAA,IAAY,sBAAA,GACf,qBAAA,GACA,yBAAA,GACA,WAAA;EA1IU;EAAA,IAwKP,cAAA,IAAkB,qBAAA;EAAA,IAIlB,QAAA,aAAqB,aAAA;EAIzB,oBAAA,CAAqB,OAAA,WAAkB,aAAA;EA3KvC;EAAA,IAgLI,OAAA,IAAW,MAAA,SAAe,iBAAA;EAO9B,SAAA,CAAU,OAAA,WAAkB,iBAAA;EAAA,IAIxB,WAAA,IAAe,MAAA;EAAA,IAIf,aAAA;EAAA,IAIA,YAAA,IAAgB,iBAAA;EAAA,IAKhB,iBAAA;EA/L8C;EAoMlD,gBAAA,CAAiB,OAAA;EAUjB,UAAA,CAAW,IAAA,UAAc,GAAA;EAgBzB,aAAA,CAAc,IAAA;EAlNF;EA6NZ,QAAA;;EAWA,OAAA;EAlKyB;EA0LnB,cAAA,IAAkB,OAAA;EAuBxB,aAAA,CAAc,MAAA;EAxKb;EAmLD,eAAA,CAAgB,QAAA,GAAW,OAAA,EAAS,qBAAA;EApJd;EAAA,IA4JlB,cAAA,IAAkB,qBAAA;EApJiB;EAyJvC,cAAA,CAAe,iBAAA;EAgBf,aAAA,CAAc,MAAA;EA7Jc;EAwK5B,eAAA,CAAgB,QAAA,GAAW,OAAA,EAAS,qBAAA;EA5JhB;;;;;;EAuLpB,eAAA,CAAgB,QAAA;AAAA"}
@@ -30,12 +30,19 @@ var DevWallet = class {
30
30
  #clientFactory;
31
31
  #persistNetworks;
32
32
  #accounts;
33
+ #selectedAddress = null;
33
34
  #events;
34
35
  #unsubscribeAdapters;
35
36
  #pendingRequest;
36
37
  #requestListeners;
37
38
  #pendingConnect;
38
39
  #connectListeners;
40
+ /** Fired every time a dApp invokes `standard:connect` (the wallet's
41
+ * authoritative "a dApp is connecting" signal). Distinct from
42
+ * `#connectListeners`, which track the *pending-request* lifecycle for the
43
+ * approval UI. Consumers (e.g. the inject's `selectAccount`) use this to
44
+ * observe that the dApp has reached the wallet rather than racing a timer. */
45
+ #connectedListeners;
39
46
  #destroyed = false;
40
47
  constructor(config) {
41
48
  if (config.adapters.length === 0) console.warn("[dev-wallet] No adapters provided. The wallet will have no accounts.");
@@ -59,6 +66,7 @@ var DevWallet = class {
59
66
  this.#requestListeners = /* @__PURE__ */ new Set();
60
67
  this.#pendingConnect = null;
61
68
  this.#connectListeners = /* @__PURE__ */ new Set();
69
+ this.#connectedListeners = /* @__PURE__ */ new Set();
62
70
  this.#setupAdapterListeners();
63
71
  }
64
72
  get version() {
@@ -74,7 +82,34 @@ var DevWallet = class {
74
82
  return SUI_CHAINS;
75
83
  }
76
84
  get accounts() {
77
- return this.#accounts;
85
+ return this.#exposedAccounts();
86
+ }
87
+ /**
88
+ * Narrow the accounts this wallet exposes to dApps (via the
89
+ * wallet-standard `accounts` array + `change` events) to a single
90
+ * address, or pass `null` to expose all aggregated accounts again.
91
+ *
92
+ * Used by the devstack page-register entry to drive headless account
93
+ * selection: dApp Kit reflects the `change` event by switching its
94
+ * connected account to the now-single exposed account (or, if not yet
95
+ * connected, auto-connects to it). No reference to the app's dApp Kit
96
+ * instance is required — selection rides the wallet-standard protocol.
97
+ */
98
+ setSelectedAccount(address) {
99
+ if (address !== null) {
100
+ const match = this.#accounts.find((a) => a.address.toLowerCase() === address.toLowerCase());
101
+ if (match === void 0) {
102
+ const available = this.#accounts.map((a) => a.address).join(", ");
103
+ throw new Error(`No dev-wallet account for address "${address}". Available: ${available || "(none)"}`);
104
+ }
105
+ this.#selectedAddress = match.address;
106
+ } else this.#selectedAddress = null;
107
+ this.#events.emit("change", { accounts: this.#exposedAccounts() });
108
+ }
109
+ /** Accounts exposed to dApps — narrowed to the selected address when set. */
110
+ #exposedAccounts() {
111
+ if (this.#selectedAddress === null) return this.#accounts;
112
+ return this.#accounts.filter((a) => a.address.toLowerCase() === this.#selectedAddress.toLowerCase());
78
113
  }
79
114
  get features() {
80
115
  return {
@@ -182,6 +217,7 @@ var DevWallet = class {
182
217
  }
183
218
  this.#requestListeners.clear();
184
219
  this.#connectListeners.clear();
220
+ this.#connectedListeners.clear();
185
221
  this.#events.all.clear();
186
222
  }
187
223
  /** Sign the pending request using the account's adapter signer and resolve the promise. */
@@ -248,6 +284,25 @@ var DevWallet = class {
248
284
  const request = this.#pendingConnect;
249
285
  for (const listener of this.#connectListeners) listener(request);
250
286
  }
287
+ /**
288
+ * Subscribe to the "a dApp invoked `standard:connect`" edge. Returns an
289
+ * unsubscribe function. Used by the page-register entry to gate its
290
+ * narrow→widen account-selection on an OBSERVED connect rather than a fixed
291
+ * timer (see `src/inject/index.ts`).
292
+ */
293
+ onDAppConnected(callback) {
294
+ this.#connectedListeners.add(callback);
295
+ return () => {
296
+ this.#connectedListeners.delete(callback);
297
+ };
298
+ }
299
+ #notifyConnectedListeners() {
300
+ for (const listener of this.#connectedListeners) try {
301
+ listener();
302
+ } catch (error) {
303
+ console.error("[dev-wallet] onDAppConnected listener threw:", error);
304
+ }
305
+ }
251
306
  #aggregateAccounts() {
252
307
  return this.#adapters.flatMap((a) => a.getAccounts().map((acc) => acc.walletAccount));
253
308
  }
@@ -255,7 +310,7 @@ var DevWallet = class {
255
310
  for (const adapter of this.#adapters) {
256
311
  const unsub = adapter.onAccountsChanged(() => {
257
312
  this.#accounts = this.#aggregateAccounts();
258
- this.#events.emit("change", { accounts: this.#accounts });
313
+ this.#events.emit("change", { accounts: this.#exposedAccounts() });
259
314
  });
260
315
  this.#unsubscribeAdapters.push(unsub);
261
316
  }
@@ -265,6 +320,7 @@ var DevWallet = class {
265
320
  return () => this.#events.off(event, listener);
266
321
  };
267
322
  #connect = async () => {
323
+ this.#notifyConnectedListeners();
268
324
  if (this.#autoConnect) return { accounts: this.accounts };
269
325
  if (this.#pendingConnect) return Promise.reject(/* @__PURE__ */ new Error("A connect request is already pending."));
270
326
  return new Promise((resolve, reject) => {
@@ -1 +1 @@
1
- {"version":3,"file":"dev-wallet.mjs","names":["#adapters","#name","#icon","#autoApprove","#autoConnect","#clientFactory","#persistNetworks","#networkUrls","#loadNetworkUrls","#clients","#activeNetwork","#accounts","#aggregateAccounts","#events","#unsubscribeAdapters","#pendingRequest","#requestListeners","#pendingConnect","#connectListeners","#setupAdapterListeners","#connect","#on","#disconnect","#signPersonalMessage","#signTransaction","#signAndExecuteTransaction","#ensureClient","#saveNetworkUrls","#destroyed","#executeSigning","#notifyRequestListeners","#notifyConnectListeners","#getSigner","#getClientForChain","#shouldAutoApprove","#enqueueRequest"],"sources":["../../src/wallet/dev-wallet.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport { SuiGrpcClient } from '@mysten/sui/grpc';\nimport { mitt, type Emitter } from '@mysten/utils';\nimport type {\n\tStandardConnectFeature,\n\tStandardConnectMethod,\n\tStandardDisconnectFeature,\n\tStandardDisconnectMethod,\n\tStandardEventsFeature,\n\tStandardEventsOnMethod,\n\tSuiFeatures,\n\tSuiSignAndExecuteTransactionMethod,\n\tSuiSignPersonalMessageMethod,\n\tSuiSignTransactionMethod,\n\tWallet,\n\tWalletAccount,\n\tWalletIcon,\n} from '@mysten/wallet-standard';\nimport { getWallets, ReadonlyWalletAccount, SUI_CHAINS } from '@mysten/wallet-standard';\n\nimport type { SignerAdapter } from '../types.js';\nimport { DEFAULT_WALLET_ICON, getNetworkFromChain, type WalletEventsMap } from './constants.js';\nimport { type SigningResult, executeSigning } from './signing.js';\n\nconst DEFAULT_WALLET_NAME = 'Dev Wallet';\nconst NETWORK_STORAGE_KEY = 'dev-wallet:networks';\n\n/**\n * Default gRPC endpoint URLs for standard Sui networks (devnet, testnet, localnet).\n */\nexport const DEFAULT_NETWORK_URLS = {\n\tdevnet: 'https://fullnode.devnet.sui.io:443',\n\ttestnet: 'https://fullnode.testnet.sui.io:443',\n\tlocalnet: 'http://127.0.0.1:9000',\n} as const;\n\n/** A pending signing request waiting for user approval via the wallet UI. */\nexport interface WalletRequest {\n\tid: string;\n\ttype: 'sign-transaction' | 'sign-and-execute-transaction' | 'sign-personal-message';\n\taccount: WalletAccount;\n\tchain: string;\n\t/** Transaction JSON string for sign/execute, Uint8Array for personal messages. */\n\tdata: string | Uint8Array;\n\tresolve: (result: SigningResult) => void;\n\treject: (error: Error) => void;\n}\n\n/** Public view of a pending signing request, omitting internal resolve/reject callbacks. */\nexport type PendingSigningRequest = Omit<WalletRequest, 'resolve' | 'reject'>;\n\nexport interface ConnectRequest {\n\tid: string;\n\tresolve: (result: { accounts: readonly WalletAccount[] }) => void;\n\treject: (error: Error) => void;\n}\n\n/** Public view of a pending connect request, omitting internal resolve/reject callbacks. */\nexport type PendingConnectRequest = Omit<ConnectRequest, 'resolve' | 'reject'>;\n\n/**\n * Auto-approval policy for signing requests.\n * `true` approves all requests; a function is called per-request and returns `true` to approve.\n */\nexport type AutoApprovePolicy =\n\t| boolean\n\t| ((request: {\n\t\t\ttype: WalletRequest['type'];\n\t\t\taccount: WalletAccount;\n\t\t\tchain: string;\n\t\t\tdata: string | Uint8Array;\n\t }) => boolean);\n\nexport interface DevWalletConfig {\n\tadapters: SignerAdapter[];\n\t/** Network URLs by name (network → gRPC endpoint). Defaults to devnet, testnet, and localnet. */\n\tnetworks?: Record<string, string>;\n\t/** Display name for the wallet. Defaults to 'Dev Wallet'. */\n\tname?: string;\n\ticon?: WalletIcon;\n\t/** Initially active network. Defaults to the first key in `networks`. */\n\tactiveNetwork?: string;\n\t/**\n\t * When set, matching requests are signed immediately without queuing for user approval.\n\t * `true` approves everything; a function is called per-request for fine-grained control.\n\t */\n\tautoApprove?: AutoApprovePolicy;\n\t/** When true, connect requests resolve immediately with all accounts. */\n\tautoConnect?: boolean;\n\t/** Factory to create a client for a given network. Defaults to SuiGrpcClient. */\n\tclientFactory?: (network: string, url: string) => ClientWithCoreApi;\n\t/**\n\t * Persist network URLs to localStorage so custom configurations survive page reloads\n\t * and are shared with popup windows.\n\t */\n\tpersistNetworks?: boolean;\n}\n\n/**\n * wallet-standard Wallet implementation for development. All signing requests are queued\n * and require explicit approval — either via the UI or programmatically via `approveRequest()`.\n */\nexport class DevWallet implements Wallet {\n\treadonly #adapters: SignerAdapter[];\n\t#networkUrls: Record<string, string>;\n\t#clients: Record<string, ClientWithCoreApi>;\n\t#activeNetwork: string;\n\treadonly #name: string;\n\treadonly #icon: WalletIcon;\n\treadonly #autoApprove: AutoApprovePolicy;\n\treadonly #autoConnect: boolean;\n\treadonly #clientFactory: (network: string, url: string) => ClientWithCoreApi;\n\treadonly #persistNetworks: boolean;\n\t#accounts: ReadonlyWalletAccount[];\n\t#events: Emitter<WalletEventsMap>;\n\t#unsubscribeAdapters: (() => void)[];\n\t#pendingRequest: WalletRequest | null;\n\t#requestListeners: Set<(request: PendingSigningRequest | null) => void>;\n\t#pendingConnect: ConnectRequest | null;\n\t#connectListeners: Set<(request: PendingConnectRequest | null) => void>;\n\t#destroyed = false;\n\n\tconstructor(config: DevWalletConfig) {\n\t\tif (config.adapters.length === 0) {\n\t\t\tconsole.warn('[dev-wallet] No adapters provided. The wallet will have no accounts.');\n\t\t}\n\t\tthis.#adapters = config.adapters;\n\t\tthis.#persistNetworks = config.persistNetworks ?? false;\n\t\tthis.#networkUrls = this.#loadNetworkUrls(config.networks ?? DEFAULT_NETWORK_URLS);\n\t\tthis.#clients = {};\n\t\tthis.#activeNetwork = config.activeNetwork ?? Object.keys(this.#networkUrls)[0] ?? '';\n\t\tthis.#name = config.name ?? DEFAULT_WALLET_NAME;\n\t\tthis.#icon = config.icon ?? DEFAULT_WALLET_ICON;\n\t\tthis.#autoApprove = config.autoApprove ?? false;\n\t\tthis.#autoConnect = config.autoConnect ?? false;\n\t\tthis.#clientFactory =\n\t\t\tconfig.clientFactory ?? ((network, url) => new SuiGrpcClient({ baseUrl: url, network }));\n\t\tthis.#accounts = this.#aggregateAccounts();\n\t\tthis.#events = mitt();\n\t\tthis.#unsubscribeAdapters = [];\n\t\tthis.#pendingRequest = null;\n\t\tthis.#requestListeners = new Set();\n\t\tthis.#pendingConnect = null;\n\t\tthis.#connectListeners = new Set();\n\n\t\tthis.#setupAdapterListeners();\n\t}\n\n\tget version() {\n\t\treturn '1.0.0' as const;\n\t}\n\n\tget name() {\n\t\treturn this.#name;\n\t}\n\n\tget icon() {\n\t\treturn this.#icon;\n\t}\n\n\tget chains() {\n\t\treturn SUI_CHAINS;\n\t}\n\n\tget accounts(): readonly ReadonlyWalletAccount[] {\n\t\treturn this.#accounts;\n\t}\n\n\tget features(): StandardConnectFeature &\n\t\tStandardEventsFeature &\n\t\tStandardDisconnectFeature &\n\t\tSuiFeatures {\n\t\treturn {\n\t\t\t'standard:connect': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tconnect: this.#connect,\n\t\t\t},\n\t\t\t'standard:events': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\ton: this.#on,\n\t\t\t},\n\t\t\t'standard:disconnect': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tdisconnect: this.#disconnect,\n\t\t\t},\n\t\t\t'sui:signPersonalMessage': {\n\t\t\t\tversion: '1.1.0',\n\t\t\t\tsignPersonalMessage: this.#signPersonalMessage,\n\t\t\t},\n\t\t\t'sui:signTransaction': {\n\t\t\t\tversion: '2.0.0',\n\t\t\t\tsignTransaction: this.#signTransaction,\n\t\t\t},\n\t\t\t'sui:signAndExecuteTransaction': {\n\t\t\t\tversion: '2.0.0',\n\t\t\t\tsignAndExecuteTransaction: this.#signAndExecuteTransaction,\n\t\t\t},\n\t\t};\n\t}\n\n\t/** The current pending signing request, or null if none. */\n\tget pendingRequest(): PendingSigningRequest | null {\n\t\treturn this.#pendingRequest;\n\t}\n\n\tget adapters(): readonly SignerAdapter[] {\n\t\treturn this.#adapters;\n\t}\n\n\tgetAdapterForAccount(address: string): SignerAdapter | undefined {\n\t\treturn this.#adapters.find((a) => a.getAccount(address) !== undefined);\n\t}\n\n\t/** Eagerly creates and returns clients for all configured networks. Prefer `getClient()` or `activeClient` for single-network access. */\n\tget clients(): Record<string, ClientWithCoreApi> {\n\t\tfor (const name of Object.keys(this.#networkUrls)) {\n\t\t\tthis.#ensureClient(name);\n\t\t}\n\t\treturn { ...this.#clients };\n\t}\n\n\tgetClient(network: string): ClientWithCoreApi {\n\t\treturn this.#ensureClient(network);\n\t}\n\n\tget networkUrls(): Record<string, string> {\n\t\treturn { ...this.#networkUrls };\n\t}\n\n\tget activeNetwork(): string {\n\t\treturn this.#activeNetwork;\n\t}\n\n\tget activeClient(): ClientWithCoreApi | null {\n\t\tif (!this.#activeNetwork || !this.#networkUrls[this.#activeNetwork]) return null;\n\t\treturn this.#ensureClient(this.#activeNetwork);\n\t}\n\n\tget availableNetworks(): string[] {\n\t\treturn Object.keys(this.#networkUrls);\n\t}\n\n\t/** Switch the active network. Emits a `change` event. */\n\tsetActiveNetwork(network: string): void {\n\t\tif (!this.#networkUrls[network]) {\n\t\t\tthrow new Error(\n\t\t\t\t`No client for network \"${network}\". Available: ${this.availableNetworks.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tthis.#activeNetwork = network;\n\t\tthis.#events.emit('change', { accounts: this.#accounts });\n\t}\n\n\taddNetwork(name: string, url: string): void {\n\t\tlet parsed: URL;\n\t\ttry {\n\t\t\tparsed = new URL(url);\n\t\t} catch {\n\t\t\tthrow new Error(`Invalid URL: ${url}`);\n\t\t}\n\t\tif (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n\t\t\tthrow new Error(`Invalid URL: must use http or https (got ${parsed.protocol})`);\n\t\t}\n\t\tthis.#networkUrls[name] = url;\n\t\tthis.#clients[name] = this.#clientFactory(name, url);\n\t\tthis.#saveNetworkUrls();\n\t\tthis.#events.emit('change', { accounts: this.#accounts });\n\t}\n\n\tremoveNetwork(name: string): void {\n\t\tdelete this.#networkUrls[name];\n\t\tdelete this.#clients[name];\n\t\tif (this.#activeNetwork === name) {\n\t\t\tthis.#activeNetwork = Object.keys(this.#networkUrls)[0] ?? '';\n\t\t}\n\t\tthis.#saveNetworkUrls();\n\t\tthis.#events.emit('change', { accounts: this.#accounts });\n\t}\n\n\t/** Register this wallet with the wallet-standard registry. Returns an unregister function. */\n\tregister(): () => void {\n\t\tif (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') {\n\t\t\tconsole.warn(\n\t\t\t\t'[@mysten-incubation/dev-wallet] DevWallet is intended for development only. Do not use in production.',\n\t\t\t);\n\t\t}\n\t\tconst walletsApi = getWallets();\n\t\treturn walletsApi.register(this);\n\t}\n\n\t/** Reject any pending requests, unsubscribe from adapters, destroy them, and clear all listeners. */\n\tdestroy(): void {\n\t\tthis.#destroyed = true;\n\t\tfor (const unsub of this.#unsubscribeAdapters) {\n\t\t\tunsub();\n\t\t}\n\t\tthis.#unsubscribeAdapters = [];\n\t\tfor (const adapter of this.#adapters) {\n\t\t\tadapter.destroy();\n\t\t}\n\t\tif (this.#pendingRequest) {\n\t\t\tthis.#pendingRequest.reject(new Error('Wallet destroyed.'));\n\t\t\tthis.#pendingRequest = null;\n\t\t}\n\t\tif (this.#pendingConnect) {\n\t\t\tthis.#pendingConnect.reject(new Error('Wallet destroyed.'));\n\t\t\tthis.#pendingConnect = null;\n\t\t}\n\t\tthis.#requestListeners.clear();\n\t\tthis.#connectListeners.clear();\n\t\tthis.#events.all.clear();\n\t}\n\n\t/** Sign the pending request using the account's adapter signer and resolve the promise. */\n\tasync approveRequest(): Promise<void> {\n\t\tconst request = this.#pendingRequest;\n\t\tif (!request) {\n\t\t\tthrow new Error('No pending request to approve.');\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.#executeSigning(\n\t\t\t\trequest.type,\n\t\t\t\trequest.account,\n\t\t\t\trequest.chain,\n\t\t\t\trequest.data,\n\t\t\t);\n\t\t\tthis.#pendingRequest = null;\n\t\t\tthis.#notifyRequestListeners();\n\t\t\trequest.resolve(result);\n\t\t} catch (error) {\n\t\t\tthis.#pendingRequest = null;\n\t\t\tthis.#notifyRequestListeners();\n\t\t\trequest.reject(error instanceof Error ? error : new Error(String(error)));\n\t\t}\n\t}\n\n\trejectRequest(reason?: string): void {\n\t\tconst request = this.#pendingRequest;\n\t\tif (!request) {\n\t\t\tthrow new Error('No pending request to reject.');\n\t\t}\n\t\tthis.#pendingRequest = null;\n\t\tthis.#notifyRequestListeners();\n\t\trequest.reject(new Error(reason ?? 'Request rejected by user.'));\n\t}\n\n\t/** Subscribe to pending request changes. Returns an unsubscribe function. */\n\tonRequestChange(callback: (request: PendingSigningRequest | null) => void): () => void {\n\t\tthis.#requestListeners.add(callback);\n\t\treturn () => {\n\t\t\tthis.#requestListeners.delete(callback);\n\t\t};\n\t}\n\n\t/** The current pending connect request, or null if none. */\n\tget pendingConnect(): PendingConnectRequest | null {\n\t\treturn this.#pendingConnect;\n\t}\n\n\t/** Expose the given addresses to the dApp. Pass an empty array to expose all accounts. */\n\tapproveConnect(selectedAddresses: string[]): void {\n\t\tconst request = this.#pendingConnect;\n\t\tif (!request) {\n\t\t\tthrow new Error('No pending connect request to approve.');\n\t\t}\n\n\t\tconst selected =\n\t\t\tselectedAddresses.length > 0\n\t\t\t\t? this.#accounts.filter((a) => selectedAddresses.includes(a.address))\n\t\t\t\t: [...this.#accounts];\n\n\t\tthis.#pendingConnect = null;\n\t\tthis.#notifyConnectListeners();\n\t\trequest.resolve({ accounts: selected });\n\t}\n\n\trejectConnect(reason?: string): void {\n\t\tconst request = this.#pendingConnect;\n\t\tif (!request) {\n\t\t\tthrow new Error('No pending connect request to reject.');\n\t\t}\n\t\tthis.#pendingConnect = null;\n\t\tthis.#notifyConnectListeners();\n\t\trequest.reject(new Error(reason ?? 'Connection rejected by user.'));\n\t}\n\n\t/** Subscribe to pending connect request changes. Returns an unsubscribe function. */\n\tonConnectChange(callback: (request: PendingConnectRequest | null) => void): () => void {\n\t\tthis.#connectListeners.add(callback);\n\t\treturn () => {\n\t\t\tthis.#connectListeners.delete(callback);\n\t\t};\n\t}\n\n\t#notifyRequestListeners() {\n\t\tconst request = this.#pendingRequest;\n\t\tfor (const listener of this.#requestListeners) {\n\t\t\tlistener(request);\n\t\t}\n\t}\n\n\t#notifyConnectListeners() {\n\t\tconst request = this.#pendingConnect;\n\t\tfor (const listener of this.#connectListeners) {\n\t\t\tlistener(request);\n\t\t}\n\t}\n\n\t#aggregateAccounts(): ReadonlyWalletAccount[] {\n\t\treturn this.#adapters.flatMap((a) => a.getAccounts().map((acc) => acc.walletAccount));\n\t}\n\n\t#setupAdapterListeners() {\n\t\tfor (const adapter of this.#adapters) {\n\t\t\tconst unsub = adapter.onAccountsChanged(() => {\n\t\t\t\tthis.#accounts = this.#aggregateAccounts();\n\t\t\t\tthis.#events.emit('change', { accounts: this.#accounts });\n\t\t\t});\n\t\t\tthis.#unsubscribeAdapters.push(unsub);\n\t\t}\n\t}\n\n\t#on: StandardEventsOnMethod = (event, listener) => {\n\t\tthis.#events.on(event, listener);\n\t\treturn () => this.#events.off(event, listener);\n\t};\n\n\t#connect: StandardConnectMethod = async () => {\n\t\t// Auto-connect: return all accounts immediately\n\t\tif (this.#autoConnect) {\n\t\t\treturn { accounts: this.accounts };\n\t\t}\n\n\t\t// Queue a connect request for user to select accounts\n\t\tif (this.#pendingConnect) {\n\t\t\treturn Promise.reject(new Error('A connect request is already pending.'));\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.#pendingConnect = {\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t};\n\t\t\tthis.#notifyConnectListeners();\n\t\t});\n\t};\n\n\t#disconnect: StandardDisconnectMethod = async () => {\n\t\t// Disconnecting ends the dApp session but does not affect wallet state.\n\t\t// The wallet retains its accounts and adapter subscriptions.\n\t};\n\n\t#getClientForChain(chain: string) {\n\t\tconst network = getNetworkFromChain(chain);\n\t\tif (!network) {\n\t\t\tthrow new Error(`Invalid chain identifier: ${chain}`);\n\t\t}\n\t\treturn this.#ensureClient(network);\n\t}\n\n\t#loadNetworkUrls(defaults: Record<string, string>): Record<string, string> {\n\t\tif (!this.#persistNetworks || typeof localStorage === 'undefined') {\n\t\t\treturn { ...defaults };\n\t\t}\n\t\ttry {\n\t\t\tconst raw = localStorage.getItem(NETWORK_STORAGE_KEY);\n\t\t\tif (raw) {\n\t\t\t\tconst parsed = JSON.parse(raw);\n\t\t\t\tif (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n\t\t\t\t\treturn parsed as Record<string, string>;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Corrupted data — fall through to defaults\n\t\t}\n\t\treturn { ...defaults };\n\t}\n\n\t#saveNetworkUrls(): void {\n\t\tif (!this.#persistNetworks || typeof localStorage === 'undefined') return;\n\t\tlocalStorage.setItem(NETWORK_STORAGE_KEY, JSON.stringify(this.#networkUrls));\n\t}\n\n\t#ensureClient(network: string): ClientWithCoreApi {\n\t\tif (!this.#clients[network]) {\n\t\t\tconst url = this.#networkUrls[network];\n\t\t\tif (!url) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No client for network \"${network}\". Available: ${this.availableNetworks.join(', ')}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.#clients[network] = this.#clientFactory(network, url);\n\t\t}\n\t\treturn this.#clients[network];\n\t}\n\n\t#getSigner(address: string) {\n\t\tfor (const adapter of this.#adapters) {\n\t\t\tconst account = adapter.getAccount(address);\n\t\t\tif (account) return account.signer;\n\t\t}\n\t\tconst allAddresses = this.#adapters.flatMap((a) => a.getAccounts().map((acc) => acc.address));\n\t\tthrow new Error(\n\t\t\t`No account found for address \"${address}\". Available addresses: ${allAddresses.join(', ')}`,\n\t\t);\n\t}\n\n\t#shouldAutoApprove(\n\t\ttype: WalletRequest['type'],\n\t\taccount: WalletAccount,\n\t\tchain: string,\n\t\tdata: string | Uint8Array,\n\t): boolean {\n\t\t// Check adapter-level opt-out first — CLI adapters never auto-sign\n\t\tconst adapter = this.getAdapterForAccount(account.address);\n\t\tif (adapter?.allowAutoSign === false) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.#autoApprove === true) {\n\t\t\treturn true;\n\t\t}\n\t\tif (typeof this.#autoApprove === 'function') {\n\t\t\treturn this.#autoApprove({ type, account, chain, data });\n\t\t}\n\t\treturn false;\n\t}\n\n\tasync #executeSigning(\n\t\ttype: WalletRequest['type'],\n\t\taccount: WalletAccount,\n\t\tchain: string,\n\t\tdata: string | Uint8Array,\n\t) {\n\t\tconst signer = this.#getSigner(account.address);\n\t\tconst client = type !== 'sign-personal-message' ? this.#getClientForChain(chain) : undefined;\n\t\treturn executeSigning({ type, signer, data, client });\n\t}\n\n\t#enqueueRequest<T extends WalletRequest['type']>(\n\t\ttype: T,\n\t\taccount: WalletAccount,\n\t\tchain: string,\n\t\tdata: string | Uint8Array,\n\t): Promise<Extract<SigningResult, { type: T }>> {\n\t\ttype Result = Extract<SigningResult, { type: T }>;\n\t\tif (this.#destroyed) {\n\t\t\treturn Promise.reject(new Error('Wallet has been destroyed.'));\n\t\t}\n\t\tif (this.#shouldAutoApprove(type, account, chain, data)) {\n\t\t\treturn this.#executeSigning(type, account, chain, data) as Promise<Result>;\n\t\t}\n\n\t\t// Only one request at a time — subsequent requests are immediately rejected.\n\t\t// DApps that batch transactions should serialize their signing calls.\n\t\tif (this.#pendingRequest) {\n\t\t\treturn Promise.reject(new Error('A signing request is already pending.'));\n\t\t}\n\n\t\treturn new Promise<Result>((resolve, reject) => {\n\t\t\tthis.#pendingRequest = {\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\ttype,\n\t\t\t\taccount,\n\t\t\t\tchain,\n\t\t\t\tdata,\n\t\t\t\tresolve: resolve as (result: SigningResult) => void,\n\t\t\t\treject,\n\t\t\t};\n\t\t\tthis.#notifyRequestListeners();\n\t\t});\n\t}\n\n\t#signPersonalMessage: SuiSignPersonalMessageMethod = async (input) => {\n\t\treturn this.#enqueueRequest(\n\t\t\t'sign-personal-message',\n\t\t\tinput.account,\n\t\t\tinput.chain ?? 'sui:unknown',\n\t\t\tinput.message,\n\t\t);\n\t};\n\n\t#signTransaction: SuiSignTransactionMethod = async (input) => {\n\t\tconst txJson = await input.transaction.toJSON();\n\t\treturn this.#enqueueRequest('sign-transaction', input.account, input.chain, txJson);\n\t};\n\n\t#signAndExecuteTransaction: SuiSignAndExecuteTransactionMethod = async (input) => {\n\t\tconst txJson = await input.transaction.toJSON();\n\t\treturn this.#enqueueRequest('sign-and-execute-transaction', input.account, input.chain, txJson);\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dev-wallet.mjs","names":["#adapters","#name","#icon","#autoApprove","#autoConnect","#clientFactory","#persistNetworks","#networkUrls","#loadNetworkUrls","#clients","#activeNetwork","#accounts","#aggregateAccounts","#events","#unsubscribeAdapters","#pendingRequest","#requestListeners","#pendingConnect","#connectListeners","#connectedListeners","#setupAdapterListeners","#exposedAccounts","#selectedAddress","#connect","#on","#disconnect","#signPersonalMessage","#signTransaction","#signAndExecuteTransaction","#ensureClient","#saveNetworkUrls","#destroyed","#executeSigning","#notifyRequestListeners","#notifyConnectListeners","#notifyConnectedListeners","#getSigner","#getClientForChain","#shouldAutoApprove","#enqueueRequest"],"sources":["../../src/wallet/dev-wallet.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport { SuiGrpcClient } from '@mysten/sui/grpc';\nimport { mitt, type Emitter } from '@mysten/utils';\nimport type {\n\tStandardConnectFeature,\n\tStandardConnectMethod,\n\tStandardDisconnectFeature,\n\tStandardDisconnectMethod,\n\tStandardEventsFeature,\n\tStandardEventsOnMethod,\n\tSuiFeatures,\n\tSuiSignAndExecuteTransactionMethod,\n\tSuiSignPersonalMessageMethod,\n\tSuiSignTransactionMethod,\n\tWallet,\n\tWalletAccount,\n\tWalletIcon,\n} from '@mysten/wallet-standard';\nimport { getWallets, ReadonlyWalletAccount, SUI_CHAINS } from '@mysten/wallet-standard';\n\nimport type { SignerAdapter } from '../types.js';\nimport { DEFAULT_WALLET_ICON, getNetworkFromChain, type WalletEventsMap } from './constants.js';\nimport { type SigningResult, executeSigning } from './signing.js';\n\nconst DEFAULT_WALLET_NAME = 'Dev Wallet';\nconst NETWORK_STORAGE_KEY = 'dev-wallet:networks';\n\n/**\n * Default gRPC endpoint URLs for standard Sui networks (devnet, testnet, localnet).\n */\nexport const DEFAULT_NETWORK_URLS = {\n\tdevnet: 'https://fullnode.devnet.sui.io:443',\n\ttestnet: 'https://fullnode.testnet.sui.io:443',\n\tlocalnet: 'http://127.0.0.1:9000',\n} as const;\n\n/** A pending signing request waiting for user approval via the wallet UI. */\nexport interface WalletRequest {\n\tid: string;\n\ttype: 'sign-transaction' | 'sign-and-execute-transaction' | 'sign-personal-message';\n\taccount: WalletAccount;\n\tchain: string;\n\t/** Transaction JSON string for sign/execute, Uint8Array for personal messages. */\n\tdata: string | Uint8Array;\n\tresolve: (result: SigningResult) => void;\n\treject: (error: Error) => void;\n}\n\n/** Public view of a pending signing request, omitting internal resolve/reject callbacks. */\nexport type PendingSigningRequest = Omit<WalletRequest, 'resolve' | 'reject'>;\n\nexport interface ConnectRequest {\n\tid: string;\n\tresolve: (result: { accounts: readonly WalletAccount[] }) => void;\n\treject: (error: Error) => void;\n}\n\n/** Public view of a pending connect request, omitting internal resolve/reject callbacks. */\nexport type PendingConnectRequest = Omit<ConnectRequest, 'resolve' | 'reject'>;\n\n/**\n * Auto-approval policy for signing requests.\n * `true` approves all requests; a function is called per-request and returns `true` to approve.\n */\nexport type AutoApprovePolicy =\n\t| boolean\n\t| ((request: {\n\t\t\ttype: WalletRequest['type'];\n\t\t\taccount: WalletAccount;\n\t\t\tchain: string;\n\t\t\tdata: string | Uint8Array;\n\t }) => boolean);\n\nexport interface DevWalletConfig {\n\tadapters: SignerAdapter[];\n\t/** Network URLs by name (network → gRPC endpoint). Defaults to devnet, testnet, and localnet. */\n\tnetworks?: Record<string, string>;\n\t/** Display name for the wallet. Defaults to 'Dev Wallet'. */\n\tname?: string;\n\ticon?: WalletIcon;\n\t/** Initially active network. Defaults to the first key in `networks`. */\n\tactiveNetwork?: string;\n\t/**\n\t * When set, matching requests are signed immediately without queuing for user approval.\n\t * `true` approves everything; a function is called per-request for fine-grained control.\n\t */\n\tautoApprove?: AutoApprovePolicy;\n\t/** When true, connect requests resolve immediately with all accounts. */\n\tautoConnect?: boolean;\n\t/** Factory to create a client for a given network. Defaults to SuiGrpcClient. */\n\tclientFactory?: (network: string, url: string) => ClientWithCoreApi;\n\t/**\n\t * Persist network URLs to localStorage so custom configurations survive page reloads\n\t * and are shared with popup windows.\n\t */\n\tpersistNetworks?: boolean;\n}\n\n/**\n * wallet-standard Wallet implementation for development. All signing requests are queued\n * and require explicit approval — either via the UI or programmatically via `approveRequest()`.\n */\nexport class DevWallet implements Wallet {\n\treadonly #adapters: SignerAdapter[];\n\t#networkUrls: Record<string, string>;\n\t#clients: Record<string, ClientWithCoreApi>;\n\t#activeNetwork: string;\n\treadonly #name: string;\n\treadonly #icon: WalletIcon;\n\treadonly #autoApprove: AutoApprovePolicy;\n\treadonly #autoConnect: boolean;\n\treadonly #clientFactory: (network: string, url: string) => ClientWithCoreApi;\n\treadonly #persistNetworks: boolean;\n\t#accounts: ReadonlyWalletAccount[];\n\t#selectedAddress: string | null = null;\n\t#events: Emitter<WalletEventsMap>;\n\t#unsubscribeAdapters: (() => void)[];\n\t#pendingRequest: WalletRequest | null;\n\t#requestListeners: Set<(request: PendingSigningRequest | null) => void>;\n\t#pendingConnect: ConnectRequest | null;\n\t#connectListeners: Set<(request: PendingConnectRequest | null) => void>;\n\t/** Fired every time a dApp invokes `standard:connect` (the wallet's\n\t * authoritative \"a dApp is connecting\" signal). Distinct from\n\t * `#connectListeners`, which track the *pending-request* lifecycle for the\n\t * approval UI. Consumers (e.g. the inject's `selectAccount`) use this to\n\t * observe that the dApp has reached the wallet rather than racing a timer. */\n\t#connectedListeners: Set<() => void>;\n\t#destroyed = false;\n\n\tconstructor(config: DevWalletConfig) {\n\t\tif (config.adapters.length === 0) {\n\t\t\tconsole.warn('[dev-wallet] No adapters provided. The wallet will have no accounts.');\n\t\t}\n\t\tthis.#adapters = config.adapters;\n\t\tthis.#persistNetworks = config.persistNetworks ?? false;\n\t\tthis.#networkUrls = this.#loadNetworkUrls(config.networks ?? DEFAULT_NETWORK_URLS);\n\t\tthis.#clients = {};\n\t\tthis.#activeNetwork = config.activeNetwork ?? Object.keys(this.#networkUrls)[0] ?? '';\n\t\tthis.#name = config.name ?? DEFAULT_WALLET_NAME;\n\t\tthis.#icon = config.icon ?? DEFAULT_WALLET_ICON;\n\t\tthis.#autoApprove = config.autoApprove ?? false;\n\t\tthis.#autoConnect = config.autoConnect ?? false;\n\t\tthis.#clientFactory =\n\t\t\tconfig.clientFactory ?? ((network, url) => new SuiGrpcClient({ baseUrl: url, network }));\n\t\tthis.#accounts = this.#aggregateAccounts();\n\t\tthis.#events = mitt();\n\t\tthis.#unsubscribeAdapters = [];\n\t\tthis.#pendingRequest = null;\n\t\tthis.#requestListeners = new Set();\n\t\tthis.#pendingConnect = null;\n\t\tthis.#connectListeners = new Set();\n\t\tthis.#connectedListeners = new Set();\n\n\t\tthis.#setupAdapterListeners();\n\t}\n\n\tget version() {\n\t\treturn '1.0.0' as const;\n\t}\n\n\tget name() {\n\t\treturn this.#name;\n\t}\n\n\tget icon() {\n\t\treturn this.#icon;\n\t}\n\n\tget chains() {\n\t\treturn SUI_CHAINS;\n\t}\n\n\tget accounts(): readonly ReadonlyWalletAccount[] {\n\t\treturn this.#exposedAccounts();\n\t}\n\n\t/**\n\t * Narrow the accounts this wallet exposes to dApps (via the\n\t * wallet-standard `accounts` array + `change` events) to a single\n\t * address, or pass `null` to expose all aggregated accounts again.\n\t *\n\t * Used by the devstack page-register entry to drive headless account\n\t * selection: dApp Kit reflects the `change` event by switching its\n\t * connected account to the now-single exposed account (or, if not yet\n\t * connected, auto-connects to it). No reference to the app's dApp Kit\n\t * instance is required — selection rides the wallet-standard protocol.\n\t */\n\tsetSelectedAccount(address: string | null): void {\n\t\tif (address !== null) {\n\t\t\tconst match = this.#accounts.find((a) => a.address.toLowerCase() === address.toLowerCase());\n\t\t\tif (match === undefined) {\n\t\t\t\tconst available = this.#accounts.map((a) => a.address).join(', ');\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No dev-wallet account for address \"${address}\". Available: ${available || '(none)'}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.#selectedAddress = match.address;\n\t\t} else {\n\t\t\tthis.#selectedAddress = null;\n\t\t}\n\t\tthis.#events.emit('change', { accounts: this.#exposedAccounts() });\n\t}\n\n\t/** Accounts exposed to dApps — narrowed to the selected address when set. */\n\t#exposedAccounts(): ReadonlyWalletAccount[] {\n\t\tif (this.#selectedAddress === null) return this.#accounts;\n\t\treturn this.#accounts.filter(\n\t\t\t(a) => a.address.toLowerCase() === this.#selectedAddress!.toLowerCase(),\n\t\t);\n\t}\n\n\tget features(): StandardConnectFeature &\n\t\tStandardEventsFeature &\n\t\tStandardDisconnectFeature &\n\t\tSuiFeatures {\n\t\treturn {\n\t\t\t'standard:connect': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tconnect: this.#connect,\n\t\t\t},\n\t\t\t'standard:events': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\ton: this.#on,\n\t\t\t},\n\t\t\t'standard:disconnect': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tdisconnect: this.#disconnect,\n\t\t\t},\n\t\t\t'sui:signPersonalMessage': {\n\t\t\t\tversion: '1.1.0',\n\t\t\t\tsignPersonalMessage: this.#signPersonalMessage,\n\t\t\t},\n\t\t\t'sui:signTransaction': {\n\t\t\t\tversion: '2.0.0',\n\t\t\t\tsignTransaction: this.#signTransaction,\n\t\t\t},\n\t\t\t'sui:signAndExecuteTransaction': {\n\t\t\t\tversion: '2.0.0',\n\t\t\t\tsignAndExecuteTransaction: this.#signAndExecuteTransaction,\n\t\t\t},\n\t\t};\n\t}\n\n\t/** The current pending signing request, or null if none. */\n\tget pendingRequest(): PendingSigningRequest | null {\n\t\treturn this.#pendingRequest;\n\t}\n\n\tget adapters(): readonly SignerAdapter[] {\n\t\treturn this.#adapters;\n\t}\n\n\tgetAdapterForAccount(address: string): SignerAdapter | undefined {\n\t\treturn this.#adapters.find((a) => a.getAccount(address) !== undefined);\n\t}\n\n\t/** Eagerly creates and returns clients for all configured networks. Prefer `getClient()` or `activeClient` for single-network access. */\n\tget clients(): Record<string, ClientWithCoreApi> {\n\t\tfor (const name of Object.keys(this.#networkUrls)) {\n\t\t\tthis.#ensureClient(name);\n\t\t}\n\t\treturn { ...this.#clients };\n\t}\n\n\tgetClient(network: string): ClientWithCoreApi {\n\t\treturn this.#ensureClient(network);\n\t}\n\n\tget networkUrls(): Record<string, string> {\n\t\treturn { ...this.#networkUrls };\n\t}\n\n\tget activeNetwork(): string {\n\t\treturn this.#activeNetwork;\n\t}\n\n\tget activeClient(): ClientWithCoreApi | null {\n\t\tif (!this.#activeNetwork || !this.#networkUrls[this.#activeNetwork]) return null;\n\t\treturn this.#ensureClient(this.#activeNetwork);\n\t}\n\n\tget availableNetworks(): string[] {\n\t\treturn Object.keys(this.#networkUrls);\n\t}\n\n\t/** Switch the active network. Emits a `change` event. */\n\tsetActiveNetwork(network: string): void {\n\t\tif (!this.#networkUrls[network]) {\n\t\t\tthrow new Error(\n\t\t\t\t`No client for network \"${network}\". Available: ${this.availableNetworks.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tthis.#activeNetwork = network;\n\t\tthis.#events.emit('change', { accounts: this.#accounts });\n\t}\n\n\taddNetwork(name: string, url: string): void {\n\t\tlet parsed: URL;\n\t\ttry {\n\t\t\tparsed = new URL(url);\n\t\t} catch {\n\t\t\tthrow new Error(`Invalid URL: ${url}`);\n\t\t}\n\t\tif (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n\t\t\tthrow new Error(`Invalid URL: must use http or https (got ${parsed.protocol})`);\n\t\t}\n\t\tthis.#networkUrls[name] = url;\n\t\tthis.#clients[name] = this.#clientFactory(name, url);\n\t\tthis.#saveNetworkUrls();\n\t\tthis.#events.emit('change', { accounts: this.#accounts });\n\t}\n\n\tremoveNetwork(name: string): void {\n\t\tdelete this.#networkUrls[name];\n\t\tdelete this.#clients[name];\n\t\tif (this.#activeNetwork === name) {\n\t\t\tthis.#activeNetwork = Object.keys(this.#networkUrls)[0] ?? '';\n\t\t}\n\t\tthis.#saveNetworkUrls();\n\t\tthis.#events.emit('change', { accounts: this.#accounts });\n\t}\n\n\t/** Register this wallet with the wallet-standard registry. Returns an unregister function. */\n\tregister(): () => void {\n\t\tif (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') {\n\t\t\tconsole.warn(\n\t\t\t\t'[@mysten-incubation/dev-wallet] DevWallet is intended for development only. Do not use in production.',\n\t\t\t);\n\t\t}\n\t\tconst walletsApi = getWallets();\n\t\treturn walletsApi.register(this);\n\t}\n\n\t/** Reject any pending requests, unsubscribe from adapters, destroy them, and clear all listeners. */\n\tdestroy(): void {\n\t\tthis.#destroyed = true;\n\t\tfor (const unsub of this.#unsubscribeAdapters) {\n\t\t\tunsub();\n\t\t}\n\t\tthis.#unsubscribeAdapters = [];\n\t\tfor (const adapter of this.#adapters) {\n\t\t\tadapter.destroy();\n\t\t}\n\t\tif (this.#pendingRequest) {\n\t\t\tthis.#pendingRequest.reject(new Error('Wallet destroyed.'));\n\t\t\tthis.#pendingRequest = null;\n\t\t}\n\t\tif (this.#pendingConnect) {\n\t\t\tthis.#pendingConnect.reject(new Error('Wallet destroyed.'));\n\t\t\tthis.#pendingConnect = null;\n\t\t}\n\t\tthis.#requestListeners.clear();\n\t\tthis.#connectListeners.clear();\n\t\tthis.#connectedListeners.clear();\n\t\tthis.#events.all.clear();\n\t}\n\n\t/** Sign the pending request using the account's adapter signer and resolve the promise. */\n\tasync approveRequest(): Promise<void> {\n\t\tconst request = this.#pendingRequest;\n\t\tif (!request) {\n\t\t\tthrow new Error('No pending request to approve.');\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.#executeSigning(\n\t\t\t\trequest.type,\n\t\t\t\trequest.account,\n\t\t\t\trequest.chain,\n\t\t\t\trequest.data,\n\t\t\t);\n\t\t\tthis.#pendingRequest = null;\n\t\t\tthis.#notifyRequestListeners();\n\t\t\trequest.resolve(result);\n\t\t} catch (error) {\n\t\t\tthis.#pendingRequest = null;\n\t\t\tthis.#notifyRequestListeners();\n\t\t\trequest.reject(error instanceof Error ? error : new Error(String(error)));\n\t\t}\n\t}\n\n\trejectRequest(reason?: string): void {\n\t\tconst request = this.#pendingRequest;\n\t\tif (!request) {\n\t\t\tthrow new Error('No pending request to reject.');\n\t\t}\n\t\tthis.#pendingRequest = null;\n\t\tthis.#notifyRequestListeners();\n\t\trequest.reject(new Error(reason ?? 'Request rejected by user.'));\n\t}\n\n\t/** Subscribe to pending request changes. Returns an unsubscribe function. */\n\tonRequestChange(callback: (request: PendingSigningRequest | null) => void): () => void {\n\t\tthis.#requestListeners.add(callback);\n\t\treturn () => {\n\t\t\tthis.#requestListeners.delete(callback);\n\t\t};\n\t}\n\n\t/** The current pending connect request, or null if none. */\n\tget pendingConnect(): PendingConnectRequest | null {\n\t\treturn this.#pendingConnect;\n\t}\n\n\t/** Expose the given addresses to the dApp. Pass an empty array to expose all accounts. */\n\tapproveConnect(selectedAddresses: string[]): void {\n\t\tconst request = this.#pendingConnect;\n\t\tif (!request) {\n\t\t\tthrow new Error('No pending connect request to approve.');\n\t\t}\n\n\t\tconst selected =\n\t\t\tselectedAddresses.length > 0\n\t\t\t\t? this.#accounts.filter((a) => selectedAddresses.includes(a.address))\n\t\t\t\t: [...this.#accounts];\n\n\t\tthis.#pendingConnect = null;\n\t\tthis.#notifyConnectListeners();\n\t\trequest.resolve({ accounts: selected });\n\t}\n\n\trejectConnect(reason?: string): void {\n\t\tconst request = this.#pendingConnect;\n\t\tif (!request) {\n\t\t\tthrow new Error('No pending connect request to reject.');\n\t\t}\n\t\tthis.#pendingConnect = null;\n\t\tthis.#notifyConnectListeners();\n\t\trequest.reject(new Error(reason ?? 'Connection rejected by user.'));\n\t}\n\n\t/** Subscribe to pending connect request changes. Returns an unsubscribe function. */\n\tonConnectChange(callback: (request: PendingConnectRequest | null) => void): () => void {\n\t\tthis.#connectListeners.add(callback);\n\t\treturn () => {\n\t\t\tthis.#connectListeners.delete(callback);\n\t\t};\n\t}\n\n\t#notifyRequestListeners() {\n\t\tconst request = this.#pendingRequest;\n\t\tfor (const listener of this.#requestListeners) {\n\t\t\tlistener(request);\n\t\t}\n\t}\n\n\t#notifyConnectListeners() {\n\t\tconst request = this.#pendingConnect;\n\t\tfor (const listener of this.#connectListeners) {\n\t\t\tlistener(request);\n\t\t}\n\t}\n\n\t/**\n\t * Subscribe to the \"a dApp invoked `standard:connect`\" edge. Returns an\n\t * unsubscribe function. Used by the page-register entry to gate its\n\t * narrow→widen account-selection on an OBSERVED connect rather than a fixed\n\t * timer (see `src/inject/index.ts`).\n\t */\n\tonDAppConnected(callback: () => void): () => void {\n\t\tthis.#connectedListeners.add(callback);\n\t\treturn () => {\n\t\t\tthis.#connectedListeners.delete(callback);\n\t\t};\n\t}\n\n\t#notifyConnectedListeners() {\n\t\tfor (const listener of this.#connectedListeners) {\n\t\t\ttry {\n\t\t\t\tlistener();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[dev-wallet] onDAppConnected listener threw:', error);\n\t\t\t}\n\t\t}\n\t}\n\n\t#aggregateAccounts(): ReadonlyWalletAccount[] {\n\t\treturn this.#adapters.flatMap((a) => a.getAccounts().map((acc) => acc.walletAccount));\n\t}\n\n\t#setupAdapterListeners() {\n\t\tfor (const adapter of this.#adapters) {\n\t\t\tconst unsub = adapter.onAccountsChanged(() => {\n\t\t\t\tthis.#accounts = this.#aggregateAccounts();\n\t\t\t\tthis.#events.emit('change', { accounts: this.#exposedAccounts() });\n\t\t\t});\n\t\t\tthis.#unsubscribeAdapters.push(unsub);\n\t\t}\n\t}\n\n\t#on: StandardEventsOnMethod = (event, listener) => {\n\t\tthis.#events.on(event, listener);\n\t\treturn () => this.#events.off(event, listener);\n\t};\n\n\t#connect: StandardConnectMethod = async () => {\n\t\t// Notify observers that a dApp has invoked `standard:connect`. This is\n\t\t// the wallet's authoritative \"a dApp reached us\" edge — fired before we\n\t\t// branch on auto/queued so it covers both the silent auto-connect path\n\t\t// and an interactive connect.\n\t\tthis.#notifyConnectedListeners();\n\n\t\t// Auto-connect: return all accounts immediately\n\t\tif (this.#autoConnect) {\n\t\t\treturn { accounts: this.accounts };\n\t\t}\n\n\t\t// Queue a connect request for user to select accounts\n\t\tif (this.#pendingConnect) {\n\t\t\treturn Promise.reject(new Error('A connect request is already pending.'));\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.#pendingConnect = {\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t};\n\t\t\tthis.#notifyConnectListeners();\n\t\t});\n\t};\n\n\t#disconnect: StandardDisconnectMethod = async () => {\n\t\t// Disconnecting ends the dApp session but does not affect wallet state.\n\t\t// The wallet retains its accounts and adapter subscriptions.\n\t};\n\n\t#getClientForChain(chain: string) {\n\t\tconst network = getNetworkFromChain(chain);\n\t\tif (!network) {\n\t\t\tthrow new Error(`Invalid chain identifier: ${chain}`);\n\t\t}\n\t\treturn this.#ensureClient(network);\n\t}\n\n\t#loadNetworkUrls(defaults: Record<string, string>): Record<string, string> {\n\t\tif (!this.#persistNetworks || typeof localStorage === 'undefined') {\n\t\t\treturn { ...defaults };\n\t\t}\n\t\ttry {\n\t\t\tconst raw = localStorage.getItem(NETWORK_STORAGE_KEY);\n\t\t\tif (raw) {\n\t\t\t\tconst parsed = JSON.parse(raw);\n\t\t\t\tif (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n\t\t\t\t\treturn parsed as Record<string, string>;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Corrupted data — fall through to defaults\n\t\t}\n\t\treturn { ...defaults };\n\t}\n\n\t#saveNetworkUrls(): void {\n\t\tif (!this.#persistNetworks || typeof localStorage === 'undefined') return;\n\t\tlocalStorage.setItem(NETWORK_STORAGE_KEY, JSON.stringify(this.#networkUrls));\n\t}\n\n\t#ensureClient(network: string): ClientWithCoreApi {\n\t\tif (!this.#clients[network]) {\n\t\t\tconst url = this.#networkUrls[network];\n\t\t\tif (!url) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No client for network \"${network}\". Available: ${this.availableNetworks.join(', ')}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.#clients[network] = this.#clientFactory(network, url);\n\t\t}\n\t\treturn this.#clients[network];\n\t}\n\n\t#getSigner(address: string) {\n\t\tfor (const adapter of this.#adapters) {\n\t\t\tconst account = adapter.getAccount(address);\n\t\t\tif (account) return account.signer;\n\t\t}\n\t\tconst allAddresses = this.#adapters.flatMap((a) => a.getAccounts().map((acc) => acc.address));\n\t\tthrow new Error(\n\t\t\t`No account found for address \"${address}\". Available addresses: ${allAddresses.join(', ')}`,\n\t\t);\n\t}\n\n\t#shouldAutoApprove(\n\t\ttype: WalletRequest['type'],\n\t\taccount: WalletAccount,\n\t\tchain: string,\n\t\tdata: string | Uint8Array,\n\t): boolean {\n\t\t// Check adapter-level opt-out first — CLI adapters never auto-sign\n\t\tconst adapter = this.getAdapterForAccount(account.address);\n\t\tif (adapter?.allowAutoSign === false) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.#autoApprove === true) {\n\t\t\treturn true;\n\t\t}\n\t\tif (typeof this.#autoApprove === 'function') {\n\t\t\treturn this.#autoApprove({ type, account, chain, data });\n\t\t}\n\t\treturn false;\n\t}\n\n\tasync #executeSigning(\n\t\ttype: WalletRequest['type'],\n\t\taccount: WalletAccount,\n\t\tchain: string,\n\t\tdata: string | Uint8Array,\n\t) {\n\t\tconst signer = this.#getSigner(account.address);\n\t\tconst client = type !== 'sign-personal-message' ? this.#getClientForChain(chain) : undefined;\n\t\treturn executeSigning({ type, signer, data, client });\n\t}\n\n\t#enqueueRequest<T extends WalletRequest['type']>(\n\t\ttype: T,\n\t\taccount: WalletAccount,\n\t\tchain: string,\n\t\tdata: string | Uint8Array,\n\t): Promise<Extract<SigningResult, { type: T }>> {\n\t\ttype Result = Extract<SigningResult, { type: T }>;\n\t\tif (this.#destroyed) {\n\t\t\treturn Promise.reject(new Error('Wallet has been destroyed.'));\n\t\t}\n\t\tif (this.#shouldAutoApprove(type, account, chain, data)) {\n\t\t\treturn this.#executeSigning(type, account, chain, data) as Promise<Result>;\n\t\t}\n\n\t\t// Only one request at a time — subsequent requests are immediately rejected.\n\t\t// DApps that batch transactions should serialize their signing calls.\n\t\tif (this.#pendingRequest) {\n\t\t\treturn Promise.reject(new Error('A signing request is already pending.'));\n\t\t}\n\n\t\treturn new Promise<Result>((resolve, reject) => {\n\t\t\tthis.#pendingRequest = {\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\ttype,\n\t\t\t\taccount,\n\t\t\t\tchain,\n\t\t\t\tdata,\n\t\t\t\tresolve: resolve as (result: SigningResult) => void,\n\t\t\t\treject,\n\t\t\t};\n\t\t\tthis.#notifyRequestListeners();\n\t\t});\n\t}\n\n\t#signPersonalMessage: SuiSignPersonalMessageMethod = async (input) => {\n\t\treturn this.#enqueueRequest(\n\t\t\t'sign-personal-message',\n\t\t\tinput.account,\n\t\t\tinput.chain ?? 'sui:unknown',\n\t\t\tinput.message,\n\t\t);\n\t};\n\n\t#signTransaction: SuiSignTransactionMethod = async (input) => {\n\t\tconst txJson = await input.transaction.toJSON();\n\t\treturn this.#enqueueRequest('sign-transaction', input.account, input.chain, txJson);\n\t};\n\n\t#signAndExecuteTransaction: SuiSignAndExecuteTransactionMethod = async (input) => {\n\t\tconst txJson = await input.transaction.toJSON();\n\t\treturn this.#enqueueRequest('sign-and-execute-transaction', input.account, input.chain, txJson);\n\t};\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"initializer.d.mts","names":[],"sources":["../../src/wallet/initializer.ts"],"mappings":";;;;;;;;;AAeA;;;UAAiB,0BAAA;EAChB,QAAA,EAAU,aAAA;EACV,IAAA;EACA,IAAA,GAAO,UAAA;EACP,WAAA,GAAc,iBAAA;EACd,WAAA;EAYoC;EAVpC,cAAA;EANA;EAQA,oBAAA;EAPA;EASA,OAAA;EARO;EAUP,SAAA,GAAY,kBAAA;EATE;EAWd,SAAA,GAAY,WAAA;EARZ;EAUA,eAAA,IAAmB,MAAA,EAAQ,SAAA;AAAA;;;;;;;;;;AA0B5B;;;;;;;;;;;;;;iBAAgB,oBAAA,CAAqB,MAAA,EAAQ,0BAAA;EAC5C,EAAA;EACA,UAAA,CAAW,KAAA;IACV,QAAA;IACA,SAAA,GAAY,OAAA,cAAqB,iBAAA;EAAA,IAC9B,OAAA;IAAU,UAAA;EAAA;AAAA"}
1
+ {"version":3,"file":"initializer.d.mts","names":[],"sources":["../../src/wallet/initializer.ts"],"mappings":";;;;;;;;;AAgBA;;;UAAiB,0BAAA;EAChB,QAAA,EAAU,aAAA;EACV,IAAA;EACA,IAAA,GAAO,UAAA;EACP,WAAA,GAAc,iBAAA;EACd,WAAA;EAYoC;EAVpC,cAAA;EANA;EAQA,oBAAA;EAPA;EASA,OAAA;EARO;EAUP,SAAA,GAAY,kBAAA;EATE;EAWd,SAAA,GAAY,WAAA;EARZ;EAUA,eAAA,IAAmB,MAAA,EAAQ,SAAA;AAAA;;;;;;;;;AAAS;AA0BrC;;;;;;;;;;;;;;iBAAgB,oBAAA,CAAqB,MAAA,EAAQ,0BAAA;EAC5C,EAAA;EACA,UAAA,CAAW,KAAA;IACV,QAAA;IACA,SAAA,GAAY,OAAA,cAAqB,iBAAA;EAAA,IAC9B,OAAA;IAAU,UAAA;EAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- import { DevWallet } from "./dev-wallet.mjs";
1
+ import { mountAndRegisterDevWallet } from "./mount-and-register.mjs";
2
2
  //#region src/wallet/initializer.ts
3
3
  /**
4
4
  * Creates a wallet initializer for `createDAppKit({ walletInitializers: [...] })`.
@@ -27,40 +27,24 @@ function devWalletInitializer(config) {
27
27
  return {
28
28
  id: "dev-wallet-initializer",
29
29
  async initialize({ networks, getClient }) {
30
- const { autoInitialize = true, createInitialAccount = true, mountUI = false } = config;
31
- if (autoInitialize) await Promise.all(config.adapters.map((a) => a.initialize()));
32
- if (createInitialAccount) {
33
- if (!config.adapters.some((a) => a.getAccounts().length > 0)) {
34
- const creatableAdapter = config.adapters.find((a) => a.createAccount && a.getAccounts().length === 0);
35
- if (creatableAdapter?.createAccount) await creatableAdapter.createAccount({ label: "Dev Account" });
36
- }
37
- }
38
30
  const networkUrls = {};
39
31
  for (const network of networks) networkUrls[network] = `dapp-kit://${network}`;
40
- const wallet = new DevWallet({
32
+ const { dispose } = await mountAndRegisterDevWallet({
41
33
  adapters: config.adapters,
42
34
  networks: networkUrls,
43
35
  name: config.name,
44
36
  icon: config.icon,
45
37
  autoApprove: config.autoApprove,
46
38
  autoConnect: config.autoConnect,
47
- clientFactory: (network) => getClient(network)
39
+ clientFactory: (network) => getClient(network),
40
+ autoInitialize: config.autoInitialize ?? true,
41
+ createInitialAccount: config.createInitialAccount ?? true,
42
+ mountUI: config.mountUI ?? false,
43
+ dockStyle: config.dockStyle,
44
+ container: config.container,
45
+ onWalletCreated: config.onWalletCreated
48
46
  });
49
- config.onWalletCreated?.(wallet);
50
- let unmountUI;
51
- if (mountUI && typeof document !== "undefined") {
52
- const { mountDevWallet } = await import("../ui/mount.mjs");
53
- unmountUI = mountDevWallet(wallet, {
54
- container: config.container,
55
- dockStyle: config.dockStyle
56
- });
57
- }
58
- const unregister = wallet.register();
59
- return { unregister() {
60
- unmountUI?.();
61
- unregister();
62
- wallet.destroy();
63
- } };
47
+ return { unregister: dispose };
64
48
  }
65
49
  };
66
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"initializer.mjs","names":[],"sources":["../../src/wallet/initializer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport type { WalletIcon } from '@mysten/wallet-standard';\n\nimport type { DevWalletDockStyle } from '../ui/dev-wallet-panel.js';\nimport type { SignerAdapter } from '../types.js';\nimport { DevWallet, type AutoApprovePolicy } from './dev-wallet.js';\n\n/**\n * Configuration for the dev wallet initializer.\n * Unlike {@link DevWalletConfig}, `networks` and `clientFactory` are omitted — they come\n * from the dApp Kit context at initialization time.\n */\nexport interface DevWalletInitializerConfig {\n\tadapters: SignerAdapter[];\n\tname?: string;\n\ticon?: WalletIcon;\n\tautoApprove?: AutoApprovePolicy;\n\tautoConnect?: boolean;\n\t/** Call `adapter.initialize()` automatically. Defaults to true. */\n\tautoInitialize?: boolean;\n\t/** Create an initial account after initialization if no accounts exist. Defaults to true. */\n\tcreateInitialAccount?: boolean;\n\t/** Mount the floating wallet drawer UI. Defaults to false. */\n\tmountUI?: boolean;\n\t/** Floating dock presentation when `mountUI` is true. Defaults to `corner-pill`. */\n\tdockStyle?: DevWalletDockStyle;\n\t/** Container element for the UI drawer. Defaults to document.body. */\n\tcontainer?: HTMLElement;\n\t/** Called with the DevWallet instance after creation. */\n\tonWalletCreated?: (wallet: DevWallet) => void;\n}\n\n/**\n * Creates a wallet initializer for `createDAppKit({ walletInitializers: [...] })`.\n * The wallet uses dApp Kit's networks and client factory and is unregistered when dApp Kit tears down.\n *\n * @example\n * ```ts\n * import { createDAppKit } from '@mysten/dapp-kit-react';\n * import { devWalletInitializer } from '@mysten-incubation/dev-wallet';\n * import { WebCryptoSignerAdapter } from '@mysten-incubation/dev-wallet/adapters';\n *\n * const dAppKit = createDAppKit({\n * networks: ['devnet', 'testnet'],\n * createClient(network) { ... },\n * walletInitializers: [\n * devWalletInitializer({\n * adapters: [new WebCryptoSignerAdapter()],\n * autoConnect: true,\n * mountUI: true,\n * }),\n * ],\n * });\n * ```\n */\nexport function devWalletInitializer(config: DevWalletInitializerConfig): {\n\tid: string;\n\tinitialize(input: {\n\t\tnetworks: readonly string[];\n\t\tgetClient: (network?: string) => ClientWithCoreApi;\n\t}): Promise<{ unregister: () => void }>;\n} {\n\treturn {\n\t\tid: 'dev-wallet-initializer',\n\t\tasync initialize({ networks, getClient }) {\n\t\t\tconst { autoInitialize = true, createInitialAccount = true, mountUI = false } = config;\n\n\t\t\t// Initialize adapters\n\t\t\tif (autoInitialize) {\n\t\t\t\tawait Promise.all(config.adapters.map((a) => a.initialize()));\n\t\t\t}\n\n\t\t\t// Create initial account if needed\n\t\t\tif (createInitialAccount) {\n\t\t\t\tconst hasAccounts = config.adapters.some((a) => a.getAccounts().length > 0);\n\t\t\t\tif (!hasAccounts) {\n\t\t\t\t\tconst creatableAdapter = config.adapters.find(\n\t\t\t\t\t\t(a) => a.createAccount && a.getAccounts().length === 0,\n\t\t\t\t\t);\n\t\t\t\t\tif (creatableAdapter?.createAccount) {\n\t\t\t\t\t\tawait creatableAdapter.createAccount({ label: 'Dev Account' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Map dApp Kit networks to DevWallet format.\n\t\t\t// DevWallet needs a Record<string, string> of network name → URL, but\n\t\t\t// the clientFactory we provide delegates to getClient, so the URLs are\n\t\t\t// never actually used. We use placeholder values.\n\t\t\tconst networkUrls: Record<string, string> = {};\n\t\t\tfor (const network of networks) {\n\t\t\t\tnetworkUrls[network] = `dapp-kit://${network}`;\n\t\t\t}\n\n\t\t\tconst wallet = new DevWallet({\n\t\t\t\tadapters: config.adapters,\n\t\t\t\tnetworks: networkUrls,\n\t\t\t\tname: config.name,\n\t\t\t\ticon: config.icon,\n\t\t\t\tautoApprove: config.autoApprove,\n\t\t\t\tautoConnect: config.autoConnect,\n\t\t\t\tclientFactory: (network) => getClient(network),\n\t\t\t});\n\n\t\t\tconfig.onWalletCreated?.(wallet);\n\n\t\t\t// Mount UI if requested\n\t\t\tlet unmountUI: (() => void) | undefined;\n\t\t\tif (mountUI && typeof document !== 'undefined') {\n\t\t\t\tconst { mountDevWallet } = await import('../ui/mount.js');\n\t\t\t\tunmountUI = mountDevWallet(wallet, {\n\t\t\t\t\tcontainer: config.container,\n\t\t\t\t\tdockStyle: config.dockStyle,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst unregister = wallet.register();\n\t\t\treturn {\n\t\t\t\tunregister() {\n\t\t\t\t\tunmountUI?.();\n\t\t\t\t\tunregister();\n\t\t\t\t\twallet.destroy();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0DA,SAAgB,qBAAqB,QAMnC;AACD,QAAO;EACN,IAAI;EACJ,MAAM,WAAW,EAAE,UAAU,aAAa;GACzC,MAAM,EAAE,iBAAiB,MAAM,uBAAuB,MAAM,UAAU,UAAU;AAGhF,OAAI,eACH,OAAM,QAAQ,IAAI,OAAO,SAAS,KAAK,MAAM,EAAE,YAAY,CAAC,CAAC;AAI9D,OAAI,sBAEH;QAAI,CADgB,OAAO,SAAS,MAAM,MAAM,EAAE,aAAa,CAAC,SAAS,EACpE,EAAa;KACjB,MAAM,mBAAmB,OAAO,SAAS,MACvC,MAAM,EAAE,iBAAiB,EAAE,aAAa,CAAC,WAAW,EACrD;AACD,SAAI,kBAAkB,cACrB,OAAM,iBAAiB,cAAc,EAAE,OAAO,eAAe,CAAC;;;GASjE,MAAM,cAAsC,EAAE;AAC9C,QAAK,MAAM,WAAW,SACrB,aAAY,WAAW,cAAc;GAGtC,MAAM,SAAS,IAAI,UAAU;IAC5B,UAAU,OAAO;IACjB,UAAU;IACV,MAAM,OAAO;IACb,MAAM,OAAO;IACb,aAAa,OAAO;IACpB,aAAa,OAAO;IACpB,gBAAgB,YAAY,UAAU,QAAQ;IAC9C,CAAC;AAEF,UAAO,kBAAkB,OAAO;GAGhC,IAAI;AACJ,OAAI,WAAW,OAAO,aAAa,aAAa;IAC/C,MAAM,EAAE,mBAAmB,MAAM,OAAO;AACxC,gBAAY,eAAe,QAAQ;KAClC,WAAW,OAAO;KAClB,WAAW,OAAO;KAClB,CAAC;;GAGH,MAAM,aAAa,OAAO,UAAU;AACpC,UAAO,EACN,aAAa;AACZ,iBAAa;AACb,gBAAY;AACZ,WAAO,SAAS;MAEjB;;EAEF"}
1
+ {"version":3,"file":"initializer.mjs","names":[],"sources":["../../src/wallet/initializer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport type { WalletIcon } from '@mysten/wallet-standard';\n\nimport type { DevWalletDockStyle } from '../ui/dev-wallet-panel.js';\nimport type { SignerAdapter } from '../types.js';\nimport type { DevWallet, AutoApprovePolicy } from './dev-wallet.js';\nimport { mountAndRegisterDevWallet } from './mount-and-register.js';\n\n/**\n * Configuration for the dev wallet initializer.\n * Unlike {@link DevWalletConfig}, `networks` and `clientFactory` are omitted — they come\n * from the dApp Kit context at initialization time.\n */\nexport interface DevWalletInitializerConfig {\n\tadapters: SignerAdapter[];\n\tname?: string;\n\ticon?: WalletIcon;\n\tautoApprove?: AutoApprovePolicy;\n\tautoConnect?: boolean;\n\t/** Call `adapter.initialize()` automatically. Defaults to true. */\n\tautoInitialize?: boolean;\n\t/** Create an initial account after initialization if no accounts exist. Defaults to true. */\n\tcreateInitialAccount?: boolean;\n\t/** Mount the floating wallet drawer UI. Defaults to false. */\n\tmountUI?: boolean;\n\t/** Floating dock presentation when `mountUI` is true. Defaults to `corner-pill`. */\n\tdockStyle?: DevWalletDockStyle;\n\t/** Container element for the UI drawer. Defaults to document.body. */\n\tcontainer?: HTMLElement;\n\t/** Called with the DevWallet instance after creation. */\n\tonWalletCreated?: (wallet: DevWallet) => void;\n}\n\n/**\n * Creates a wallet initializer for `createDAppKit({ walletInitializers: [...] })`.\n * The wallet uses dApp Kit's networks and client factory and is unregistered when dApp Kit tears down.\n *\n * @example\n * ```ts\n * import { createDAppKit } from '@mysten/dapp-kit-react';\n * import { devWalletInitializer } from '@mysten-incubation/dev-wallet';\n * import { WebCryptoSignerAdapter } from '@mysten-incubation/dev-wallet/adapters';\n *\n * const dAppKit = createDAppKit({\n * networks: ['devnet', 'testnet'],\n * createClient(network) { ... },\n * walletInitializers: [\n * devWalletInitializer({\n * adapters: [new WebCryptoSignerAdapter()],\n * autoConnect: true,\n * mountUI: true,\n * }),\n * ],\n * });\n * ```\n */\nexport function devWalletInitializer(config: DevWalletInitializerConfig): {\n\tid: string;\n\tinitialize(input: {\n\t\tnetworks: readonly string[];\n\t\tgetClient: (network?: string) => ClientWithCoreApi;\n\t}): Promise<{ unregister: () => void }>;\n} {\n\treturn {\n\t\tid: 'dev-wallet-initializer',\n\t\tasync initialize({ networks, getClient }) {\n\t\t\t// Map dApp Kit networks to DevWallet format.\n\t\t\t// DevWallet needs a Record<string, string> of network name → URL, but\n\t\t\t// the clientFactory we provide delegates to getClient, so the URLs are\n\t\t\t// never actually used. We use placeholder values.\n\t\t\tconst networkUrls: Record<string, string> = {};\n\t\t\tfor (const network of networks) {\n\t\t\t\tnetworkUrls[network] = `dapp-kit://${network}`;\n\t\t\t}\n\n\t\t\t// Delegate the construct → init-adapter → mount-UI → register → dispose\n\t\t\t// sequence to the shared core helper; this initializer only supplies the\n\t\t\t// dApp-Kit-sourced networks + client factory and the `onWalletCreated`\n\t\t\t// hook. `createInitialAccount`/`autoInitialize` default to TRUE here (the\n\t\t\t// initializer's historical behavior — its adapters start empty); `mountUI`\n\t\t\t// defaults to FALSE (dApp Kit typically renders its own connect UI).\n\t\t\tconst { dispose } = await mountAndRegisterDevWallet({\n\t\t\t\tadapters: config.adapters,\n\t\t\t\tnetworks: networkUrls,\n\t\t\t\tname: config.name,\n\t\t\t\ticon: config.icon,\n\t\t\t\tautoApprove: config.autoApprove,\n\t\t\t\tautoConnect: config.autoConnect,\n\t\t\t\tclientFactory: (network) => getClient(network),\n\t\t\t\tautoInitialize: config.autoInitialize ?? true,\n\t\t\t\tcreateInitialAccount: config.createInitialAccount ?? true,\n\t\t\t\tmountUI: config.mountUI ?? false,\n\t\t\t\tdockStyle: config.dockStyle,\n\t\t\t\tcontainer: config.container,\n\t\t\t\tonWalletCreated: config.onWalletCreated,\n\t\t\t});\n\n\t\t\treturn { unregister: dispose };\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,SAAgB,qBAAqB,QAMnC;CACD,OAAO;EACN,IAAI;EACJ,MAAM,WAAW,EAAE,UAAU,aAAa;GAKzC,MAAM,cAAsC,CAAC;GAC7C,KAAK,MAAM,WAAW,UACrB,YAAY,WAAW,cAAc;GAStC,MAAM,EAAE,YAAY,MAAM,0BAA0B;IACnD,UAAU,OAAO;IACjB,UAAU;IACV,MAAM,OAAO;IACb,MAAM,OAAO;IACb,aAAa,OAAO;IACpB,aAAa,OAAO;IACpB,gBAAgB,YAAY,UAAU,OAAO;IAC7C,gBAAgB,OAAO,kBAAkB;IACzC,sBAAsB,OAAO,wBAAwB;IACrD,SAAS,OAAO,WAAW;IAC3B,WAAW,OAAO;IAClB,WAAW,OAAO;IAClB,iBAAiB,OAAO;GACzB,CAAC;GAED,OAAO,EAAE,YAAY,QAAQ;EAC9B;CACD;AACD"}
@@ -0,0 +1,44 @@
1
+ import { DevWallet, DevWalletConfig } from "./dev-wallet.mjs";
2
+ import { DevWalletDockStyle } from "../ui/dev-wallet-panel.mjs";
3
+
4
+ //#region src/wallet/mount-and-register.d.ts
5
+ interface MountAndRegisterDevWalletOptions extends DevWalletConfig {
6
+ /** Call `adapter.initialize()` on every adapter before registering. Defaults to true. */
7
+ autoInitialize?: boolean;
8
+ /**
9
+ * Create an initial account after initialization when no adapter has any
10
+ * accounts (uses the first adapter that supports `createAccount`). Defaults
11
+ * to false — most managed/remote adapters (devstack, CLI) bring their own
12
+ * accounts and must NOT have a throwaway one fabricated.
13
+ */
14
+ createInitialAccount?: boolean;
15
+ /** Mount the floating wallet drawer UI (no-op when `document` is undefined). Defaults to true. */
16
+ mountUI?: boolean;
17
+ /** Floating dock presentation when `mountUI` is true. */
18
+ dockStyle?: DevWalletDockStyle;
19
+ /** Container element for the UI drawer. Defaults to `document.body`. */
20
+ container?: HTMLElement;
21
+ /** Called with the `DevWallet` once constructed, before the UI is mounted
22
+ * and the wallet is registered. */
23
+ onWalletCreated?: (wallet: DevWallet) => void;
24
+ }
25
+ interface MountAndRegisterDevWalletResult {
26
+ readonly wallet: DevWallet;
27
+ /** Unmount the UI, unregister from wallet-standard, and destroy the wallet (+ adapters). */
28
+ readonly dispose: () => void;
29
+ }
30
+ /**
31
+ * Construct a {@link DevWallet} from adapters, initialize the adapters, mount
32
+ * the drawer UI, register it with the wallet-standard registry, and return the
33
+ * wallet plus a single `dispose()` that tears all of that down again.
34
+ *
35
+ * This is the imperative "bring a dev wallet up on the page" path shared by the
36
+ * React hook (`useDevWallet`), the dApp-Kit initializer (`devWalletInitializer`),
37
+ * and the devstack page-register entry (`src/inject`). Those call sites only
38
+ * differ in HOW they obtain `adapters` / `networks` — the construct → init →
39
+ * mount → register → dispose sequence is identical, so it lives here once.
40
+ */
41
+ declare function mountAndRegisterDevWallet(options: MountAndRegisterDevWalletOptions): Promise<MountAndRegisterDevWalletResult>;
42
+ //#endregion
43
+ export { MountAndRegisterDevWalletOptions, MountAndRegisterDevWalletResult, mountAndRegisterDevWallet };
44
+ //# sourceMappingURL=mount-and-register.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount-and-register.d.mts","names":[],"sources":["../../src/wallet/mount-and-register.ts"],"mappings":";;;;UAMiB,gCAAA,SAAyC,eAAA;;EAEzD,cAAA;EAFiD;;;;;;EASjD,oBAAA;EATwE;EAWxE,OAAA;EATA;EAWA,SAAA,GAAY,kBAAA;EAFZ;EAIA,SAAA,GAAY,WAAA;EAFA;;EAKZ,eAAA,IAAmB,MAAA,EAAQ,SAAA;AAAA;AAAA,UAGX,+BAAA;EAAA,SACP,MAAA,EAAQ,SAAS;EAJU;EAAA,SAM3B,OAAA;AAAA;;;;;;;;AAAO;AAcjB;;;iBAAsB,yBAAA,CACrB,OAAA,EAAS,gCAAA,GACP,OAAA,CAAQ,+BAAA"}