@mysten-incubation/dev-wallet 0.0.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/LICENSE +189 -0
  3. package/dist/_virtual/{_@oxc-project_runtime@0.107.0 → _@oxc-project_runtime@0.127.0}/helpers/decorate.mjs +2 -3
  4. package/dist/adapters/base-adapter.mjs +6 -7
  5. package/dist/adapters/base-adapter.mjs.map +1 -1
  6. package/dist/adapters/browser.d.mts +4 -1
  7. package/dist/adapters/browser.mjs +4 -2
  8. package/dist/adapters/build-managed-account.mjs +8 -10
  9. package/dist/adapters/build-managed-account.mjs.map +1 -1
  10. package/dist/adapters/devstack-adapter.d.mts +111 -0
  11. package/dist/adapters/devstack-adapter.d.mts.map +1 -0
  12. package/dist/adapters/devstack-adapter.mjs +224 -0
  13. package/dist/adapters/devstack-adapter.mjs.map +1 -0
  14. package/dist/adapters/devstack-paths.d.mts +11 -0
  15. package/dist/adapters/devstack-paths.d.mts.map +1 -0
  16. package/dist/adapters/devstack-paths.mjs +11 -0
  17. package/dist/adapters/devstack-paths.mjs.map +1 -0
  18. package/dist/adapters/fork-relay.d.mts +109 -0
  19. package/dist/adapters/fork-relay.d.mts.map +1 -0
  20. package/dist/adapters/fork-relay.mjs +208 -0
  21. package/dist/adapters/fork-relay.mjs.map +1 -0
  22. package/dist/adapters/idb-store.mjs +12 -16
  23. package/dist/adapters/idb-store.mjs.map +1 -1
  24. package/dist/adapters/in-memory-adapter.mjs +4 -10
  25. package/dist/adapters/in-memory-adapter.mjs.map +1 -1
  26. package/dist/adapters/passkey-adapter.mjs +4 -12
  27. package/dist/adapters/passkey-adapter.mjs.map +1 -1
  28. package/dist/adapters/remote-cli-adapter.mjs +37 -72
  29. package/dist/adapters/remote-cli-adapter.mjs.map +1 -1
  30. package/dist/adapters/webcrypto-adapter.mjs +2 -4
  31. package/dist/adapters/webcrypto-adapter.mjs.map +1 -1
  32. package/dist/bin/cli.mjs +9 -22
  33. package/dist/bin/cli.mjs.map +1 -1
  34. package/dist/client/dev-wallet-client.mjs +13 -28
  35. package/dist/client/dev-wallet-client.mjs.map +1 -1
  36. package/dist/client/index.mjs +1 -2
  37. package/dist/client/request-handler.mjs +36 -42
  38. package/dist/client/request-handler.mjs.map +1 -1
  39. package/dist/index.mjs +1 -2
  40. package/dist/react/components.d.mts +9 -9
  41. package/dist/react/components.d.mts.map +1 -1
  42. package/dist/react/components.mjs +2 -5
  43. package/dist/react/components.mjs.map +1 -1
  44. package/dist/react/context.d.mts +3 -3
  45. package/dist/react/context.d.mts.map +1 -1
  46. package/dist/react/context.mjs +3 -8
  47. package/dist/react/context.mjs.map +1 -1
  48. package/dist/react/index.mjs +1 -2
  49. package/dist/react/useDevWallet.d.mts +3 -0
  50. package/dist/react/useDevWallet.d.mts.map +1 -1
  51. package/dist/react/useDevWallet.mjs +9 -14
  52. package/dist/react/useDevWallet.mjs.map +1 -1
  53. package/dist/server/cli-signing-middleware.mjs +7 -20
  54. package/dist/server/cli-signing-middleware.mjs.map +1 -1
  55. package/dist/server/index.mjs +1 -2
  56. package/dist/standalone/assets/{in-memory-adapter-CBF4h2KD.js → in-memory-adapter-qRkNfj9O.js} +1 -1
  57. package/dist/standalone/assets/main-DDltQnzR.js +3954 -0
  58. package/dist/standalone/assets/{webcrypto-adapter-DysAubFb.js → webcrypto-adapter-FejcrL9x.js} +1 -1
  59. package/dist/standalone/index.html +11 -12
  60. package/dist/ui/copy-controller.mjs +3 -3
  61. package/dist/ui/copy-controller.mjs.map +1 -1
  62. package/dist/ui/dev-wallet-account-selector.d.mts +3 -4
  63. package/dist/ui/dev-wallet-account-selector.d.mts.map +1 -1
  64. package/dist/ui/dev-wallet-account-selector.mjs +48 -25
  65. package/dist/ui/dev-wallet-account-selector.mjs.map +1 -1
  66. package/dist/ui/dev-wallet-accounts.d.mts +9 -4
  67. package/dist/ui/dev-wallet-accounts.d.mts.map +1 -1
  68. package/dist/ui/dev-wallet-accounts.mjs +62 -140
  69. package/dist/ui/dev-wallet-accounts.mjs.map +1 -1
  70. package/dist/ui/dev-wallet-balances.d.mts +10 -3
  71. package/dist/ui/dev-wallet-balances.d.mts.map +1 -1
  72. package/dist/ui/dev-wallet-balances.mjs +241 -43
  73. package/dist/ui/dev-wallet-balances.mjs.map +1 -1
  74. package/dist/ui/dev-wallet-connect.d.mts +3 -3
  75. package/dist/ui/dev-wallet-connect.d.mts.map +1 -1
  76. package/dist/ui/dev-wallet-connect.mjs +24 -16
  77. package/dist/ui/dev-wallet-connect.mjs.map +1 -1
  78. package/dist/ui/dev-wallet-dropdown.d.mts +3 -3
  79. package/dist/ui/dev-wallet-dropdown.d.mts.map +1 -1
  80. package/dist/ui/dev-wallet-dropdown.mjs +37 -47
  81. package/dist/ui/dev-wallet-dropdown.mjs.map +1 -1
  82. package/dist/ui/dev-wallet-fork-panel.d.mts +43 -0
  83. package/dist/ui/dev-wallet-fork-panel.d.mts.map +1 -0
  84. package/dist/ui/dev-wallet-fork-panel.mjs +500 -0
  85. package/dist/ui/dev-wallet-fork-panel.mjs.map +1 -0
  86. package/dist/ui/dev-wallet-network-badge.d.mts +3 -4
  87. package/dist/ui/dev-wallet-network-badge.d.mts.map +1 -1
  88. package/dist/ui/dev-wallet-network-badge.mjs +52 -21
  89. package/dist/ui/dev-wallet-network-badge.mjs.map +1 -1
  90. package/dist/ui/dev-wallet-new-account.d.mts +3 -4
  91. package/dist/ui/dev-wallet-new-account.d.mts.map +1 -1
  92. package/dist/ui/dev-wallet-new-account.mjs +31 -105
  93. package/dist/ui/dev-wallet-new-account.mjs.map +1 -1
  94. package/dist/ui/dev-wallet-objects.d.mts +3 -3
  95. package/dist/ui/dev-wallet-objects.d.mts.map +1 -1
  96. package/dist/ui/dev-wallet-objects.mjs +76 -39
  97. package/dist/ui/dev-wallet-objects.mjs.map +1 -1
  98. package/dist/ui/dev-wallet-panel.d.mts +24 -4
  99. package/dist/ui/dev-wallet-panel.d.mts.map +1 -1
  100. package/dist/ui/dev-wallet-panel.mjs +247 -64
  101. package/dist/ui/dev-wallet-panel.mjs.map +1 -1
  102. package/dist/ui/dev-wallet-popup.d.mts +3 -5
  103. package/dist/ui/dev-wallet-popup.d.mts.map +1 -1
  104. package/dist/ui/dev-wallet-popup.mjs +19 -15
  105. package/dist/ui/dev-wallet-popup.mjs.map +1 -1
  106. package/dist/ui/dev-wallet-settings.d.mts +3 -4
  107. package/dist/ui/dev-wallet-settings.d.mts.map +1 -1
  108. package/dist/ui/dev-wallet-settings.mjs +149 -97
  109. package/dist/ui/dev-wallet-settings.mjs.map +1 -1
  110. package/dist/ui/dev-wallet-signing-modal.d.mts +11 -4
  111. package/dist/ui/dev-wallet-signing-modal.d.mts.map +1 -1
  112. package/dist/ui/dev-wallet-signing-modal.mjs +46 -18
  113. package/dist/ui/dev-wallet-signing-modal.mjs.map +1 -1
  114. package/dist/ui/dev-wallet-signing.d.mts +9 -3
  115. package/dist/ui/dev-wallet-signing.d.mts.map +1 -1
  116. package/dist/ui/dev-wallet-signing.mjs +119 -130
  117. package/dist/ui/dev-wallet-signing.mjs.map +1 -1
  118. package/dist/ui/dev-wallet-standalone.d.mts +8 -3
  119. package/dist/ui/dev-wallet-standalone.d.mts.map +1 -1
  120. package/dist/ui/dev-wallet-standalone.mjs +303 -38
  121. package/dist/ui/dev-wallet-standalone.mjs.map +1 -1
  122. package/dist/ui/dev-wallet-tab-bar.d.mts +13 -5
  123. package/dist/ui/dev-wallet-tab-bar.d.mts.map +1 -1
  124. package/dist/ui/dev-wallet-tab-bar.mjs +143 -82
  125. package/dist/ui/dev-wallet-tab-bar.mjs.map +1 -1
  126. package/dist/ui/index.d.mts +3 -2
  127. package/dist/ui/index.mjs +2 -2
  128. package/dist/ui/mount.d.mts +14 -1
  129. package/dist/ui/mount.d.mts.map +1 -1
  130. package/dist/ui/mount.mjs +5 -2
  131. package/dist/ui/mount.mjs.map +1 -1
  132. package/dist/ui/styles.mjs +428 -66
  133. package/dist/ui/styles.mjs.map +1 -1
  134. package/dist/ui/transaction-analyzer.mjs +19 -30
  135. package/dist/ui/transaction-analyzer.mjs.map +1 -1
  136. package/dist/ui/utils.d.mts +59 -0
  137. package/dist/ui/utils.d.mts.map +1 -0
  138. package/dist/ui/utils.mjs +42 -15
  139. package/dist/ui/utils.mjs.map +1 -1
  140. package/dist/ui/wallet-controller.mjs +89 -20
  141. package/dist/ui/wallet-controller.mjs.map +1 -1
  142. package/dist/wallet/constants.d.mts +9 -0
  143. package/dist/wallet/constants.d.mts.map +1 -0
  144. package/dist/wallet/constants.mjs +1 -1
  145. package/dist/wallet/dev-wallet.mjs +42 -99
  146. package/dist/wallet/dev-wallet.mjs.map +1 -1
  147. package/dist/wallet/initializer.d.mts +3 -0
  148. package/dist/wallet/initializer.d.mts.map +1 -1
  149. package/dist/wallet/initializer.mjs +9 -14
  150. package/dist/wallet/initializer.mjs.map +1 -1
  151. package/dist/wallet/signing.mjs +8 -21
  152. package/dist/wallet/signing.mjs.map +1 -1
  153. package/package.json +8 -6
  154. package/src/adapters/browser.ts +21 -0
  155. package/src/adapters/devstack-adapter.ts +342 -0
  156. package/src/adapters/devstack-paths.ts +15 -0
  157. package/src/adapters/fork-relay.ts +321 -0
  158. package/src/app/index.html +10 -11
  159. package/src/react/useDevWallet.ts +5 -1
  160. package/src/ui/dev-wallet-account-selector.ts +44 -17
  161. package/src/ui/dev-wallet-accounts.ts +87 -124
  162. package/src/ui/dev-wallet-balances.ts +248 -27
  163. package/src/ui/dev-wallet-connect.ts +19 -8
  164. package/src/ui/dev-wallet-dropdown.ts +7 -5
  165. package/src/ui/dev-wallet-fork-panel.ts +591 -0
  166. package/src/ui/dev-wallet-network-badge.ts +49 -10
  167. package/src/ui/dev-wallet-new-account.ts +21 -62
  168. package/src/ui/dev-wallet-objects.ts +59 -19
  169. package/src/ui/dev-wallet-panel.ts +261 -42
  170. package/src/ui/dev-wallet-popup.ts +12 -6
  171. package/src/ui/dev-wallet-settings.ts +159 -94
  172. package/src/ui/dev-wallet-signing-modal.ts +47 -7
  173. package/src/ui/dev-wallet-signing.ts +124 -97
  174. package/src/ui/dev-wallet-standalone.ts +310 -22
  175. package/src/ui/dev-wallet-tab-bar.ts +132 -70
  176. package/src/ui/index.ts +3 -0
  177. package/src/ui/mount.ts +23 -1
  178. package/src/ui/styles.ts +434 -58
  179. package/src/ui/utils.ts +66 -0
  180. package/src/ui/wallet-controller.ts +103 -5
  181. package/src/wallet/initializer.ts +7 -1
  182. package/dist/standalone/assets/main-VE4olb-Q.js +0 -2841
