@shieldedtech/moth-wallet 0.2.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 (230) hide show
  1. package/README.md +62 -0
  2. package/dist/contract/args-parser.d.ts +29 -0
  3. package/dist/contract/args-parser.d.ts.map +1 -0
  4. package/dist/contract/args-parser.js +123 -0
  5. package/dist/contract/args-parser.js.map +1 -0
  6. package/dist/contract/artifact-loader.d.ts +26 -0
  7. package/dist/contract/artifact-loader.d.ts.map +1 -0
  8. package/dist/contract/artifact-loader.js +129 -0
  9. package/dist/contract/artifact-loader.js.map +1 -0
  10. package/dist/contract/call.d.ts +32 -0
  11. package/dist/contract/call.d.ts.map +1 -0
  12. package/dist/contract/call.js +245 -0
  13. package/dist/contract/call.js.map +1 -0
  14. package/dist/contract/deploy.d.ts +36 -0
  15. package/dist/contract/deploy.d.ts.map +1 -0
  16. package/dist/contract/deploy.js +388 -0
  17. package/dist/contract/deploy.js.map +1 -0
  18. package/dist/contract/fungible-token.d.ts +40 -0
  19. package/dist/contract/fungible-token.d.ts.map +1 -0
  20. package/dist/contract/fungible-token.js +88 -0
  21. package/dist/contract/fungible-token.js.map +1 -0
  22. package/dist/contract/initial-private-state.d.ts +18 -0
  23. package/dist/contract/initial-private-state.d.ts.map +1 -0
  24. package/dist/contract/initial-private-state.js +44 -0
  25. package/dist/contract/initial-private-state.js.map +1 -0
  26. package/dist/contract/maintenance.d.ts +72 -0
  27. package/dist/contract/maintenance.d.ts.map +1 -0
  28. package/dist/contract/maintenance.js +430 -0
  29. package/dist/contract/maintenance.js.map +1 -0
  30. package/dist/contract/state.d.ts +16 -0
  31. package/dist/contract/state.d.ts.map +1 -0
  32. package/dist/contract/state.js +18 -0
  33. package/dist/contract/state.js.map +1 -0
  34. package/dist/contract/witness-loader.d.ts +3 -0
  35. package/dist/contract/witness-loader.d.ts.map +1 -0
  36. package/dist/contract/witness-loader.js +27 -0
  37. package/dist/contract/witness-loader.js.map +1 -0
  38. package/dist/daemon/api-keys.d.ts +66 -0
  39. package/dist/daemon/api-keys.d.ts.map +1 -0
  40. package/dist/daemon/api-keys.js +222 -0
  41. package/dist/daemon/api-keys.js.map +1 -0
  42. package/dist/daemon/audit-log.d.ts +65 -0
  43. package/dist/daemon/audit-log.d.ts.map +1 -0
  44. package/dist/daemon/audit-log.js +73 -0
  45. package/dist/daemon/audit-log.js.map +1 -0
  46. package/dist/daemon/client.d.ts +63 -0
  47. package/dist/daemon/client.d.ts.map +1 -0
  48. package/dist/daemon/client.js +214 -0
  49. package/dist/daemon/client.js.map +1 -0
  50. package/dist/daemon/confirmation-queue.d.ts +46 -0
  51. package/dist/daemon/confirmation-queue.d.ts.map +1 -0
  52. package/dist/daemon/confirmation-queue.js +92 -0
  53. package/dist/daemon/confirmation-queue.js.map +1 -0
  54. package/dist/daemon/index.d.ts +23 -0
  55. package/dist/daemon/index.d.ts.map +1 -0
  56. package/dist/daemon/index.js +26 -0
  57. package/dist/daemon/index.js.map +1 -0
  58. package/dist/daemon/protocol.d.ts +40 -0
  59. package/dist/daemon/protocol.d.ts.map +1 -0
  60. package/dist/daemon/protocol.js +104 -0
  61. package/dist/daemon/protocol.js.map +1 -0
  62. package/dist/daemon/server.d.ts +158 -0
  63. package/dist/daemon/server.d.ts.map +1 -0
  64. package/dist/daemon/server.js +297 -0
  65. package/dist/daemon/server.js.map +1 -0
  66. package/dist/daemon/wallet-handlers.d.ts +37 -0
  67. package/dist/daemon/wallet-handlers.d.ts.map +1 -0
  68. package/dist/daemon/wallet-handlers.js +533 -0
  69. package/dist/daemon/wallet-handlers.js.map +1 -0
  70. package/dist/daemon/wallet-rpc-parsers.d.ts +14 -0
  71. package/dist/daemon/wallet-rpc-parsers.d.ts.map +1 -0
  72. package/dist/daemon/wallet-rpc-parsers.js +259 -0
  73. package/dist/daemon/wallet-rpc-parsers.js.map +1 -0
  74. package/dist/daemon/wallet-rpc-types.d.ts +138 -0
  75. package/dist/daemon/wallet-rpc-types.d.ts.map +1 -0
  76. package/dist/daemon/wallet-rpc-types.js +11 -0
  77. package/dist/daemon/wallet-rpc-types.js.map +1 -0
  78. package/dist/diagnostics/fs-timing-store.d.ts +29 -0
  79. package/dist/diagnostics/fs-timing-store.d.ts.map +1 -0
  80. package/dist/diagnostics/fs-timing-store.js +81 -0
  81. package/dist/diagnostics/fs-timing-store.js.map +1 -0
  82. package/dist/diagnostics/timings.d.ts +64 -0
  83. package/dist/diagnostics/timings.d.ts.map +1 -0
  84. package/dist/diagnostics/timings.js +100 -0
  85. package/dist/diagnostics/timings.js.map +1 -0
  86. package/dist/index.d.ts +37 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +47 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/network/indexer-client.d.ts +66 -0
  91. package/dist/network/indexer-client.d.ts.map +1 -0
  92. package/dist/network/indexer-client.js +112 -0
  93. package/dist/network/indexer-client.js.map +1 -0
  94. package/dist/network/node-client.d.ts +27 -0
  95. package/dist/network/node-client.d.ts.map +1 -0
  96. package/dist/network/node-client.js +94 -0
  97. package/dist/network/node-client.js.map +1 -0
  98. package/dist/proof/client.d.ts +15 -0
  99. package/dist/proof/client.d.ts.map +1 -0
  100. package/dist/proof/client.js +77 -0
  101. package/dist/proof/client.js.map +1 -0
  102. package/dist/proof/provider.d.ts +12 -0
  103. package/dist/proof/provider.d.ts.map +1 -0
  104. package/dist/proof/provider.js +96 -0
  105. package/dist/proof/provider.js.map +1 -0
  106. package/dist/providers/index.d.ts +2 -0
  107. package/dist/providers/index.d.ts.map +1 -0
  108. package/dist/providers/index.js +2 -0
  109. package/dist/providers/index.js.map +1 -0
  110. package/dist/providers/midnight-provider.d.ts +11 -0
  111. package/dist/providers/midnight-provider.d.ts.map +1 -0
  112. package/dist/providers/midnight-provider.js +30 -0
  113. package/dist/providers/midnight-provider.js.map +1 -0
  114. package/dist/storage/adapter.d.ts +8 -0
  115. package/dist/storage/adapter.d.ts.map +1 -0
  116. package/dist/storage/adapter.js +2 -0
  117. package/dist/storage/adapter.js.map +1 -0
  118. package/dist/storage/fs-adapter.d.ts +14 -0
  119. package/dist/storage/fs-adapter.d.ts.map +1 -0
  120. package/dist/storage/fs-adapter.js +126 -0
  121. package/dist/storage/fs-adapter.js.map +1 -0
  122. package/dist/storage/safe-path.d.ts +13 -0
  123. package/dist/storage/safe-path.d.ts.map +1 -0
  124. package/dist/storage/safe-path.js +35 -0
  125. package/dist/storage/safe-path.js.map +1 -0
  126. package/dist/sync/activity.d.ts +53 -0
  127. package/dist/sync/activity.d.ts.map +1 -0
  128. package/dist/sync/activity.js +92 -0
  129. package/dist/sync/activity.js.map +1 -0
  130. package/dist/sync/dust-registration-estimate.d.ts +54 -0
  131. package/dist/sync/dust-registration-estimate.d.ts.map +1 -0
  132. package/dist/sync/dust-registration-estimate.js +103 -0
  133. package/dist/sync/dust-registration-estimate.js.map +1 -0
  134. package/dist/sync/node-sync-store.d.ts +10 -0
  135. package/dist/sync/node-sync-store.d.ts.map +1 -0
  136. package/dist/sync/node-sync-store.js +42 -0
  137. package/dist/sync/node-sync-store.js.map +1 -0
  138. package/dist/sync/operations.d.ts +138 -0
  139. package/dist/sync/operations.d.ts.map +1 -0
  140. package/dist/sync/operations.js +395 -0
  141. package/dist/sync/operations.js.map +1 -0
  142. package/dist/sync/preseed-parts.d.ts +18 -0
  143. package/dist/sync/preseed-parts.d.ts.map +1 -0
  144. package/dist/sync/preseed-parts.js +33 -0
  145. package/dist/sync/preseed-parts.js.map +1 -0
  146. package/dist/sync/preseed.d.ts +95 -0
  147. package/dist/sync/preseed.d.ts.map +1 -0
  148. package/dist/sync/preseed.js +365 -0
  149. package/dist/sync/preseed.js.map +1 -0
  150. package/dist/sync/progress.d.ts +45 -0
  151. package/dist/sync/progress.d.ts.map +1 -0
  152. package/dist/sync/progress.js +51 -0
  153. package/dist/sync/progress.js.map +1 -0
  154. package/dist/sync/sdk-dedup.d.ts +53 -0
  155. package/dist/sync/sdk-dedup.d.ts.map +1 -0
  156. package/dist/sync/sdk-dedup.js +134 -0
  157. package/dist/sync/sdk-dedup.js.map +1 -0
  158. package/dist/sync/sync-store.d.ts +33 -0
  159. package/dist/sync/sync-store.d.ts.map +1 -0
  160. package/dist/sync/sync-store.js +45 -0
  161. package/dist/sync/sync-store.js.map +1 -0
  162. package/dist/sync/wallet-sync.d.ts +153 -0
  163. package/dist/sync/wallet-sync.d.ts.map +1 -0
  164. package/dist/sync/wallet-sync.js +943 -0
  165. package/dist/sync/wallet-sync.js.map +1 -0
  166. package/dist/types/errors.d.ts +18 -0
  167. package/dist/types/errors.d.ts.map +1 -0
  168. package/dist/types/errors.js +33 -0
  169. package/dist/types/errors.js.map +1 -0
  170. package/dist/types/exit-codes.d.ts +8 -0
  171. package/dist/types/exit-codes.d.ts.map +1 -0
  172. package/dist/types/exit-codes.js +7 -0
  173. package/dist/types/exit-codes.js.map +1 -0
  174. package/dist/types/index.d.ts +6 -0
  175. package/dist/types/index.d.ts.map +1 -0
  176. package/dist/types/index.js +3 -0
  177. package/dist/types/index.js.map +1 -0
  178. package/dist/types/network.d.ts +65 -0
  179. package/dist/types/network.d.ts.map +1 -0
  180. package/dist/types/network.js +108 -0
  181. package/dist/types/network.js.map +1 -0
  182. package/dist/types/tokens.d.ts +3 -0
  183. package/dist/types/tokens.d.ts.map +1 -0
  184. package/dist/types/tokens.js +11 -0
  185. package/dist/types/tokens.js.map +1 -0
  186. package/dist/types/transaction.d.ts +13 -0
  187. package/dist/types/transaction.d.ts.map +1 -0
  188. package/dist/types/transaction.js +2 -0
  189. package/dist/types/transaction.js.map +1 -0
  190. package/dist/types/wallet.d.ts +82 -0
  191. package/dist/types/wallet.d.ts.map +1 -0
  192. package/dist/types/wallet.js +2 -0
  193. package/dist/types/wallet.js.map +1 -0
  194. package/dist/wallet/address-validate.d.ts +7 -0
  195. package/dist/wallet/address-validate.d.ts.map +1 -0
  196. package/dist/wallet/address-validate.js +28 -0
  197. package/dist/wallet/address-validate.js.map +1 -0
  198. package/dist/wallet/address.d.ts +32 -0
  199. package/dist/wallet/address.d.ts.map +1 -0
  200. package/dist/wallet/address.js +107 -0
  201. package/dist/wallet/address.js.map +1 -0
  202. package/dist/wallet/app-secret.d.ts +15 -0
  203. package/dist/wallet/app-secret.d.ts.map +1 -0
  204. package/dist/wallet/app-secret.js +45 -0
  205. package/dist/wallet/app-secret.js.map +1 -0
  206. package/dist/wallet/balance-format.d.ts +12 -0
  207. package/dist/wallet/balance-format.d.ts.map +1 -0
  208. package/dist/wallet/balance-format.js +51 -0
  209. package/dist/wallet/balance-format.js.map +1 -0
  210. package/dist/wallet/batch-transfer.d.ts +36 -0
  211. package/dist/wallet/batch-transfer.d.ts.map +1 -0
  212. package/dist/wallet/batch-transfer.js +93 -0
  213. package/dist/wallet/batch-transfer.js.map +1 -0
  214. package/dist/wallet/keystore.d.ts +16 -0
  215. package/dist/wallet/keystore.d.ts.map +1 -0
  216. package/dist/wallet/keystore.js +76 -0
  217. package/dist/wallet/keystore.js.map +1 -0
  218. package/dist/wallet/manager.d.ts +77 -0
  219. package/dist/wallet/manager.d.ts.map +1 -0
  220. package/dist/wallet/manager.js +474 -0
  221. package/dist/wallet/manager.js.map +1 -0
  222. package/dist/wallet/mnemonic.d.ts +5 -0
  223. package/dist/wallet/mnemonic.d.ts.map +1 -0
  224. package/dist/wallet/mnemonic.js +28 -0
  225. package/dist/wallet/mnemonic.js.map +1 -0
  226. package/dist/wallet/sign-message.d.ts +20 -0
  227. package/dist/wallet/sign-message.d.ts.map +1 -0
  228. package/dist/wallet/sign-message.js +58 -0
  229. package/dist/wallet/sign-message.js.map +1 -0
  230. package/package.json +55 -0
