@mysten-incubation/dev-wallet 0.0.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 (213) hide show
  1. package/README.md +250 -0
  2. package/dist/_virtual/_@oxc-project_runtime@0.107.0/helpers/decorate.mjs +10 -0
  3. package/dist/adapters/base-adapter.d.mts +33 -0
  4. package/dist/adapters/base-adapter.d.mts.map +1 -0
  5. package/dist/adapters/base-adapter.mjs +77 -0
  6. package/dist/adapters/base-adapter.mjs.map +1 -0
  7. package/dist/adapters/browser.d.mts +8 -0
  8. package/dist/adapters/browser.mjs +8 -0
  9. package/dist/adapters/build-managed-account.d.mts +12 -0
  10. package/dist/adapters/build-managed-account.d.mts.map +1 -0
  11. package/dist/adapters/build-managed-account.mjs +30 -0
  12. package/dist/adapters/build-managed-account.mjs.map +1 -0
  13. package/dist/adapters/idb-store.mjs +73 -0
  14. package/dist/adapters/idb-store.mjs.map +1 -0
  15. package/dist/adapters/in-memory-adapter.d.mts +16 -0
  16. package/dist/adapters/in-memory-adapter.d.mts.map +1 -0
  17. package/dist/adapters/in-memory-adapter.mjs +44 -0
  18. package/dist/adapters/in-memory-adapter.mjs.map +1 -0
  19. package/dist/adapters/passkey-adapter.d.mts +31 -0
  20. package/dist/adapters/passkey-adapter.d.mts.map +1 -0
  21. package/dist/adapters/passkey-adapter.mjs +87 -0
  22. package/dist/adapters/passkey-adapter.mjs.map +1 -0
  23. package/dist/adapters/remote-cli-adapter.d.mts +65 -0
  24. package/dist/adapters/remote-cli-adapter.d.mts.map +1 -0
  25. package/dist/adapters/remote-cli-adapter.mjs +299 -0
  26. package/dist/adapters/remote-cli-adapter.mjs.map +1 -0
  27. package/dist/adapters/webcrypto-adapter.d.mts +20 -0
  28. package/dist/adapters/webcrypto-adapter.d.mts.map +1 -0
  29. package/dist/adapters/webcrypto-adapter.mjs +68 -0
  30. package/dist/adapters/webcrypto-adapter.mjs.map +1 -0
  31. package/dist/bin/cli.d.mts +1 -0
  32. package/dist/bin/cli.mjs +183 -0
  33. package/dist/bin/cli.mjs.map +1 -0
  34. package/dist/client/dev-wallet-client.d.mts +57 -0
  35. package/dist/client/dev-wallet-client.d.mts.map +1 -0
  36. package/dist/client/dev-wallet-client.mjs +223 -0
  37. package/dist/client/dev-wallet-client.mjs.map +1 -0
  38. package/dist/client/index.d.mts +3 -0
  39. package/dist/client/index.mjs +4 -0
  40. package/dist/client/request-handler.d.mts +42 -0
  41. package/dist/client/request-handler.d.mts.map +1 -0
  42. package/dist/client/request-handler.mjs +115 -0
  43. package/dist/client/request-handler.mjs.map +1 -0
  44. package/dist/index.d.mts +5 -0
  45. package/dist/index.mjs +4 -0
  46. package/dist/react/components.d.mts +32 -0
  47. package/dist/react/components.d.mts.map +1 -0
  48. package/dist/react/components.mjs +53 -0
  49. package/dist/react/components.mjs.map +1 -0
  50. package/dist/react/context.d.mts +22 -0
  51. package/dist/react/context.d.mts.map +1 -0
  52. package/dist/react/context.mjs +25 -0
  53. package/dist/react/context.mjs.map +1 -0
  54. package/dist/react/index.d.mts +4 -0
  55. package/dist/react/index.mjs +5 -0
  56. package/dist/react/useDevWallet.d.mts +38 -0
  57. package/dist/react/useDevWallet.d.mts.map +1 -0
  58. package/dist/react/useDevWallet.mjs +89 -0
  59. package/dist/react/useDevWallet.mjs.map +1 -0
  60. package/dist/server/cli-signing-middleware.d.mts +22 -0
  61. package/dist/server/cli-signing-middleware.d.mts.map +1 -0
  62. package/dist/server/cli-signing-middleware.mjs +117 -0
  63. package/dist/server/cli-signing-middleware.mjs.map +1 -0
  64. package/dist/server/index.d.mts +2 -0
  65. package/dist/server/index.mjs +3 -0
  66. package/dist/standalone/assets/in-memory-adapter-CBF4h2KD.js +1 -0
  67. package/dist/standalone/assets/main-VE4olb-Q.js +2841 -0
  68. package/dist/standalone/assets/webcrypto-adapter-DysAubFb.js +1 -0
  69. package/dist/standalone/bookmarklet.js +5 -0
  70. package/dist/standalone/index.html +48 -0
  71. package/dist/types.d.mts +55 -0
  72. package/dist/types.d.mts.map +1 -0
  73. package/dist/ui/copy-controller.mjs +43 -0
  74. package/dist/ui/copy-controller.mjs.map +1 -0
  75. package/dist/ui/dev-wallet-account-selector.d.mts +24 -0
  76. package/dist/ui/dev-wallet-account-selector.d.mts.map +1 -0
  77. package/dist/ui/dev-wallet-account-selector.mjs +268 -0
  78. package/dist/ui/dev-wallet-account-selector.mjs.map +1 -0
  79. package/dist/ui/dev-wallet-accounts.d.mts +29 -0
  80. package/dist/ui/dev-wallet-accounts.d.mts.map +1 -0
  81. package/dist/ui/dev-wallet-accounts.mjs +524 -0
  82. package/dist/ui/dev-wallet-accounts.mjs.map +1 -0
  83. package/dist/ui/dev-wallet-balances.d.mts +26 -0
  84. package/dist/ui/dev-wallet-balances.d.mts.map +1 -0
  85. package/dist/ui/dev-wallet-balances.mjs +130 -0
  86. package/dist/ui/dev-wallet-balances.mjs.map +1 -0
  87. package/dist/ui/dev-wallet-connect.d.mts +31 -0
  88. package/dist/ui/dev-wallet-connect.d.mts.map +1 -0
  89. package/dist/ui/dev-wallet-connect.mjs +225 -0
  90. package/dist/ui/dev-wallet-connect.mjs.map +1 -0
  91. package/dist/ui/dev-wallet-dropdown.d.mts +27 -0
  92. package/dist/ui/dev-wallet-dropdown.d.mts.map +1 -0
  93. package/dist/ui/dev-wallet-dropdown.mjs +121 -0
  94. package/dist/ui/dev-wallet-dropdown.mjs.map +1 -0
  95. package/dist/ui/dev-wallet-network-badge.d.mts +21 -0
  96. package/dist/ui/dev-wallet-network-badge.d.mts.map +1 -0
  97. package/dist/ui/dev-wallet-network-badge.mjs +121 -0
  98. package/dist/ui/dev-wallet-network-badge.mjs.map +1 -0
  99. package/dist/ui/dev-wallet-new-account.d.mts +31 -0
  100. package/dist/ui/dev-wallet-new-account.d.mts.map +1 -0
  101. package/dist/ui/dev-wallet-new-account.mjs +577 -0
  102. package/dist/ui/dev-wallet-new-account.mjs.map +1 -0
  103. package/dist/ui/dev-wallet-objects.d.mts +26 -0
  104. package/dist/ui/dev-wallet-objects.d.mts.map +1 -0
  105. package/dist/ui/dev-wallet-objects.mjs +276 -0
  106. package/dist/ui/dev-wallet-objects.mjs.map +1 -0
  107. package/dist/ui/dev-wallet-panel.d.mts +22 -0
  108. package/dist/ui/dev-wallet-panel.d.mts.map +1 -0
  109. package/dist/ui/dev-wallet-panel.mjs +192 -0
  110. package/dist/ui/dev-wallet-panel.mjs.map +1 -0
  111. package/dist/ui/dev-wallet-popup.d.mts +36 -0
  112. package/dist/ui/dev-wallet-popup.d.mts.map +1 -0
  113. package/dist/ui/dev-wallet-popup.mjs +137 -0
  114. package/dist/ui/dev-wallet-popup.mjs.map +1 -0
  115. package/dist/ui/dev-wallet-settings.d.mts +33 -0
  116. package/dist/ui/dev-wallet-settings.d.mts.map +1 -0
  117. package/dist/ui/dev-wallet-settings.mjs +635 -0
  118. package/dist/ui/dev-wallet-settings.mjs.map +1 -0
  119. package/dist/ui/dev-wallet-signing-modal.d.mts +32 -0
  120. package/dist/ui/dev-wallet-signing-modal.d.mts.map +1 -0
  121. package/dist/ui/dev-wallet-signing-modal.mjs +115 -0
  122. package/dist/ui/dev-wallet-signing-modal.mjs.map +1 -0
  123. package/dist/ui/dev-wallet-signing.d.mts +25 -0
  124. package/dist/ui/dev-wallet-signing.d.mts.map +1 -0
  125. package/dist/ui/dev-wallet-signing.mjs +544 -0
  126. package/dist/ui/dev-wallet-signing.mjs.map +1 -0
  127. package/dist/ui/dev-wallet-standalone.d.mts +23 -0
  128. package/dist/ui/dev-wallet-standalone.d.mts.map +1 -0
  129. package/dist/ui/dev-wallet-standalone.mjs +129 -0
  130. package/dist/ui/dev-wallet-standalone.mjs.map +1 -0
  131. package/dist/ui/dev-wallet-tab-bar.d.mts +19 -0
  132. package/dist/ui/dev-wallet-tab-bar.d.mts.map +1 -0
  133. package/dist/ui/dev-wallet-tab-bar.mjs +143 -0
  134. package/dist/ui/dev-wallet-tab-bar.mjs.map +1 -0
  135. package/dist/ui/index.d.mts +17 -0
  136. package/dist/ui/index.mjs +18 -0
  137. package/dist/ui/mount.d.mts +11 -0
  138. package/dist/ui/mount.d.mts.map +1 -0
  139. package/dist/ui/mount.mjs +17 -0
  140. package/dist/ui/mount.mjs.map +1 -0
  141. package/dist/ui/styles.mjs +250 -0
  142. package/dist/ui/styles.mjs.map +1 -0
  143. package/dist/ui/transaction-analyzer.mjs +58 -0
  144. package/dist/ui/transaction-analyzer.mjs.map +1 -0
  145. package/dist/ui/utils.mjs +98 -0
  146. package/dist/ui/utils.mjs.map +1 -0
  147. package/dist/ui/wallet-controller.mjs +275 -0
  148. package/dist/ui/wallet-controller.mjs.map +1 -0
  149. package/dist/wallet/constants.mjs +11 -0
  150. package/dist/wallet/constants.mjs.map +1 -0
  151. package/dist/wallet/dev-wallet.d.mts +118 -0
  152. package/dist/wallet/dev-wallet.d.mts.map +1 -0
  153. package/dist/wallet/dev-wallet.mjs +424 -0
  154. package/dist/wallet/dev-wallet.mjs.map +1 -0
  155. package/dist/wallet/initializer.d.mts +63 -0
  156. package/dist/wallet/initializer.d.mts.map +1 -0
  157. package/dist/wallet/initializer.mjs +75 -0
  158. package/dist/wallet/initializer.mjs.map +1 -0
  159. package/dist/wallet/signing.d.mts +35 -0
  160. package/dist/wallet/signing.d.mts.map +1 -0
  161. package/dist/wallet/signing.mjs +69 -0
  162. package/dist/wallet/signing.mjs.map +1 -0
  163. package/package.json +124 -0
  164. package/src/adapters/base-adapter.ts +93 -0
  165. package/src/adapters/browser.ts +15 -0
  166. package/src/adapters/build-managed-account.ts +33 -0
  167. package/src/adapters/idb-store.ts +87 -0
  168. package/src/adapters/in-memory-adapter.ts +51 -0
  169. package/src/adapters/passkey-adapter.ts +120 -0
  170. package/src/adapters/remote-cli-adapter.ts +388 -0
  171. package/src/adapters/webcrypto-adapter.ts +96 -0
  172. package/src/app/bookmarklet-entry.ts +77 -0
  173. package/src/app/index.html +48 -0
  174. package/src/app/main.ts +245 -0
  175. package/src/app/tsconfig.json +3 -0
  176. package/src/bin/cli.ts +214 -0
  177. package/src/client/dev-wallet-client.ts +280 -0
  178. package/src/client/index.ts +7 -0
  179. package/src/client/request-handler.ts +161 -0
  180. package/src/index.ts +19 -0
  181. package/src/react/components.ts +64 -0
  182. package/src/react/context.ts +38 -0
  183. package/src/react/index.ts +16 -0
  184. package/src/react/useDevWallet.ts +118 -0
  185. package/src/server/cli-signing-middleware.ts +146 -0
  186. package/src/server/index.ts +8 -0
  187. package/src/types.ts +58 -0
  188. package/src/ui/copy-controller.ts +49 -0
  189. package/src/ui/dev-wallet-account-selector.ts +283 -0
  190. package/src/ui/dev-wallet-accounts.ts +578 -0
  191. package/src/ui/dev-wallet-balances.ts +171 -0
  192. package/src/ui/dev-wallet-connect.ts +259 -0
  193. package/src/ui/dev-wallet-dropdown.ts +138 -0
  194. package/src/ui/dev-wallet-network-badge.ts +128 -0
  195. package/src/ui/dev-wallet-new-account.ts +662 -0
  196. package/src/ui/dev-wallet-objects.ts +336 -0
  197. package/src/ui/dev-wallet-panel.ts +207 -0
  198. package/src/ui/dev-wallet-popup.ts +169 -0
  199. package/src/ui/dev-wallet-settings.ts +692 -0
  200. package/src/ui/dev-wallet-signing-modal.ts +137 -0
  201. package/src/ui/dev-wallet-signing.ts +624 -0
  202. package/src/ui/dev-wallet-standalone.ts +136 -0
  203. package/src/ui/dev-wallet-tab-bar.ts +151 -0
  204. package/src/ui/index.ts +26 -0
  205. package/src/ui/mount.ts +21 -0
  206. package/src/ui/styles.ts +252 -0
  207. package/src/ui/transaction-analyzer.ts +60 -0
  208. package/src/ui/utils.ts +118 -0
  209. package/src/ui/wallet-controller.ts +340 -0
  210. package/src/wallet/constants.ts +17 -0
  211. package/src/wallet/dev-wallet.ts +597 -0
  212. package/src/wallet/initializer.ts +124 -0
  213. package/src/wallet/signing.ts +85 -0