package/src/ui/utils.ts CHANGED
@@ -31,6 +31,59 @@ export function getCoinSymbol(coinType: string): string {
31
31
  }
32
32
  }
33
33
 
34
+ /**
35
+ * Subset of the generated `coins.ts` entry shape that the UI needs for
36
+ * formatting and labelling. Matches the manifest `CoinEntry` shape emitted
37
+ * by `StackHandleEmitter` (`coins.ts`) so consumers can pass the generated
38
+ * `coins` record directly. Kept structurally-typed (no devstack import —
39
+ * dev-wallet must not depend on the devstack package).
40
+ */
41
+ export interface CoinManifestEntry {
42
+ readonly type: string;
43
+ readonly decimals: number;
44
+ readonly symbol?: string;
45
+ readonly displayName?: string;
46
+ readonly iconUrl?: string;
47
+ }
48
+
49
+ /** A record keyed by coin name (e.g. `'mUSDC'`) mapping to entry metadata.
50
+ * Pass the generated `coins` constant — `<DevWalletPanel coins={coins} />`
51
+ * — to pre-seed UI metadata and skip per-coin RPC fetches on UI load. */
52
+ export type CoinRecord = Readonly<Record<string, CoinManifestEntry>>;
53
+
54
+ /** Build a fast `coinType → entry` lookup from the name-keyed generated
55
+ * record. Normalizes coin-type strings so callers can hit it with either
56
+ * the short (`0x2::sui::SUI`) or fully-padded form. */
57
+ export function indexCoinsByType(
58
+ coins: CoinRecord | null | undefined,
59
+ ): ReadonlyMap<string, CoinManifestEntry> {
60
+ const map = new Map<string, CoinManifestEntry>();
61
+ if (!coins) return map;
62
+ for (const entry of Object.values(coins)) {
63
+ try {
64
+ map.set(normalizeStructTag(entry.type), entry);
65
+ } catch {
66
+ map.set(entry.type, entry);
67
+ }
68
+ }
69
+ return map;
70
+ }
71
+
72
+ /** Look up a coin's metadata by its on-chain type string. Both the input
73
+ * `coinType` and the index entries are matched on their normalized form
74
+ * so callers don't have to canonicalize. Returns `undefined` for unknown
75
+ * coins — the caller decides whether to fall back to an RPC fetch. */
76
+ export function lookupCoinByType(
77
+ index: ReadonlyMap<string, CoinManifestEntry>,
78
+ coinType: string,
79
+ ): CoinManifestEntry | undefined {
80
+ try {
81
+ return index.get(normalizeStructTag(coinType));
82
+ } catch {
83
+ return index.get(coinType);
84
+ }
85
+ }
86
+
34
87
  /** Check if a type string is a Coin wrapper (0x2::coin::Coin<...>) */
