@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
@@ -1,13 +1,10 @@
1
1
  import { analyze, analyzers } from "@mysten/wallet-sdk";
2
-
3
2
  //#region src/ui/transaction-analyzer.ts
4
3
  async function analyzeTransaction(txData, client) {
5
- if (!client) {
6
- return {
7
- kind: "error",
8
- message: "No client available to analyze transaction"
9
- };
10
- }
4
+ if (!client) return {
5
+ kind: "error",
6
+ message: "No client available to analyze transaction"
7
+ };
11
8
  try {
12
9
  const result = await analyze({
13
10
  commands: analyzers.commands,
@@ -16,22 +13,18 @@ async function analyzeTransaction(txData, client) {
16
13
  client,
17
14
  transaction: txData
18
15
  });
19
- if (result.commands.result) {
20
- return {
21
- kind: "rich",
22
- analysis: {
23
- commands: result.commands.result,
24
- coinFlows: result.coinFlows.result?.outflows ?? null
25
- }
26
- };
27
- }
16
+ if (result.commands.result) return {
17
+ kind: "rich",
18
+ analysis: {
19
+ commands: result.commands.result,
20
+ coinFlows: result.coinFlows.result?.outflows ?? null
21
+ }
22
+ };
28
23
  const issues = result.commands.issues ?? result.coinFlows.issues ?? [];
29
- if (issues.length > 0) {
30
- return {
31
- kind: "error",
32
- message: issues.map((i) => i.message).join("\n")
33
- };
34
- }
24
+ if (issues.length > 0) return {
25
+ kind: "error",
26
+ message: issues.map((i) => i.message).join("\n")
27
+ };
35
28
  return {
36
29
  kind: "error",
37
30
  message: "Transaction analysis returned no results"
@@ -39,20 +32,16 @@ async function analyzeTransaction(txData, client) {
39
32
  } catch (e) {
40
33
  const raw = e instanceof Error ? e.message : String(e);
41
34
  let message;
42
- if (raw.includes("fetch") || raw.includes("network") || raw.includes("ECONNREFUSED")) {
43
- message = `Network error: ${raw}`;
44
- } else if (raw.includes("deserialize") || raw.includes("BCS") || raw.includes("parse")) {
45
- message = `Invalid transaction data: ${raw}`;
46
- } else {
47
- message = raw;
48
- }
35
+ if (raw.includes("fetch") || raw.includes("network") || raw.includes("ECONNREFUSED")) message = `Network error: ${raw}`;
36
+ else if (raw.includes("deserialize") || raw.includes("BCS") || raw.includes("parse")) message = `Invalid transaction data: ${raw}`;
37
+ else message = raw;
49
38
  return {
50
39
  kind: "error",
51
40
  message
52
41
  };
53
42
  }
54
43
  }
55
-
56
44
  //#endregion
57
45
  export { analyzeTransaction };
46
+
58
47
  //# sourceMappingURL=transaction-analyzer.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-analyzer.mjs","names":[],"sources":["../../src/ui/transaction-analyzer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport type { AnalyzedCommand, CoinFlow } from '@mysten/wallet-sdk';\nimport { analyze, analyzers } from '@mysten/wallet-sdk';\n\nexport interface TransactionAnalysis {\n\tcommands: AnalyzedCommand[];\n\tcoinFlows: CoinFlow[] | null;\n}\n\ntype AnalysisResult =\n\t| { kind: 'rich'; analysis: TransactionAnalysis }\n\t| { kind: 'error'; message: string };\n\nexport async function analyzeTransaction(\n\ttxData: string,\n\tclient?: ClientWithCoreApi | null,\n): Promise<AnalysisResult> {\n\tif (!client) {\n\t\treturn { kind: 'error', message: 'No client available to analyze transaction' };\n\t}\n\n\ttry {\n\t\tconst result = await analyze(\n\t\t\t{ commands: analyzers.commands, coinFlows: analyzers.coinFlows },\n\t\t\t{ client, transaction: txData },\n\t\t);\n\t\tif (result.commands.result) {\n\t\t\treturn {\n\t\t\t\tkind: 'rich',\n\t\t\t\tanalysis: {\n\t\t\t\t\tcommands: result.commands.result,\n\t\t\t\t\tcoinFlows: result.coinFlows.result?.outflows ?? null,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst issues = result.commands.issues ?? result.coinFlows.issues ?? [];\n\t\tif (issues.length > 0) {\n\t\t\treturn {\n\t\t\t\tkind: 'error',\n\t\t\t\tmessage: issues.map((i: { message: string }) => i.message).join('\\n'),\n\t\t\t};\n\t\t}\n\t\treturn { kind: 'error', message: 'Transaction analysis returned no results' };\n\t} catch (e) {\n\t\tconst raw = e instanceof Error ? e.message : String(e);\n\t\tlet message: string;\n\t\tif (raw.includes('fetch') || raw.includes('network') || raw.includes('ECONNREFUSED')) {\n\t\t\tmessage = `Network error: ${raw}`;\n\t\t} else if (raw.includes('deserialize') || raw.includes('BCS') || raw.includes('parse')) {\n\t\t\tmessage = `Invalid transaction data: ${raw}`;\n\t\t} else {\n\t\t\tmessage = raw;\n\t\t}\n\t\treturn { kind: 'error', message };\n\t}\n}\n"],"mappings":";;;AAgBA,eAAsB,mBACrB,QACA,QAC0B;AAC1B,KAAI,CAAC,QAAQ;AACZ,SAAO;GAAE,MAAM;GAAS,SAAS;GAA8C;;AAGhF,KAAI;EACH,MAAM,SAAS,MAAM,QACpB;GAAE,UAAU,UAAU;GAAU,WAAW,UAAU;GAAW,EAChE;GAAE;GAAQ,aAAa;GAAQ,CAC/B;AACD,MAAI,OAAO,SAAS,QAAQ;AAC3B,UAAO;IACN,MAAM;IACN,UAAU;KACT,UAAU,OAAO,SAAS;KAC1B,WAAW,OAAO,UAAU,QAAQ,YAAY;KAChD;IACD;;EAGF,MAAM,SAAS,OAAO,SAAS,UAAU,OAAO,UAAU,UAAU,EAAE;AACtE,MAAI,OAAO,SAAS,GAAG;AACtB,UAAO;IACN,MAAM;IACN,SAAS,OAAO,KAAK,MAA2B,EAAE,QAAQ,CAAC,KAAK,KAAK;IACrE;;AAEF,SAAO;GAAE,MAAM;GAAS,SAAS;GAA4C;UACrE,GAAG;EACX,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;EACtD,IAAI;AACJ,MAAI,IAAI,SAAS,QAAQ,IAAI,IAAI,SAAS,UAAU,IAAI,IAAI,SAAS,eAAe,EAAE;AACrF,aAAU,kBAAkB;aAClB,IAAI,SAAS,cAAc,IAAI,IAAI,SAAS,MAAM,IAAI,IAAI,SAAS,QAAQ,EAAE;AACvF,aAAU,6BAA6B;SACjC;AACN,aAAU;;AAEX,SAAO;GAAE,MAAM;GAAS;GAAS"}
1
+ {"version":3,"file":"transaction-analyzer.mjs","names":[],"sources":["../../src/ui/transaction-analyzer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\nimport type { AnalyzedCommand, CoinFlow } from '@mysten/wallet-sdk';\nimport { analyze, analyzers } from '@mysten/wallet-sdk';\n\nexport interface TransactionAnalysis {\n\tcommands: AnalyzedCommand[];\n\tcoinFlows: CoinFlow[] | null;\n}\n\ntype AnalysisResult =\n\t| { kind: 'rich'; analysis: TransactionAnalysis }\n\t| { kind: 'error'; message: string };\n\nexport async function analyzeTransaction(\n\ttxData: string,\n\tclient?: ClientWithCoreApi | null,\n): Promise<AnalysisResult> {\n\tif (!client) {\n\t\treturn { kind: 'error', message: 'No client available to analyze transaction' };\n\t}\n\n\ttry {\n\t\tconst result = await analyze(\n\t\t\t{ commands: analyzers.commands, coinFlows: analyzers.coinFlows },\n\t\t\t{ client, transaction: txData },\n\t\t);\n\t\tif (result.commands.result) {\n\t\t\treturn {\n\t\t\t\tkind: 'rich',\n\t\t\t\tanalysis: {\n\t\t\t\t\tcommands: result.commands.result,\n\t\t\t\t\tcoinFlows: result.coinFlows.result?.outflows ?? null,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst issues = result.commands.issues ?? result.coinFlows.issues ?? [];\n\t\tif (issues.length > 0) {\n\t\t\treturn {\n\t\t\t\tkind: 'error',\n\t\t\t\tmessage: issues.map((i: { message: string }) => i.message).join('\\n'),\n\t\t\t};\n\t\t}\n\t\treturn { kind: 'error', message: 'Transaction analysis returned no results' };\n\t} catch (e) {\n\t\tconst raw = e instanceof Error ? e.message : String(e);\n\t\tlet message: string;\n\t\tif (raw.includes('fetch') || raw.includes('network') || raw.includes('ECONNREFUSED')) {\n\t\t\tmessage = `Network error: ${raw}`;\n\t\t} else if (raw.includes('deserialize') || raw.includes('BCS') || raw.includes('parse')) {\n\t\t\tmessage = `Invalid transaction data: ${raw}`;\n\t\t} else {\n\t\t\tmessage = raw;\n\t\t}\n\t\treturn { kind: 'error', message };\n\t}\n}\n"],"mappings":";;AAgBA,eAAsB,mBACrB,QACA,QAC0B;AAC1B,KAAI,CAAC,OACJ,QAAO;EAAE,MAAM;EAAS,SAAS;EAA8C;AAGhF,KAAI;EACH,MAAM,SAAS,MAAM,QACpB;GAAE,UAAU,UAAU;GAAU,WAAW,UAAU;GAAW,EAChE;GAAE;GAAQ,aAAa;GAAQ,CAC/B;AACD,MAAI,OAAO,SAAS,OACnB,QAAO;GACN,MAAM;GACN,UAAU;IACT,UAAU,OAAO,SAAS;IAC1B,WAAW,OAAO,UAAU,QAAQ,YAAY;IAChD;GACD;EAGF,MAAM,SAAS,OAAO,SAAS,UAAU,OAAO,UAAU,UAAU,EAAE;AACtE,MAAI,OAAO,SAAS,EACnB,QAAO;GACN,MAAM;GACN,SAAS,OAAO,KAAK,MAA2B,EAAE,QAAQ,CAAC,KAAK,KAAK;GACrE;AAEF,SAAO;GAAE,MAAM;GAAS,SAAS;GAA4C;UACrE,GAAG;EACX,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;EACtD,IAAI;AACJ,MAAI,IAAI,SAAS,QAAQ,IAAI,IAAI,SAAS,UAAU,IAAI,IAAI,SAAS,eAAe,CACnF,WAAU,kBAAkB;WAClB,IAAI,SAAS,cAAc,IAAI,IAAI,SAAS,MAAM,IAAI,IAAI,SAAS,QAAQ,CACrF,WAAU,6BAA6B;MAEvC,WAAU;AAEX,SAAO;GAAE,MAAM;GAAS;GAAS"}
@@ -0,0 +1,59 @@
1
+ //#region src/ui/utils.d.ts
2
+ declare function isSuiCoinType(coinType: string): boolean;
3
+ declare function formatAddress(address: string): string;
4
+ declare function getCoinSymbol(coinType: string): string;
5
+ /**
6
+ * Subset of the generated `coins.ts` entry shape that the UI needs for
7
+ * formatting and labelling. Matches the manifest `CoinEntry` shape emitted
8
+ * by `StackHandleEmitter` (`coins.ts`) so consumers can pass the generated
9
+ * `coins` record directly. Kept structurally-typed (no devstack import —
10
+ * dev-wallet must not depend on the devstack package).
11
+ */
12
+ interface CoinManifestEntry {
13
+ readonly type: string;
14
+ readonly decimals: number;
15
+ readonly symbol?: string;
16
+ readonly displayName?: string;
17
+ readonly iconUrl?: string;
18
+ }
19
+ /** A record keyed by coin name (e.g. `'mUSDC'`) mapping to entry metadata.
20
+ * Pass the generated `coins` constant — `<DevWalletPanel coins={coins} />`
21
+ * — to pre-seed UI metadata and skip per-coin RPC fetches on UI load. */
22
+ type CoinRecord = Readonly<Record<string, CoinManifestEntry>>;
23
+ /** Build a fast `coinType → entry` lookup from the name-keyed generated
24
+ * record. Normalizes coin-type strings so callers can hit it with either
25
+ * the short (`0x2::sui::SUI`) or fully-padded form. */
26
+ declare function indexCoinsByType(coins: CoinRecord | null | undefined): ReadonlyMap<string, CoinManifestEntry>;
27
+ /** Look up a coin's metadata by its on-chain type string. Both the input
28
+ * `coinType` and the index entries are matched on their normalized form
29
+ * so callers don't have to canonicalize. Returns `undefined` for unknown
30
+ * coins — the caller decides whether to fall back to an RPC fetch. */
31
+ declare function lookupCoinByType(index: ReadonlyMap<string, CoinManifestEntry>, coinType: string): CoinManifestEntry | undefined;
32
+ /** Check if a type string is a Coin wrapper (0x2::coin::Coin<...>) */
33
+ declare function isCoinType(type: string): boolean;
34
+ /** Extract the short struct name from a full Move type string */
35
+ declare function getTypeName(type: string): string;
36
+ declare function copyToClipboard(text: string): Promise<boolean>;
37
+ declare const NETWORK_COLORS: Record<string, string>;
38
+ /** Returns true when the network literal names a fork-mode runtime.
39
+ * Used by the badge + accounts panel + signing modal to surface the
40
+ * "no real chain" caveat — Phase 4 P4.17-P4.20. */
41
+ declare function isForkNetwork(network: string): boolean;
42
+ interface PairableAdapter {
43
+ readonly isPaired: boolean;
44
+ }
45
+ declare function isPairableAdapter(adapter: unknown): adapter is PairableAdapter;
46
+ /** Dispatch a composed, bubbling custom event from a host element. */
47
+ declare function emitEvent(host: HTMLElement, name: string, detail?: unknown): void;
48
+ /** Clone a Set and toggle an item in/out of it. */
49
+ declare function toggleSetItem<T>(set: Set<T>, item: T): Set<T>;
50
+ /** Extract a user-facing error message, with a fallback for non-Error throws. */
51
+ declare function getErrorMessage(error: unknown, fallback: string): string;
52
+ /** Find the adapter that owns a given address. */
53
+ declare function findAdapterForAddress<T extends {
54
+ getAccount(address: string): unknown;
55
+ }>(adapters: readonly T[], address: string): T | undefined;
56
+ declare function formatCoinBalance(balance: string | bigint, decimals: number): string;
57
+ //#endregion
58
+ export { CoinRecord };
59
+ //# sourceMappingURL=utils.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.mts","names":[],"sources":["../../src/ui/utils.ts"],"mappings":";iBAWgB,aAAA,CAAc,QAAA;AAAA,iBAQd,aAAA,CAAc,OAAA;AAAA,iBAKd,aAAA,CAAc,QAAA;AAb9B;;;;;AAQA;;AARA,UA6BiB,iBAAA;EAAA,SACP,IAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA;AAAA;;AALV;;KAWY,UAAA,GAAa,QAAA,CAAS,MAAA,SAAe,iBAAA;;;;iBAKjC,gBAAA,CACf,KAAA,EAAO,UAAA,sBACL,WAAA,SAAoB,iBAAA;;;;;iBAiBP,gBAAA,CACf,KAAA,EAAO,WAAA,SAAoB,iBAAA,GAC3B,QAAA,WACE,iBAAA;;iBASa,UAAA,CAAW,IAAA;;iBASX,WAAA,CAAY,IAAA;AAAA,iBAQN,eAAA,CAAgB,IAAA,WAAe,OAAA;AAAA,cASxC,cAAA,EAAgB,MAAA;;;;iBAgBb,aAAA,CAAc,OAAA;AAAA,UAIb,eAAA;EAAA,SACP,QAAA;AAAA;AAAA,iBAGM,iBAAA,CAAkB,OAAA,YAAmB,OAAA,IAAW,eAAA;;iBAKhD,SAAA,CAAU,IAAA,EAAM,WAAA,EAAa,IAAA,UAAc,MAAA;;iBAK3C,aAAA,GAAA,CAAiB,GAAA,EAAK,GAAA,CAAI,CAAA,GAAI,IAAA,EAAM,CAAA,GAAI,GAAA,CAAI,CAAA;;iBAW5C,eAAA,CAAgB,KAAA,WAAgB,QAAA;;iBAOhC,qBAAA;EAAkC,UAAA,CAAW,OAAA;AAAA,EAAA,CAC5D,QAAA,WAAmB,CAAA,IACnB,OAAA,WACE,CAAA;AAAA,iBAIa,iBAAA,CAAkB,OAAA,mBAA0B,QAAA"}
package/dist/ui/utils.mjs CHANGED
@@ -1,6 +1,5 @@
1
- import { getNetworkFromChain } from "../wallet/constants.mjs";
1
+ import "../wallet/constants.mjs";
2
2
  import { normalizeStructTag, parseStructTag } from "@mysten/sui/utils";
3
-
4
3
  //#region src/ui/utils.ts
5
4
  const NORMALIZED_SUI_COIN_TYPE = "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI";
6
5
  const NORMALIZED_COIN_PREFIX = "0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<";
@@ -17,12 +16,35 @@ function formatAddress(address) {
17
16
  }
18
17
  function getCoinSymbol(coinType) {
19
18
  try {
20
- const tag = parseStructTag(coinType);
21
- return tag.name;
19
+ return parseStructTag(coinType).name;
22
20
  } catch {
23
21
  return coinType;
24
22
  }
25
23
  }
24
+ /** Build a fast `coinType → entry` lookup from the name-keyed generated
25
+ * record. Normalizes coin-type strings so callers can hit it with either
26
+ * the short (`0x2::sui::SUI`) or fully-padded form. */
27
+ function indexCoinsByType(coins) {
28
+ const map = /* @__PURE__ */ new Map();
29
+ if (!coins) return map;
30
+ for (const entry of Object.values(coins)) try {
31
+ map.set(normalizeStructTag(entry.type), entry);
32
+ } catch {
33
+ map.set(entry.type, entry);
34
+ }
35
+ return map;
36
+ }
37
+ /** Look up a coin's metadata by its on-chain type string. Both the input
38
+ * `coinType` and the index entries are matched on their normalized form
39
+ * so callers don't have to canonicalize. Returns `undefined` for unknown
40
+ * coins — the caller decides whether to fall back to an RPC fetch. */
41
+ function lookupCoinByType(index, coinType) {
42
+ try {
43
+ return index.get(normalizeStructTag(coinType));
44
+ } catch {
45
+ return index.get(coinType);
46
+ }
47
+ }
26
48
  /** Check if a type string is a Coin wrapper (0x2::coin::Coin<...>) */
27
49
  function isCoinType(type) {
28
50
  try {
@@ -51,8 +73,17 @@ const NETWORK_COLORS = {
51
73
  mainnet: "#f97316",
52
74
  testnet: "#22c55e",
53
75
  devnet: "#3b82f6",
54
- localnet: "#6b7280"
76
+ localnet: "#6b7280",
77
+ "mainnet-fork": "#eab308",
78
+ "testnet-fork": "#eab308",
79
+ "devnet-fork": "#eab308"
55
80
  };
81
+ /** Returns true when the network literal names a fork-mode runtime.
82
+ * Used by the badge + accounts panel + signing modal to surface the
83
+ * "no real chain" caveat — Phase 4 P4.17-P4.20. */
84
+ function isForkNetwork(network) {
85
+ return network.endsWith("-fork");
86
+ }
56
87
  function isPairableAdapter(adapter) {
57
88
  return adapter != null && typeof adapter === "object" && "isPaired" in adapter;
58
89
  }
@@ -67,11 +98,8 @@ function emitEvent(host, name, detail) {
67
98
  /** Clone a Set and toggle an item in/out of it. */
68
99
  function toggleSetItem(set, item) {
69
100
  const next = new Set(set);
70
- if (next.has(item)) {
71
- next.delete(item);
72
- } else {
73
- next.add(item);
74
- }
101
+ if (next.has(item)) next.delete(item);
102
+ else next.add(item);
75
103
  return next;
76
104
  }
77
105
  /** Extract a user-facing error message, with a fallback for non-Error throws. */
@@ -80,7 +108,7 @@ function getErrorMessage(error, fallback) {
80
108
  }
81
109
  /** Find the adapter that owns a given address. */
82
110
  function findAdapterForAddress(adapters, address) {
83
- return adapters.find((a) => a.getAccount(address) !== undefined);
111
+ return adapters.find((a) => a.getAccount(address) !== void 0);
84
112
  }
85
113
  function formatCoinBalance(balance, decimals) {
86
114
  if (decimals === 0) return balance.toString();
@@ -89,10 +117,9 @@ function formatCoinBalance(balance, decimals) {
89
117
  const whole = value / divisor;
90
118
  const fraction = value % divisor;
91
119
  if (fraction === 0n) return whole.toString();
92
- const fractionStr = fraction.toString().padStart(decimals, "0").replace(/0+$/, "");
93
- return `${whole}.${fractionStr}`;
120
+ return `${whole}.${fraction.toString().padStart(decimals, "0").replace(/0+$/, "")}`;
94
121
  }
95
-
96
122
  //#endregion
97
- export { NETWORK_COLORS, copyToClipboard, emitEvent, findAdapterForAddress, formatAddress, formatCoinBalance, getCoinSymbol, getErrorMessage, getTypeName, isCoinType, isPairableAdapter, toggleSetItem };
123
+ export { NETWORK_COLORS, copyToClipboard, emitEvent, findAdapterForAddress, formatAddress, formatCoinBalance, getCoinSymbol, getErrorMessage, getTypeName, indexCoinsByType, isCoinType, isForkNetwork, isPairableAdapter, isSuiCoinType, lookupCoinByType, toggleSetItem };
124
+
98
125
  //# sourceMappingURL=utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../src/ui/utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { normalizeStructTag, parseStructTag } from '@mysten/sui/utils';\n\nconst NORMALIZED_SUI_COIN_TYPE =\n\t'0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI';\n\nconst NORMALIZED_COIN_PREFIX =\n\t'0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<';\n\nexport function isSuiCoinType(coinType: string): boolean {\n\ttry {\n\t\treturn normalizeStructTag(coinType) === NORMALIZED_SUI_COIN_TYPE;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function formatAddress(address: string): string {\n\tif (address.length <= 16) return address;\n\treturn `${address.slice(0, 8)}...${address.slice(-6)}`;\n}\n\nexport function getCoinSymbol(coinType: string): string {\n\ttry {\n\t\tconst tag = parseStructTag(coinType);\n\t\treturn tag.name;\n\t} catch {\n\t\treturn coinType;\n\t}\n}\n\n/** Check if a type string is a Coin wrapper (0x2::coin::Coin<...>) */\nexport function isCoinType(type: string): boolean {\n\ttry {\n\t\treturn normalizeStructTag(type).startsWith(NORMALIZED_COIN_PREFIX);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Extract the short struct name from a full Move type string */\nexport function getTypeName(type: string): string {\n\ttry {\n\t\treturn parseStructTag(type).name;\n\t} catch {\n\t\treturn type;\n\t}\n}\n\nexport async function copyToClipboard(text: string): Promise<boolean> {\n\ttry {\n\t\tawait navigator.clipboard.writeText(text);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport const NETWORK_COLORS: Record<string, string> = {\n\tmainnet: '#f97316',\n\ttestnet: '#22c55e',\n\tdevnet: '#3b82f6',\n\tlocalnet: '#6b7280',\n};\n\nexport interface PairableAdapter {\n\treadonly isPaired: boolean;\n}\n\nexport function isPairableAdapter(adapter: unknown): adapter is PairableAdapter {\n\treturn adapter != null && typeof adapter === 'object' && 'isPaired' in adapter;\n}\n\n/** Dispatch a composed, bubbling custom event from a host element. */\nexport function emitEvent(host: HTMLElement, name: string, detail?: unknown): void {\n\thost.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail }));\n}\n\n/** Clone a Set and toggle an item in/out of it. */\nexport function toggleSetItem<T>(set: Set<T>, item: T): Set<T> {\n\tconst next = new Set(set);\n\tif (next.has(item)) {\n\t\tnext.delete(item);\n\t} else {\n\t\tnext.add(item);\n\t}\n\treturn next;\n}\n\n/** Extract a user-facing error message, with a fallback for non-Error throws. */\nexport function getErrorMessage(error: unknown, fallback: string): string {\n\treturn error instanceof Error ? error.message : fallback;\n}\n\nexport { getNetworkFromChain } from '../wallet/constants.js';\n\n/** Find the adapter that owns a given address. */\nexport function findAdapterForAddress<T extends { getAccount(address: string): unknown }>(\n\tadapters: readonly T[],\n\taddress: string,\n): T | undefined {\n\treturn adapters.find((a) => a.getAccount(address) !== undefined);\n}\n\nexport function formatCoinBalance(balance: string | bigint, decimals: number): string {\n\tif (decimals === 0) return balance.toString();\n\n\tconst value = typeof balance === 'string' ? BigInt(balance) : balance;\n\tconst divisor = BigInt(10 ** decimals);\n\tconst whole = value / divisor;\n\tconst fraction = value % divisor;\n\n\tif (fraction === 0n) return whole.toString();\n\tconst fractionStr = fraction.toString().padStart(decimals, '0').replace(/0+$/, '');\n\treturn `${whole}.${fractionStr}`;\n}\n"],"mappings":";;;;AAKA,MAAM,2BACL;AAED,MAAM,yBACL;AAED,SAAgB,cAAc,UAA2B;AACxD,KAAI;AACH,SAAO,mBAAmB,SAAS,KAAK;SACjC;AACP,SAAO;;;AAIT,SAAgB,cAAc,SAAyB;AACtD,KAAI,QAAQ,UAAU,GAAI,QAAO;AACjC,QAAO,GAAG,QAAQ,MAAM,GAAG,EAAE,CAAC,KAAK,QAAQ,MAAM,CAAC,EAAE;;AAGrD,SAAgB,cAAc,UAA0B;AACvD,KAAI;EACH,MAAM,MAAM,eAAe,SAAS;AACpC,SAAO,IAAI;SACJ;AACP,SAAO;;;;AAKT,SAAgB,WAAW,MAAuB;AACjD,KAAI;AACH,SAAO,mBAAmB,KAAK,CAAC,WAAW,uBAAuB;SAC3D;AACP,SAAO;;;;AAKT,SAAgB,YAAY,MAAsB;AACjD,KAAI;AACH,SAAO,eAAe,KAAK,CAAC;SACrB;AACP,SAAO;;;AAIT,eAAsB,gBAAgB,MAAgC;AACrE,KAAI;AACH,QAAM,UAAU,UAAU,UAAU,KAAK;AACzC,SAAO;SACA;AACP,SAAO;;;AAIT,MAAa,iBAAyC;CACrD,SAAS;CACT,SAAS;CACT,QAAQ;CACR,UAAU;CACV;AAMD,SAAgB,kBAAkB,SAA8C;AAC/E,QAAO,WAAW,QAAQ,OAAO,YAAY,YAAY,cAAc;;;AAIxE,SAAgB,UAAU,MAAmB,MAAc,QAAwB;AAClF,MAAK,cAAc,IAAI,YAAY,MAAM;EAAE,SAAS;EAAM,UAAU;EAAM;EAAQ,CAAC,CAAC;;;AAIrF,SAAgB,cAAiB,KAAa,MAAiB;CAC9D,MAAM,OAAO,IAAI,IAAI,IAAI;AACzB,KAAI,KAAK,IAAI,KAAK,EAAE;AACnB,OAAK,OAAO,KAAK;QACX;AACN,OAAK,IAAI,KAAK;;AAEf,QAAO;;;AAIR,SAAgB,gBAAgB,OAAgB,UAA0B;AACzE,QAAO,iBAAiB,QAAQ,MAAM,UAAU;;;AAMjD,SAAgB,sBACf,UACA,SACgB;AAChB,QAAO,SAAS,MAAM,MAAM,EAAE,WAAW,QAAQ,KAAK,UAAU;;AAGjE,SAAgB,kBAAkB,SAA0B,UAA0B;AACrF,KAAI,aAAa,EAAG,QAAO,QAAQ,UAAU;CAE7C,MAAM,QAAQ,OAAO,YAAY,WAAW,OAAO,QAAQ,GAAG;CAC9D,MAAM,UAAU,OAAO,MAAM,SAAS;CACtC,MAAM,QAAQ,QAAQ;CACtB,MAAM,WAAW,QAAQ;AAEzB,KAAI,aAAa,GAAI,QAAO,MAAM,UAAU;CAC5C,MAAM,cAAc,SAAS,UAAU,CAAC,SAAS,UAAU,IAAI,CAAC,QAAQ,OAAO,GAAG;AAClF,QAAO,GAAG,MAAM,GAAG"}
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../src/ui/utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { normalizeStructTag, parseStructTag } from '@mysten/sui/utils';\n\nconst NORMALIZED_SUI_COIN_TYPE =\n\t'0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI';\n\nconst NORMALIZED_COIN_PREFIX =\n\t'0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<';\n\nexport function isSuiCoinType(coinType: string): boolean {\n\ttry {\n\t\treturn normalizeStructTag(coinType) === NORMALIZED_SUI_COIN_TYPE;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function formatAddress(address: string): string {\n\tif (address.length <= 16) return address;\n\treturn `${address.slice(0, 8)}...${address.slice(-6)}`;\n}\n\nexport function getCoinSymbol(coinType: string): string {\n\ttry {\n\t\tconst tag = parseStructTag(coinType);\n\t\treturn tag.name;\n\t} catch {\n\t\treturn coinType;\n\t}\n}\n\n/**\n * Subset of the generated `coins.ts` entry shape that the UI needs for\n * formatting and labelling. Matches the manifest `CoinEntry` shape emitted\n * by `StackHandleEmitter` (`coins.ts`) so consumers can pass the generated\n * `coins` record directly. Kept structurally-typed (no devstack import —\n * dev-wallet must not depend on the devstack package).\n */\nexport interface CoinManifestEntry {\n\treadonly type: string;\n\treadonly decimals: number;\n\treadonly symbol?: string;\n\treadonly displayName?: string;\n\treadonly iconUrl?: string;\n}\n\n/** A record keyed by coin name (e.g. `'mUSDC'`) mapping to entry metadata.\n * Pass the generated `coins` constant — `<DevWalletPanel coins={coins} />`\n * — to pre-seed UI metadata and skip per-coin RPC fetches on UI load. */\nexport type CoinRecord = Readonly<Record<string, CoinManifestEntry>>;\n\n/** Build a fast `coinType → entry` lookup from the name-keyed generated\n * record. Normalizes coin-type strings so callers can hit it with either\n * the short (`0x2::sui::SUI`) or fully-padded form. */\nexport function indexCoinsByType(\n\tcoins: CoinRecord | null | undefined,\n): ReadonlyMap<string, CoinManifestEntry> {\n\tconst map = new Map<string, CoinManifestEntry>();\n\tif (!coins) return map;\n\tfor (const entry of Object.values(coins)) {\n\t\ttry {\n\t\t\tmap.set(normalizeStructTag(entry.type), entry);\n\t\t} catch {\n\t\t\tmap.set(entry.type, entry);\n\t\t}\n\t}\n\treturn map;\n}\n\n/** Look up a coin's metadata by its on-chain type string. Both the input\n * `coinType` and the index entries are matched on their normalized form\n * so callers don't have to canonicalize. Returns `undefined` for unknown\n * coins — the caller decides whether to fall back to an RPC fetch. */\nexport function lookupCoinByType(\n\tindex: ReadonlyMap<string, CoinManifestEntry>,\n\tcoinType: string,\n): CoinManifestEntry | undefined {\n\ttry {\n\t\treturn index.get(normalizeStructTag(coinType));\n\t} catch {\n\t\treturn index.get(coinType);\n\t}\n}\n\n/** Check if a type string is a Coin wrapper (0x2::coin::Coin<...>) */\nexport function isCoinType(type: string): boolean {\n\ttry {\n\t\treturn normalizeStructTag(type).startsWith(NORMALIZED_COIN_PREFIX);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Extract the short struct name from a full Move type string */\nexport function getTypeName(type: string): string {\n\ttry {\n\t\treturn parseStructTag(type).name;\n\t} catch {\n\t\treturn type;\n\t}\n}\n\nexport async function copyToClipboard(text: string): Promise<boolean> {\n\ttry {\n\t\tawait navigator.clipboard.writeText(text);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport const NETWORK_COLORS: Record<string, string> = {\n\tmainnet: '#f97316',\n\ttestnet: '#22c55e',\n\tdevnet: '#3b82f6',\n\tlocalnet: '#6b7280',\n\t// Fork variants render an amber stripe so the operator can't mistake\n\t// a forked stack for the real upstream at a glance. Same hue family\n\t// as the mainnet orange but pushed warmer/yellower for contrast.\n\t'mainnet-fork': '#eab308',\n\t'testnet-fork': '#eab308',\n\t'devnet-fork': '#eab308',\n};\n\n/** Returns true when the network literal names a fork-mode runtime.\n * Used by the badge + accounts panel + signing modal to surface the\n * \"no real chain\" caveat — Phase 4 P4.17-P4.20. */\nexport function isForkNetwork(network: string): boolean {\n\treturn network.endsWith('-fork');\n}\n\nexport interface PairableAdapter {\n\treadonly isPaired: boolean;\n}\n\nexport function isPairableAdapter(adapter: unknown): adapter is PairableAdapter {\n\treturn adapter != null && typeof adapter === 'object' && 'isPaired' in adapter;\n}\n\n/** Dispatch a composed, bubbling custom event from a host element. */\nexport function emitEvent(host: HTMLElement, name: string, detail?: unknown): void {\n\thost.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail }));\n}\n\n/** Clone a Set and toggle an item in/out of it. */\nexport function toggleSetItem<T>(set: Set<T>, item: T): Set<T> {\n\tconst next = new Set(set);\n\tif (next.has(item)) {\n\t\tnext.delete(item);\n\t} else {\n\t\tnext.add(item);\n\t}\n\treturn next;\n}\n\n/** Extract a user-facing error message, with a fallback for non-Error throws. */\nexport function getErrorMessage(error: unknown, fallback: string): string {\n\treturn error instanceof Error ? error.message : fallback;\n}\n\nexport { getNetworkFromChain } from '../wallet/constants.js';\n\n/** Find the adapter that owns a given address. */\nexport function findAdapterForAddress<T extends { getAccount(address: string): unknown }>(\n\tadapters: readonly T[],\n\taddress: string,\n): T | undefined {\n\treturn adapters.find((a) => a.getAccount(address) !== undefined);\n}\n\nexport function formatCoinBalance(balance: string | bigint, decimals: number): string {\n\tif (decimals === 0) return balance.toString();\n\n\tconst value = typeof balance === 'string' ? BigInt(balance) : balance;\n\tconst divisor = BigInt(10 ** decimals);\n\tconst whole = value / divisor;\n\tconst fraction = value % divisor;\n\n\tif (fraction === 0n) return whole.toString();\n\tconst fractionStr = fraction.toString().padStart(decimals, '0').replace(/0+$/, '');\n\treturn `${whole}.${fractionStr}`;\n}\n"],"mappings":";;;AAKA,MAAM,2BACL;AAED,MAAM,yBACL;AAED,SAAgB,cAAc,UAA2B;AACxD,KAAI;AACH,SAAO,mBAAmB,SAAS,KAAK;SACjC;AACP,SAAO;;;AAIT,SAAgB,cAAc,SAAyB;AACtD,KAAI,QAAQ,UAAU,GAAI,QAAO;AACjC,QAAO,GAAG,QAAQ,MAAM,GAAG,EAAE,CAAC,KAAK,QAAQ,MAAM,GAAG;;AAGrD,SAAgB,cAAc,UAA0B;AACvD,KAAI;AAEH,SADY,eAAe,SACpB,CAAI;SACJ;AACP,SAAO;;;;;;AA2BT,SAAgB,iBACf,OACyC;CACzC,MAAM,sBAAM,IAAI,KAAgC;AAChD,KAAI,CAAC,MAAO,QAAO;AACnB,MAAK,MAAM,SAAS,OAAO,OAAO,MAAM,CACvC,KAAI;AACH,MAAI,IAAI,mBAAmB,MAAM,KAAK,EAAE,MAAM;SACvC;AACP,MAAI,IAAI,MAAM,MAAM,MAAM;;AAG5B,QAAO;;;;;;AAOR,SAAgB,iBACf,OACA,UACgC;AAChC,KAAI;AACH,SAAO,MAAM,IAAI,mBAAmB,SAAS,CAAC;SACvC;AACP,SAAO,MAAM,IAAI,SAAS;;;;AAK5B,SAAgB,WAAW,MAAuB;AACjD,KAAI;AACH,SAAO,mBAAmB,KAAK,CAAC,WAAW,uBAAuB;SAC3D;AACP,SAAO;;;;AAKT,SAAgB,YAAY,MAAsB;AACjD,KAAI;AACH,SAAO,eAAe,KAAK,CAAC;SACrB;AACP,SAAO;;;AAIT,eAAsB,gBAAgB,MAAgC;AACrE,KAAI;AACH,QAAM,UAAU,UAAU,UAAU,KAAK;AACzC,SAAO;SACA;AACP,SAAO;;;AAIT,MAAa,iBAAyC;CACrD,SAAS;CACT,SAAS;CACT,QAAQ;CACR,UAAU;CAIV,gBAAgB;CAChB,gBAAgB;CAChB,eAAe;CACf;;;;AAKD,SAAgB,cAAc,SAA0B;AACvD,QAAO,QAAQ,SAAS,QAAQ;;AAOjC,SAAgB,kBAAkB,SAA8C;AAC/E,QAAO,WAAW,QAAQ,OAAO,YAAY,YAAY,cAAc;;;AAIxE,SAAgB,UAAU,MAAmB,MAAc,QAAwB;AAClF,MAAK,cAAc,IAAI,YAAY,MAAM;EAAE,SAAS;EAAM,UAAU;EAAM;EAAQ,CAAC,CAAC;;;AAIrF,SAAgB,cAAiB,KAAa,MAAiB;CAC9D,MAAM,OAAO,IAAI,IAAI,IAAI;AACzB,KAAI,KAAK,IAAI,KAAK,CACjB,MAAK,OAAO,KAAK;KAEjB,MAAK,IAAI,KAAK;AAEf,QAAO;;;AAIR,SAAgB,gBAAgB,OAAgB,UAA0B;AACzE,QAAO,iBAAiB,QAAQ,MAAM,UAAU;;;AAMjD,SAAgB,sBACf,UACA,SACgB;AAChB,QAAO,SAAS,MAAM,MAAM,EAAE,WAAW,QAAQ,KAAK,OAAU;;AAGjE,SAAgB,kBAAkB,SAA0B,UAA0B;AACrF,KAAI,aAAa,EAAG,QAAO,QAAQ,UAAU;CAE7C,MAAM,QAAQ,OAAO,YAAY,WAAW,OAAO,QAAQ,GAAG;CAC9D,MAAM,UAAU,OAAO,MAAM,SAAS;CACtC,MAAM,QAAQ,QAAQ;CACtB,MAAM,WAAW,QAAQ;AAEzB,KAAI,aAAa,GAAI,QAAO,MAAM,UAAU;AAE5C,QAAO,GAAG,MAAM,GADI,SAAS,UAAU,CAAC,SAAS,UAAU,IAAI,CAAC,QAAQ,OAAO,GAC5D"}
@@ -1,14 +1,15 @@
1
1
  import { getNetworkFromChain } from "../wallet/constants.mjs";
2
+ import { isForkNetwork } from "./utils.mjs";
2
3
  import "./dev-wallet-account-selector.mjs";
3
4
  import "./dev-wallet-balances.mjs";
4
5
  import "./dev-wallet-connect.mjs";
6
+ import "./dev-wallet-fork-panel.mjs";
5
7
  import "./dev-wallet-network-badge.mjs";
6
8
  import "./dev-wallet-objects.mjs";
7
9
  import "./dev-wallet-settings.mjs";
8
10
  import "./dev-wallet-signing-modal.mjs";
9
11
  import "./dev-wallet-tab-bar.mjs";
10
12
  import { html, nothing } from "lit";
11
-
12
13
  //#region src/ui/wallet-controller.ts
13
14
  /**
14
15
  * Lit Reactive Controller that encapsulates all shared wallet management logic
@@ -18,10 +19,10 @@ import { html, nothing } from "lit";
18
19
  * render fragments to this controller, keeping only layout-specific code.
19
20
  */
20
21
  var WalletController = class {
21
- #wallet = null;
22
- #unsubscribeEvents = null;
23
- #unsubscribeRequests = null;
24
- #unsubscribeConnect = null;
22
+ #wallet;
23
+ #unsubscribeEvents;
24
+ #unsubscribeRequests;
25
+ #unsubscribeConnect;
25
26
  constructor(host) {
26
27
  this.activeTab = "assets";
27
28
  this.accounts = [];
@@ -29,6 +30,13 @@ var WalletController = class {
29
30
  this.pendingRequest = null;
30
31
  this.pendingConnect = null;
31
32
  this.bookmarkletOrigin = "";
33
+ this.coins = null;
34
+ this.forkRelay = null;
35
+ this.forkUpstream = "";
36
+ this.#wallet = null;
37
+ this.#unsubscribeEvents = null;
38
+ this.#unsubscribeRequests = null;
39
+ this.#unsubscribeConnect = null;
32
40
  this.host = host;
33
41
  host.addController(this);
34
42
  }
@@ -61,9 +69,7 @@ var WalletController = class {
61
69
  if (!accountsChanged && !pendingChanged) return;
62
70
  if (accountsChanged) {
63
71
  this.accounts = [...newAccounts];
64
- if (this.activeAccountIndex >= newAccounts.length && newAccounts.length > 0) {
65
- this.activeAccountIndex = newAccounts.length - 1;
66
- }
72
+ if (this.activeAccountIndex >= newAccounts.length && newAccounts.length > 0) this.activeAccountIndex = newAccounts.length - 1;
67
73
  }
68
74
  this.pendingRequest = newPending;
69
75
  this.host.requestUpdate();
@@ -79,12 +85,10 @@ var WalletController = class {
79
85
  if (!this.#wallet) return null;
80
86
  if (this.pendingRequest) {
81
87
  const network = getNetworkFromChain(this.pendingRequest.chain);
82
- if (network) {
83
- try {
84
- return this.#wallet.getClient(network);
85
- } catch {
86
- return this.#wallet.activeClient;
87
- }
88
+ if (network) try {
89
+ return this.#wallet.getClient(network);
90
+ } catch {
91
+ return this.#wallet.activeClient;
88
92
  }
89
93
  }
90
94
  return this.#wallet.activeClient;
@@ -160,6 +164,8 @@ var WalletController = class {
160
164
  exportparts="balance-list, loading: balances-loading, error-message: balances-error-message, empty-state: balances-empty-state"
161
165
  .address=${this.activeAddress}
162
166
  .client=${this.getActiveClient()}
167
+ .network=${this.#wallet.activeNetwork}
168
+ .coins=${this.coins}
163
169
  ></dev-wallet-balances>
164
170
  </div>
165
171
  ` : nothing}
@@ -168,11 +174,15 @@ var WalletController = class {
168
174
  renderObjectsTab() {
169
175
  return html`
170
176
  ${this.renderAccountSelector()}
171
- <dev-wallet-objects
172
- exportparts="object-list, loading: objects-loading, error-message: objects-error-message, empty-state: objects-empty-state, load-more-button"
173
- .address=${this.activeAddress}
174
- .client=${this.getActiveClient()}
175
- ></dev-wallet-objects>
177
+ ${this.activeAddress && this.#wallet ? html`
178
+ <div class="section">
179
+ <dev-wallet-objects
180
+ exportparts="object-list, loading: objects-loading, error-message: objects-error-message, empty-state: objects-empty-state, load-more-button"
181
+ .address=${this.activeAddress}
182
+ .client=${this.getActiveClient()}
183
+ ></dev-wallet-objects>
184
+ </div>
185
+ ` : nothing}
176
186
  `;
177
187
  }
178
188
  renderSettingsTab() {
@@ -188,12 +198,49 @@ var WalletController = class {
188
198
  ></dev-wallet-settings>
189
199
  `;
190
200
  }
201
+ renderForkTab() {
202
+ if (!this.#isForkMode()) return nothing;
203
+ return html`
204
+ <dev-wallet-fork-panel
205
+ exportparts="
206
+ fork-banner,
207
+ status-grid,
208
+ status-checkpoint,
209
+ status-clock,
210
+ status-clock-iso,
211
+ status-auto-tick,
212
+ status-loading,
213
+ status-error,
214
+ status-empty,
215
+ advance-clock-input,
216
+ advance-clock-button,
217
+ advance-checkpoint-input,
218
+ advance-checkpoint-button,
219
+ action-error,
220
+ slot-list,
221
+ slot-item,
222
+ slot-item-active,
223
+ slot-toggle,
224
+ slots-empty,
225
+ slots-error,
226
+ empty-state
227
+ "
228
+ .relay=${this.forkRelay}
229
+ .upstream=${this.#resolveUpstreamLabel()}
230
+ @fork-impersonation-changed=${(e) => this.handleForkImpersonationChanged(e)}
231
+ ></dev-wallet-fork-panel>
232
+ `;
233
+ }
191
234
  renderTabContent() {
192
235
  if (this.activeTab === "assets") return this.renderAssetsTab();
193
236
  if (this.activeTab === "objects") return this.renderObjectsTab();
237
+ if (this.activeTab === "fork") return this.renderForkTab();
194
238
  if (this.activeTab === "settings") return this.renderSettingsTab();
195
239
  return nothing;
196
240
  }
241
+ handleForkImpersonationChanged(_e) {
242
+ this.host.requestUpdate();
243
+ }
197
244
  renderSigningModal() {
198
245
  if (!this.pendingRequest) return nothing;
199
246
  return html`
@@ -201,6 +248,7 @@ var WalletController = class {
201
248
  exportparts="signing-approve-button, signing-reject-button, signing-request-type, signing-empty-state, signing-error-message, signing-footer, dialog: signing-dialog"
202
249
  .request=${this.pendingRequest}
203
250
  .client=${this.getActiveClient()}
251
+ .coins=${this.coins}
204
252
  .walletName=${this.#wallet?.name ?? "Dev Wallet"}
205
253
  @approve=${() => this.handleApprove()}
206
254
  @reject=${() => this.handleReject()}
@@ -244,10 +292,31 @@ var WalletController = class {
244
292
  <dev-wallet-tab-bar
245
293
  exportparts="tab-bar, tab"
246
294
  .active=${this.activeTab}
295
+ .showFork=${this.#isForkMode()}
247
296
  @tab-changed=${(e) => this.handleTabChanged(e)}
248
297
  ></dev-wallet-tab-bar>
249
298
  `;
250
299
  }
300
+ /** Phase 5 Subtopic 6 (P5.8.5) — the Fork tab + panel render only
301
+ * when the active stack is in fork mode. Two signals satisfy that:
302
+ * 1. The host passed in a `ForkRelay` (built from the manifest's
303
+ * wallet endpoint — devstack only constructs one when
304
+ * `meta.runtime === 'forked'`).
305
+ * 2. The active network literal ends in `-fork` (catch-all for
306
+ * when the relay is wired but the user switched to a
307
+ * non-fork network from the badge dropdown).
308
+ * Both signals must agree — otherwise the tab is hidden. */
309
+ #isForkMode() {
310
+ if (this.forkRelay === null) return false;
311
+ const active = this.#wallet?.activeNetwork;
312
+ if (!active) return false;
313
+ return isForkNetwork(active);
314
+ }
315
+ #resolveUpstreamLabel() {
316
+ if (this.forkUpstream !== "") return this.forkUpstream;
317
+ const active = this.#wallet?.activeNetwork ?? "";
318
+ return active.endsWith("-fork") ? active.replace(/-fork$/, "") : "";
319
+ }
251
320
  #subscribe() {
252
321
  if (!this.#wallet) return;
253
322
  this.#unsubscribeEvents = this.#wallet.features["standard:events"].on("change", () => {
@@ -269,7 +338,7 @@ var WalletController = class {
269
338
  this.#unsubscribeConnect = null;
270
339
  }
271
340
  };
272
-
273
341
  //#endregion
274
342
  export { WalletController };
343
+
275
344
  //# sourceMappingURL=wallet-controller.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"wallet-controller.mjs","names":["#wallet","#unsubscribe","#subscribe","#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 { 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-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';\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\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></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<dev-wallet-objects\n\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.address=${this.activeAddress}\n\t\t\t\t.client=${this.getActiveClient()}\n\t\t\t></dev-wallet-objects>\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\trenderTabContent() {\n\t\tif (this.activeTab === 'assets') return this.renderAssetsTab();\n\t\tif (this.activeTab === 'objects') return this.renderObjectsTab();\n\t\tif (this.activeTab === 'settings') return this.renderSettingsTab();\n\t\treturn nothing;\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.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@tab-changed=${(e: CustomEvent) => this.handleTabChanged(e)}\n\t\t\t></dev-wallet-tab-bar>\n\t\t`;\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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"}
@@ -0,0 +1,9 @@
1
+ import { StandardEventsListeners, WalletIcon } from "@mysten/wallet-standard";
2
+
3
+ //#region src/wallet/constants.d.ts
4
+ type WalletEventsMap = { [E in keyof StandardEventsListeners]: Parameters<StandardEventsListeners[E]>[0] };
5
+ /** Extract the network name from a chain identifier (e.g. 'sui:devnet' → 'devnet'). */
6
+ declare function getNetworkFromChain(chain: string): string | undefined;
7
+ /** Default wallet icon shared between DevWallet and DevWalletClient. */
8
+ declare const DEFAULT_WALLET_ICON: WalletIcon;
9
+ //# sourceMappingURL=constants.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.mts","names":[],"sources":["../../src/wallet/constants.ts"],"mappings":";;;KAKY,eAAA,iBACC,uBAAA,GAA0B,UAAA,CAAW,uBAAA,CAAwB,CAAA;;iBAI1D,mBAAA,CAAoB,KAAA;;cAKvB,mBAAA,EAAqB,UAAA"}
@@ -5,7 +5,7 @@ function getNetworkFromChain(chain) {
5
5
  }
6
6
  /** Default wallet icon shared between DevWallet and DevWalletClient. */
7
7
  const DEFAULT_WALLET_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCIgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0Ij4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0id2FsbGV0R3JhZCIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+CiAgICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiM2MzY2RjEiIC8+CiAgICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6IzI1NjNFQiIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImZsYXBHcmFkIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzgxOENGOCIgLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjojNEY0NkU1IiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICA8L2RlZnM+CiAgPCEtLSBTaGFkb3cgLS0+CiAgPHJlY3QgeD0iOSIgeT0iMjEiIHdpZHRoPSI1MCIgaGVpZ2h0PSIzNiIgcng9IjYiIHJ5PSI2IiBmaWxsPSIjMDAwIiBvcGFjaXR5PSIwLjEiIC8+CiAgPCEtLSBXYWxsZXQgYm9keSAtLT4KICA8cmVjdCB4PSI2IiB5PSIxOCIgd2lkdGg9IjUwIiBoZWlnaHQ9IjM2IiByeD0iNiIgcnk9IjYiIGZpbGw9InVybCgjd2FsbGV0R3JhZCkiIC8+CiAgPCEtLSBGbGFwIC0tPgogIDxwYXRoIGQ9Ik02IDI2IEw2IDIyIEM2IDE1IDggMTIgMTQgMTIgTDQ2IDEyIEM1MiAxMiA1NiAxNSA1NiAyMiBMNTYgMjYgWiIgZmlsbD0idXJsKCNmbGFwR3JhZCkiIC8+CiAgPCEtLSBDbGFzcCAtLT4KICA8cmVjdCB4PSI0MiIgeT0iMzAiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgcng9IjQiIHJ5PSI0IiBmaWxsPSIjNDMzOENBIiAvPgogIDwhLS0gR29sZCBjb2luIGluIGNsYXNwIC0tPgogIDxjaXJjbGUgY3g9IjQ4IiBjeT0iMzYiIHI9IjMuNSIgZmlsbD0iI0ZDRDM0RCIgLz4KICA8Y2lyY2xlIGN4PSI0OCIgY3k9IjM2IiByPSIyIiBmaWxsPSIjRjU5RTBCIiAvPgogIDwhLS0gRW1ib3NzZWQgRFcgdGV4dCAtLT4KICA8dGV4dCB4PSIyNiIgeT0iNDUiIGZvbnQtZmFtaWx5PSJBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0iOTAwIiBmb250LXNpemU9IjE4IiBmaWxsPSIjMzczMEEzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBkb21pbmFudC1iYXNlbGluZT0ibWlkZGxlIiBsZXR0ZXItc3BhY2luZz0iMiI+RFc8L3RleHQ+CiAgPHRleHQgeD0iMjYiIHk9IjQ0IiBmb250LWZhbWlseT0iQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZiIgZm9udC13ZWlnaHQ9IjkwMCIgZm9udC1zaXplPSIxOCIgZmlsbD0iI0M3RDJGRSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGxlIiBsZXR0ZXItc3BhY2luZz0iMiI+RFc8L3RleHQ+Cjwvc3ZnPgo=";
8
-
9
8
  //#endregion
10
9
  export { DEFAULT_WALLET_ICON, getNetworkFromChain };
10
+
11
11
  //# sourceMappingURL=constants.mjs.map