@@ -0,0 +1,58 @@
1
+ import { analyze, analyzers } from "@mysten/wallet-sdk";
2
+
3
+ //#region src/ui/transaction-analyzer.ts
4
+ async function analyzeTransaction(txData, client) {
5
+ if (!client) {
6
+ return {
7
+ kind: "error",
8
+ message: "No client available to analyze transaction"
9
+ };
10
+ }
11
+ try {
12
+ const result = await analyze({
13
+ commands: analyzers.commands,
14
+ coinFlows: analyzers.coinFlows
15
+ }, {
16
+ client,
17
+ transaction: txData
18
+ });
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
+ }
28
+ 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
+ }
35
+ return {
36
+ kind: "error",
37
+ message: "Transaction analysis returned no results"
38
+ };
39
+ } catch (e) {
40
+ const raw = e instanceof Error ? e.message : String(e);
41
+ 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
+ }
49
+ return {
50
+ kind: "error",
51
+ message
52
+ };
53
+ }
54
+ }
55
+
56
+ //#endregion
57
+ export { analyzeTransaction };
58
+ //# sourceMappingURL=transaction-analyzer.mjs.map
@@ -0,0 +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"}
@@ -0,0 +1,98 @@
1
+ import { getNetworkFromChain } from "../wallet/constants.mjs";
2
+ import { normalizeStructTag, parseStructTag } from "@mysten/sui/utils";
3
+
4
+ //#region src/ui/utils.ts
5
+ const NORMALIZED_SUI_COIN_TYPE = "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI";
6
+ const NORMALIZED_COIN_PREFIX = "0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<";
7
+ function isSuiCoinType(coinType) {
8
+ try {
9
+ return normalizeStructTag(coinType) === NORMALIZED_SUI_COIN_TYPE;
10
+ } catch {
11
+ return false;
12
+ }
13
+ }
14
+ function formatAddress(address) {
15
+ if (address.length <= 16) return address;
16
+ return `${address.slice(0, 8)}...${address.slice(-6)}`;
17
+ }
18
+ function getCoinSymbol(coinType) {
19
+ try {
20
+ const tag = parseStructTag(coinType);
21
+ return tag.name;
22
+ } catch {
23
+ return coinType;
24
+ }
25
+ }
26
+ /** Check if a type string is a Coin wrapper (0x2::coin::Coin<...>) */
27
+ function isCoinType(type) {
28
+ try {
29
+ return normalizeStructTag(type).startsWith(NORMALIZED_COIN_PREFIX);
30
+ } catch {
31
+ return false;
32
+ }
33
+ }
34
+ /** Extract the short struct name from a full Move type string */
35
+ function getTypeName(type) {
36
+ try {
37
+ return parseStructTag(type).name;
38
+ } catch {
39
+ return type;
40
+ }
41
+ }
42
+ async function copyToClipboard(text) {
43
+ try {
44
+ await navigator.clipboard.writeText(text);
45
+ return true;
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
50
+ const NETWORK_COLORS = {
51
+ mainnet: "#f97316",
52
+ testnet: "#22c55e",
53
+ devnet: "#3b82f6",
54
+ localnet: "#6b7280"
55
+ };
56
+ function isPairableAdapter(adapter) {
57
+ return adapter != null && typeof adapter === "object" && "isPaired" in adapter;
58
+ }
59
+ /** Dispatch a composed, bubbling custom event from a host element. */
60
+ function emitEvent(host, name, detail) {
61
+ host.dispatchEvent(new CustomEvent(name, {
62
+ bubbles: true,
63
+ composed: true,
64
+ detail
65
+ }));
66
+ }
67
+ /** Clone a Set and toggle an item in/out of it. */
68
+ function toggleSetItem(set, item) {
69
+ const next = new Set(set);
70
+ if (next.has(item)) {
71
+ next.delete(item);
72
+ } else {
73
+ next.add(item);
74
+ }
75
+ return next;
76
+ }
77
+ /** Extract a user-facing error message, with a fallback for non-Error throws. */
78
+ function getErrorMessage(error, fallback) {
79
+ return error instanceof Error ? error.message : fallback;
80
+ }
81
+ /** Find the adapter that owns a given address. */
82
+ function findAdapterForAddress(adapters, address) {
83
+ return adapters.find((a) => a.getAccount(address) !== undefined);
84
+ }
85
+ function formatCoinBalance(balance, decimals) {
86
+ if (decimals === 0) return balance.toString();
87
+ const value = typeof balance === "string" ? BigInt(balance) : balance;
88
+ const divisor = BigInt(10 ** decimals);
89
+ const whole = value / divisor;
90
+ const fraction = value % divisor;
91
+ if (fraction === 0n) return whole.toString();
92
+ const fractionStr = fraction.toString().padStart(decimals, "0").replace(/0+$/, "");
93
+ return `${whole}.${fractionStr}`;
94
+ }
95
+
96
+ //#endregion
97
+ export { NETWORK_COLORS, copyToClipboard, emitEvent, findAdapterForAddress, formatAddress, formatCoinBalance, getCoinSymbol, getErrorMessage, getTypeName, isCoinType, isPairableAdapter, toggleSetItem };
98
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +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"}
@@ -0,0 +1,275 @@
1
+ import { getNetworkFromChain } from "../wallet/constants.mjs";
2
+ import "./dev-wallet-account-selector.mjs";
3
+ import "./dev-wallet-balances.mjs";
4
+ import "./dev-wallet-connect.mjs";
5
+ import "./dev-wallet-network-badge.mjs";
6
+ import "./dev-wallet-objects.mjs";
7
+ import "./dev-wallet-settings.mjs";
8
+ import "./dev-wallet-signing-modal.mjs";
9
+ import "./dev-wallet-tab-bar.mjs";
10
+ import { html, nothing } from "lit";
11
+
12
+ //#region src/ui/wallet-controller.ts
13
+ /**
14
+ * Lit Reactive Controller that encapsulates all shared wallet management logic
15
+ * between `dev-wallet-panel` and `dev-wallet-standalone`.
16
+ *
17
+ * Both components delegate state management, event subscription, and shared
18
+ * render fragments to this controller, keeping only layout-specific code.
19
+ */
20
+ var WalletController = class {
21
+ #wallet = null;
22
+ #unsubscribeEvents = null;
23
+ #unsubscribeRequests = null;
24
+ #unsubscribeConnect = null;
25
+ constructor(host) {
26
+ this.activeTab = "assets";
27
+ this.accounts = [];
28
+ this.activeAccountIndex = 0;
29
+ this.pendingRequest = null;
30
+ this.pendingConnect = null;
31
+ this.bookmarkletOrigin = "";
32
+ this.host = host;
33
+ host.addController(this);
34
+ }
35
+ get wallet() {
36
+ return this.#wallet;
37
+ }
38
+ get activeAddress() {
39
+ return this.accounts[this.activeAccountIndex]?.address ?? "";
40
+ }
41
+ set wallet(value) {
42
+ if (value === this.#wallet) return;
43
+ this.#unsubscribe();
44
+ this.#wallet = value;
45
+ this.#subscribe();
46
+ this.syncState();
47
+ }
48
+ hostConnected() {
49
+ this.#subscribe();
50
+ this.syncState();
51
+ }
52
+ hostDisconnected() {
53
+ this.#unsubscribe();
54
+ }
55
+ syncState() {
56
+ if (!this.#wallet) return;
57
+ const newAccounts = this.#wallet.accounts;
58
+ const newPending = this.#wallet.pendingRequest;
59
+ const accountsChanged = newAccounts.length !== this.accounts.length || newAccounts.some((a, i) => a.address !== this.accounts[i]?.address);
60
+ const pendingChanged = newPending !== this.pendingRequest;
61
+ if (!accountsChanged && !pendingChanged) return;
62
+ if (accountsChanged) {
63
+ this.accounts = [...newAccounts];
64
+ if (this.activeAccountIndex >= newAccounts.length && newAccounts.length > 0) {
65
+ this.activeAccountIndex = newAccounts.length - 1;
66
+ }
67
+ }
68
+ this.pendingRequest = newPending;
69
+ this.host.requestUpdate();
70
+ }
71
+ syncConnectState() {
72
+ if (!this.#wallet) return;
73
+ const newConnect = this.#wallet.pendingConnect;
74
+ if (newConnect === this.pendingConnect) return;
75
+ this.pendingConnect = newConnect;
76
+ this.host.requestUpdate();
77
+ }
78
+ getActiveClient() {
79
+ if (!this.#wallet) return null;
80
+ if (this.pendingRequest) {
81
+ 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
+ }
89
+ }
90
+ return this.#wallet.activeClient;
91
+ }
92
+ async handleApprove() {
93
+ if (!this.#wallet) return;
94
+ try {
95
+ await this.#wallet.approveRequest();
96
+ } catch (error) {
97
+ console.error("[dev-wallet] approve failed:", error);
98
+ }
99
+ }
100
+ handleReject() {
101
+ if (!this.#wallet) return;
102
+ try {
103
+ this.#wallet.rejectRequest();
104
+ } catch (error) {
105
+ console.error("[dev-wallet] reject failed:", error);
106
+ }
107
+ }
108
+ handleTabChanged(e) {
109
+ this.activeTab = e.detail.tab;
110
+ this.host.requestUpdate();
111
+ }
112
+ handleNetworkChanged(e) {
113
+ this.#wallet?.setActiveNetwork(e.detail.network);
114
+ }
115
+ handleAccountSelected(e) {
116
+ const index = this.accounts.findIndex((a) => a.address === e.detail.account.address);
117
+ if (index !== -1) {
118
+ this.activeAccountIndex = index;
119
+ this.host.requestUpdate();
120
+ }
121
+ }
122
+ handleApproveConnect(e) {
123
+ e.stopPropagation();
124
+ if (!this.#wallet) return;
125
+ try {
126
+ this.#wallet.approveConnect(e.detail.selectedAddresses);
127
+ } catch (error) {
128
+ console.error("[dev-wallet] connect approve failed:", error);
129
+ }
130
+ }
131
+ handleRejectConnect(e) {
132
+ e?.preventDefault();
133
+ if (e instanceof CustomEvent) e.stopPropagation();
134
+ if (!this.#wallet) return;
135
+ try {
136
+ this.#wallet.rejectConnect();
137
+ } catch (error) {
138
+ console.error("[dev-wallet] connect reject failed:", error);
139
+ }
140
+ }
141
+ renderAccountSelector() {
142
+ return html`
143
+ <div class="section">
144
+ <dev-wallet-account-selector
145
+ exportparts="trigger: selector-trigger, copy-button: selector-copy-button, empty-state: selector-empty-state"
146
+ .accounts=${this.accounts}
147
+ .adapters=${this.#wallet ? [...this.#wallet.adapters] : []}
148
+ .activeAddress=${this.activeAddress}
149
+ @account-selected=${(e) => this.handleAccountSelected(e)}
150
+ ></dev-wallet-account-selector>
151
+ </div>
152
+ `;
153
+ }
154
+ renderAssetsTab() {
155
+ return html`
156
+ ${this.renderAccountSelector()}
157
+ ${this.activeAddress && this.#wallet ? html`
158
+ <div class="section">
159
+ <dev-wallet-balances
160
+ exportparts="balance-list, loading: balances-loading, error-message: balances-error-message, empty-state: balances-empty-state"
161
+ .address=${this.activeAddress}
162
+ .client=${this.getActiveClient()}
163
+ ></dev-wallet-balances>
164
+ </div>
165
+ ` : nothing}
166
+ `;
167
+ }
168
+ renderObjectsTab() {
169
+ return html`
170
+ ${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>
176
+ `;
177
+ }
178
+ renderSettingsTab() {
179
+ return html`
180
+ <dev-wallet-settings
181
+ exportparts="accounts-account-list, accounts-add-button, accounts-empty-state"
182
+ .wallet=${this.#wallet}
183
+ .accounts=${this.accounts}
184
+ .adapters=${this.#wallet ? [...this.#wallet.adapters] : []}
185
+ .activeAddress=${this.activeAddress}
186
+ .bookmarkletOrigin=${this.bookmarkletOrigin}
187
+ @account-selected=${(e) => this.handleAccountSelected(e)}
188
+ ></dev-wallet-settings>
189
+ `;
190
+ }
191
+ renderTabContent() {
192
+ if (this.activeTab === "assets") return this.renderAssetsTab();
193
+ if (this.activeTab === "objects") return this.renderObjectsTab();
194
+ if (this.activeTab === "settings") return this.renderSettingsTab();
195
+ return nothing;
196
+ }
197
+ renderSigningModal() {
198
+ if (!this.pendingRequest) return nothing;
199
+ return html`
200
+ <dev-wallet-signing-modal
201
+ exportparts="signing-approve-button, signing-reject-button, signing-request-type, signing-empty-state, signing-error-message, signing-footer, dialog: signing-dialog"
202
+ .request=${this.pendingRequest}
203
+ .client=${this.getActiveClient()}
204
+ .walletName=${this.#wallet?.name ?? "Dev Wallet"}
205
+ @approve=${() => this.handleApprove()}
206
+ @reject=${() => this.handleReject()}
207
+ ></dev-wallet-signing-modal>
208
+ `;
209
+ }
210
+ renderConnectPicker() {
211
+ if (!this.pendingConnect) return nothing;
212
+ const allAccounts = this.#wallet ? this.#wallet.adapters.flatMap((a) => a.getAccounts().map((acc) => ({
213
+ address: acc.address,
214
+ label: acc.label,
215
+ adapterName: a.name
216
+ }))) : [];
217
+ return html`
218
+ <dialog class="connect-dialog" @cancel=${(e) => this.handleRejectConnect(e)}>
219
+ <div class="connect-dialog-header">
220
+ <span class="connect-dialog-title">${this.#wallet?.name ?? "Dev Wallet"}</span>
221
+ </div>
222
+ <dev-wallet-connect
223
+ exportparts="approve-button: connect-approve-button, reject-button: connect-reject-button, account-list: connect-account-list, error-message: connect-error-message"
224
+ .accounts=${allAccounts}
225
+ @approve=${(e) => this.handleApproveConnect(e)}
226
+ @reject=${(e) => this.handleRejectConnect(e)}
227
+ ></dev-wallet-connect>
228
+ </dialog>
229
+ `;
230
+ }
231
+ renderNetworkBadge() {
232
+ if (!this.#wallet) return nothing;
233
+ return html`
234
+ <dev-wallet-network-badge
235
+ exportparts="trigger: network-trigger"
236
+ .active=${this.#wallet.activeNetwork}
237
+ .networks=${this.#wallet.availableNetworks}
238
+ @network-changed=${(e) => this.handleNetworkChanged(e)}
239
+ ></dev-wallet-network-badge>
240
+ `;
241
+ }
242
+ renderTabBar() {
243
+ return html`
244
+ <dev-wallet-tab-bar
245
+ exportparts="tab-bar, tab"
246
+ .active=${this.activeTab}
247
+ @tab-changed=${(e) => this.handleTabChanged(e)}
248
+ ></dev-wallet-tab-bar>
249
+ `;
250
+ }
251
+ #subscribe() {
252
+ if (!this.#wallet) return;
253
+ this.#unsubscribeEvents = this.#wallet.features["standard:events"].on("change", () => {
254
+ this.syncState();
255
+ });
256
+ this.#unsubscribeRequests = this.#wallet.onRequestChange(() => {
257
+ this.syncState();
258
+ });
259
+ this.#unsubscribeConnect = this.#wallet.onConnectChange(() => {
260
+ this.syncConnectState();
261
+ });
262
+ }
263
+ #unsubscribe() {
264
+ this.#unsubscribeEvents?.();
265
+ this.#unsubscribeEvents = null;
266
+ this.#unsubscribeRequests?.();
267
+ this.#unsubscribeRequests = null;
268
+ this.#unsubscribeConnect?.();
269
+ this.#unsubscribeConnect = null;
270
+ }
271
+ };
272
+
273
+ //#endregion
274
+ export { WalletController };
275
+ //# sourceMappingURL=wallet-controller.mjs.map
@@ -0,0 +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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"}
@@ -0,0 +1,11 @@
1
+ //#region src/wallet/constants.ts
2
+ /** Extract the network name from a chain identifier (e.g. 'sui:devnet' → 'devnet'). */
3
+ function getNetworkFromChain(chain) {
4
+ return chain.split(":")[1];
5
+ }
6
+ /** Default wallet icon shared between DevWallet and DevWalletClient. */
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
+ //#endregion
10
+ export { DEFAULT_WALLET_ICON, getNetworkFromChain };
11
+ //# sourceMappingURL=constants.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../../src/wallet/constants.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { StandardEventsListeners, WalletIcon } from '@mysten/wallet-standard';\n\nexport type WalletEventsMap = {\n\t[E in keyof StandardEventsListeners]: Parameters<StandardEventsListeners[E]>[0];\n};\n\n/** Extract the network name from a chain identifier (e.g. 'sui:devnet' → 'devnet'). */\nexport function getNetworkFromChain(chain: string): string | undefined {\n\treturn chain.split(':')[1];\n}\n\n/** Default wallet icon shared between DevWallet and DevWalletClient. */\nexport const DEFAULT_WALLET_ICON: WalletIcon =\n\t'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCIgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0Ij4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0id2FsbGV0R3JhZCIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+CiAgICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiM2MzY2RjEiIC8+CiAgICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6IzI1NjNFQiIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImZsYXBHcmFkIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzgxOENGOCIgLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjojNEY0NkU1IiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICA8L2RlZnM+CiAgPCEtLSBTaGFkb3cgLS0+CiAgPHJlY3QgeD0iOSIgeT0iMjEiIHdpZHRoPSI1MCIgaGVpZ2h0PSIzNiIgcng9IjYiIHJ5PSI2IiBmaWxsPSIjMDAwIiBvcGFjaXR5PSIwLjEiIC8+CiAgPCEtLSBXYWxsZXQgYm9keSAtLT4KICA8cmVjdCB4PSI2IiB5PSIxOCIgd2lkdGg9IjUwIiBoZWlnaHQ9IjM2IiByeD0iNiIgcnk9IjYiIGZpbGw9InVybCgjd2FsbGV0R3JhZCkiIC8+CiAgPCEtLSBGbGFwIC0tPgogIDxwYXRoIGQ9Ik02IDI2IEw2IDIyIEM2IDE1IDggMTIgMTQgMTIgTDQ2IDEyIEM1MiAxMiA1NiAxNSA1NiAyMiBMNTYgMjYgWiIgZmlsbD0idXJsKCNmbGFwR3JhZCkiIC8+CiAgPCEtLSBDbGFzcCAtLT4KICA8cmVjdCB4PSI0MiIgeT0iMzAiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxMiIgcng9IjQiIHJ5PSI0IiBmaWxsPSIjNDMzOENBIiAvPgogIDwhLS0gR29sZCBjb2luIGluIGNsYXNwIC0tPgogIDxjaXJjbGUgY3g9IjQ4IiBjeT0iMzYiIHI9IjMuNSIgZmlsbD0iI0ZDRDM0RCIgLz4KICA8Y2lyY2xlIGN4PSI0OCIgY3k9IjM2IiByPSIyIiBmaWxsPSIjRjU5RTBCIiAvPgogIDwhLS0gRW1ib3NzZWQgRFcgdGV4dCAtLT4KICA8dGV4dCB4PSIyNiIgeT0iNDUiIGZvbnQtZmFtaWx5PSJBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0iOTAwIiBmb250LXNpemU9IjE4IiBmaWxsPSIjMzczMEEzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBkb21pbmFudC1iYXNlbGluZT0ibWlkZGxlIiBsZXR0ZXItc3BhY2luZz0iMiI+RFc8L3RleHQ+CiAgPHRleHQgeD0iMjYiIHk9IjQ0IiBmb250LWZhbWlseT0iQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZiIgZm9udC13ZWlnaHQ9IjkwMCIgZm9udC1zaXplPSIxOCIgZmlsbD0iI0M3RDJGRSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGxlIiBsZXR0ZXItc3BhY2luZz0iMiI+RFc8L3RleHQ+Cjwvc3ZnPgo=';\n"],"mappings":";;AAUA,SAAgB,oBAAoB,OAAmC;AACtE,QAAO,MAAM,MAAM,IAAI,CAAC;;;AAIzB,MAAa,sBACZ"}
@@ -0,0 +1,118 @@
1
+ import { SignerAdapter } from "../types.mjs";
2
+ import { SigningResult } from "./signing.mjs";
3
+ import { ReadonlyWalletAccount, StandardConnectFeature, StandardDisconnectFeature, StandardEventsFeature, SuiFeatures, Wallet, WalletAccount, WalletIcon } from "@mysten/wallet-standard";
4
+ import { ClientWithCoreApi } from "@mysten/sui/client";
5
+
6
+ //#region src/wallet/dev-wallet.d.ts
7
+ /**
8
+ * Default gRPC endpoint URLs for standard Sui networks (devnet, testnet, localnet).
9
+ */
10
+ declare const DEFAULT_NETWORK_URLS: {
11
+ readonly devnet: "https://fullnode.devnet.sui.io:443";
12
+ readonly testnet: "https://fullnode.testnet.sui.io:443";
13
+ readonly localnet: "http://127.0.0.1:9000";
14
+ };
15
+ /** A pending signing request waiting for user approval via the wallet UI. */
16
+ interface WalletRequest {
17
+ id: string;
18
+ type: 'sign-transaction' | 'sign-and-execute-transaction' | 'sign-personal-message';
19
+ account: WalletAccount;
20
+ chain: string;
21
+ /** Transaction JSON string for sign/execute, Uint8Array for personal messages. */
22
+ data: string | Uint8Array;
23
+ resolve: (result: SigningResult) => void;
24
+ reject: (error: Error) => void;
25
+ }
26
+ /** Public view of a pending signing request, omitting internal resolve/reject callbacks. */
27
+ type PendingSigningRequest = Omit<WalletRequest, 'resolve' | 'reject'>;
28
+ interface ConnectRequest {
29
+ id: string;
30
+ resolve: (result: {
31
+ accounts: readonly WalletAccount[];
32
+ }) => void;
33
+ reject: (error: Error) => void;
34
+ }
35
+ /** Public view of a pending connect request, omitting internal resolve/reject callbacks. */
36
+ type PendingConnectRequest = Omit<ConnectRequest, 'resolve' | 'reject'>;
37
+ /**
38
+ * Auto-approval policy for signing requests.
39
+ * `true` approves all requests; a function is called per-request and returns `true` to approve.
40
+ */
41
+ type AutoApprovePolicy = boolean | ((request: {
42
+ type: WalletRequest['type'];
43
+ account: WalletAccount;
44
+ chain: string;
45
+ data: string | Uint8Array;
46
+ }) => boolean);
47
+ interface DevWalletConfig {
48
+ adapters: SignerAdapter[];
49
+ /** Network URLs by name (network → gRPC endpoint). Defaults to devnet, testnet, and localnet. */
50
+ networks?: Record<string, string>;
51
+ /** Display name for the wallet. Defaults to 'Dev Wallet'. */
52
+ name?: string;
53
+ icon?: WalletIcon;
54
+ /** Initially active network. Defaults to the first key in `networks`. */
55
+ activeNetwork?: string;
56
+ /**
57
+ * When set, matching requests are signed immediately without queuing for user approval.
58
+ * `true` approves everything; a function is called per-request for fine-grained control.
59
+ */
60
+ autoApprove?: AutoApprovePolicy;
61
+ /** When true, connect requests resolve immediately with all accounts. */
62
+ autoConnect?: boolean;
63
+ /** Factory to create a client for a given network. Defaults to SuiGrpcClient. */
64
+ clientFactory?: (network: string, url: string) => ClientWithCoreApi;
65
+ /**
66
+ * Persist network URLs to localStorage so custom configurations survive page reloads
67
+ * and are shared with popup windows.
68
+ */
69
+ persistNetworks?: boolean;
70
+ }
71
+ /**
72
+ * wallet-standard Wallet implementation for development. All signing requests are queued
73
+ * and require explicit approval — either via the UI or programmatically via `approveRequest()`.
74
+ */
75
+ declare class DevWallet implements Wallet {
76
+ #private;
77
+ constructor(config: DevWalletConfig);
78
+ get version(): "1.0.0";
79
+ get name(): string;
80
+ get icon(): `data:image/svg+xml;base64,${string}` | `data:image/webp;base64,${string}` | `data:image/png;base64,${string}` | `data:image/gif;base64,${string}`;
81
+ get chains(): readonly ["sui:devnet", "sui:testnet", "sui:localnet", "sui:mainnet"];
82
+ get accounts(): readonly ReadonlyWalletAccount[];
83
+ get features(): StandardConnectFeature & StandardEventsFeature & StandardDisconnectFeature & SuiFeatures;
84
+ /** The current pending signing request, or null if none. */
85
+ get pendingRequest(): PendingSigningRequest | null;
86
+ get adapters(): readonly SignerAdapter[];
87
+ getAdapterForAccount(address: string): SignerAdapter | undefined;
88
+ /** Eagerly creates and returns clients for all configured networks. Prefer `getClient()` or `activeClient` for single-network access. */
89
+ get clients(): Record<string, ClientWithCoreApi>;
90
+ getClient(network: string): ClientWithCoreApi;
91
+ get networkUrls(): Record<string, string>;
92
+ get activeNetwork(): string;
93
+ get activeClient(): ClientWithCoreApi | null;
94
+ get availableNetworks(): string[];
95
+ /** Switch the active network. Emits a `change` event. */
96
+ setActiveNetwork(network: string): void;
97
+ addNetwork(name: string, url: string): void;
98
+ removeNetwork(name: string): void;
99
+ /** Register this wallet with the wallet-standard registry. Returns an unregister function. */
100
+ register(): () => void;
101
+ /** Reject any pending requests, unsubscribe from adapters, destroy them, and clear all listeners. */
102
+ destroy(): void;
103
+ /** Sign the pending request using the account's adapter signer and resolve the promise. */
104
+ approveRequest(): Promise<void>;
105
+ rejectRequest(reason?: string): void;
106
+ /** Subscribe to pending request changes. Returns an unsubscribe function. */
107
+ onRequestChange(callback: (request: PendingSigningRequest | null) => void): () => void;
108
+ /** The current pending connect request, or null if none. */
109
+ get pendingConnect(): PendingConnectRequest | null;
110
+ /** Expose the given addresses to the dApp. Pass an empty array to expose all accounts. */
111
+ approveConnect(selectedAddresses: string[]): void;
112
+ rejectConnect(reason?: string): void;
113
+ /** Subscribe to pending connect request changes. Returns an unsubscribe function. */
114
+ onConnectChange(callback: (request: PendingConnectRequest | null) => void): () => void;
115
+ }
116
+ //#endregion
117
+ export { AutoApprovePolicy, DEFAULT_NETWORK_URLS, DevWallet, DevWalletConfig, PendingConnectRequest, PendingSigningRequest };
118
+ //# sourceMappingURL=dev-wallet.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-wallet.d.mts","names":[],"sources":["../../src/wallet/dev-wallet.ts"],"mappings":";;;;;;;AAiCA;;cAAa,oBAAA;EAAA;;;;;UAOI,aAAA;EAChB,EAAA;EACA,IAAA;EACA,OAAA,EAAS,aAAA;EACT,KAAA;EAEe;EAAf,IAAA,WAAe,UAAA;EACf,OAAA,GAAU,MAAA,EAAQ,aAAA;EAClB,MAAA,GAAS,KAAA,EAAO,KAAA;AAAA;;KAIL,qBAAA,GAAwB,IAAA,CAAK,aAAA;AAAA,UAExB,cAAA;EAChB,EAAA;EACA,OAAA,GAAU,MAAA;IAAU,QAAA,WAAmB,aAAA;EAAA;EACvC,MAAA,GAAS,KAAA,EAAO,KAAA;AAAA;;KAIL,qBAAA,GAAwB,IAAA,CAAK,cAAA;;;;;KAM7B,iBAAA,eAEP,OAAA;EACF,IAAA,EAAM,aAAA;EACN,OAAA,EAAS,aAAA;EACT,KAAA;EACA,IAAA,WAAe,UAAA;AAAA;AAAA,UAGD,eAAA;EAChB,QAAA,EAAU,aAAA;EApBW;EAsBrB,QAAA,GAAW,MAAA;EAvBX;EAyBA,IAAA;EACA,IAAA,GAAO,UAAA;EA1BG;EA4BV,aAAA;EA3BgB;;;;EAgChB,WAAA,GAAc,iBAAA;EA5BkB;EA8BhC,WAAA;EA9BmC;EAgCnC,aAAA,IAAiB,OAAA,UAAiB,GAAA,aAAgB,iBAAA;EA1BvC;;;;EA+BX,eAAA;AAAA;;;;;cAOY,SAAA,YAAqB,MAAA;EAAA;cAoBrB,MAAA,EAAQ,eAAA;EAAA,IA0BhB,OAAA,CAAA;EAAA,IAIA,IAAA,CAAA;EAAA,IAIA,IAAA,CAAA;EAAA,IAIA,MAAA,CAAA;EAAA,IAIA,QAAA,CAAA,YAAqB,qBAAA;EAAA,IAIrB,QAAA,CAAA,GAAY,sBAAA,GACf,qBAAA,GACA,yBAAA,GACA,WAAA;EAlG8B;EAAA,IAgI3B,cAAA,CAAA,GAAkB,qBAAA;EAAA,IAIlB,QAAA,CAAA,YAAqB,aAAA;EAIzB,oBAAA,CAAqB,OAAA,WAAkB,aAAA;EAlIhC;EAAA,IAuIH,OAAA,CAAA,GAAW,MAAA,SAAe,iBAAA;EAO9B,SAAA,CAAU,OAAA,WAAkB,iBAAA;EAAA,IAIxB,WAAA,CAAA,GAAe,MAAA;EAAA,IAIf,aAAA,CAAA;EAAA,IAIA,YAAA,CAAA,GAAgB,iBAAA;EAAA,IAKhB,iBAAA,CAAA;EAlKJ;EAuKA,gBAAA,CAAiB,OAAA;EAUjB,UAAA,CAAW,IAAA,UAAc,GAAA;EAgBzB,aAAA,CAAc,IAAA;EA9LP;EAyMP,QAAA,CAAA;EAlMA;EA6MA,OAAA,CAAA;EA3MA;EAkOM,cAAA,CAAA,GAAkB,OAAA;EAuBxB,aAAA,CAAc,MAAA;EAvPoB;EAkQlC,eAAA,CAAgB,QAAA,GAAW,OAAA,EAAS,qBAAA;EA7PpC;EAAA,IAqQI,cAAA,CAAA,GAAkB,qBAAA;EArQP;EA0Qf,cAAA,CAAe,iBAAA;EAgBf,aAAA,CAAc,MAAA;;EAWd,eAAA,CAAgB,QAAA,GAAW,OAAA,EAAS,qBAAA;AAAA"}