35
88
  export function isCoinType(type: string): boolean {
36
89
  try {
@@ -63,8 +116,21 @@ export const NETWORK_COLORS: Record<string, string> = {
63
116
  testnet: '#22c55e',
64
117
  devnet: '#3b82f6',
65
118
  localnet: '#6b7280',
119
+ // Fork variants render an amber stripe so the operator can't mistake
120
+ // a forked stack for the real upstream at a glance. Same hue family
121
+ // as the mainnet orange but pushed warmer/yellower for contrast.
122
+ 'mainnet-fork': '#eab308',
123
+ 'testnet-fork': '#eab308',
124
+ 'devnet-fork': '#eab308',
66
125
  };
67
126
 
127
+ /** Returns true when the network literal names a fork-mode runtime.
128
+ * Used by the badge + accounts panel + signing modal to surface the
129
+ * "no real chain" caveat — Phase 4 P4.17-P4.20. */
130
+ export function isForkNetwork(network: string): boolean {
131
+ return network.endsWith('-fork');
132
+ }
133
+
68
134
  export interface PairableAdapter {
69
135
  readonly isPaired: boolean;
70
136
  }
@@ -6,6 +6,7 @@ import type { ReadonlyWalletAccount } from '@mysten/wallet-standard';
6
6
  import { html, nothing } from 'lit';
7
7
  import type { ReactiveController, ReactiveControllerHost } from 'lit';
8
8
 
9
+ import type { ForkRelay } from '../adapters/fork-relay.js';
9
10
  import { getNetworkFromChain } from '../wallet/constants.js';
10
11
  import type {
11
12
  DevWallet,
@@ -15,12 +16,15 @@ import type {
15
16
  import './dev-wallet-account-selector.js';
16
17
  import './dev-wallet-balances.js';
17
18
  import './dev-wallet-connect.js';
19
+ import './dev-wallet-fork-panel.js';
18
20
  import './dev-wallet-network-badge.js';
19
21
  import './dev-wallet-objects.js';
20
22
  import './dev-wallet-settings.js';
21
23
  import './dev-wallet-signing-modal.js';
22
24
  import type { TabId } from './dev-wallet-tab-bar.js';
23
25
  import './dev-wallet-tab-bar.js';
26
+ import type { CoinRecord } from './utils.js';
27
+ import { isForkNetwork } from './utils.js';
24
28
 
25
29
  /**
26
30
  * Lit Reactive Controller that encapsulates all shared wallet management logic
@@ -38,6 +42,20 @@ export class WalletController implements ReactiveController {
38
42
  pendingRequest: PendingSigningRequest | null = null;
39
43
  pendingConnect: PendingConnectRequest | null = null;
40
44
  bookmarkletOrigin = '';
45
+ /** Pre-seeded coin metadata (typically the generated `coins` constant from
46
+ * devstack codegen). Forwarded to `<dev-wallet-balances>` and the
47
+ * signing modal so they can skip per-coin RPC waterfalls. */
48
+ coins: CoinRecord | null = null;
49
+ /** Phase 5 Subtopic 6 — when set, the controller surfaces a Fork
50
+ * tab and binds it to this relay. The hosting custom element
51
+ * (`dev-wallet-panel`) constructs the relay from the manifest's
52
+ * wallet endpoint and pipes it through as a property. */
53
+ forkRelay: ForkRelay | null = null;
54
+ /** Upstream label (`'mainnet'`, etc.) sourced from the manifest. Used
55
+ * by the fork panel banner and by `renderTabBar` to decide whether
56
+ * to render the Fork tab. Falls back to inferring from the active
57
+ * network literal (`'*-fork'`) when not provided. */
58
+ forkUpstream = '';
41
59
 
42
60
  #wallet: DevWallet | null = null;
43
61
  #unsubscribeEvents: (() => void) | null = null;
@@ -210,6 +228,8 @@ export class WalletController implements ReactiveController {
210
228
  exportparts="balance-list, loading: balances-loading, error-message: balances-error-message, empty-state: balances-empty-state"
211
229
  .address=${this.activeAddress}
212
230
  .client=${this.getActiveClient()}
231
+ .network=${this.#wallet.activeNetwork}
232
+ .coins=${this.coins}
213
233
  ></dev-wallet-balances>
214
234
  </div>
215
235
  `
@@ -220,11 +240,17 @@ export class WalletController implements ReactiveController {
220
240
  renderObjectsTab() {
221
241
  return html`
222
242
  ${this.renderAccountSelector()}
223
- <dev-wallet-objects
224
- exportparts="object-list, loading: objects-loading, error-message: objects-error-message, empty-state: objects-empty-state, load-more-button"
225
- .address=${this.activeAddress}
226
- .client=${this.getActiveClient()}
227
- ></dev-wallet-objects>
243
+ ${this.activeAddress && this.#wallet
244
+ ? html`
245
+ <div class="section">
246
+ <dev-wallet-objects
247
+ exportparts="object-list, loading: objects-loading, error-message: objects-error-message, empty-state: objects-empty-state, load-more-button"
248
+ .address=${this.activeAddress}
249
+ .client=${this.getActiveClient()}
250
+ ></dev-wallet-objects>
251
+ </div>
252
+ `
253
+ : nothing}
228
254
  `;
229
255
  }
230
256
 
@@ -242,13 +268,61 @@ export class WalletController implements ReactiveController {
242
268
  `;
243
269
  }
244
270
 
271
+ renderForkTab() {
272
+ // Defence-in-depth: the tab itself is hidden unless `#isForkMode`
273
+ // returns true, but render-time we re-check so direct
274
+ // `activeTab = 'fork'` writes don't end up rendering the panel
275
+ // against a bundled-mode stack.
276
+ if (!this.#isForkMode()) return nothing;
277
+ return html`
278
+ <dev-wallet-fork-panel
279
+ exportparts="
280
+ fork-banner,
281
+ status-grid,
282
+ status-checkpoint,
283
+ status-clock,
284
+ status-clock-iso,
285
+ status-auto-tick,
286
+ status-loading,
287
+ status-error,
288
+ status-empty,
289
+ advance-clock-input,
290
+ advance-clock-button,
291
+ advance-checkpoint-input,
292
+ advance-checkpoint-button,
293
+ action-error,
294
+ slot-list,
295
+ slot-item,
296
+ slot-item-active,
297
+ slot-toggle,
298
+ slots-empty,
299
+ slots-error,
300
+ empty-state
301
+ "
302
+ .relay=${this.forkRelay}
303
+ .upstream=${this.#resolveUpstreamLabel()}
304
+ @fork-impersonation-changed=${(e: CustomEvent) => this.handleForkImpersonationChanged(e)}
305
+ ></dev-wallet-fork-panel>
306
+ `;
307
+ }
308
+
245
309
  renderTabContent() {
246
310
  if (this.activeTab === 'assets') return this.renderAssetsTab();
247
311
  if (this.activeTab === 'objects') return this.renderObjectsTab();
312
+ if (this.activeTab === 'fork') return this.renderForkTab();
248
313
  if (this.activeTab === 'settings') return this.renderSettingsTab();
249
314
  return nothing;
250
315
  }
251
316
 
317
+ handleForkImpersonationChanged(_e: CustomEvent): void {
318
+ // Slot changes can affect the impersonation banner in the signing
319
+ // modal (Phase 4 P4.19), so request a re-render. The actual flag
320
+ // flip happens in the signing-modal's own derivation from
321
+ // `account.source`, which the devstack adapter updates when the
322
+ // server-side toggle resolves.
323
+ this.host.requestUpdate();
324
+ }
325
+
252
326
  renderSigningModal() {
253
327
  if (!this.pendingRequest) return nothing;
254
328
 
@@ -257,6 +331,7 @@ export class WalletController implements ReactiveController {
257
331
  exportparts="signing-approve-button, signing-reject-button, signing-request-type, signing-empty-state, signing-error-message, signing-footer, dialog: signing-dialog"
258
332
  .request=${this.pendingRequest}
259
333
  .client=${this.getActiveClient()}
334
+ .coins=${this.coins}
260
335
  .walletName=${this.#wallet?.name ?? 'Dev Wallet'}
261
336
  @approve=${() => this.handleApprove()}
262
337
  @reject=${() => this.handleReject()}
@@ -309,11 +384,34 @@ export class WalletController implements ReactiveController {
309
384
  <dev-wallet-tab-bar
310
385
  exportparts="tab-bar, tab"
311
386
  .active=${this.activeTab}
387
+ .showFork=${this.#isForkMode()}
312
388
  @tab-changed=${(e: CustomEvent) => this.handleTabChanged(e)}
313
389
  ></dev-wallet-tab-bar>
314
390
  `;
315
391
  }
316
392
 
393
+ /** Phase 5 Subtopic 6 (P5.8.5) — the Fork tab + panel render only
394
+ * when the active stack is in fork mode. Two signals satisfy that:
395
+ * 1. The host passed in a `ForkRelay` (built from the manifest's
396
+ * wallet endpoint — devstack only constructs one when
397
+ * `meta.runtime === 'forked'`).
398
+ * 2. The active network literal ends in `-fork` (catch-all for
399
+ * when the relay is wired but the user switched to a
400
+ * non-fork network from the badge dropdown).
401
+ * Both signals must agree — otherwise the tab is hidden. */
402
+ #isForkMode(): boolean {
403
+ if (this.forkRelay === null) return false;
404
+ const active = this.#wallet?.activeNetwork;
405
+ if (!active) return false;
406
+ return isForkNetwork(active);
407
+ }
408
+
409
+ #resolveUpstreamLabel(): string {
410
+ if (this.forkUpstream !== '') return this.forkUpstream;
411
+ const active = this.#wallet?.activeNetwork ?? '';
412
+ return active.endsWith('-fork') ? active.replace(/-fork$/, '') : '';
413
+ }
414
+
317
415
  // ── Subscriptions ───────────────────────────────────────────────────────
318
416
 
319
417
  #subscribe(): void {
@@ -4,6 +4,7 @@
4
4
  import type { ClientWithCoreApi } from '@mysten/sui/client';
5
5
  import type { WalletIcon } from '@mysten/wallet-standard';
6
6
 
7
+ import type { DevWalletDockStyle } from '../ui/dev-wallet-panel.js';
7
8
  import type { SignerAdapter } from '../types.js';
8
9
  import { DevWallet, type AutoApprovePolicy } from './dev-wallet.js';
9
10
 
@@ -24,6 +25,8 @@ export interface DevWalletInitializerConfig {
24
25
  createInitialAccount?: boolean;
25
26
  /** Mount the floating wallet drawer UI. Defaults to false. */
26
27
  mountUI?: boolean;
28
+ /** Floating dock presentation when `mountUI` is true. Defaults to `corner-pill`. */
29
+ dockStyle?: DevWalletDockStyle;
27
30
  /** Container element for the UI drawer. Defaults to document.body. */
28
31
  container?: HTMLElement;
29
32
  /** Called with the DevWallet instance after creation. */
@@ -108,7 +111,10 @@ export function devWalletInitializer(config: DevWalletInitializerConfig): {
108
111
  let unmountUI: (() => void) | undefined;
109
112
  if (mountUI && typeof document !== 'undefined') {
110
113
  const { mountDevWallet } = await import('../ui/mount.js');
111
- unmountUI = mountDevWallet(wallet, { container: config.container });
114
+ unmountUI = mountDevWallet(wallet, {
115
+ container: config.container,
116
+ dockStyle: config.dockStyle,
117
+ });
112
118
  }
113
119
 
114
120
  const unregister = wallet.register();