@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,87 @@
1
+ import { buildManagedAccount } from "./build-managed-account.mjs";
2
+ import { BaseSignerAdapter } from "./base-adapter.mjs";
3
+ import { IDBStore } from "./idb-store.mjs";
4
+ import { PasskeyKeypair } from "@mysten/sui/keypairs/passkey";
5
+
6
+ //#region src/adapters/passkey-adapter.ts
7
+ const DEFAULT_DB_NAME = "dev-wallet-passkey";
8
+ const DEFAULT_STORE_NAME = "accounts";
9
+ const META_KEY = "__passkey_accounts__";
10
+ /**
11
+ * Signer adapter backed by WebAuthn passkeys. Each signing operation triggers a
12
+ * browser biometric/PIN prompt. Account metadata is persisted in IndexedDB;
13
+ * private keys are managed by the browser/OS and never enter JavaScript.
14
+ *
15
+ * Browser only — requires `navigator.credentials` and `indexedDB`.
16
+ */
17
+ var PasskeySignerAdapter = class extends BaseSignerAdapter {
18
+ #store;
19
+ #provider;
20
+ constructor(options) {
21
+ super();
22
+ this.id = "passkey";
23
+ this.name = "Passkey Signer";
24
+ this.allowAutoSign = false;
25
+ this.#store = new IDBStore(options?.dbName ?? DEFAULT_DB_NAME, options?.storeName ?? DEFAULT_STORE_NAME);
26
+ this.#provider = options?.provider ?? null;
27
+ }
28
+ #getProvider() {
29
+ if (!this.#provider) {
30
+ throw new Error("PasskeySignerAdapter not initialized. Call initialize() first.");
31
+ }
32
+ return this.#provider;
33
+ }
34
+ async initialize() {
35
+ if (!this.#provider) {
36
+ const { BrowserPasskeyProvider } = await import("@mysten/sui/keypairs/passkey");
37
+ this.#provider = new BrowserPasskeyProvider("Dev Wallet Passkey", { rp: { id: globalThis.location?.hostname } });
38
+ }
39
+ const stored = await this.#store.get(META_KEY);
40
+ if (!stored) return;
41
+ const provider = this.#getProvider();
42
+ this.setInitialAccounts(stored.map((meta) => {
43
+ const publicKeyBytes = new Uint8Array(meta.publicKeyBytes);
44
+ const credentialId = meta.credentialId ? new Uint8Array(meta.credentialId) : undefined;
45
+ const signer = new PasskeyKeypair(publicKeyBytes, provider, credentialId);
46
+ return buildManagedAccount(signer, meta.address, meta.label);
47
+ }));
48
+ }
49
+ getDefaultLabel() {
50
+ return `Passkey Account ${this.getAccounts().length + 1}`;
51
+ }
52
+ async createAccount(options) {
53
+ const signer = await PasskeyKeypair.getPasskeyInstance(this.#getProvider());
54
+ const address = signer.toSuiAddress();
55
+ const label = options?.label ?? this.getDefaultLabel();
56
+ const managedAccount = buildManagedAccount(signer, address, label);
57
+ this.addAccount(managedAccount);
58
+ await this.#saveMeta();
59
+ return managedAccount;
60
+ }
61
+ async renameAccount(address, label) {
62
+ if (!this._performRename(address, label)) return false;
63
+ await this.#saveMeta();
64
+ return true;
65
+ }
66
+ async removeAccount(address) {
67
+ if (!this.removeAccountByAddress(address)) return false;
68
+ await this.#saveMeta();
69
+ return true;
70
+ }
71
+ async #saveMeta() {
72
+ const meta = this.getAccounts().map((a) => {
73
+ const credentialId = a.signer.getCredentialId?.();
74
+ return {
75
+ address: a.address,
76
+ label: a.label,
77
+ publicKeyBytes: [...a.signer.getPublicKey().toRawBytes()],
78
+ ...credentialId && { credentialId: [...credentialId] }
79
+ };
80
+ });
81
+ await this.#store.set(META_KEY, meta);
82
+ }
83
+ };
84
+
85
+ //#endregion
86
+ export { PasskeySignerAdapter };
87
+ //# sourceMappingURL=passkey-adapter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-adapter.mjs","names":["#store","#provider","#getProvider","#saveMeta"],"sources":["../../src/adapters/passkey-adapter.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { PasskeyKeypair } from '@mysten/sui/keypairs/passkey';\nimport type { PasskeyProvider } from '@mysten/sui/keypairs/passkey';\n\nimport type { CreateAccountOptions } from '../types.js';\nimport { BaseSignerAdapter } from './base-adapter.js';\nimport { buildManagedAccount } from './build-managed-account.js';\nimport { IDBStore } from './idb-store.js';\n\n/** Metadata stored in IndexedDB for each passkey account. */\ninterface StoredPasskeyMeta {\n\taddress: string;\n\tlabel: string;\n\t/** Compressed secp256r1 public key (33 bytes, stored as number array). */\n\tpublicKeyBytes: number[];\n\t/** WebAuthn credential ID (stored as number array). Used to constrain credential selection during signing. */\n\tcredentialId?: number[];\n}\n\nconst DEFAULT_DB_NAME = 'dev-wallet-passkey';\nconst DEFAULT_STORE_NAME = 'accounts';\nconst META_KEY = '__passkey_accounts__';\n\n/**\n * Signer adapter backed by WebAuthn passkeys. Each signing operation triggers a\n * browser biometric/PIN prompt. Account metadata is persisted in IndexedDB;\n * private keys are managed by the browser/OS and never enter JavaScript.\n *\n * Browser only — requires `navigator.credentials` and `indexedDB`.\n */\nexport class PasskeySignerAdapter extends BaseSignerAdapter {\n\treadonly id = 'passkey';\n\treadonly name = 'Passkey Signer';\n\treadonly allowAutoSign = false;\n\n\t#store: IDBStore;\n\t#provider: PasskeyProvider | null;\n\n\tconstructor(options?: { dbName?: string; storeName?: string; provider?: PasskeyProvider }) {\n\t\tsuper();\n\t\tthis.#store = new IDBStore(\n\t\t\toptions?.dbName ?? DEFAULT_DB_NAME,\n\t\t\toptions?.storeName ?? DEFAULT_STORE_NAME,\n\t\t);\n\t\t// Allow injecting a custom provider (useful for testing)\n\t\tthis.#provider = options?.provider ?? null;\n\t}\n\n\t#getProvider(): PasskeyProvider {\n\t\tif (!this.#provider) {\n\t\t\tthrow new Error('PasskeySignerAdapter not initialized. Call initialize() first.');\n\t\t}\n\t\treturn this.#provider;\n\t}\n\n\tasync initialize(): Promise<void> {\n\t\tif (!this.#provider) {\n\t\t\tconst { BrowserPasskeyProvider } = await import('@mysten/sui/keypairs/passkey');\n\t\t\tthis.#provider = new BrowserPasskeyProvider('Dev Wallet Passkey', {\n\t\t\t\trp: { id: globalThis.location?.hostname },\n\t\t\t});\n\t\t}\n\n\t\tconst stored = await this.#store.get<StoredPasskeyMeta[]>(META_KEY);\n\t\tif (!stored) return;\n\n\t\tconst provider = this.#getProvider();\n\t\tthis.setInitialAccounts(\n\t\t\tstored.map((meta) => {\n\t\t\t\tconst publicKeyBytes = new Uint8Array(meta.publicKeyBytes);\n\t\t\t\tconst credentialId = meta.credentialId ? new Uint8Array(meta.credentialId) : undefined;\n\t\t\t\tconst signer = new PasskeyKeypair(publicKeyBytes, provider, credentialId);\n\t\t\t\treturn buildManagedAccount(signer, meta.address, meta.label);\n\t\t\t}),\n\t\t);\n\t}\n\n\tprotected override getDefaultLabel(): string {\n\t\treturn `Passkey Account ${this.getAccounts().length + 1}`;\n\t}\n\n\tasync createAccount(options?: CreateAccountOptions) {\n\t\tconst signer = await PasskeyKeypair.getPasskeyInstance(this.#getProvider());\n\t\tconst address = signer.toSuiAddress();\n\t\tconst label = options?.label ?? this.getDefaultLabel();\n\n\t\tconst managedAccount = buildManagedAccount(signer, address, label);\n\t\tthis.addAccount(managedAccount);\n\t\tawait this.#saveMeta();\n\n\t\treturn managedAccount;\n\t}\n\n\tasync renameAccount(address: string, label: string): Promise<boolean> {\n\t\tif (!this._performRename(address, label)) return false;\n\t\tawait this.#saveMeta();\n\t\treturn true;\n\t}\n\n\tasync removeAccount(address: string): Promise<boolean> {\n\t\tif (!this.removeAccountByAddress(address)) return false;\n\t\tawait this.#saveMeta();\n\t\treturn true;\n\t}\n\n\tasync #saveMeta(): Promise<void> {\n\t\tconst meta: StoredPasskeyMeta[] = this.getAccounts().map((a) => {\n\t\t\tconst credentialId = (a.signer as PasskeyKeypair).getCredentialId?.();\n\t\t\treturn {\n\t\t\t\taddress: a.address,\n\t\t\t\tlabel: a.label,\n\t\t\t\tpublicKeyBytes: [...a.signer.getPublicKey().toRawBytes()],\n\t\t\t\t...(credentialId && { credentialId: [...credentialId] }),\n\t\t\t};\n\t\t});\n\t\tawait this.#store.set(META_KEY, meta);\n\t}\n}\n"],"mappings":";;;;;;AAqBA,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;AAC3B,MAAM,WAAW;;;;;;;;AASjB,IAAa,uBAAb,cAA0C,kBAAkB;CAK3D;CACA;CAEA,YAAY,SAA+E;AAC1F,SAAO;YARM;cACE;uBACS;AAOxB,QAAKA,QAAS,IAAI,SACjB,SAAS,UAAU,iBACnB,SAAS,aAAa,mBACtB;AAED,QAAKC,WAAY,SAAS,YAAY;;CAGvC,eAAgC;AAC/B,MAAI,CAAC,MAAKA,UAAW;AACpB,SAAM,IAAI,MAAM,iEAAiE;;AAElF,SAAO,MAAKA;;CAGb,MAAM,aAA4B;AACjC,MAAI,CAAC,MAAKA,UAAW;GACpB,MAAM,EAAE,2BAA2B,MAAM,OAAO;AAChD,SAAKA,WAAY,IAAI,uBAAuB,sBAAsB,EACjE,IAAI,EAAE,IAAI,WAAW,UAAU,UAAU,EACzC,CAAC;;EAGH,MAAM,SAAS,MAAM,MAAKD,MAAO,IAAyB,SAAS;AACnE,MAAI,CAAC,OAAQ;EAEb,MAAM,WAAW,MAAKE,aAAc;AACpC,OAAK,mBACJ,OAAO,KAAK,SAAS;GACpB,MAAM,iBAAiB,IAAI,WAAW,KAAK,eAAe;GAC1D,MAAM,eAAe,KAAK,eAAe,IAAI,WAAW,KAAK,aAAa,GAAG;GAC7E,MAAM,SAAS,IAAI,eAAe,gBAAgB,UAAU,aAAa;AACzE,UAAO,oBAAoB,QAAQ,KAAK,SAAS,KAAK,MAAM;IAC3D,CACF;;CAGF,AAAmB,kBAA0B;AAC5C,SAAO,mBAAmB,KAAK,aAAa,CAAC,SAAS;;CAGvD,MAAM,cAAc,SAAgC;EACnD,MAAM,SAAS,MAAM,eAAe,mBAAmB,MAAKA,aAAc,CAAC;EAC3E,MAAM,UAAU,OAAO,cAAc;EACrC,MAAM,QAAQ,SAAS,SAAS,KAAK,iBAAiB;EAEtD,MAAM,iBAAiB,oBAAoB,QAAQ,SAAS,MAAM;AAClE,OAAK,WAAW,eAAe;AAC/B,QAAM,MAAKC,UAAW;AAEtB,SAAO;;CAGR,MAAM,cAAc,SAAiB,OAAiC;AACrE,MAAI,CAAC,KAAK,eAAe,SAAS,MAAM,CAAE,QAAO;AACjD,QAAM,MAAKA,UAAW;AACtB,SAAO;;CAGR,MAAM,cAAc,SAAmC;AACtD,MAAI,CAAC,KAAK,uBAAuB,QAAQ,CAAE,QAAO;AAClD,QAAM,MAAKA,UAAW;AACtB,SAAO;;CAGR,OAAMA,WAA2B;EAChC,MAAM,OAA4B,KAAK,aAAa,CAAC,KAAK,MAAM;GAC/D,MAAM,eAAgB,EAAE,OAA0B,mBAAmB;AACrE,UAAO;IACN,SAAS,EAAE;IACX,OAAO,EAAE;IACT,gBAAgB,CAAC,GAAG,EAAE,OAAO,cAAc,CAAC,YAAY,CAAC;IACzD,GAAI,gBAAgB,EAAE,cAAc,CAAC,GAAG,aAAa,EAAE;IACvD;IACA;AACF,QAAM,MAAKH,MAAO,IAAI,UAAU,KAAK"}
@@ -0,0 +1,65 @@
1
+ import { ImportAccountOptions, ManagedAccount } from "../types.mjs";
2
+ import { BaseSignerAdapter } from "./base-adapter.mjs";
3
+ import { PublicKey, SignatureScheme, Signer } from "@mysten/sui/cryptography";
4
+
5
+ //#region src/adapters/remote-cli-adapter.d.ts
6
+ /**
7
+ * A {@link Signer} that delegates transaction signing to a server HTTP endpoint
8
+ * backed by `sui keytool sign`. Private keys never enter JavaScript.
9
+ *
10
+ * `signPersonalMessage()` is not supported — `sui keytool sign` only accepts
11
+ * BCS-serialized `TransactionData`.
12
+ */
13
+ declare class CliProxySigner extends Signer {
14
+ #private;
15
+ constructor(options: {
16
+ address: string;
17
+ publicKey: PublicKey;
18
+ scheme: SignatureScheme;
19
+ serverOrigin: string;
20
+ authToken?: string | null;
21
+ });
22
+ sign(_bytes: Uint8Array): Promise<Uint8Array<ArrayBuffer>>;
23
+ getKeyScheme(): SignatureScheme;
24
+ getPublicKey(): PublicKey;
25
+ toSuiAddress(): string;
26
+ signTransaction(bytes: Uint8Array): Promise<{
27
+ bytes: string;
28
+ signature: string;
29
+ }>;
30
+ signPersonalMessage(_bytes: Uint8Array): Promise<never>;
31
+ }
32
+ /**
33
+ * {@link SignerAdapter} that delegates signing to a server running the `sui` CLI.
34
+ *
35
+ * Authentication uses a token-in-URL approach: the CLI server prints a URL with
36
+ * a token, which gets stored in `localStorage` for subsequent page loads. Imported
37
+ * account addresses are also persisted so they survive CLI restarts.
38
+ */
39
+ declare class RemoteCliAdapter extends BaseSignerAdapter {
40
+ #private;
41
+ readonly id = "remote-cli";
42
+ readonly name = "Remote CLI Signer";
43
+ readonly allowAutoSign = false;
44
+ protected getDefaultLabel(): string;
45
+ static storageKey(suffix: string): string;
46
+ static get STORAGE_KEY(): string;
47
+ static get TOKEN_KEY(): string;
48
+ constructor(options?: {
49
+ serverOrigin?: string;
50
+ token?: string;
51
+ });
52
+ get isPaired(): boolean;
53
+ initialize(): Promise<void>;
54
+ listAvailableAccounts(): Promise<Array<{
55
+ address: string;
56
+ scheme: string;
57
+ alias: string | null;
58
+ }>>;
59
+ importAccount(options: ImportAccountOptions): Promise<ManagedAccount>;
60
+ removeAccount(address: string): Promise<boolean>;
61
+ destroy(): void;
62
+ }
63
+ //#endregion
64
+ export { CliProxySigner, RemoteCliAdapter };
65
+ //# sourceMappingURL=remote-cli-adapter.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-cli-adapter.d.mts","names":[],"sources":["../../src/adapters/remote-cli-adapter.ts"],"mappings":";;;;;;AAqEA;;;;;;cAAa,cAAA,SAAuB,MAAA;EAAA;cAOvB,OAAA;IACX,OAAA;IACA,SAAA,EAAW,SAAA;IACX,MAAA,EAAQ,eAAA;IACR,YAAA;IACA,SAAA;EAAA;EAUK,IAAA,CAAK,MAAA,EAAQ,UAAA,GAAa,OAAA,CAAQ,UAAA,CAAW,WAAA;EAOnD,YAAA,CAAA,GAAgB,eAAA;EAIhB,YAAA,CAAA,GAAgB,SAAA;EAIP,YAAA,CAAA;EAIM,eAAA,CAAgB,KAAA,EAAO,UAAA,GAAU,OAAA;;;;EA8BjC,mBAAA,CAAoB,MAAA,EAAQ,UAAA,GAAa,OAAA;AAAA;;;;;;;;cAgB5C,gBAAA,SAAyB,iBAAA;EAAA;WAC5B,EAAA;EAAA,SACA,IAAA;EAAA,SACA,aAAA;EAAA,UAEU,eAAA,CAAA;EAAA,OAOZ,UAAA,CAAW,MAAA;EAAA,WAKP,WAAA,CAAA;EAAA,WAIA,SAAA,CAAA;cASC,OAAA;IAAY,YAAA;IAAuB,KAAA;EAAA;EAAA,IAgB3C,QAAA,CAAA;EAIE,UAAA,CAAA,GAAc,OAAA;EAyBd,qBAAA,CAAA,GAAyB,OAAA,CAC9B,KAAA;IAAQ,OAAA;IAAiB,MAAA;IAAgB,KAAA;EAAA;EAgBpC,aAAA,CAAc,OAAA,EAAS,oBAAA,GAAuB,OAAA,CAAQ,cAAA;EA2BtD,aAAA,CAAc,OAAA,WAAkB,OAAA;EAQ7B,OAAA,CAAA;AAAA"}
@@ -0,0 +1,299 @@
1
+ import { buildManagedAccount } from "./build-managed-account.mjs";
2
+ import { BaseSignerAdapter } from "./base-adapter.mjs";
3
+ import { fromBase64, toBase64 } from "@mysten/sui/utils";
4
+ import { Ed25519PublicKey } from "@mysten/sui/keypairs/ed25519";
5
+ import { Signer } from "@mysten/sui/cryptography";
6
+ import { Secp256k1PublicKey } from "@mysten/sui/keypairs/secp256k1";
7
+ import { Secp256r1PublicKey } from "@mysten/sui/keypairs/secp256r1";
8
+
9
+ //#region src/adapters/remote-cli-adapter.ts
10
+ /**
11
+ * Wallet features advertised by CLI-backed accounts.
12
+ * Personal message signing is not supported because the `sui keytool sign`
13
+ * command only accepts BCS-serialized TransactionData.
14
+ */
15
+ const CLI_WALLET_FEATURES = ["sui:signTransaction", "sui:signAndExecuteTransaction"];
16
+ /** Cache TTL for the CLI server accounts fetch (milliseconds). */
17
+ const ACCOUNTS_CACHE_TTL_MS = 5e3;
18
+ /** Thrown when the server rejects a request with a 401 or 403 status. */
19
+ var AuthError = class extends Error {
20
+ constructor() {
21
+ super("Unauthorized");
22
+ this.name = "AuthError";
23
+ }
24
+ };
25
+ /** Map CLI `keyScheme` strings to SDK {@link SignatureScheme} values. */
26
+ const KEY_SCHEME_MAP = {
27
+ ed25519: "ED25519",
28
+ secp256k1: "Secp256k1",
29
+ secp256r1: "Secp256r1"
30
+ };
31
+ function publicKeyFromSuiBytes(publicBase64Key, scheme) {
32
+ const allBytes = fromBase64(publicBase64Key);
33
+ const rawBytes = allBytes.slice(1);
34
+ switch (scheme) {
35
+ case "ED25519": return new Ed25519PublicKey(rawBytes);
36
+ case "Secp256k1": return new Secp256k1PublicKey(rawBytes);
37
+ case "Secp256r1": return new Secp256r1PublicKey(rawBytes);
38
+ default: throw new Error(`Unsupported key scheme: ${scheme}`);
39
+ }
40
+ }
41
+ /**
42
+ * A {@link Signer} that delegates transaction signing to a server HTTP endpoint
43
+ * backed by `sui keytool sign`. Private keys never enter JavaScript.
44
+ *
45
+ * `signPersonalMessage()` is not supported — `sui keytool sign` only accepts
46
+ * BCS-serialized `TransactionData`.
47
+ */
48
+ var CliProxySigner = class extends Signer {
49
+ #address;
50
+ #publicKey;
51
+ #scheme;
52
+ #serverOrigin;
53
+ #authToken;
54
+ constructor(options) {
55
+ super();
56
+ this.#address = options.address;
57
+ this.#publicKey = options.publicKey;
58
+ this.#scheme = options.scheme;
59
+ this.#serverOrigin = options.serverOrigin;
60
+ this.#authToken = options.authToken ?? null;
61
+ }
62
+ async sign(_bytes) {
63
+ throw new Error("CliProxySigner does not support direct digest signing. " + "Transaction signing is handled via the sui CLI.");
64
+ }
65
+ getKeyScheme() {
66
+ return this.#scheme;
67
+ }
68
+ getPublicKey() {
69
+ return this.#publicKey;
70
+ }
71
+ toSuiAddress() {
72
+ return this.#address;
73
+ }
74
+ async signTransaction(bytes) {
75
+ const headers = { "Content-Type": "application/json" };
76
+ if (this.#authToken) {
77
+ headers["Authorization"] = `Bearer ${this.#authToken}`;
78
+ }
79
+ const res = await fetch(`${this.#serverOrigin}/api/v1/sign-transaction`, {
80
+ method: "POST",
81
+ headers,
82
+ body: JSON.stringify({
83
+ address: this.#address,
84
+ txBytes: toBase64(bytes)
85
+ })
86
+ });
87
+ if (!res.ok) {
88
+ const body = await res.json().catch(() => ({}));
89
+ throw new Error(`Transaction signing failed: ${body.error ?? res.statusText}`);
90
+ }
91
+ const { suiSignature } = await res.json();
92
+ if (typeof suiSignature !== "string" || suiSignature.length === 0) {
93
+ throw new Error("Transaction signing failed: server returned invalid signature");
94
+ }
95
+ return {
96
+ bytes: toBase64(bytes),
97
+ signature: suiSignature
98
+ };
99
+ }
100
+ async signPersonalMessage(_bytes) {
101
+ throw new Error("Personal message signing is not supported in CLI mode. " + "The sui keytool sign command only supports TransactionData. " + "Use --adapter=webcrypto or --adapter=memory for personal message signing.");
102
+ }
103
+ };
104
+ /**
105
+ * {@link SignerAdapter} that delegates signing to a server running the `sui` CLI.
106
+ *
107
+ * Authentication uses a token-in-URL approach: the CLI server prints a URL with
108
+ * a token, which gets stored in `localStorage` for subsequent page loads. Imported
109
+ * account addresses are also persisted so they survive CLI restarts.
110
+ */
111
+ var RemoteCliAdapter = class RemoteCliAdapter extends BaseSignerAdapter {
112
+ getDefaultLabel() {
113
+ return `CLI Account ${this.getAccounts().length + 1}`;
114
+ }
115
+ static storageKey(suffix) {
116
+ const origin = typeof location !== "undefined" ? location.origin : "unknown";
117
+ return `dev-wallet:${suffix}:${origin}`;
118
+ }
119
+ static get STORAGE_KEY() {
120
+ return RemoteCliAdapter.storageKey("cli-imported-addresses");
121
+ }
122
+ static get TOKEN_KEY() {
123
+ return RemoteCliAdapter.storageKey("cli-token");
124
+ }
125
+ #serverOrigin;
126
+ #authToken = null;
127
+ #allServerAccounts = [];
128
+ #lastFetch = null;
129
+ constructor(options) {
130
+ super();
131
+ this.id = "remote-cli";
132
+ this.name = "Remote CLI Signer";
133
+ this.allowAutoSign = false;
134
+ const origin = options?.serverOrigin ?? "";
135
+ if (origin) {
136
+ try {
137
+ new URL(origin);
138
+ } catch {
139
+ throw new Error(`Invalid serverOrigin URL: "${origin}"`);
140
+ }
141
+ }
142
+ this.#serverOrigin = origin;
143
+ if (options?.token) {
144
+ this.#authToken = options.token;
145
+ }
146
+ }
147
+ get isPaired() {
148
+ return this.#authToken !== null;
149
+ }
150
+ async initialize() {
151
+ if (!this.#authToken && typeof localStorage !== "undefined") {
152
+ const stored = localStorage.getItem(RemoteCliAdapter.TOKEN_KEY);
153
+ if (stored) {
154
+ this.#authToken = stored;
155
+ }
156
+ }
157
+ if (this.#authToken) {
158
+ try {
159
+ await this.#fetchServerAccounts();
160
+ await this.#restoreImportedAccounts();
161
+ } catch (error) {
162
+ if (error instanceof AuthError) {
163
+ this.#authToken = null;
164
+ if (typeof localStorage !== "undefined") {
165
+ localStorage.removeItem(RemoteCliAdapter.TOKEN_KEY);
166
+ }
167
+ } else {
168
+ console.warn("[dev-wallet] CLI adapter initialization failed:", error);
169
+ }
170
+ }
171
+ }
172
+ }
173
+ async listAvailableAccounts() {
174
+ await this.#fetchServerAccounts();
175
+ const importedAddresses = new Set(this._accounts.map((a) => a.address));
176
+ return this.#allServerAccounts.filter((info) => {
177
+ const scheme = KEY_SCHEME_MAP[info.keyScheme];
178
+ return scheme && !importedAddresses.has(info.suiAddress);
179
+ }).map((info) => ({
180
+ address: info.suiAddress,
181
+ scheme: info.keyScheme,
182
+ alias: info.alias
183
+ }));
184
+ }
185
+ async importAccount(options) {
186
+ const address = options.address;
187
+ if (!address) {
188
+ throw new Error("Remote CLI adapter requires an address to import");
189
+ }
190
+ if (this._accounts.some((a) => a.address === address)) {
191
+ throw new Error(`Account ${address} is already imported`);
192
+ }
193
+ await this.#fetchServerAccounts();
194
+ const info = this.#allServerAccounts.find((a) => a.suiAddress === address);
195
+ if (!info) {
196
+ throw new Error(`Account ${address} not found on server`);
197
+ }
198
+ const scheme = KEY_SCHEME_MAP[info.keyScheme];
199
+ if (!scheme) {
200
+ throw new Error(`Unsupported key scheme: ${info.keyScheme}`);
201
+ }
202
+ const account = this.#serverAccountToManaged(info, scheme, options.label);
203
+ this.addAccount(account);
204
+ this.#saveImportedAddresses();
205
+ return account;
206
+ }
207
+ async removeAccount(address) {
208
+ const removed = this.removeAccountByAddress(address);
209
+ if (removed) {
210
+ this.#saveImportedAddresses();
211
+ }
212
+ return removed;
213
+ }
214
+ destroy() {
215
+ this.#allServerAccounts = [];
216
+ this.#authToken = null;
217
+ if (typeof localStorage !== "undefined") {
218
+ localStorage.removeItem(RemoteCliAdapter.TOKEN_KEY);
219
+ localStorage.removeItem(RemoteCliAdapter.STORAGE_KEY);
220
+ }
221
+ super.destroy();
222
+ }
223
+ #authHeaders() {
224
+ const headers = { "Content-Type": "application/json" };
225
+ if (this.#authToken) {
226
+ headers["Authorization"] = `Bearer ${this.#authToken}`;
227
+ }
228
+ return headers;
229
+ }
230
+ async #fetchServerAccounts(forceRefresh = false) {
231
+ if (!forceRefresh && this.#lastFetch && Date.now() - this.#lastFetch.time < ACCOUNTS_CACHE_TTL_MS) {
232
+ this.#allServerAccounts = this.#lastFetch.result;
233
+ return;
234
+ }
235
+ const res = await fetch(`${this.#serverOrigin}/api/v1/accounts`, { headers: this.#authHeaders() });
236
+ if (res.status === 401 || res.status === 403) {
237
+ throw new AuthError();
238
+ }
239
+ if (!res.ok) {
240
+ throw new Error(`Failed to fetch accounts: ${res.statusText}`);
241
+ }
242
+ const { accounts } = await res.json();
243
+ this.#allServerAccounts = accounts;
244
+ this.#lastFetch = {
245
+ time: Date.now(),
246
+ result: accounts
247
+ };
248
+ }
249
+ async #restoreImportedAccounts() {
250
+ const saved = this.#loadImportedAddresses();
251
+ if (saved.length === 0) return;
252
+ const existingAddresses = new Set(this.getAccounts().map((a) => a.address));
253
+ const restored = [];
254
+ for (const address of saved) {
255
+ if (existingAddresses.has(address)) continue;
256
+ const info = this.#allServerAccounts.find((a) => a.suiAddress === address);
257
+ if (!info) continue;
258
+ const scheme = KEY_SCHEME_MAP[info.keyScheme];
259
+ if (!scheme) continue;
260
+ restored.push(this.#serverAccountToManaged(info, scheme));
261
+ }
262
+ if (restored.length > 0) {
263
+ this.setInitialAccounts([...this.getAccounts(), ...restored]);
264
+ }
265
+ }
266
+ #loadImportedAddresses() {
267
+ if (typeof localStorage === "undefined") return [];
268
+ try {
269
+ const raw = localStorage.getItem(RemoteCliAdapter.STORAGE_KEY);
270
+ if (!raw) return [];
271
+ const parsed = JSON.parse(raw);
272
+ if (!Array.isArray(parsed)) return [];
273
+ return parsed.filter((v) => typeof v === "string");
274
+ } catch {
275
+ return [];
276
+ }
277
+ }
278
+ #saveImportedAddresses() {
279
+ if (typeof localStorage === "undefined") return;
280
+ const addresses = this._accounts.map((a) => a.address);
281
+ localStorage.setItem(RemoteCliAdapter.STORAGE_KEY, JSON.stringify(addresses));
282
+ }
283
+ #serverAccountToManaged(info, scheme, label) {
284
+ const publicKey = publicKeyFromSuiBytes(info.publicBase64Key, scheme);
285
+ const signer = new CliProxySigner({
286
+ address: info.suiAddress,
287
+ publicKey,
288
+ scheme,
289
+ serverOrigin: this.#serverOrigin,
290
+ authToken: this.#authToken
291
+ });
292
+ const accountLabel = label ?? info.alias ?? this.getDefaultLabel();
293
+ return buildManagedAccount(signer, info.suiAddress, accountLabel, CLI_WALLET_FEATURES);
294
+ }
295
+ };
296
+
297
+ //#endregion
298
+ export { CliProxySigner, RemoteCliAdapter };
299
+ //# sourceMappingURL=remote-cli-adapter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-cli-adapter.mjs","names":["#address","#publicKey","#scheme","#serverOrigin","#authToken","#fetchServerAccounts","#restoreImportedAccounts","#allServerAccounts","#serverAccountToManaged","#saveImportedAddresses","#lastFetch","#authHeaders","#loadImportedAddresses"],"sources":["../../src/adapters/remote-cli-adapter.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Signer } from '@mysten/sui/cryptography';\nimport type { PublicKey, SignatureScheme } from '@mysten/sui/cryptography';\nimport { Ed25519PublicKey } from '@mysten/sui/keypairs/ed25519';\nimport { Secp256k1PublicKey } from '@mysten/sui/keypairs/secp256k1';\nimport { Secp256r1PublicKey } from '@mysten/sui/keypairs/secp256r1';\nimport { fromBase64, toBase64 } from '@mysten/sui/utils';\nimport type { ImportAccountOptions, ManagedAccount } from '../types.js';\nimport { BaseSignerAdapter } from './base-adapter.js';\nimport { buildManagedAccount } from './build-managed-account.js';\n\n/**\n * Wallet features advertised by CLI-backed accounts.\n * Personal message signing is not supported because the `sui keytool sign`\n * command only accepts BCS-serialized TransactionData.\n */\nconst CLI_WALLET_FEATURES = ['sui:signTransaction', 'sui:signAndExecuteTransaction'] as const;\n\n/** Cache TTL for the CLI server accounts fetch (milliseconds). */\nconst ACCOUNTS_CACHE_TTL_MS = 5000;\n\n/** Thrown when the server rejects a request with a 401 or 403 status. */\nclass AuthError extends Error {\n\tconstructor() {\n\t\tsuper('Unauthorized');\n\t\tthis.name = 'AuthError';\n\t}\n}\n\n/** Map CLI `keyScheme` strings to SDK {@link SignatureScheme} values. */\nconst KEY_SCHEME_MAP: Record<string, SignatureScheme> = {\n\ted25519: 'ED25519',\n\tsecp256k1: 'Secp256k1',\n\tsecp256r1: 'Secp256r1',\n};\n\n/** Account metadata returned by the server `/api/v1/accounts` endpoint. */\ninterface ServerAccountInfo {\n\tsuiAddress: string;\n\tpublicBase64Key: string;\n\tkeyScheme: string;\n\talias: string | null;\n}\n\nfunction publicKeyFromSuiBytes(publicBase64Key: string, scheme: SignatureScheme): PublicKey {\n\tconst allBytes = fromBase64(publicBase64Key);\n\tconst rawBytes = allBytes.slice(1);\n\n\tswitch (scheme) {\n\t\tcase 'ED25519':\n\t\t\treturn new Ed25519PublicKey(rawBytes);\n\t\tcase 'Secp256k1':\n\t\t\treturn new Secp256k1PublicKey(rawBytes);\n\t\tcase 'Secp256r1':\n\t\t\treturn new Secp256r1PublicKey(rawBytes);\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported key scheme: ${scheme}`);\n\t}\n}\n\n/**\n * A {@link Signer} that delegates transaction signing to a server HTTP endpoint\n * backed by `sui keytool sign`. Private keys never enter JavaScript.\n *\n * `signPersonalMessage()` is not supported — `sui keytool sign` only accepts\n * BCS-serialized `TransactionData`.\n */\nexport class CliProxySigner extends Signer {\n\t#address: string;\n\t#publicKey: PublicKey;\n\t#scheme: SignatureScheme;\n\t#serverOrigin: string;\n\t#authToken: string | null;\n\n\tconstructor(options: {\n\t\taddress: string;\n\t\tpublicKey: PublicKey;\n\t\tscheme: SignatureScheme;\n\t\tserverOrigin: string;\n\t\tauthToken?: string | null;\n\t}) {\n\t\tsuper();\n\t\tthis.#address = options.address;\n\t\tthis.#publicKey = options.publicKey;\n\t\tthis.#scheme = options.scheme;\n\t\tthis.#serverOrigin = options.serverOrigin;\n\t\tthis.#authToken = options.authToken ?? null;\n\t}\n\n\tasync sign(_bytes: Uint8Array): Promise<Uint8Array<ArrayBuffer>> {\n\t\tthrow new Error(\n\t\t\t'CliProxySigner does not support direct digest signing. ' +\n\t\t\t\t'Transaction signing is handled via the sui CLI.',\n\t\t);\n\t}\n\n\tgetKeyScheme(): SignatureScheme {\n\t\treturn this.#scheme;\n\t}\n\n\tgetPublicKey(): PublicKey {\n\t\treturn this.#publicKey;\n\t}\n\n\toverride toSuiAddress(): string {\n\t\treturn this.#address;\n\t}\n\n\toverride async signTransaction(bytes: Uint8Array) {\n\t\tconst headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\t\tif (this.#authToken) {\n\t\t\theaders['Authorization'] = `Bearer ${this.#authToken}`;\n\t\t}\n\n\t\tconst res = await fetch(`${this.#serverOrigin}/api/v1/sign-transaction`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders,\n\t\t\tbody: JSON.stringify({\n\t\t\t\taddress: this.#address,\n\t\t\t\ttxBytes: toBase64(bytes),\n\t\t\t}),\n\t\t});\n\n\t\tif (!res.ok) {\n\t\t\tconst body = await res.json().catch(() => ({}));\n\t\t\tthrow new Error(`Transaction signing failed: ${body.error ?? res.statusText}`);\n\t\t}\n\n\t\tconst { suiSignature } = await res.json();\n\t\tif (typeof suiSignature !== 'string' || suiSignature.length === 0) {\n\t\t\tthrow new Error('Transaction signing failed: server returned invalid signature');\n\t\t}\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: suiSignature,\n\t\t};\n\t}\n\n\toverride async signPersonalMessage(_bytes: Uint8Array): Promise<never> {\n\t\tthrow new Error(\n\t\t\t'Personal message signing is not supported in CLI mode. ' +\n\t\t\t\t'The sui keytool sign command only supports TransactionData. ' +\n\t\t\t\t'Use --adapter=webcrypto or --adapter=memory for personal message signing.',\n\t\t);\n\t}\n}\n\n/**\n * {@link SignerAdapter} that delegates signing to a server running the `sui` CLI.\n *\n * Authentication uses a token-in-URL approach: the CLI server prints a URL with\n * a token, which gets stored in `localStorage` for subsequent page loads. Imported\n * account addresses are also persisted so they survive CLI restarts.\n */\nexport class RemoteCliAdapter extends BaseSignerAdapter {\n\treadonly id = 'remote-cli';\n\treadonly name = 'Remote CLI Signer';\n\treadonly allowAutoSign = false;\n\n\tprotected override getDefaultLabel(): string {\n\t\treturn `CLI Account ${this.getAccounts().length + 1}`;\n\t}\n\n\t// Keys are scoped per origin to prevent cross-site leakage on shared localhost setups.\n\t// localStorage is used rather than sessionStorage because popup wallet flows\n\t// (DevWalletClient) may open new tabs that need access to the token.\n\tstatic storageKey(suffix: string): string {\n\t\tconst origin = typeof location !== 'undefined' ? location.origin : 'unknown';\n\t\treturn `dev-wallet:${suffix}:${origin}`;\n\t}\n\n\tstatic get STORAGE_KEY(): string {\n\t\treturn RemoteCliAdapter.storageKey('cli-imported-addresses');\n\t}\n\n\tstatic get TOKEN_KEY(): string {\n\t\treturn RemoteCliAdapter.storageKey('cli-token');\n\t}\n\n\t#serverOrigin: string;\n\t#authToken: string | null = null;\n\t#allServerAccounts: ServerAccountInfo[] = [];\n\t#lastFetch: { time: number; result: ServerAccountInfo[] } | null = null;\n\n\tconstructor(options?: { serverOrigin?: string; token?: string }) {\n\t\tsuper();\n\t\tconst origin = options?.serverOrigin ?? '';\n\t\tif (origin) {\n\t\t\ttry {\n\t\t\t\tnew URL(origin);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(`Invalid serverOrigin URL: \"${origin}\"`);\n\t\t\t}\n\t\t}\n\t\tthis.#serverOrigin = origin;\n\t\tif (options?.token) {\n\t\t\tthis.#authToken = options.token;\n\t\t}\n\t}\n\n\tget isPaired(): boolean {\n\t\treturn this.#authToken !== null;\n\t}\n\n\tasync initialize(): Promise<void> {\n\t\tif (!this.#authToken && typeof localStorage !== 'undefined') {\n\t\t\tconst stored = localStorage.getItem(RemoteCliAdapter.TOKEN_KEY);\n\t\t\tif (stored) {\n\t\t\t\tthis.#authToken = stored;\n\t\t\t}\n\t\t}\n\n\t\tif (this.#authToken) {\n\t\t\ttry {\n\t\t\t\tawait this.#fetchServerAccounts();\n\t\t\t\tawait this.#restoreImportedAccounts();\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof AuthError) {\n\t\t\t\t\tthis.#authToken = null;\n\t\t\t\t\tif (typeof localStorage !== 'undefined') {\n\t\t\t\t\t\tlocalStorage.removeItem(RemoteCliAdapter.TOKEN_KEY);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn('[dev-wallet] CLI adapter initialization failed:', error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tasync listAvailableAccounts(): Promise<\n\t\tArray<{ address: string; scheme: string; alias: string | null }>\n\t> {\n\t\tawait this.#fetchServerAccounts();\n\t\tconst importedAddresses = new Set(this._accounts.map((a) => a.address));\n\t\treturn this.#allServerAccounts\n\t\t\t.filter((info) => {\n\t\t\t\tconst scheme = KEY_SCHEME_MAP[info.keyScheme];\n\t\t\t\treturn scheme && !importedAddresses.has(info.suiAddress);\n\t\t\t})\n\t\t\t.map((info) => ({\n\t\t\t\taddress: info.suiAddress,\n\t\t\t\tscheme: info.keyScheme,\n\t\t\t\talias: info.alias,\n\t\t\t}));\n\t}\n\n\tasync importAccount(options: ImportAccountOptions): Promise<ManagedAccount> {\n\t\tconst address = options.address;\n\t\tif (!address) {\n\t\t\tthrow new Error('Remote CLI adapter requires an address to import');\n\t\t}\n\n\t\tif (this._accounts.some((a) => a.address === address)) {\n\t\t\tthrow new Error(`Account ${address} is already imported`);\n\t\t}\n\n\t\tawait this.#fetchServerAccounts();\n\t\tconst info = this.#allServerAccounts.find((a) => a.suiAddress === address);\n\t\tif (!info) {\n\t\t\tthrow new Error(`Account ${address} not found on server`);\n\t\t}\n\n\t\tconst scheme = KEY_SCHEME_MAP[info.keyScheme];\n\t\tif (!scheme) {\n\t\t\tthrow new Error(`Unsupported key scheme: ${info.keyScheme}`);\n\t\t}\n\n\t\tconst account = this.#serverAccountToManaged(info, scheme, options.label);\n\t\tthis.addAccount(account);\n\t\tthis.#saveImportedAddresses();\n\t\treturn account;\n\t}\n\n\tasync removeAccount(address: string): Promise<boolean> {\n\t\tconst removed = this.removeAccountByAddress(address);\n\t\tif (removed) {\n\t\t\tthis.#saveImportedAddresses();\n\t\t}\n\t\treturn removed;\n\t}\n\n\toverride destroy(): void {\n\t\tthis.#allServerAccounts = [];\n\t\tthis.#authToken = null;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.removeItem(RemoteCliAdapter.TOKEN_KEY);\n\t\t\tlocalStorage.removeItem(RemoteCliAdapter.STORAGE_KEY);\n\t\t}\n\t\tsuper.destroy();\n\t}\n\n\t#authHeaders(): Record<string, string> {\n\t\tconst headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\t\tif (this.#authToken) {\n\t\t\theaders['Authorization'] = `Bearer ${this.#authToken}`;\n\t\t}\n\t\treturn headers;\n\t}\n\n\tasync #fetchServerAccounts(forceRefresh = false): Promise<void> {\n\t\tif (\n\t\t\t!forceRefresh &&\n\t\t\tthis.#lastFetch &&\n\t\t\tDate.now() - this.#lastFetch.time < ACCOUNTS_CACHE_TTL_MS\n\t\t) {\n\t\t\tthis.#allServerAccounts = this.#lastFetch.result;\n\t\t\treturn;\n\t\t}\n\t\tconst res = await fetch(`${this.#serverOrigin}/api/v1/accounts`, {\n\t\t\theaders: this.#authHeaders(),\n\t\t});\n\t\tif (res.status === 401 || res.status === 403) {\n\t\t\tthrow new AuthError();\n\t\t}\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`Failed to fetch accounts: ${res.statusText}`);\n\t\t}\n\n\t\tconst { accounts } = (await res.json()) as { accounts: ServerAccountInfo[] };\n\t\tthis.#allServerAccounts = accounts;\n\t\tthis.#lastFetch = { time: Date.now(), result: accounts };\n\t}\n\n\tasync #restoreImportedAccounts(): Promise<void> {\n\t\tconst saved = this.#loadImportedAddresses();\n\t\tif (saved.length === 0) return;\n\n\t\tconst existingAddresses = new Set(this.getAccounts().map((a) => a.address));\n\t\tconst restored: ManagedAccount[] = [];\n\n\t\tfor (const address of saved) {\n\t\t\tif (existingAddresses.has(address)) continue;\n\n\t\t\tconst info = this.#allServerAccounts.find((a) => a.suiAddress === address);\n\t\t\tif (!info) continue; // Account no longer on server — skip\n\n\t\t\tconst scheme = KEY_SCHEME_MAP[info.keyScheme];\n\t\t\tif (!scheme) continue;\n\n\t\t\trestored.push(this.#serverAccountToManaged(info, scheme));\n\t\t}\n\n\t\tif (restored.length > 0) {\n\t\t\tthis.setInitialAccounts([...this.getAccounts(), ...restored]);\n\t\t}\n\t}\n\n\t#loadImportedAddresses(): string[] {\n\t\tif (typeof localStorage === 'undefined') return [];\n\t\ttry {\n\t\t\tconst raw = localStorage.getItem(RemoteCliAdapter.STORAGE_KEY);\n\t\t\tif (!raw) return [];\n\t\t\tconst parsed: unknown = JSON.parse(raw);\n\t\t\tif (!Array.isArray(parsed)) return [];\n\t\t\treturn parsed.filter((v): v is string => typeof v === 'string');\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t#saveImportedAddresses(): void {\n\t\tif (typeof localStorage === 'undefined') return;\n\t\tconst addresses = this._accounts.map((a) => a.address);\n\t\tlocalStorage.setItem(RemoteCliAdapter.STORAGE_KEY, JSON.stringify(addresses));\n\t}\n\n\t#serverAccountToManaged(\n\t\tinfo: ServerAccountInfo,\n\t\tscheme: SignatureScheme,\n\t\tlabel?: string,\n\t): ManagedAccount {\n\t\tconst publicKey = publicKeyFromSuiBytes(info.publicBase64Key, scheme);\n\n\t\tconst signer = new CliProxySigner({\n\t\t\taddress: info.suiAddress,\n\t\t\tpublicKey,\n\t\t\tscheme,\n\t\t\tserverOrigin: this.#serverOrigin,\n\t\t\tauthToken: this.#authToken,\n\t\t});\n\n\t\tconst accountLabel = label ?? info.alias ?? this.getDefaultLabel();\n\n\t\treturn buildManagedAccount(signer, info.suiAddress, accountLabel, CLI_WALLET_FEATURES);\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { CreateAccountOptions, ManagedAccount } from "../types.mjs";
2
+ import { BaseSignerAdapter } from "./base-adapter.mjs";
3
+
4
+ //#region src/adapters/webcrypto-adapter.d.ts
5
+ declare class WebCryptoSignerAdapter extends BaseSignerAdapter {
6
+ #private;
7
+ readonly id = "webcrypto";
8
+ readonly name = "WebCrypto Signer";
9
+ constructor(options?: {
10
+ dbName?: string;
11
+ storeName?: string;
12
+ });
13
+ initialize(): Promise<void>;
14
+ createAccount(options?: CreateAccountOptions): Promise<ManagedAccount>;
15
+ renameAccount(address: string, label: string): Promise<boolean>;
16
+ removeAccount(address: string): Promise<boolean>;
17
+ }
18
+ //#endregion
19
+ export { WebCryptoSignerAdapter };
20
+ //# sourceMappingURL=webcrypto-adapter.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webcrypto-adapter.d.mts","names":[],"sources":["../../src/adapters/webcrypto-adapter.ts"],"mappings":";;;;cAoBa,sBAAA,SAA+B,iBAAA;EAAA;WAClC,EAAA;EAAA,SACA,IAAA;cAIG,OAAA;IAAY,MAAA;IAAiB,SAAA;EAAA;EAQnC,UAAA,CAAA,GAAc,OAAA;EA0Bd,aAAA,CAAc,OAAA,GAAU,oBAAA,GAAuB,OAAA,CAAQ,cAAA;EAcvD,aAAA,CAAc,OAAA,UAAiB,KAAA,WAAgB,OAAA;EAM/C,aAAA,CAAc,OAAA,WAAkB,OAAA;AAAA"}
@@ -0,0 +1,68 @@
1
+ import { buildManagedAccount } from "./build-managed-account.mjs";
2
+ import { BaseSignerAdapter } from "./base-adapter.mjs";
3
+ import { IDBStore } from "./idb-store.mjs";
4
+ import { WebCryptoSigner } from "@mysten/signers/webcrypto";
5
+
6
+ //#region src/adapters/webcrypto-adapter.ts
7
+ const DEFAULT_DB_NAME = "dev-wallet-webcrypto";
8
+ const DEFAULT_STORE_NAME = "accounts";
9
+ const META_KEY = "__account_meta__";
10
+ var WebCryptoSignerAdapter = class extends BaseSignerAdapter {
11
+ #store;
12
+ constructor(options) {
13
+ super();
14
+ this.id = "webcrypto";
15
+ this.name = "WebCrypto Signer";
16
+ this.#store = new IDBStore(options?.dbName ?? DEFAULT_DB_NAME, options?.storeName ?? DEFAULT_STORE_NAME);
17
+ }
18
+ async initialize() {
19
+ const allEntries = await this.#store.entries();
20
+ const meta = await this.#store.get(META_KEY) ?? [];
21
+ const accounts = [];
22
+ for (const [key, value] of allEntries) {
23
+ if (key === META_KEY) continue;
24
+ const address = key;
25
+ try {
26
+ const exported = value;
27
+ const signer = WebCryptoSigner.import(exported);
28
+ const accountMeta = meta.find((m) => m.address === address);
29
+ accounts.push(buildManagedAccount(signer, address, accountMeta?.label ?? "Account"));
30
+ } catch (error) {
31
+ console.warn(`[dev-wallet] Failed to load account ${address}, skipping:`, error);
32
+ }
33
+ }
34
+ this.setInitialAccounts(accounts);
35
+ }
36
+ async createAccount(options) {
37
+ const signer = await WebCryptoSigner.generate();
38
+ const address = signer.getPublicKey().toSuiAddress();
39
+ const label = options?.label ?? this.getDefaultLabel();
40
+ const managedAccount = buildManagedAccount(signer, address, label);
41
+ await this.#store.set(address, signer.export());
42
+ this.addAccount(managedAccount);
43
+ await this.#saveMeta();
44
+ return managedAccount;
45
+ }
46
+ async renameAccount(address, label) {
47
+ if (!this._performRename(address, label)) return false;
48
+ await this.#saveMeta();
49
+ return true;
50
+ }
51
+ async removeAccount(address) {
52
+ if (!this.removeAccountByAddress(address)) return false;
53
+ await this.#store.del(address);
54
+ await this.#saveMeta();
55
+ return true;
56
+ }
57
+ async #saveMeta() {
58
+ const meta = this.getAccounts().map((a) => ({
59
+ address: a.address,
60
+ label: a.label
61
+ }));
62
+ await this.#store.set(META_KEY, meta);
63
+ }
64
+ };
65
+
66
+ //#endregion
67
+ export { WebCryptoSignerAdapter };
68
+ //# sourceMappingURL=webcrypto-adapter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webcrypto-adapter.mjs","names":["#store","#saveMeta"],"sources":["../../src/adapters/webcrypto-adapter.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ExportedWebCryptoKeypair } from '@mysten/signers/webcrypto';\nimport { WebCryptoSigner } from '@mysten/signers/webcrypto';\n\nimport type { CreateAccountOptions, ManagedAccount } from '../types.js';\nimport { BaseSignerAdapter } from './base-adapter.js';\nimport { buildManagedAccount } from './build-managed-account.js';\nimport { IDBStore } from './idb-store.js';\n\ninterface StoredAccountMeta {\n\taddress: string;\n\tlabel: string;\n}\n\nconst DEFAULT_DB_NAME = 'dev-wallet-webcrypto';\nconst DEFAULT_STORE_NAME = 'accounts';\nconst META_KEY = '__account_meta__';\n\nexport class WebCryptoSignerAdapter extends BaseSignerAdapter {\n\treadonly id = 'webcrypto';\n\treadonly name = 'WebCrypto Signer';\n\n\t#store: IDBStore;\n\n\tconstructor(options?: { dbName?: string; storeName?: string }) {\n\t\tsuper();\n\t\tthis.#store = new IDBStore(\n\t\t\toptions?.dbName ?? DEFAULT_DB_NAME,\n\t\t\toptions?.storeName ?? DEFAULT_STORE_NAME,\n\t\t);\n\t}\n\n\tasync initialize(): Promise<void> {\n\t\tconst allEntries = await this.#store.entries<\n\t\t\tstring,\n\t\t\tExportedWebCryptoKeypair | StoredAccountMeta[]\n\t\t>();\n\t\tconst meta: StoredAccountMeta[] = (await this.#store.get<StoredAccountMeta[]>(META_KEY)) ?? [];\n\n\t\tconst accounts = [];\n\n\t\tfor (const [key, value] of allEntries) {\n\t\t\tif (key === META_KEY) continue;\n\n\t\t\tconst address = key as string;\n\t\t\ttry {\n\t\t\t\tconst exported = value as ExportedWebCryptoKeypair;\n\t\t\t\tconst signer = WebCryptoSigner.import(exported);\n\t\t\t\tconst accountMeta = meta.find((m) => m.address === address);\n\t\t\t\taccounts.push(buildManagedAccount(signer, address, accountMeta?.label ?? 'Account'));\n\t\t\t} catch (error) {\n\t\t\t\tconsole.warn(`[dev-wallet] Failed to load account ${address}, skipping:`, error);\n\t\t\t}\n\t\t}\n\n\t\tthis.setInitialAccounts(accounts);\n\t}\n\n\tasync createAccount(options?: CreateAccountOptions): Promise<ManagedAccount> {\n\t\tconst signer = await WebCryptoSigner.generate();\n\t\tconst address = signer.getPublicKey().toSuiAddress();\n\t\tconst label = options?.label ?? this.getDefaultLabel();\n\n\t\tconst managedAccount = buildManagedAccount(signer, address, label);\n\n\t\tawait this.#store.set(address, signer.export());\n\t\tthis.addAccount(managedAccount);\n\t\tawait this.#saveMeta();\n\n\t\treturn managedAccount;\n\t}\n\n\tasync renameAccount(address: string, label: string): Promise<boolean> {\n\t\tif (!this._performRename(address, label)) return false;\n\t\tawait this.#saveMeta();\n\t\treturn true;\n\t}\n\n\tasync removeAccount(address: string): Promise<boolean> {\n\t\tif (!this.removeAccountByAddress(address)) return false;\n\n\t\tawait this.#store.del(address);\n\t\tawait this.#saveMeta();\n\t\treturn true;\n\t}\n\n\tasync #saveMeta(): Promise<void> {\n\t\tconst meta: StoredAccountMeta[] = this.getAccounts().map((a) => ({\n\t\t\taddress: a.address,\n\t\t\tlabel: a.label,\n\t\t}));\n\t\tawait this.#store.set(META_KEY, meta);\n\t}\n}\n"],"mappings":";;;;;;AAgBA,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;AAC3B,MAAM,WAAW;AAEjB,IAAa,yBAAb,cAA4C,kBAAkB;CAI7D;CAEA,YAAY,SAAmD;AAC9D,SAAO;YANM;cACE;AAMf,QAAKA,QAAS,IAAI,SACjB,SAAS,UAAU,iBACnB,SAAS,aAAa,mBACtB;;CAGF,MAAM,aAA4B;EACjC,MAAM,aAAa,MAAM,MAAKA,MAAO,SAGlC;EACH,MAAM,OAA6B,MAAM,MAAKA,MAAO,IAAyB,SAAS,IAAK,EAAE;EAE9F,MAAM,WAAW,EAAE;AAEnB,OAAK,MAAM,CAAC,KAAK,UAAU,YAAY;AACtC,OAAI,QAAQ,SAAU;GAEtB,MAAM,UAAU;AAChB,OAAI;IACH,MAAM,WAAW;IACjB,MAAM,SAAS,gBAAgB,OAAO,SAAS;IAC/C,MAAM,cAAc,KAAK,MAAM,MAAM,EAAE,YAAY,QAAQ;AAC3D,aAAS,KAAK,oBAAoB,QAAQ,SAAS,aAAa,SAAS,UAAU,CAAC;YAC5E,OAAO;AACf,YAAQ,KAAK,uCAAuC,QAAQ,cAAc,MAAM;;;AAIlF,OAAK,mBAAmB,SAAS;;CAGlC,MAAM,cAAc,SAAyD;EAC5E,MAAM,SAAS,MAAM,gBAAgB,UAAU;EAC/C,MAAM,UAAU,OAAO,cAAc,CAAC,cAAc;EACpD,MAAM,QAAQ,SAAS,SAAS,KAAK,iBAAiB;EAEtD,MAAM,iBAAiB,oBAAoB,QAAQ,SAAS,MAAM;AAElE,QAAM,MAAKA,MAAO,IAAI,SAAS,OAAO,QAAQ,CAAC;AAC/C,OAAK,WAAW,eAAe;AAC/B,QAAM,MAAKC,UAAW;AAEtB,SAAO;;CAGR,MAAM,cAAc,SAAiB,OAAiC;AACrE,MAAI,CAAC,KAAK,eAAe,SAAS,MAAM,CAAE,QAAO;AACjD,QAAM,MAAKA,UAAW;AACtB,SAAO;;CAGR,MAAM,cAAc,SAAmC;AACtD,MAAI,CAAC,KAAK,uBAAuB,QAAQ,CAAE,QAAO;AAElD,QAAM,MAAKD,MAAO,IAAI,QAAQ;AAC9B,QAAM,MAAKC,UAAW;AACtB,SAAO;;CAGR,OAAMA,WAA2B;EAChC,MAAM,OAA4B,KAAK,aAAa,CAAC,KAAK,OAAO;GAChE,SAAS,EAAE;GACX,OAAO,EAAE;GACT,EAAE;AACH,QAAM,MAAKD,MAAO,IAAI,UAAU,KAAK"}
@@ -0,0 +1 @@
1
+ export { };