@@ -0,0 +1,395 @@
1
+ // Wallet operations via WalletFacade — send, designate, dedesignate.
2
+ // Architecture follows mn-tui's wallet.ts pattern. See NOTICE for attribution.
3
+ import * as Rx from 'rxjs';
4
+ import * as ledger from '@midnight-ntwrk/ledger-v8';
5
+ import { MidnightBech32m, ShieldedAddress, UnshieldedAddress, DustAddress, } from '@midnightntwrk/wallet-sdk/address-format';
6
+ import { createKeystore } from '@midnightntwrk/wallet-sdk/unshielded';
7
+ import { HDWallet, Roles } from '@midnightntwrk/wallet-sdk/hd';
8
+ import { setNetworkId } from '@midnight-ntwrk/midnight-js/network-id';
9
+ import { NIGHT_TOKEN_ID } from './wallet-sync.js';
10
+ import { estimateRegistrationAffordability, DustRegistrationNotYetError, } from './dust-registration-estimate.js';
11
+ // Re-exported from the module that throws it, so a consumer importing the
12
+ // registration API by subpath (packages/browser does) gets the error type it has
13
+ // to catch from the same place — without also reaching for the estimate module.
14
+ export { DustRegistrationNotYetError };
15
+ // Multi-output transfer builder (kept from main): groups requests by kind so a
16
+ // single transaction can carry several tokens/recipients — the extension's
17
+ // batch send and the CLI both rely on it.
18
+ function combinedTransfers(networkId, requests) {
19
+ const grouped = new Map();
20
+ for (const req of requests) {
21
+ const parsed = MidnightBech32m.parse(req.to);
22
+ const receiverAddress = req.type === 'unshielded'
23
+ ? parsed.decode(UnshieldedAddress, networkId)
24
+ : parsed.decode(ShieldedAddress, networkId);
25
+ const outputs = grouped.get(req.type) ?? [];
26
+ outputs.push({ type: req.tokenId, amount: req.amount, receiverAddress });
27
+ grouped.set(req.type, outputs);
28
+ }
29
+ // The map already pairs each kind with same-kind outputs; the cast collapses
30
+ // the inferred shape onto the SDK's discriminated CombinedTokenTransfer union.
31
+ return [...grouped.entries()].map(([type, outputs]) => ({ type, outputs }));
32
+ }
33
+ /**
34
+ * Derive the typed key bundle from a 64-char BIP-39 hex seed. Option A key
35
+ * model (v8's D-KM-3): callers derive once at unlock and discard the raw seed
36
+ * immediately — the bundle holds everything the write paths need, so the seed
37
+ * is never threaded through the daemon or the extension messaging layers.
38
+ */
39
+ export function deriveWalletKeys(seedHex) {
40
+ const hdWallet = HDWallet.fromSeed(Buffer.from(seedHex, 'hex'));
41
+ if (hdWallet.type !== 'seedOk')
42
+ throw new Error('Invalid seed');
43
+ const result = hdWallet.hdWallet
44
+ .selectAccount(0)
45
+ .selectRoles([Roles.Zswap, Roles.NightExternal, Roles.Dust])
46
+ .deriveKeysAt(0);
47
+ if (result.type !== 'keysDerived')
48
+ throw new Error('Key derivation failed');
49
+ hdWallet.hdWallet.clear();
50
+ return {
51
+ shieldedSecretKeys: ledger.ZswapSecretKeys.fromSeed(result.keys[Roles.Zswap]),
52
+ dustSecretKey: ledger.DustSecretKey.fromSeed(result.keys[Roles.Dust]),
53
+ nightExternalKey: result.keys[Roles.NightExternal],
54
+ };
55
+ }
56
+ // Legacy private alias — internal callers that predate deriveWalletKeys.
57
+ function deriveKeysFromSeed(seedHex) {
58
+ return deriveWalletKeys(seedHex);
59
+ }
60
+ /**
61
+ * Substrate tx-pool rejects a transaction whose hash is already in the pool
62
+ * with error 1013 "Transaction Already Imported". Because a finalized tx has a
63
+ * fixed hash, this fires whenever we resubmit identical bytes — which means the
64
+ * transaction already reached the node, so it should be treated as success.
65
+ */
66
+ function isAlreadyImported(e) {
67
+ const msg = e instanceof Error ? e.message : String(e);
68
+ return msg.includes('1013') || /already imported/i.test(msg);
69
+ }
70
+ /**
71
+ * A connection-level failure where the transaction likely never reached the
72
+ * node — the only case worth resending. A node that evaluated the transaction
73
+ * and rejected it (bad proof, insufficient funds, low priority, …) returns a
74
+ * deterministic verdict; resending the identical bytes only makes the user
75
+ * wait for the same answer, so those rejections must surface immediately.
76
+ */
77
+ function isTransient(e) {
78
+ const msg = e instanceof Error ? e.message : String(e);
79
+ return /disconnect|not connected|connection|websocket|socket hang up|time\s?d?\s?out|timeout|ECONN|ENOTFOUND|network|fetch failed|1006/i.test(msg);
80
+ }
81
+ /**
82
+ * Submit an already-finalized transaction, classifying failures so the user
83
+ * only waits through a retry when one could actually help:
84
+ *
85
+ * - "Already Imported" (1013): a prior attempt's identical bytes already reached
86
+ * the pool — that IS submitted, so report success with the tx's own hash.
87
+ * - Transient connection failure: resend (the tx may never have arrived).
88
+ * - Any other error is the node's deterministic rejection: surface it at once,
89
+ * without burning retries the user has to wait through.
90
+ */
91
+ async function submitWithRetry(facade, finalized, attempts = 3, delayMs = 5_000) {
92
+ for (let attempt = 1; attempt <= attempts; attempt++) {
93
+ try {
94
+ // The facade resolves to an intent identifier (`identifiers().at(-1)`),
95
+ // but everything downstream — indexer status queries, tx-history entries
96
+ // (WalletEntry.hash), explorers, and the activity feed's pending-row
97
+ // reconciliation — is keyed by the transaction hash. Return that.
98
+ await facade.submitTransaction(finalized);
99
+ return finalized.transactionHash();
100
+ }
101
+ catch (e) {
102
+ if (isAlreadyImported(e))
103
+ return finalized.transactionHash();
104
+ if (attempt === attempts || !isTransient(e))
105
+ throw e;
106
+ await new Promise((r) => setTimeout(r, delayMs));
107
+ }
108
+ }
109
+ throw new Error('unreachable');
110
+ }
111
+ /**
112
+ * Build, prove and sign a transfer, stopping short of submission.
113
+ * The dApp connector's makeTransfer/submitTransaction split needs the
114
+ * finalized transaction as a standalone artifact; sendTokens composes this
115
+ * with submission.
116
+ */
117
+ export async function buildTransferTransaction(facade, keys, networkId, requests, onProgress) {
118
+ setNetworkId(networkId);
119
+ const ks = createKeystore(keys.nightExternalKey, networkId);
120
+ const transfers = combinedTransfers(networkId, requests);
121
+ const ttl = new Date(Date.now() + 30 * 60_000);
122
+ onProgress?.('building');
123
+ const recipe = await facade.transferTransaction(transfers, { shieldedSecretKeys: keys.shieldedSecretKeys, dustSecretKey: keys.dustSecretKey }, { ttl });
124
+ onProgress?.('proving');
125
+ const signed = await facade.signRecipe(recipe, (payload) => ks.signData(payload));
126
+ return facade.finalizeRecipe(signed);
127
+ }
128
+ /**
129
+ * Estimate the complete DUST fee for a transfer, including the balancing
130
+ * transaction that pays it. The facade's transfer builder books selected
131
+ * inputs even when fee payment is disabled, so the temporary base transaction
132
+ * is always reverted before returning.
133
+ */
134
+ export async function estimateTransferFee(facade, keys, networkId, requests) {
135
+ setNetworkId(networkId);
136
+ const transfers = combinedTransfers(networkId, requests);
137
+ const ttl = new Date(Date.now() + 30 * 60_000);
138
+ const recipe = await facade.transferTransaction(transfers, { shieldedSecretKeys: keys.shieldedSecretKeys, dustSecretKey: keys.dustSecretKey }, { ttl, payFees: false });
139
+ try {
140
+ return await facade.estimateTransactionFee(recipe.transaction, keys.dustSecretKey, { ttl });
141
+ }
142
+ finally {
143
+ await facade.revertTransaction(recipe.transaction);
144
+ }
145
+ }
146
+ /**
147
+ * Submit a previously built transfer with retries.
148
+ */
149
+ export async function submitFinalizedTransaction(facade, finalized) {
150
+ return submitWithRetry(facade, finalized);
151
+ }
152
+ /**
153
+ * Send tokens via the wallet facade using a pre-derived key bundle. Prefer this
154
+ * over {@link sendTokens} when the caller already holds WalletKeys (the daemon
155
+ * and the extension, which derive once at unlock and drop the seed — Option A /
156
+ * D-KM-3, docs/spec/wallet-service/05-key-management.md).
157
+ */
158
+ export async function sendTokensWithKeys(facade, keys, networkId, requests, onProgress) {
159
+ const finalized = await buildTransferTransaction(facade, keys, networkId, requests, onProgress);
160
+ onProgress?.('submitting');
161
+ return submitFinalizedTransaction(facade, finalized);
162
+ }
163
+ /**
164
+ * Balance a dApp-supplied transaction (connector `balanceSealedTransaction` /
165
+ * `balanceUnsealedTransaction`): pay fees and add wallet inputs/outputs to
166
+ * remove imbalances, then prove + bind into a submit-ready FinalizedTransaction.
167
+ *
168
+ * `sealed` selects the input stage:
169
+ * - sealed → Transaction<SignatureEnabled, Proof, Binding> (FinalizedTransaction)
170
+ * - unsealed → Transaction<SignatureEnabled, Proof, PreBinding> (UnboundTransaction)
171
+ *
172
+ * The prove/finalize tail is the same as {@link buildTransferTransaction}.
173
+ */
174
+ export async function balanceTransaction(facade, keys, networkId, txBytes, sealed, onProgress) {
175
+ setNetworkId(networkId);
176
+ const ks = createKeystore(keys.nightExternalKey, networkId);
177
+ const secretKeys = { shieldedSecretKeys: keys.shieldedSecretKeys, dustSecretKey: keys.dustSecretKey };
178
+ const ttl = new Date(Date.now() + 30 * 60_000);
179
+ onProgress?.('building');
180
+ const recipe = sealed
181
+ ? await facade.balanceFinalizedTransaction(ledger.Transaction.deserialize('signature', 'proof', 'binding', txBytes), secretKeys, { ttl })
182
+ : await facade.balanceUnboundTransaction(ledger.Transaction.deserialize('signature', 'proof', 'pre-binding', txBytes), secretKeys, { ttl });
183
+ onProgress?.('proving');
184
+ const signed = await facade.signRecipe(recipe, (payload) => ks.signData(payload));
185
+ return facade.finalizeRecipe(signed);
186
+ }
187
+ /**
188
+ * Build a swap intent (connector `makeIntent`): the wallet's half of a swap,
189
+ * providing `inputs` (spent) and `outputs` (sent to recipients). Returns the
190
+ * raw unproven, unbound transaction from the SDK's `initSwap` — deliberately
191
+ * NOT proven or bound, so the dApp can combine it with the counterparty's half
192
+ * before the combined transaction is proven, balanced, and submitted.
193
+ *
194
+ * NOTE: the connector's `intentId` option is not honored — the SDK's `initSwap`
195
+ * exposes no segment-id control, so callers cannot pin the intent's id or opt
196
+ * out of transaction merging.
197
+ */
198
+ export async function buildSwapIntent(facade, keys, networkId, inputs, outputs, payFees, onProgress) {
199
+ setNetworkId(networkId);
200
+ const swapInputs = {};
201
+ for (const input of inputs) {
202
+ const bucket = (swapInputs[input.type] ??= {});
203
+ bucket[input.tokenId] = (bucket[input.tokenId] ?? 0n) + input.amount;
204
+ }
205
+ const grouped = new Map();
206
+ for (const out of outputs) {
207
+ const parsed = MidnightBech32m.parse(out.to);
208
+ const receiverAddress = out.type === 'unshielded'
209
+ ? parsed.decode(UnshieldedAddress, networkId)
210
+ : parsed.decode(ShieldedAddress, networkId);
211
+ const list = grouped.get(out.type) ?? [];
212
+ list.push({ type: out.tokenId, amount: out.amount, receiverAddress });
213
+ grouped.set(out.type, list);
214
+ }
215
+ const swapOutputs = [...grouped.entries()].map(([type, outs]) => ({ type, outputs: outs }));
216
+ const ttl = new Date(Date.now() + 30 * 60_000);
217
+ onProgress?.('building');
218
+ const recipe = await facade.initSwap(swapInputs, swapOutputs, { shieldedSecretKeys: keys.shieldedSecretKeys, dustSecretKey: keys.dustSecretKey }, { ttl, payFees });
219
+ return recipe.transaction;
220
+ }
221
+ /**
222
+ * Send tokens via the wallet facade. Convenience wrapper that derives a
223
+ * WalletKeys bundle from the seed and delegates to
224
+ * {@link sendTokensWithKeys}. Holds the seed in memory only for the
225
+ * duration of derivation — used by paths like the in-process `moth
226
+ * transfer` CLI command that already work in terms of seedHex.
227
+ */
228
+ export async function sendTokens(facade, seedHex, networkId, requests, onProgress) {
229
+ return sendTokensWithKeys(facade, deriveWalletKeys(seedHex), networkId, requests, onProgress);
230
+ }
231
+ /**
232
+ * List the active wallet's NIGHT UTXOs (registered + unregistered).
233
+ * Waits for the unshielded sub-wallet to be strict-complete — does NOT gate on
234
+ * aggregate `isSynced`, which never becomes true for a fresh wallet whose only
235
+ * activity is unshielded (e.g. a faucet-funded test wallet pre-dust-register).
236
+ */
237
+ export async function listNightUtxos(facade) {
238
+ const state = await Rx.firstValueFrom(facade.state().pipe(Rx.filter((s) => s.unshielded?.progress?.isStrictlyComplete?.() === true)));
239
+ const coins = state.unshielded.availableCoins.filter((c) => c.utxo.type === NIGHT_TOKEN_ID);
240
+ return coins.map((c) => ({
241
+ raw: c,
242
+ value: BigInt(c.utxo.value),
243
+ registered: c.meta.registeredForDustGeneration,
244
+ }));
245
+ }
246
+ /**
247
+ * Register NIGHT UTXOs for DUST generation, using a pre-derived
248
+ * WalletKeys bundle (D-KM-3 path — preferred over the seedHex variant
249
+ * for daemon callers).
250
+ */
251
+ export async function designateForDustWithKeys(facade, keys, networkId, receiver, onProgress, selectedUtxos) {
252
+ setNetworkId(networkId);
253
+ const ks = createKeystore(keys.nightExternalKey, networkId);
254
+ return designateForDustImpl(facade, ks, networkId, receiver, onProgress, selectedUtxos);
255
+ }
256
+ /**
257
+ * Register NIGHT UTXOs for DUST generation.
258
+ * If `selectedUtxos` is provided, registers exactly those; otherwise auto-selects
259
+ * all currently unregistered NIGHT UTXOs.
260
+ */
261
+ export async function designateForDust(facade, seedHex, networkId, receiver, onProgress, selectedUtxos) {
262
+ setNetworkId(networkId);
263
+ const keys = deriveKeysFromSeed(seedHex);
264
+ const ks = createKeystore(keys.nightExternalKey, networkId);
265
+ return designateForDustImpl(facade, ks, networkId, receiver, onProgress, selectedUtxos);
266
+ }
267
+ /**
268
+ * Whether registration can pay its own fee yet, and if not, how long until it
269
+ * can. Reads state and builds a throwaway transaction for costing; books
270
+ * nothing and spends nothing.
271
+ *
272
+ * Registration is self-funding — it draws on the DUST its NIGHT would have
273
+ * generated had it been registered all along — but that backdated amount starts
274
+ * at zero and grows with the NIGHT's age, so a freshly funded wallet cannot
275
+ * cover the fee yet. Without asking first, the wallet builds, proves, fails on
276
+ * the SDK's guard, and reports a defect where the honest answer is "not yet, try
277
+ * in about six minutes". See sync/dust-registration-estimate.ts.
278
+ */
279
+ export async function estimateDustRegistration(facade, selectedUtxos) {
280
+ const utxos = selectedUtxos?.length
281
+ ? selectedUtxos.map((u) => u.raw)
282
+ : await unregisteredNightUtxos(facade);
283
+ // Nothing to register: no fee, and no accrual to wait for. The caller
284
+ // distinguishes this from "not yet" via its own no-night handling.
285
+ if (utxos.length === 0) {
286
+ return { fee: 0n, available: 0n, rate: 0n, maxAvailable: 0n, affordable: true, secondsUntilAffordable: 0 };
287
+ }
288
+ const { fee, dustGenerationEstimations } = await facade.estimateRegistration(utxos);
289
+ return estimateRegistrationAffordability(fee, dustGenerationEstimations.map((e) => ({
290
+ generatedNow: e.dust.generatedNow,
291
+ rate: e.dust.rate,
292
+ maxCap: e.dust.maxCap,
293
+ registeredForDustGeneration: e.utxo.registeredForDustGeneration,
294
+ })));
295
+ }
296
+ /** Unshielded NIGHT not yet backing DUST — the set a registration would use.
297
+ * Gates on unshielded strict-complete only; see designateForDustImpl. */
298
+ async function unregisteredNightUtxos(facade) {
299
+ const state = await Rx.firstValueFrom(facade.state().pipe(Rx.filter((s) => s.unshielded?.progress?.isStrictlyComplete?.() === true)));
300
+ return state.unshielded.availableCoins.filter((c) => c.utxo.type === NIGHT_TOKEN_ID && !c.meta.registeredForDustGeneration);
301
+ }
302
+ // Shared body used by both designateForDust(seedHex) and
303
+ // designateForDustWithKeys(walletKeys).
304
+ async function designateForDustImpl(facade, ks, networkId, receiver, onProgress, selectedUtxos) {
305
+ let utxos;
306
+ if (selectedUtxos && selectedUtxos.length > 0) {
307
+ utxos = selectedUtxos.map((u) => u.raw);
308
+ }
309
+ else {
310
+ // Registration only reads unshielded NIGHT UTXOs; gating on aggregate
311
+ // `isSynced` deadlocks a fresh wallet whose shielded/DUST streams have no
312
+ // events yet (registration itself creates the first DUST event). Shared with
313
+ // estimateDustRegistration so the pre-flight cannot cost a different set
314
+ // from the one the registration actually uses.
315
+ utxos = await unregisteredNightUtxos(facade);
316
+ }
317
+ if (utxos.length === 0)
318
+ return null;
319
+ onProgress?.('building');
320
+ let dustReceiver;
321
+ if (receiver) {
322
+ try {
323
+ dustReceiver = MidnightBech32m.parse(receiver).decode(DustAddress, networkId);
324
+ }
325
+ catch (e) {
326
+ // Never fall back silently: the caller explicitly chose a receiver, and
327
+ // defaulting would quietly send their DUST somewhere they didn't pick.
328
+ throw new Error(`Invalid DUST address "${receiver}" for network "${networkId}": ${e instanceof Error ? e.message : e}`);
329
+ }
330
+ }
331
+ let recipe;
332
+ try {
333
+ recipe = await facade.registerNightUtxosForDustGeneration(utxos, ks.getPublicKey(), (payload) => ks.signData(payload), dustReceiver);
334
+ }
335
+ catch (e) {
336
+ // Registration self-funds from the DUST its NIGHT would already have
337
+ // generated, and that amount starts at zero — so on a freshly funded wallet
338
+ // the SDK refuses before proving. Re-costing tells us whether that is what
339
+ // happened, and by how much: the affordability figures are the ground truth
340
+ // here, not the SDK's message text, which we would otherwise have to match
341
+ // by string and re-match on every SDK release.
342
+ //
343
+ // Only on the failure path, so a registration that was always going to
344
+ // succeed pays nothing for this.
345
+ const estimate = await estimateDustRegistration(facade, selectedUtxos).catch(() => null);
346
+ if (estimate && !estimate.affordable)
347
+ throw new DustRegistrationNotYetError(estimate, e);
348
+ throw e;
349
+ }
350
+ onProgress?.('proving');
351
+ const finalized = await facade.finalizeRecipe(recipe);
352
+ onProgress?.('submitting');
353
+ return submitWithRetry(facade, finalized);
354
+ }
355
+ /**
356
+ * Deregister NIGHT UTXOs from DUST generation, using a pre-derived
357
+ * WalletKeys bundle (D-KM-3 path).
358
+ */
359
+ export async function dedesignateFromDustWithKeys(facade, keys, networkId, onProgress, selectedUtxos) {
360
+ setNetworkId(networkId);
361
+ const ks = createKeystore(keys.nightExternalKey, networkId);
362
+ return dedesignateFromDustImpl(facade, ks, keys, onProgress, selectedUtxos);
363
+ }
364
+ /**
365
+ * Deregister NIGHT UTXOs from DUST generation.
366
+ * If `selectedUtxos` is provided, deregisters exactly those; otherwise auto-selects
367
+ * all currently registered NIGHT UTXOs.
368
+ */
369
+ export async function dedesignateFromDust(facade, seedHex, networkId, onProgress, selectedUtxos) {
370
+ setNetworkId(networkId);
371
+ const keys = deriveKeysFromSeed(seedHex);
372
+ const ks = createKeystore(keys.nightExternalKey, networkId);
373
+ return dedesignateFromDustImpl(facade, ks, keys, onProgress, selectedUtxos);
374
+ }
375
+ async function dedesignateFromDustImpl(facade, ks, keys, onProgress, selectedUtxos) {
376
+ let utxos;
377
+ if (selectedUtxos && selectedUtxos.length > 0) {
378
+ utxos = selectedUtxos.map((u) => u.raw);
379
+ }
380
+ else {
381
+ // Gate on unshielded strict-complete only — see designateForDustImpl
382
+ // above for why `s.isSynced` is the wrong predicate here.
383
+ const state = await Rx.firstValueFrom(facade.state().pipe(Rx.filter((s) => s.unshielded?.progress?.isStrictlyComplete?.() === true)));
384
+ utxos = state.unshielded.availableCoins.filter((c) => c.meta.registeredForDustGeneration === true);
385
+ }
386
+ if (utxos.length === 0)
387
+ throw new Error('No registered NIGHT UTXOs to deregister');
388
+ onProgress?.('building');
389
+ const recipe = await facade.deregisterFromDustGeneration(utxos, ks.getPublicKey(), (payload) => ks.signData(payload));
390
+ const balancedRecipe = await facade.balanceUnprovenTransaction(recipe.transaction, { shieldedSecretKeys: keys.shieldedSecretKeys, dustSecretKey: keys.dustSecretKey }, { ttl: new Date(Date.now() + 30 * 60_000) });
391
+ onProgress?.('submitting');
392
+ const finalized = await facade.finalizeRecipe(balancedRecipe);
393
+ return submitWithRetry(facade, finalized);
394
+ }
395
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/sync/operations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { WalletPart } from './sync-store.js';
2
+ /** The parts a pre-seed can supply. History is not seeded; it rebuilds itself. */
3
+ export declare const SEEDABLE_PARTS: readonly ["shielded", "unshielded", "dust"];
4
+ export type SeedablePart = (typeof SEEDABLE_PARTS)[number];
5
+ /**
6
+ * The seedable parts with no cached state, in a fixed order.
7
+ *
8
+ * A part that already has a cache is at least as far along as the reference, so
9
+ * seeding over it would discard progress. Anything absent is a candidate,
10
+ * whether this is a brand-new wallet (all three) or a rebuild of one
11
+ * (just the evicted part).
12
+ */
13
+ export declare function partsToSeed(cached: Partial<Record<SeedablePart, string | null>>): SeedablePart[];
14
+ /** Whether a pre-seed attempt is worth making at all. */
15
+ export declare function shouldAttemptPreSeed(cached: Partial<Record<SeedablePart, string | null>>): boolean;
16
+ /** Narrowing helper for callers holding the wider WalletPart union. */
17
+ export declare function isSeedablePart(part: WalletPart): part is SeedablePart;
18
+ //# sourceMappingURL=preseed-parts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preseed-parts.d.ts","sourceRoot":"","sources":["../../src/sync/preseed-parts.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAEhD,kFAAkF;AAClF,eAAO,MAAM,cAAc,6CAA8C,CAAC;AAE1E,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,YAAY,EAAE,CAEhG;AAED,yDAAyD;AACzD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,OAAO,CAElG;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,IAAI,YAAY,CAErE"}
@@ -0,0 +1,33 @@
1
+ // Which sub-wallet caches a pre-seed should fill in.
2
+ //
3
+ // Split out and WASM-free so the decision is unit-testable without loading the
4
+ // ledger — the same split as sync/progress.ts.
5
+ //
6
+ // This exists because the decision was once made by proxy: the pre-seed gate
7
+ // tested the SHIELDED cache alone, standing in for "this wallet has no state
8
+ // yet". That proxy failed exactly where it mattered. A DUST rebuild evicts the
9
+ // dust cache and nothing else, so shielded was still present, the gate stayed
10
+ // shut, and dust walked all 1.4M events from genesis — 78.6 min on preprod —
11
+ // while a usable reference sat unused.
12
+ /** The parts a pre-seed can supply. History is not seeded; it rebuilds itself. */
13
+ export const SEEDABLE_PARTS = ['shielded', 'unshielded', 'dust'];
14
+ /**
15
+ * The seedable parts with no cached state, in a fixed order.
16
+ *
17
+ * A part that already has a cache is at least as far along as the reference, so
18
+ * seeding over it would discard progress. Anything absent is a candidate,
19
+ * whether this is a brand-new wallet (all three) or a rebuild of one
20
+ * (just the evicted part).
21
+ */
22
+ export function partsToSeed(cached) {
23
+ return SEEDABLE_PARTS.filter((part) => !cached[part]);
24
+ }
25
+ /** Whether a pre-seed attempt is worth making at all. */
26
+ export function shouldAttemptPreSeed(cached) {
27
+ return partsToSeed(cached).length > 0;
28
+ }
29
+ /** Narrowing helper for callers holding the wider WalletPart union. */
30
+ export function isSeedablePart(part) {
31
+ return SEEDABLE_PARTS.includes(part);
32
+ }
33
+ //# sourceMappingURL=preseed-parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preseed-parts.js","sourceRoot":"","sources":["../../src/sync/preseed-parts.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,+EAA+E;AAC/E,+CAA+C;AAC/C,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,6EAA6E;AAC7E,uCAAuC;AAIvC,kFAAkF;AAClF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,CAAU,CAAC;AAI1E;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,MAAoD;IAC9E,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,oBAAoB,CAAC,MAAoD;IACvF,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AACxC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,OAAQ,cAAoC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,95 @@
1
+ import type { NetworkConfig } from '../types/network.js';
2
+ import { type SyncStateStore } from './sync-store.js';
3
+ import { type WalletKeys } from './operations.js';
4
+ export interface EmptyRefStates {
5
+ shielded: string;
6
+ unshielded: string;
7
+ dust: string;
8
+ /**
9
+ * Chain height this reference was synced to. Callers MUST refuse to pre-seed a
10
+ * wallet whose birthday precedes it: the reference carries the chain's state at
11
+ * this height, so seeding a wallet that was already active earlier would skip
12
+ * that wallet's own history. Compared against `birthday` (also a height) —
13
+ * never against a snapshot `offset`, which is an event index.
14
+ */
15
+ height: number;
16
+ }
17
+ /** Reference-build progress, for surfacing an hour-long job in the UI. */
18
+ export interface WarmProgress {
19
+ /** Dust events applied so far — the sub-wallet that dominates the build. */
20
+ applied: number;
21
+ /** Dust events the chain currently has. Grows slowly as the chain advances. */
22
+ total: number;
23
+ synced: boolean;
24
+ }
25
+ /**
26
+ * Ensure an empty reference wallet is synced to chain tip for this network.
27
+ * The first call per network syncs from genesis (or restores from cache).
28
+ * Subsequent calls return the cached result immediately.
29
+ */
30
+ export declare function ensureEmptyRefCache(network: NetworkConfig, onProgress?: (msg: string) => void, store?: SyncStateStore,
31
+ /**
32
+ * Build the reference if none is warm yet. OFF by default, and deliberately
33
+ * so: building means syncing an empty wallet to chain tip, which dust makes a
34
+ * tens-of-minutes job. On the wallet-startup path that would block the user's
35
+ * own wallet from starting, which is far worse than letting it sync from
36
+ * genesis in the background. Callers that mean to pay the cost use
37
+ * warmEmptyRefCache().
38
+ */
39
+ opts?: {
40
+ build?: boolean;
41
+ onWarmProgress?: (p: WarmProgress) => void;
42
+ }): Promise<EmptyRefStates | null>;
43
+ /**
44
+ * Build (or resume building) the empty reference wallet for a network, syncing
45
+ * it all the way to chain tip so it can actually pre-seed new wallets.
46
+ *
47
+ * This is the slow one: the first build walks the whole chain, which dust makes
48
+ * a tens-of-minutes job on preprod. It is worth paying once per network per
49
+ * machine, because afterwards every new wallet — and every dust rebuild — starts
50
+ * at tip instead of genesis. Intended for a background task or an explicit
51
+ * command, never the wallet-startup path.
52
+ */
53
+ /**
54
+ * Sync an EXISTING reference forward to chain tip, instead of rebuilding it.
55
+ *
56
+ * ensureEmptyRefCache short-circuits on a warm reference, so before this the only
57
+ * way to update one was to delete it and walk the chain again — 53.6 min on
58
+ * preprod. That was never a limitation of the mechanism, only of the entry
59
+ * points: buildEmptyRefCache already resumes from whatever reference state the
60
+ * store holds (it syncs under EMPTY_REF_WALLET, and startWalletSync restores that
61
+ * wallet's cache like any other), so catching up costs the drift and nothing more.
62
+ *
63
+ * A stale reference is safe to use — it only means more catch-up for the wallets
64
+ * it seeds, at roughly half a second per hour of age — so this is an optimisation,
65
+ * not a repair. Run it before cutting a release, or on a schedule.
66
+ */
67
+ export declare function refreshEmptyRefCache(network: NetworkConfig, onProgress?: (msg: string) => void, store?: SyncStateStore, onWarmProgress?: (p: WarmProgress) => void): Promise<EmptyRefStates | null>;
68
+ export declare function warmEmptyRefCache(network: NetworkConfig, onProgress?: (msg: string) => void, store?: SyncStateStore, onWarmProgress?: (p: WarmProgress) => void): Promise<EmptyRefStates | null>;
69
+ /**
70
+ * Whether this network has a reference at chain tip, without building anything.
71
+ * Lets a UI distinguish "not started" from "in progress" from "done" — a build
72
+ * runs for an hour, so reporting it as perpetually in progress is misleading.
73
+ */
74
+ export declare function preseedReferenceStatus(network: NetworkConfig, store?: SyncStateStore): Promise<{
75
+ ready: boolean;
76
+ height: number | null;
77
+ }>;
78
+ /**
79
+ * Pre-seed a newly generated wallet's sync state from the empty reference.
80
+ *
81
+ * - Shielded: reference's Zswap tree + offset, new wallet's public keys, empty coins
82
+ * - Unshielded: new wallet's public key, reference's indexer cursor, empty UTXOs
83
+ * - Dust: reference state as-is with the new wallet's dust public key swapped in.
84
+ * Dust ledger events are global (the indexer streams `dustLedgerEvents` keyed
85
+ * by a global id), and a wallet holding no NIGHT has no designations of its
86
+ * own to preserve, so the reference's generation tree and cursor transfer
87
+ * directly. This is the expensive one to get right: without it dust walks the
88
+ * whole chain, which is minutes-to-an-hour where shielded takes seconds.
89
+ */
90
+ export declare function preSeedNewWallet(walletKeys: WalletKeys, networkId: string, emptyRef: EmptyRefStates): {
91
+ shielded: string;
92
+ unshielded: string;
93
+ dust?: string;
94
+ } | null;
95
+ //# sourceMappingURL=preseed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preseed.d.ts","sourceRoot":"","sources":["../../src/sync/preseed.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAA6E,KAAK,cAAc,EAAkB,MAAM,iBAAiB,CAAC;AAEjJ,OAAO,EAAmB,KAAK,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AA+FD;;;;GAIG;AAOH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,aAAa,EACtB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EAClC,KAAK,CAAC,EAAE,cAAc;AACtB;;;;;;;GAOG;AACH,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,CAAA;CAAE,GACrE,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA8BhC;AAED;;;;;;;;;GASG;AACH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,aAAa,EACtB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EAClC,KAAK,CAAC,EAAE,cAAc,EACtB,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,GACzC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAiBhC;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,aAAa,EACtB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EAClC,KAAK,CAAC,EAAE,cAAc,EACtB,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,GACzC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAEhC;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,aAAa,EACtB,KAAK,CAAC,EAAE,cAAc,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAIpD;AA+FD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,GACvB;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAC,GAAG,IAAI,CAgE9D"}