@mysten-incubation/dev-wallet 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +76 -2
- package/dist/_virtual/{_@oxc-project_runtime@0.127.0/helpers → _@oxc-project_runtime@0.135.0/helpers/esm}/decorate.mjs +1 -1
- package/dist/adapters/base-adapter.d.mts.map +1 -1
- package/dist/adapters/base-adapter.mjs.map +1 -1
- package/dist/adapters/build-managed-account.mjs.map +1 -1
- package/dist/adapters/devstack-adapter.d.mts.map +1 -1
- package/dist/adapters/devstack-adapter.mjs.map +1 -1
- package/dist/adapters/devstack-paths.d.mts.map +1 -1
- package/dist/adapters/devstack-paths.mjs.map +1 -1
- package/dist/adapters/fork-relay.d.mts.map +1 -1
- package/dist/adapters/fork-relay.mjs.map +1 -1
- package/dist/adapters/idb-store.mjs.map +1 -1
- package/dist/adapters/in-memory-adapter.d.mts.map +1 -1
- package/dist/adapters/in-memory-adapter.mjs.map +1 -1
- package/dist/adapters/passkey-adapter.d.mts.map +1 -1
- package/dist/adapters/passkey-adapter.mjs.map +1 -1
- package/dist/adapters/remote-cli-adapter.d.mts.map +1 -1
- package/dist/adapters/remote-cli-adapter.mjs.map +1 -1
- package/dist/adapters/webcrypto-adapter.d.mts.map +1 -1
- package/dist/adapters/webcrypto-adapter.mjs.map +1 -1
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/client/dev-wallet-client.d.mts.map +1 -1
- package/dist/client/dev-wallet-client.mjs.map +1 -1
- package/dist/client/request-handler.d.mts.map +1 -1
- package/dist/client/request-handler.mjs.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/inject/index.d.mts +61 -0
- package/dist/inject/index.d.mts.map +1 -0
- package/dist/inject/index.mjs +67 -0
- package/dist/inject/index.mjs.map +1 -0
- package/dist/react/components.d.mts +6 -8
- package/dist/react/components.d.mts.map +1 -1
- package/dist/react/components.mjs.map +1 -1
- package/dist/react/context.d.mts +2 -3
- package/dist/react/context.d.mts.map +1 -1
- package/dist/react/context.mjs.map +1 -1
- package/dist/react/useDevWallet.d.mts +3 -11
- package/dist/react/useDevWallet.d.mts.map +1 -1
- package/dist/react/useDevWallet.mjs +14 -36
- package/dist/react/useDevWallet.mjs.map +1 -1
- package/dist/server/cli-signing-middleware.d.mts.map +1 -1
- package/dist/server/cli-signing-middleware.mjs.map +1 -1
- package/dist/standalone/assets/base-adapter-DET6CP7z.js +1 -0
- package/dist/standalone/assets/in-memory-adapter-CX7xym4e.js +1 -0
- package/dist/standalone/assets/main-CuOnBmaa.js +7 -0
- package/dist/standalone/assets/webcrypto-adapter-CUQmbHDy.js +1 -0
- package/dist/standalone/bookmarklet.js +5 -5
- package/dist/standalone/index.html +2 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/ui/copy-controller.mjs.map +1 -1
- package/dist/ui/dev-wallet-account-selector.d.mts +2 -3
- package/dist/ui/dev-wallet-account-selector.d.mts.map +1 -1
- package/dist/ui/dev-wallet-account-selector.mjs +1 -1
- package/dist/ui/dev-wallet-account-selector.mjs.map +1 -1
- package/dist/ui/dev-wallet-accounts.d.mts +2 -3
- package/dist/ui/dev-wallet-accounts.d.mts.map +1 -1
- package/dist/ui/dev-wallet-accounts.mjs +1 -1
- package/dist/ui/dev-wallet-accounts.mjs.map +1 -1
- package/dist/ui/dev-wallet-balances.d.mts +2 -3
- package/dist/ui/dev-wallet-balances.d.mts.map +1 -1
- package/dist/ui/dev-wallet-balances.mjs +1 -1
- package/dist/ui/dev-wallet-balances.mjs.map +1 -1
- package/dist/ui/dev-wallet-connect.d.mts +2 -3
- package/dist/ui/dev-wallet-connect.d.mts.map +1 -1
- package/dist/ui/dev-wallet-connect.mjs +1 -1
- package/dist/ui/dev-wallet-connect.mjs.map +1 -1
- package/dist/ui/dev-wallet-dropdown.d.mts +2 -3
- package/dist/ui/dev-wallet-dropdown.d.mts.map +1 -1
- package/dist/ui/dev-wallet-dropdown.mjs +1 -1
- package/dist/ui/dev-wallet-dropdown.mjs.map +1 -1
- package/dist/ui/dev-wallet-fork-panel.d.mts +2 -3
- package/dist/ui/dev-wallet-fork-panel.d.mts.map +1 -1
- package/dist/ui/dev-wallet-fork-panel.mjs +1 -1
- package/dist/ui/dev-wallet-fork-panel.mjs.map +1 -1
- package/dist/ui/dev-wallet-network-badge.d.mts +2 -3
- package/dist/ui/dev-wallet-network-badge.d.mts.map +1 -1
- package/dist/ui/dev-wallet-network-badge.mjs +1 -1
- package/dist/ui/dev-wallet-network-badge.mjs.map +1 -1
- package/dist/ui/dev-wallet-new-account.d.mts +2 -3
- package/dist/ui/dev-wallet-new-account.d.mts.map +1 -1
- package/dist/ui/dev-wallet-new-account.mjs +1 -1
- package/dist/ui/dev-wallet-new-account.mjs.map +1 -1
- package/dist/ui/dev-wallet-objects.d.mts +2 -3
- package/dist/ui/dev-wallet-objects.d.mts.map +1 -1
- package/dist/ui/dev-wallet-objects.mjs +1 -1
- package/dist/ui/dev-wallet-objects.mjs.map +1 -1
- package/dist/ui/dev-wallet-panel.d.mts +2 -3
- package/dist/ui/dev-wallet-panel.d.mts.map +1 -1
- package/dist/ui/dev-wallet-panel.mjs +1 -1
- package/dist/ui/dev-wallet-panel.mjs.map +1 -1
- package/dist/ui/dev-wallet-popup.d.mts +2 -3
- package/dist/ui/dev-wallet-popup.d.mts.map +1 -1
- package/dist/ui/dev-wallet-popup.mjs +1 -1
- package/dist/ui/dev-wallet-popup.mjs.map +1 -1
- package/dist/ui/dev-wallet-settings.d.mts +2 -3
- package/dist/ui/dev-wallet-settings.d.mts.map +1 -1
- package/dist/ui/dev-wallet-settings.mjs +1 -1
- package/dist/ui/dev-wallet-settings.mjs.map +1 -1
- package/dist/ui/dev-wallet-signing-modal.d.mts +2 -3
- package/dist/ui/dev-wallet-signing-modal.d.mts.map +1 -1
- package/dist/ui/dev-wallet-signing-modal.mjs +1 -1
- package/dist/ui/dev-wallet-signing-modal.mjs.map +1 -1
- package/dist/ui/dev-wallet-signing.d.mts +2 -3
- package/dist/ui/dev-wallet-signing.d.mts.map +1 -1
- package/dist/ui/dev-wallet-signing.mjs +2 -1
- package/dist/ui/dev-wallet-signing.mjs.map +1 -1
- package/dist/ui/dev-wallet-standalone.d.mts +2 -3
- package/dist/ui/dev-wallet-standalone.d.mts.map +1 -1
- package/dist/ui/dev-wallet-standalone.mjs +1 -1
- package/dist/ui/dev-wallet-standalone.mjs.map +1 -1
- package/dist/ui/dev-wallet-tab-bar.d.mts +1 -2
- package/dist/ui/dev-wallet-tab-bar.d.mts.map +1 -1
- package/dist/ui/dev-wallet-tab-bar.mjs +1 -1
- package/dist/ui/dev-wallet-tab-bar.mjs.map +1 -1
- package/dist/ui/mount.mjs.map +1 -1
- package/dist/ui/styles.mjs.map +1 -1
- package/dist/ui/transaction-analyzer.mjs.map +1 -1
- package/dist/ui/utils.d.mts.map +1 -1
- package/dist/ui/utils.mjs.map +1 -1
- package/dist/ui/wallet-controller.mjs.map +1 -1
- package/dist/wallet/constants.d.mts.map +1 -1
- package/dist/wallet/constants.mjs.map +1 -1
- package/dist/wallet/dev-wallet.d.mts +19 -0
- package/dist/wallet/dev-wallet.d.mts.map +1 -1
- package/dist/wallet/dev-wallet.mjs +58 -2
- package/dist/wallet/dev-wallet.mjs.map +1 -1
- package/dist/wallet/initializer.d.mts.map +1 -1
- package/dist/wallet/initializer.mjs +10 -26
- package/dist/wallet/initializer.mjs.map +1 -1
- package/dist/wallet/mount-and-register.d.mts +44 -0
- package/dist/wallet/mount-and-register.d.mts.map +1 -0
- package/dist/wallet/mount-and-register.mjs +46 -0
- package/dist/wallet/mount-and-register.mjs.map +1 -0
- package/dist/wallet/signing.d.mts.map +1 -1
- package/dist/wallet/signing.mjs.map +1 -1
- package/package.json +26 -22
- package/src/index.ts +5 -0
- package/src/inject/index.ts +200 -0
- package/src/react/useDevWallet.ts +26 -71
- package/src/ui/dev-wallet-signing.ts +2 -0
- package/src/wallet/dev-wallet.ts +75 -2
- package/src/wallet/initializer.ts +16 -42
- package/src/wallet/mount-and-register.ts +93 -0
- package/dist/standalone/assets/in-memory-adapter-qRkNfj9O.js +0 -1
- package/dist/standalone/assets/main-DDltQnzR.js +0 -3954
- 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,
|
|
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;
|
|
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,
|
|
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.#
|
|
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.#
|
|
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":";;;;;;AA2BA,MAAM,sBAAsB;AAC5B,MAAM,sBAAsB;;;;AAK5B,MAAa,uBAAuB;CACnC,QAAQ;CACR,SAAS;CACT,UAAU;CACV;;;;;AAoED,IAAa,YAAb,MAAyC;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,aAAa;CAEb,YAAY,QAAyB;AACpC,MAAI,OAAO,SAAS,WAAW,EAC9B,SAAQ,KAAK,uEAAuE;AAErF,QAAA,WAAiB,OAAO;AACxB,QAAA,kBAAwB,OAAO,mBAAmB;AAClD,QAAA,cAAoB,MAAA,gBAAsB,OAAO,YAAY,qBAAqB;AAClF,QAAA,UAAgB,EAAE;AAClB,QAAA,gBAAsB,OAAO,iBAAiB,OAAO,KAAK,MAAA,YAAkB,CAAC,MAAM;AACnF,QAAA,OAAa,OAAO,QAAQ;AAC5B,QAAA,OAAa,OAAO,QAAA;AACpB,QAAA,cAAoB,OAAO,eAAe;AAC1C,QAAA,cAAoB,OAAO,eAAe;AAC1C,QAAA,gBACC,OAAO,mBAAmB,SAAS,QAAQ,IAAI,cAAc;GAAE,SAAS;GAAK;GAAS,CAAC;AACxF,QAAA,WAAiB,MAAA,mBAAyB;AAC1C,QAAA,SAAe,MAAM;AACrB,QAAA,sBAA4B,EAAE;AAC9B,QAAA,iBAAuB;AACvB,QAAA,mCAAyB,IAAI,KAAK;AAClC,QAAA,iBAAuB;AACvB,QAAA,mCAAyB,IAAI,KAAK;AAElC,QAAA,uBAA6B;;CAG9B,IAAI,UAAU;AACb,SAAO;;CAGR,IAAI,OAAO;AACV,SAAO,MAAA;;CAGR,IAAI,OAAO;AACV,SAAO,MAAA;;CAGR,IAAI,SAAS;AACZ,SAAO;;CAGR,IAAI,WAA6C;AAChD,SAAO,MAAA;;CAGR,IAAI,WAGS;AACZ,SAAO;GACN,oBAAoB;IACnB,SAAS;IACT,SAAS,MAAA;IACT;GACD,mBAAmB;IAClB,SAAS;IACT,IAAI,MAAA;IACJ;GACD,uBAAuB;IACtB,SAAS;IACT,YAAY,MAAA;IACZ;GACD,2BAA2B;IAC1B,SAAS;IACT,qBAAqB,MAAA;IACrB;GACD,uBAAuB;IACtB,SAAS;IACT,iBAAiB,MAAA;IACjB;GACD,iCAAiC;IAChC,SAAS;IACT,2BAA2B,MAAA;IAC3B;GACD;;;CAIF,IAAI,iBAA+C;AAClD,SAAO,MAAA;;CAGR,IAAI,WAAqC;AACxC,SAAO,MAAA;;CAGR,qBAAqB,SAA4C;AAChE,SAAO,MAAA,SAAe,MAAM,MAAM,EAAE,WAAW,QAAQ,KAAK,OAAU;;;CAIvE,IAAI,UAA6C;AAChD,OAAK,MAAM,QAAQ,OAAO,KAAK,MAAA,YAAkB,CAChD,OAAA,aAAmB,KAAK;AAEzB,SAAO,EAAE,GAAG,MAAA,SAAe;;CAG5B,UAAU,SAAoC;AAC7C,SAAO,MAAA,aAAmB,QAAQ;;CAGnC,IAAI,cAAsC;AACzC,SAAO,EAAE,GAAG,MAAA,aAAmB;;CAGhC,IAAI,gBAAwB;AAC3B,SAAO,MAAA;;CAGR,IAAI,eAAyC;AAC5C,MAAI,CAAC,MAAA,iBAAuB,CAAC,MAAA,YAAkB,MAAA,eAAsB,QAAO;AAC5E,SAAO,MAAA,aAAmB,MAAA,cAAoB;;CAG/C,IAAI,oBAA8B;AACjC,SAAO,OAAO,KAAK,MAAA,YAAkB;;;CAItC,iBAAiB,SAAuB;AACvC,MAAI,CAAC,MAAA,YAAkB,SACtB,OAAM,IAAI,MACT,0BAA0B,QAAQ,gBAAgB,KAAK,kBAAkB,KAAK,KAAK,GACnF;AAEF,QAAA,gBAAsB;AACtB,QAAA,OAAa,KAAK,UAAU,EAAE,UAAU,MAAA,UAAgB,CAAC;;CAG1D,WAAW,MAAc,KAAmB;EAC3C,IAAI;AACJ,MAAI;AACH,YAAS,IAAI,IAAI,IAAI;UACd;AACP,SAAM,IAAI,MAAM,gBAAgB,MAAM;;AAEvC,MAAI,OAAO,aAAa,WAAW,OAAO,aAAa,SACtD,OAAM,IAAI,MAAM,4CAA4C,OAAO,SAAS,GAAG;AAEhF,QAAA,YAAkB,QAAQ;AAC1B,QAAA,QAAc,QAAQ,MAAA,cAAoB,MAAM,IAAI;AACpD,QAAA,iBAAuB;AACvB,QAAA,OAAa,KAAK,UAAU,EAAE,UAAU,MAAA,UAAgB,CAAC;;CAG1D,cAAc,MAAoB;AACjC,SAAO,MAAA,YAAkB;AACzB,SAAO,MAAA,QAAc;AACrB,MAAI,MAAA,kBAAwB,KAC3B,OAAA,gBAAsB,OAAO,KAAK,MAAA,YAAkB,CAAC,MAAM;AAE5D,QAAA,iBAAuB;AACvB,QAAA,OAAa,KAAK,UAAU,EAAE,UAAU,MAAA,UAAgB,CAAC;;;CAI1D,WAAuB;AACtB,MAAI,OAAO,YAAY,eAAe,QAAQ,KAAK,aAAa,aAC/D,SAAQ,KACP,wGACA;AAGF,SADmB,YACZ,CAAW,SAAS,KAAK;;;CAIjC,UAAgB;AACf,QAAA,YAAkB;AAClB,OAAK,MAAM,SAAS,MAAA,oBACnB,QAAO;AAER,QAAA,sBAA4B,EAAE;AAC9B,OAAK,MAAM,WAAW,MAAA,SACrB,SAAQ,SAAS;AAElB,MAAI,MAAA,gBAAsB;AACzB,SAAA,eAAqB,uBAAO,IAAI,MAAM,oBAAoB,CAAC;AAC3D,SAAA,iBAAuB;;AAExB,MAAI,MAAA,gBAAsB;AACzB,SAAA,eAAqB,uBAAO,IAAI,MAAM,oBAAoB,CAAC;AAC3D,SAAA,iBAAuB;;AAExB,QAAA,iBAAuB,OAAO;AAC9B,QAAA,iBAAuB,OAAO;AAC9B,QAAA,OAAa,IAAI,OAAO;;;CAIzB,MAAM,iBAAgC;EACrC,MAAM,UAAU,MAAA;AAChB,MAAI,CAAC,QACJ,OAAM,IAAI,MAAM,iCAAiC;AAGlD,MAAI;GACH,MAAM,SAAS,MAAM,MAAA,eACpB,QAAQ,MACR,QAAQ,SACR,QAAQ,OACR,QAAQ,KACR;AACD,SAAA,iBAAuB;AACvB,SAAA,wBAA8B;AAC9B,WAAQ,QAAQ,OAAO;WACf,OAAO;AACf,SAAA,iBAAuB;AACvB,SAAA,wBAA8B;AAC9B,WAAQ,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC,CAAC;;;CAI3E,cAAc,QAAuB;EACpC,MAAM,UAAU,MAAA;AAChB,MAAI,CAAC,QACJ,OAAM,IAAI,MAAM,gCAAgC;AAEjD,QAAA,iBAAuB;AACvB,QAAA,wBAA8B;AAC9B,UAAQ,OAAO,IAAI,MAAM,UAAU,4BAA4B,CAAC;;;CAIjE,gBAAgB,UAAuE;AACtF,QAAA,iBAAuB,IAAI,SAAS;AACpC,eAAa;AACZ,SAAA,iBAAuB,OAAO,SAAS;;;;CAKzC,IAAI,iBAA+C;AAClD,SAAO,MAAA;;;CAIR,eAAe,mBAAmC;EACjD,MAAM,UAAU,MAAA;AAChB,MAAI,CAAC,QACJ,OAAM,IAAI,MAAM,yCAAyC;EAG1D,MAAM,WACL,kBAAkB,SAAS,IACxB,MAAA,SAAe,QAAQ,MAAM,kBAAkB,SAAS,EAAE,QAAQ,CAAC,GACnE,CAAC,GAAG,MAAA,SAAe;AAEvB,QAAA,iBAAuB;AACvB,QAAA,wBAA8B;AAC9B,UAAQ,QAAQ,EAAE,UAAU,UAAU,CAAC;;CAGxC,cAAc,QAAuB;EACpC,MAAM,UAAU,MAAA;AAChB,MAAI,CAAC,QACJ,OAAM,IAAI,MAAM,wCAAwC;AAEzD,QAAA,iBAAuB;AACvB,QAAA,wBAA8B;AAC9B,UAAQ,OAAO,IAAI,MAAM,UAAU,+BAA+B,CAAC;;;CAIpE,gBAAgB,UAAuE;AACtF,QAAA,iBAAuB,IAAI,SAAS;AACpC,eAAa;AACZ,SAAA,iBAAuB,OAAO,SAAS;;;CAIzC,0BAA0B;EACzB,MAAM,UAAU,MAAA;AAChB,OAAK,MAAM,YAAY,MAAA,iBACtB,UAAS,QAAQ;;CAInB,0BAA0B;EACzB,MAAM,UAAU,MAAA;AAChB,OAAK,MAAM,YAAY,MAAA,iBACtB,UAAS,QAAQ;;CAInB,qBAA8C;AAC7C,SAAO,MAAA,SAAe,SAAS,MAAM,EAAE,aAAa,CAAC,KAAK,QAAQ,IAAI,cAAc,CAAC;;CAGtF,yBAAyB;AACxB,OAAK,MAAM,WAAW,MAAA,UAAgB;GACrC,MAAM,QAAQ,QAAQ,wBAAwB;AAC7C,UAAA,WAAiB,MAAA,mBAAyB;AAC1C,UAAA,OAAa,KAAK,UAAU,EAAE,UAAU,MAAA,UAAgB,CAAC;KACxD;AACF,SAAA,oBAA0B,KAAK,MAAM;;;CAIvC,OAA+B,OAAO,aAAa;AAClD,QAAA,OAAa,GAAG,OAAO,SAAS;AAChC,eAAa,MAAA,OAAa,IAAI,OAAO,SAAS;;CAG/C,WAAkC,YAAY;AAE7C,MAAI,MAAA,YACH,QAAO,EAAE,UAAU,KAAK,UAAU;AAInC,MAAI,MAAA,eACH,QAAO,QAAQ,uBAAO,IAAI,MAAM,wCAAwC,CAAC;AAG1E,SAAO,IAAI,SAAS,SAAS,WAAW;AACvC,SAAA,iBAAuB;IACtB,IAAI,OAAO,YAAY;IACvB;IACA;IACA;AACD,SAAA,wBAA8B;IAC7B;;CAGH,cAAwC,YAAY;CAKpD,mBAAmB,OAAe;EACjC,MAAM,UAAU,oBAAoB,MAAM;AAC1C,MAAI,CAAC,QACJ,OAAM,IAAI,MAAM,6BAA6B,QAAQ;AAEtD,SAAO,MAAA,aAAmB,QAAQ;;CAGnC,iBAAiB,UAA0D;AAC1E,MAAI,CAAC,MAAA,mBAAyB,OAAO,iBAAiB,YACrD,QAAO,EAAE,GAAG,UAAU;AAEvB,MAAI;GACH,MAAM,MAAM,aAAa,QAAQ,oBAAoB;AACrD,OAAI,KAAK;IACR,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,QAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,OAAO,CAC1E,QAAO;;UAGF;AAGR,SAAO,EAAE,GAAG,UAAU;;CAGvB,mBAAyB;AACxB,MAAI,CAAC,MAAA,mBAAyB,OAAO,iBAAiB,YAAa;AACnE,eAAa,QAAQ,qBAAqB,KAAK,UAAU,MAAA,YAAkB,CAAC;;CAG7E,cAAc,SAAoC;AACjD,MAAI,CAAC,MAAA,QAAc,UAAU;GAC5B,MAAM,MAAM,MAAA,YAAkB;AAC9B,OAAI,CAAC,IACJ,OAAM,IAAI,MACT,0BAA0B,QAAQ,gBAAgB,KAAK,kBAAkB,KAAK,KAAK,GACnF;AAEF,SAAA,QAAc,WAAW,MAAA,cAAoB,SAAS,IAAI;;AAE3D,SAAO,MAAA,QAAc;;CAGtB,WAAW,SAAiB;AAC3B,OAAK,MAAM,WAAW,MAAA,UAAgB;GACrC,MAAM,UAAU,QAAQ,WAAW,QAAQ;AAC3C,OAAI,QAAS,QAAO,QAAQ;;EAE7B,MAAM,eAAe,MAAA,SAAe,SAAS,MAAM,EAAE,aAAa,CAAC,KAAK,QAAQ,IAAI,QAAQ,CAAC;AAC7F,QAAM,IAAI,MACT,iCAAiC,QAAQ,0BAA0B,aAAa,KAAK,KAAK,GAC1F;;CAGF,mBACC,MACA,SACA,OACA,MACU;AAGV,MADgB,KAAK,qBAAqB,QAAQ,QAC9C,EAAS,kBAAkB,MAC9B,QAAO;AAGR,MAAI,MAAA,gBAAsB,KACzB,QAAO;AAER,MAAI,OAAO,MAAA,gBAAsB,WAChC,QAAO,MAAA,YAAkB;GAAE;GAAM;GAAS;GAAO;GAAM,CAAC;AAEzD,SAAO;;CAGR,OAAA,eACC,MACA,SACA,OACA,MACC;AAGD,SAAO,eAAe;GAAE;GAAM,QAFf,MAAA,UAAgB,QAAQ,QAET;GAAQ;GAAM,QAD7B,SAAS,0BAA0B,MAAA,kBAAwB,MAAM,GAAG;GAC/B,CAAC;;CAGtD,gBACC,MACA,SACA,OACA,MAC+C;AAE/C,MAAI,MAAA,UACH,QAAO,QAAQ,uBAAO,IAAI,MAAM,6BAA6B,CAAC;AAE/D,MAAI,MAAA,kBAAwB,MAAM,SAAS,OAAO,KAAK,CACtD,QAAO,MAAA,eAAqB,MAAM,SAAS,OAAO,KAAK;AAKxD,MAAI,MAAA,eACH,QAAO,QAAQ,uBAAO,IAAI,MAAM,wCAAwC,CAAC;AAG1E,SAAO,IAAI,SAAiB,SAAS,WAAW;AAC/C,SAAA,iBAAuB;IACtB,IAAI,OAAO,YAAY;IACvB;IACA;IACA;IACA;IACS;IACT;IACA;AACD,SAAA,wBAA8B;IAC7B;;CAGH,uBAAqD,OAAO,UAAU;AACrE,SAAO,MAAA,eACN,yBACA,MAAM,SACN,MAAM,SAAS,eACf,MAAM,QACN;;CAGF,mBAA6C,OAAO,UAAU;EAC7D,MAAM,SAAS,MAAM,MAAM,YAAY,QAAQ;AAC/C,SAAO,MAAA,eAAqB,oBAAoB,MAAM,SAAS,MAAM,OAAO,OAAO;;CAGpF,6BAAiE,OAAO,UAAU;EACjF,MAAM,SAAS,MAAM,MAAM,YAAY,QAAQ;AAC/C,SAAO,MAAA,eAAqB,gCAAgC,MAAM,SAAS,MAAM,OAAO,OAAO"}
|
|
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":";;;;;;AA2BA,MAAM,sBAAsB;AAC5B,MAAM,sBAAsB;;;;AAK5B,MAAa,uBAAuB;CACnC,QAAQ;CACR,SAAS;CACT,UAAU;AACX;;;;;AAoEA,IAAa,YAAb,MAAyC;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,mBAAkC;CAClC;CACA;CACA;CACA;CACA;CACA;;;;;;CAMA;CACA,aAAa;CAEb,YAAY,QAAyB;EACpC,IAAI,OAAO,SAAS,WAAW,GAC9B,QAAQ,KAAK,sEAAsE;EAEpF,KAAKA,YAAY,OAAO;EACxB,KAAKM,mBAAmB,OAAO,mBAAmB;EAClD,KAAKC,eAAe,KAAKC,iBAAiB,OAAO,YAAY,oBAAoB;EACjF,KAAKC,WAAW,CAAC;EACjB,KAAKC,iBAAiB,OAAO,iBAAiB,OAAO,KAAK,KAAKH,YAAY,CAAC,CAAC,MAAM;EACnF,KAAKN,QAAQ,OAAO,QAAQ;EAC5B,KAAKC,QAAQ,OAAO,QAAA;EACpB,KAAKC,eAAe,OAAO,eAAe;EAC1C,KAAKC,eAAe,OAAO,eAAe;EAC1C,KAAKC,iBACJ,OAAO,mBAAmB,SAAS,QAAQ,IAAI,cAAc;GAAE,SAAS;GAAK;EAAQ,CAAC;EACvF,KAAKM,YAAY,KAAKC,mBAAmB;EACzC,KAAKC,UAAU,KAAK;EACpB,KAAKC,uBAAuB,CAAC;EAC7B,KAAKC,kBAAkB;EACvB,KAAKC,oCAAoB,IAAI,IAAI;EACjC,KAAKC,kBAAkB;EACvB,KAAKC,oCAAoB,IAAI,IAAI;EACjC,KAAKC,sCAAsB,IAAI,IAAI;EAEnC,KAAKC,uBAAuB;CAC7B;CAEA,IAAI,UAAU;EACb,OAAO;CACR;CAEA,IAAI,OAAO;EACV,OAAO,KAAKnB;CACb;CAEA,IAAI,OAAO;EACV,OAAO,KAAKC;CACb;CAEA,IAAI,SAAS;EACZ,OAAO;CACR;CAEA,IAAI,WAA6C;EAChD,OAAO,KAAKmB,iBAAiB;CAC9B;;;;;;;;;;;;CAaA,mBAAmB,SAA8B;EAChD,IAAI,YAAY,MAAM;GACrB,MAAM,QAAQ,KAAKV,UAAU,MAAM,MAAM,EAAE,QAAQ,YAAY,MAAM,QAAQ,YAAY,CAAC;GAC1F,IAAI,UAAU,QAAW;IACxB,MAAM,YAAY,KAAKA,UAAU,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI;IAChE,MAAM,IAAI,MACT,sCAAsC,QAAQ,gBAAgB,aAAa,UAC5E;GACD;GACA,KAAKW,mBAAmB,MAAM;EAC/B,OACC,KAAKA,mBAAmB;EAEzB,KAAKT,QAAQ,KAAK,UAAU,EAAE,UAAU,KAAKQ,iBAAiB,EAAE,CAAC;CAClE;;CAGA,mBAA4C;EAC3C,IAAI,KAAKC,qBAAqB,MAAM,OAAO,KAAKX;EAChD,OAAO,KAAKA,UAAU,QACpB,MAAM,EAAE,QAAQ,YAAY,MAAM,KAAKW,iBAAkB,YAAY,CACvE;CACD;CAEA,IAAI,WAGS;EACZ,OAAO;GACN,oBAAoB;IACnB,SAAS;IACT,SAAS,KAAKC;GACf;GACA,mBAAmB;IAClB,SAAS;IACT,IAAI,KAAKC;GACV;GACA,uBAAuB;IACtB,SAAS;IACT,YAAY,KAAKC;GAClB;GACA,2BAA2B;IAC1B,SAAS;IACT,qBAAqB,KAAKC;GAC3B;GACA,uBAAuB;IACtB,SAAS;IACT,iBAAiB,KAAKC;GACvB;GACA,iCAAiC;IAChC,SAAS;IACT,2BAA2B,KAAKC;GACjC;EACD;CACD;;CAGA,IAAI,iBAA+C;EAClD,OAAO,KAAKb;CACb;CAEA,IAAI,WAAqC;EACxC,OAAO,KAAKf;CACb;CAEA,qBAAqB,SAA4C;EAChE,OAAO,KAAKA,UAAU,MAAM,MAAM,EAAE,WAAW,OAAO,MAAM,MAAS;CACtE;;CAGA,IAAI,UAA6C;EAChD,KAAK,MAAM,QAAQ,OAAO,KAAK,KAAKO,YAAY,GAC/C,KAAKsB,cAAc,IAAI;EAExB,OAAO,EAAE,GAAG,KAAKpB,SAAS;CAC3B;CAEA,UAAU,SAAoC;EAC7C,OAAO,KAAKoB,cAAc,OAAO;CAClC;CAEA,IAAI,cAAsC;EACzC,OAAO,EAAE,GAAG,KAAKtB,aAAa;CAC/B;CAEA,IAAI,gBAAwB;EAC3B,OAAO,KAAKG;CACb;CAEA,IAAI,eAAyC;EAC5C,IAAI,CAAC,KAAKA,kBAAkB,CAAC,KAAKH,aAAa,KAAKG,iBAAiB,OAAO;EAC5E,OAAO,KAAKmB,cAAc,KAAKnB,cAAc;CAC9C;CAEA,IAAI,oBAA8B;EACjC,OAAO,OAAO,KAAK,KAAKH,YAAY;CACrC;;CAGA,iBAAiB,SAAuB;EACvC,IAAI,CAAC,KAAKA,aAAa,UACtB,MAAM,IAAI,MACT,0BAA0B,QAAQ,gBAAgB,KAAK,kBAAkB,KAAK,IAAI,GACnF;EAED,KAAKG,iBAAiB;EACtB,KAAKG,QAAQ,KAAK,UAAU,EAAE,UAAU,KAAKF,UAAU,CAAC;CACzD;CAEA,WAAW,MAAc,KAAmB;EAC3C,IAAI;EACJ,IAAI;GACH,SAAS,IAAI,IAAI,GAAG;EACrB,QAAQ;GACP,MAAM,IAAI,MAAM,gBAAgB,KAAK;EACtC;EACA,IAAI,OAAO,aAAa,WAAW,OAAO,aAAa,UACtD,MAAM,IAAI,MAAM,4CAA4C,OAAO,SAAS,EAAE;EAE/E,KAAKJ,aAAa,QAAQ;EAC1B,KAAKE,SAAS,QAAQ,KAAKJ,eAAe,MAAM,GAAG;EACnD,KAAKyB,iBAAiB;EACtB,KAAKjB,QAAQ,KAAK,UAAU,EAAE,UAAU,KAAKF,UAAU,CAAC;CACzD;CAEA,cAAc,MAAoB;EACjC,OAAO,KAAKJ,aAAa;EACzB,OAAO,KAAKE,SAAS;EACrB,IAAI,KAAKC,mBAAmB,MAC3B,KAAKA,iBAAiB,OAAO,KAAK,KAAKH,YAAY,CAAC,CAAC,MAAM;EAE5D,KAAKuB,iBAAiB;EACtB,KAAKjB,QAAQ,KAAK,UAAU,EAAE,UAAU,KAAKF,UAAU,CAAC;CACzD;;CAGA,WAAuB;EACtB,IAAI,OAAO,YAAY,eAAe,QAAQ,KAAK,aAAa,cAC/D,QAAQ,KACP,uGACD;EAGD,OADmB,WACZ,CAAA,CAAW,SAAS,IAAI;CAChC;;CAGA,UAAgB;EACf,KAAKoB,aAAa;EAClB,KAAK,MAAM,SAAS,KAAKjB,sBACxB,MAAM;EAEP,KAAKA,uBAAuB,CAAC;EAC7B,KAAK,MAAM,WAAW,KAAKd,WAC1B,QAAQ,QAAQ;EAEjB,IAAI,KAAKe,iBAAiB;GACzB,KAAKA,gBAAgB,uBAAO,IAAI,MAAM,mBAAmB,CAAC;GAC1D,KAAKA,kBAAkB;EACxB;EACA,IAAI,KAAKE,iBAAiB;GACzB,KAAKA,gBAAgB,uBAAO,IAAI,MAAM,mBAAmB,CAAC;GAC1D,KAAKA,kBAAkB;EACxB;EACA,KAAKD,kBAAkB,MAAM;EAC7B,KAAKE,kBAAkB,MAAM;EAC7B,KAAKC,oBAAoB,MAAM;EAC/B,KAAKN,QAAQ,IAAI,MAAM;CACxB;;CAGA,MAAM,iBAAgC;EACrC,MAAM,UAAU,KAAKE;EACrB,IAAI,CAAC,SACJ,MAAM,IAAI,MAAM,gCAAgC;EAGjD,IAAI;GACH,MAAM,SAAS,MAAM,KAAKiB,gBACzB,QAAQ,MACR,QAAQ,SACR,QAAQ,OACR,QAAQ,IACT;GACA,KAAKjB,kBAAkB;GACvB,KAAKkB,wBAAwB;GAC7B,QAAQ,QAAQ,MAAM;EACvB,SAAS,OAAO;GACf,KAAKlB,kBAAkB;GACvB,KAAKkB,wBAAwB;GAC7B,QAAQ,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;EACzE;CACD;CAEA,cAAc,QAAuB;EACpC,MAAM,UAAU,KAAKlB;EACrB,IAAI,CAAC,SACJ,MAAM,IAAI,MAAM,+BAA+B;EAEhD,KAAKA,kBAAkB;EACvB,KAAKkB,wBAAwB;EAC7B,QAAQ,OAAO,IAAI,MAAM,UAAU,2BAA2B,CAAC;CAChE;;CAGA,gBAAgB,UAAuE;EACtF,KAAKjB,kBAAkB,IAAI,QAAQ;EACnC,aAAa;GACZ,KAAKA,kBAAkB,OAAO,QAAQ;EACvC;CACD;;CAGA,IAAI,iBAA+C;EAClD,OAAO,KAAKC;CACb;;CAGA,eAAe,mBAAmC;EACjD,MAAM,UAAU,KAAKA;EACrB,IAAI,CAAC,SACJ,MAAM,IAAI,MAAM,wCAAwC;EAGzD,MAAM,WACL,kBAAkB,SAAS,IACxB,KAAKN,UAAU,QAAQ,MAAM,kBAAkB,SAAS,EAAE,OAAO,CAAC,IAClE,CAAC,GAAG,KAAKA,SAAS;EAEtB,KAAKM,kBAAkB;EACvB,KAAKiB,wBAAwB;EAC7B,QAAQ,QAAQ,EAAE,UAAU,SAAS,CAAC;CACvC;CAEA,cAAc,QAAuB;EACpC,MAAM,UAAU,KAAKjB;EACrB,IAAI,CAAC,SACJ,MAAM,IAAI,MAAM,uCAAuC;EAExD,KAAKA,kBAAkB;EACvB,KAAKiB,wBAAwB;EAC7B,QAAQ,OAAO,IAAI,MAAM,UAAU,8BAA8B,CAAC;CACnE;;CAGA,gBAAgB,UAAuE;EACtF,KAAKhB,kBAAkB,IAAI,QAAQ;EACnC,aAAa;GACZ,KAAKA,kBAAkB,OAAO,QAAQ;EACvC;CACD;CAEA,0BAA0B;EACzB,MAAM,UAAU,KAAKH;EACrB,KAAK,MAAM,YAAY,KAAKC,mBAC3B,SAAS,OAAO;CAElB;CAEA,0BAA0B;EACzB,MAAM,UAAU,KAAKC;EACrB,KAAK,MAAM,YAAY,KAAKC,mBAC3B,SAAS,OAAO;CAElB;;;;;;;CAQA,gBAAgB,UAAkC;EACjD,KAAKC,oBAAoB,IAAI,QAAQ;EACrC,aAAa;GACZ,KAAKA,oBAAoB,OAAO,QAAQ;EACzC;CACD;CAEA,4BAA4B;EAC3B,KAAK,MAAM,YAAY,KAAKA,qBAC3B,IAAI;GACH,SAAS;EACV,SAAS,OAAO;GACf,QAAQ,MAAM,gDAAgD,KAAK;EACpE;CAEF;CAEA,qBAA8C;EAC7C,OAAO,KAAKnB,UAAU,SAAS,MAAM,EAAE,YAAY,CAAC,CAAC,KAAK,QAAQ,IAAI,aAAa,CAAC;CACrF;CAEA,yBAAyB;EACxB,KAAK,MAAM,WAAW,KAAKA,WAAW;GACrC,MAAM,QAAQ,QAAQ,wBAAwB;IAC7C,KAAKW,YAAY,KAAKC,mBAAmB;IACzC,KAAKC,QAAQ,KAAK,UAAU,EAAE,UAAU,KAAKQ,iBAAiB,EAAE,CAAC;GAClE,CAAC;GACD,KAAKP,qBAAqB,KAAK,KAAK;EACrC;CACD;CAEA,OAA+B,OAAO,aAAa;EAClD,KAAKD,QAAQ,GAAG,OAAO,QAAQ;EAC/B,aAAa,KAAKA,QAAQ,IAAI,OAAO,QAAQ;CAC9C;CAEA,WAAkC,YAAY;EAK7C,KAAKsB,0BAA0B;EAG/B,IAAI,KAAK/B,cACR,OAAO,EAAE,UAAU,KAAK,SAAS;EAIlC,IAAI,KAAKa,iBACR,OAAO,QAAQ,uBAAO,IAAI,MAAM,uCAAuC,CAAC;EAGzE,OAAO,IAAI,SAAS,SAAS,WAAW;GACvC,KAAKA,kBAAkB;IACtB,IAAI,OAAO,WAAW;IACtB;IACA;GACD;GACA,KAAKiB,wBAAwB;EAC9B,CAAC;CACF;CAEA,cAAwC,YAAY,CAGpD;CAEA,mBAAmB,OAAe;EACjC,MAAM,UAAU,oBAAoB,KAAK;EACzC,IAAI,CAAC,SACJ,MAAM,IAAI,MAAM,6BAA6B,OAAO;EAErD,OAAO,KAAKL,cAAc,OAAO;CAClC;CAEA,iBAAiB,UAA0D;EAC1E,IAAI,CAAC,KAAKvB,oBAAoB,OAAO,iBAAiB,aACrD,OAAO,EAAE,GAAG,SAAS;EAEtB,IAAI;GACH,MAAM,MAAM,aAAa,QAAQ,mBAAmB;GACpD,IAAI,KAAK;IACR,MAAM,SAAS,KAAK,MAAM,GAAG;IAC7B,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,MAAM,GACzE,OAAO;GAET;EACD,QAAQ,CAER;EACA,OAAO,EAAE,GAAG,SAAS;CACtB;CAEA,mBAAyB;EACxB,IAAI,CAAC,KAAKA,oBAAoB,OAAO,iBAAiB,aAAa;EACnE,aAAa,QAAQ,qBAAqB,KAAK,UAAU,KAAKC,YAAY,CAAC;CAC5E;CAEA,cAAc,SAAoC;EACjD,IAAI,CAAC,KAAKE,SAAS,UAAU;GAC5B,MAAM,MAAM,KAAKF,aAAa;GAC9B,IAAI,CAAC,KACJ,MAAM,IAAI,MACT,0BAA0B,QAAQ,gBAAgB,KAAK,kBAAkB,KAAK,IAAI,GACnF;GAED,KAAKE,SAAS,WAAW,KAAKJ,eAAe,SAAS,GAAG;EAC1D;EACA,OAAO,KAAKI,SAAS;CACtB;CAEA,WAAW,SAAiB;EAC3B,KAAK,MAAM,WAAW,KAAKT,WAAW;GACrC,MAAM,UAAU,QAAQ,WAAW,OAAO;GAC1C,IAAI,SAAS,OAAO,QAAQ;EAC7B;EACA,MAAM,eAAe,KAAKA,UAAU,SAAS,MAAM,EAAE,YAAY,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC;EAC5F,MAAM,IAAI,MACT,iCAAiC,QAAQ,0BAA0B,aAAa,KAAK,IAAI,GAC1F;CACD;CAEA,mBACC,MACA,SACA,OACA,MACU;EAGV,IADgB,KAAK,qBAAqB,QAAQ,OAC9C,CAAA,EAAS,kBAAkB,OAC9B,OAAO;EAGR,IAAI,KAAKG,iBAAiB,MACzB,OAAO;EAER,IAAI,OAAO,KAAKA,iBAAiB,YAChC,OAAO,KAAKA,aAAa;GAAE;GAAM;GAAS;GAAO;EAAK,CAAC;EAExD,OAAO;CACR;CAEA,MAAM6B,gBACL,MACA,SACA,OACA,MACC;EAGD,OAAO,eAAe;GAAE;GAAM,QAFf,KAAKI,WAAW,QAAQ,OAET;GAAQ;GAAM,QAD7B,SAAS,0BAA0B,KAAKC,mBAAmB,KAAK,IAAI;EAChC,CAAC;CACrD;CAEA,gBACC,MACA,SACA,OACA,MAC+C;EAE/C,IAAI,KAAKN,YACR,OAAO,QAAQ,uBAAO,IAAI,MAAM,4BAA4B,CAAC;EAE9D,IAAI,KAAKO,mBAAmB,MAAM,SAAS,OAAO,IAAI,GACrD,OAAO,KAAKN,gBAAgB,MAAM,SAAS,OAAO,IAAI;EAKvD,IAAI,KAAKjB,iBACR,OAAO,QAAQ,uBAAO,IAAI,MAAM,uCAAuC,CAAC;EAGzE,OAAO,IAAI,SAAiB,SAAS,WAAW;GAC/C,KAAKA,kBAAkB;IACtB,IAAI,OAAO,WAAW;IACtB;IACA;IACA;IACA;IACS;IACT;GACD;GACA,KAAKkB,wBAAwB;EAC9B,CAAC;CACF;CAEA,uBAAqD,OAAO,UAAU;EACrE,OAAO,KAAKM,gBACX,yBACA,MAAM,SACN,MAAM,SAAS,eACf,MAAM,OACP;CACD;CAEA,mBAA6C,OAAO,UAAU;EAC7D,MAAM,SAAS,MAAM,MAAM,YAAY,OAAO;EAC9C,OAAO,KAAKA,gBAAgB,oBAAoB,MAAM,SAAS,MAAM,OAAO,MAAM;CACnF;CAEA,6BAAiE,OAAO,UAAU;EACjF,MAAM,SAAS,MAAM,MAAM,YAAY,OAAO;EAC9C,OAAO,KAAKA,gBAAgB,gCAAgC,MAAM,SAAS,MAAM,OAAO,MAAM;CAC/F;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initializer.d.mts","names":[],"sources":["../../src/wallet/initializer.ts"],"mappings":";;;;;;;;;
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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,
|
|
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"}
|