@needmoretruth/nmts-cli 0.17.2 → 0.34.1

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 (419) hide show
  1. package/AGENTS.md +124 -516
  2. package/CHANGELOG.md +98 -0
  3. package/README.ko.md +374 -467
  4. package/README.md +384 -465
  5. package/dist/account-proof.d.ts +29 -0
  6. package/dist/account-proof.js +6 -6
  7. package/dist/account.d.ts +18 -0
  8. package/dist/account.js +5 -5
  9. package/dist/agent-host.d.ts +71 -0
  10. package/dist/agent-host.js +169 -0
  11. package/dist/api-advice.d.ts +2 -0
  12. package/dist/api-advice.js +210 -0
  13. package/dist/api-key.d.ts +79 -0
  14. package/dist/api-key.js +7 -7
  15. package/dist/api-refusal.d.ts +14 -0
  16. package/dist/api-refusal.js +8 -0
  17. package/dist/api.d.ts +114 -0
  18. package/dist/api.js +59 -162
  19. package/dist/args.d.ts +160 -0
  20. package/dist/args.js +118 -30
  21. package/dist/artifact-about.d.ts +49 -0
  22. package/dist/autonomy.d.ts +39 -0
  23. package/dist/autonomy.js +110 -32
  24. package/dist/code-access.d.ts +29 -0
  25. package/dist/code-access.js +3 -3
  26. package/dist/code-vault.d.ts +38 -0
  27. package/dist/code-vault.js +8 -8
  28. package/dist/collision.d.ts +67 -0
  29. package/dist/collision.js +1 -1
  30. package/dist/commands/accept-terms.d.ts +11 -0
  31. package/dist/commands/accept-terms.js +106 -0
  32. package/dist/commands/balance.d.ts +7 -0
  33. package/dist/commands/balance.js +54 -1
  34. package/dist/commands/create-code-file.d.ts +24 -0
  35. package/dist/commands/create-code-file.js +93 -0
  36. package/dist/commands/create-link.d.ts +10 -0
  37. package/dist/commands/create-link.js +232 -0
  38. package/dist/commands/create.d.ts +20 -0
  39. package/dist/commands/create.js +43 -102
  40. package/dist/commands/credits.d.ts +9 -0
  41. package/dist/commands/credits.js +110 -0
  42. package/dist/commands/delete-account.d.ts +11 -0
  43. package/dist/commands/delete-account.js +63 -0
  44. package/dist/commands/deposit.d.ts +7 -0
  45. package/dist/commands/deposit.js +85 -0
  46. package/dist/commands/devices.d.ts +12 -0
  47. package/dist/commands/devices.js +144 -0
  48. package/dist/commands/documents.d.ts +35 -0
  49. package/dist/commands/documents.js +212 -0
  50. package/dist/commands/env.d.ts +5 -0
  51. package/dist/commands/env.js +10 -2
  52. package/dist/commands/erase.d.ts +13 -0
  53. package/dist/commands/erase.js +193 -0
  54. package/dist/commands/expiring.d.ts +19 -0
  55. package/dist/commands/extend.d.ts +33 -0
  56. package/dist/commands/extend.js +54 -15
  57. package/dist/commands/get.d.ts +18 -0
  58. package/dist/commands/key-manage.d.ts +11 -0
  59. package/dist/commands/key-manage.js +162 -0
  60. package/dist/commands/key.d.ts +28 -0
  61. package/dist/commands/key.js +249 -0
  62. package/dist/commands/kit.d.ts +11 -0
  63. package/dist/commands/kit.js +7 -7
  64. package/dist/commands/listfile.d.ts +13 -0
  65. package/dist/commands/listfile.js +12 -5
  66. package/dist/commands/login.d.ts +18 -0
  67. package/dist/commands/login.js +19 -19
  68. package/dist/commands/logout.d.ts +1 -0
  69. package/dist/commands/logout.js +1 -1
  70. package/dist/commands/losses.d.ts +12 -0
  71. package/dist/commands/losses.js +180 -0
  72. package/dist/commands/ls.d.ts +23 -0
  73. package/dist/commands/marks-dispatch.d.ts +2 -0
  74. package/dist/commands/marks-dispatch.js +51 -0
  75. package/dist/commands/marks.d.ts +46 -0
  76. package/dist/commands/marks.js +80 -0
  77. package/dist/commands/mcp.d.ts +24 -0
  78. package/dist/commands/mcp.js +70 -5
  79. package/dist/commands/mode.d.ts +8 -0
  80. package/dist/commands/mode.js +60 -24
  81. package/dist/commands/on-collision.d.ts +6 -0
  82. package/dist/commands/organise.d.ts +46 -0
  83. package/dist/commands/padding.d.ts +7 -0
  84. package/dist/commands/padding.js +114 -0
  85. package/dist/commands/public-code.d.ts +9 -0
  86. package/dist/commands/public-code.js +8 -8
  87. package/dist/commands/pull.d.ts +27 -0
  88. package/dist/commands/push-wallet.d.ts +19 -0
  89. package/dist/commands/push-wallet.js +69 -0
  90. package/dist/commands/push.d.ts +47 -0
  91. package/dist/commands/push.js +37 -7
  92. package/dist/commands/put-wallet.d.ts +77 -0
  93. package/dist/commands/put-wallet.js +316 -0
  94. package/dist/commands/put.d.ts +56 -0
  95. package/dist/commands/put.js +53 -6
  96. package/dist/commands/rebuild.d.ts +18 -0
  97. package/dist/commands/rebuild.js +108 -10
  98. package/dist/commands/receive.d.ts +24 -0
  99. package/dist/commands/recovery-dispatch.d.ts +2 -0
  100. package/dist/commands/recovery-dispatch.js +34 -0
  101. package/dist/commands/recovery-list.d.ts +11 -0
  102. package/dist/commands/recovery-list.js +6 -6
  103. package/dist/commands/recovery.d.ts +25 -0
  104. package/dist/commands/recovery.js +2 -2
  105. package/dist/commands/rollback.d.ts +9 -0
  106. package/dist/commands/rollback.js +118 -0
  107. package/dist/commands/s3.d.ts +23 -0
  108. package/dist/commands/s3.js +6 -6
  109. package/dist/commands/settings.d.ts +5 -0
  110. package/dist/commands/settings.js +21 -6
  111. package/dist/commands/share-dispatch.d.ts +2 -0
  112. package/dist/commands/share-dispatch.js +46 -0
  113. package/dist/commands/share.d.ts +14 -0
  114. package/dist/commands/share.js +13 -3
  115. package/dist/commands/shares-sent.d.ts +18 -0
  116. package/dist/commands/shares-sent.js +95 -0
  117. package/dist/commands/support.d.ts +24 -0
  118. package/dist/commands/support.js +321 -0
  119. package/dist/commands/sweep.d.ts +11 -0
  120. package/dist/commands/tip.d.ts +11 -0
  121. package/dist/commands/tip.js +86 -0
  122. package/dist/commands/trash.d.ts +17 -0
  123. package/dist/commands/trash.js +1 -1
  124. package/dist/commands/trial.d.ts +7 -0
  125. package/dist/commands/trial.js +16 -18
  126. package/dist/commands/unlock.d.ts +16 -0
  127. package/dist/commands/unlock.js +159 -0
  128. package/dist/commands/update.d.ts +42 -0
  129. package/dist/commands/update.js +1 -1
  130. package/dist/commands/usage.d.ts +8 -0
  131. package/dist/commands/verify.d.ts +18 -0
  132. package/dist/commands/verify.js +10 -6
  133. package/dist/commands/wallet-activity.d.ts +26 -0
  134. package/dist/commands/wallet-activity.js +117 -0
  135. package/dist/commands/wallet-donate.d.ts +26 -0
  136. package/dist/commands/wallet-donate.js +163 -0
  137. package/dist/commands/wallet-hall.d.ts +35 -0
  138. package/dist/commands/wallet-hall.js +214 -0
  139. package/dist/commands/wallet-send.d.ts +22 -0
  140. package/dist/commands/wallet-send.js +153 -0
  141. package/dist/commands/wallet-storage-ops.d.ts +24 -0
  142. package/dist/commands/wallet-storage-ops.js +215 -0
  143. package/dist/commands/wallet-storage.d.ts +18 -0
  144. package/dist/commands/wallet-storage.js +95 -0
  145. package/dist/commands/wallet-swap.d.ts +32 -0
  146. package/dist/commands/wallet-swap.js +287 -0
  147. package/dist/commands/wallet.d.ts +36 -0
  148. package/dist/commands/wallet.js +57 -15
  149. package/dist/commands/whoami.d.ts +10 -0
  150. package/dist/commands/whoami.js +24 -6
  151. package/dist/consent.d.ts +140 -0
  152. package/dist/consent.js +89 -30
  153. package/dist/credentials.d.ts +146 -0
  154. package/dist/credentials.js +10 -10
  155. package/dist/crypto-surface.d.ts +197 -0
  156. package/dist/crypto.d.ts +81 -0
  157. package/dist/crypto.js +13 -0
  158. package/dist/deposit.d.ts +25 -0
  159. package/dist/deposit.js +78 -0
  160. package/dist/download-part.d.ts +40 -0
  161. package/dist/download-sink.d.ts +76 -0
  162. package/dist/download.d.ts +79 -0
  163. package/dist/download.js +3 -3
  164. package/dist/drive-paths.d.ts +73 -0
  165. package/dist/environment.d.ts +62 -0
  166. package/dist/environment.js +29 -9
  167. package/dist/errors.d.ts +22 -0
  168. package/dist/errors.js +3 -3
  169. package/dist/exit.d.ts +44 -0
  170. package/dist/expiry.d.ts +58 -0
  171. package/dist/extend-budget.d.ts +35 -0
  172. package/dist/extend-budget.js +81 -0
  173. package/dist/extend-chain.d.ts +43 -0
  174. package/dist/extend-chain.js +40 -3
  175. package/dist/extend-plan.d.ts +148 -0
  176. package/dist/extend-plan.js +1 -1
  177. package/dist/gate.d.ts +18 -0
  178. package/dist/gate.js +100 -0
  179. package/dist/guards.d.ts +2 -0
  180. package/dist/help.d.ts +20 -0
  181. package/dist/help.js +199 -33
  182. package/dist/human-check.d.ts +23 -0
  183. package/dist/index.d.ts +42 -0
  184. package/dist/index.js +49 -0
  185. package/dist/item-trash.d.ts +1 -0
  186. package/dist/kit-file.d.ts +56 -0
  187. package/dist/kit-file.js +10 -10
  188. package/dist/list-file.d.ts +88 -0
  189. package/dist/list-file.js +90 -7
  190. package/dist/list-view-find.d.ts +15 -0
  191. package/dist/list-view-order.d.ts +32 -0
  192. package/dist/main.d.ts +12 -0
  193. package/dist/main.js +112 -113
  194. package/dist/manifest-chunk-cache.d.ts +14 -0
  195. package/dist/manifest-chunk-cache.js +103 -0
  196. package/dist/manifest-chunk-flow.d.ts +81 -0
  197. package/dist/manifest-chunk-flow.js +307 -0
  198. package/dist/manifest-create.d.ts +23 -0
  199. package/dist/manifest-create.js +26 -30
  200. package/dist/manifest-write.d.ts +161 -0
  201. package/dist/manifest-write.js +42 -33
  202. package/dist/manifest.d.ts +82 -0
  203. package/dist/manifest.js +69 -21
  204. package/dist/mark-render.d.ts +26 -0
  205. package/dist/mcp-args.d.ts +17 -0
  206. package/dist/mcp-ask.d.ts +43 -0
  207. package/dist/mcp-ask.js +100 -0
  208. package/dist/mcp-tools/context.d.ts +46 -0
  209. package/dist/mcp-tools/credits.d.ts +3 -0
  210. package/dist/mcp-tools/credits.js +61 -0
  211. package/dist/mcp-tools/files.d.ts +3 -0
  212. package/dist/mcp-tools/files.js +34 -0
  213. package/dist/mcp-tools/organise.d.ts +3 -0
  214. package/dist/mcp-tools/organise.js +82 -2
  215. package/dist/mcp-tools/reads.d.ts +3 -0
  216. package/dist/mcp-tools/reads.js +132 -4
  217. package/dist/mcp-tools/share.d.ts +3 -0
  218. package/dist/mcp-tools/share.js +26 -7
  219. package/dist/mcp-tools/support.d.ts +3 -0
  220. package/dist/mcp-tools/support.js +140 -0
  221. package/dist/mcp-tools/tiers.d.ts +31 -0
  222. package/dist/mcp-tools/tiers.js +147 -0
  223. package/dist/mcp.d.ts +80 -0
  224. package/dist/mcp.js +110 -9
  225. package/dist/net-retry.d.ts +38 -0
  226. package/dist/network.d.ts +10 -0
  227. package/dist/notice.d.ts +7 -0
  228. package/dist/notice.js +7 -7
  229. package/dist/product.d.ts +29 -0
  230. package/dist/product.js +1 -1
  231. package/dist/progress.d.ts +37 -0
  232. package/dist/prompt.d.ts +31 -0
  233. package/dist/prompt.js +1 -1
  234. package/dist/rebuild-key-check.d.ts +26 -0
  235. package/dist/rebuild-key-check.js +90 -0
  236. package/dist/rebuild.d.ts +87 -0
  237. package/dist/rebuild.js +26 -4
  238. package/dist/recovery-assemble.d.ts +40 -0
  239. package/dist/recovery-assemble.js +1 -1
  240. package/dist/recovery-build.d.ts +40 -0
  241. package/dist/recovery-map-file.d.ts +53 -0
  242. package/dist/recovery-map-file.js +4 -4
  243. package/dist/recovery-map.d.ts +197 -0
  244. package/dist/recovery-release.d.ts +104 -0
  245. package/dist/recovery-seq.d.ts +10 -0
  246. package/dist/recovery-source.d.ts +50 -0
  247. package/dist/redact.d.ts +70 -0
  248. package/dist/redact.js +212 -0
  249. package/dist/registration.d.ts +30 -0
  250. package/dist/registration.js +5 -5
  251. package/dist/risk.d.ts +380 -0
  252. package/dist/risk.js +206 -0
  253. package/dist/run-log.d.ts +78 -0
  254. package/dist/run-log.js +301 -0
  255. package/dist/s3/listing.d.ts +47 -0
  256. package/dist/s3/multipart.d.ts +21 -0
  257. package/dist/s3/response-sink.d.ts +8 -0
  258. package/dist/s3/same-file.d.ts +54 -0
  259. package/dist/s3/server.d.ts +58 -0
  260. package/dist/s3/server.js +2 -2
  261. package/dist/s3/sigv4.d.ts +46 -0
  262. package/dist/s3/sigv4.js +1 -1
  263. package/dist/s3/staging.d.ts +10 -0
  264. package/dist/s3/xml.d.ts +28 -0
  265. package/dist/safe-path.d.ts +41 -0
  266. package/dist/seal.d.ts +120 -0
  267. package/dist/secret-reader.d.ts +28 -0
  268. package/dist/server.d.ts +9 -0
  269. package/dist/session.d.ts +32 -0
  270. package/dist/session.js +1 -1
  271. package/dist/setup-questions.d.ts +7 -0
  272. package/dist/share.d.ts +108 -0
  273. package/dist/share.js +1 -1
  274. package/dist/shared/lib/crypto/size-padding.d.ts +55 -0
  275. package/dist/shared/lib/crypto/size-padding.js +5 -0
  276. package/dist/shared/lib/drive/manifest-chunks.d.ts +95 -0
  277. package/dist/shared/lib/drive/manifest-chunks.js +252 -0
  278. package/dist/shared/lib/drive/manifest-codec.d.ts +214 -0
  279. package/dist/shared/lib/drive/manifest-codec.js +7 -7
  280. package/dist/shared/lib/drive/manifest-index.d.ts +98 -0
  281. package/dist/shared/lib/drive/manifest-ops.d.ts +167 -0
  282. package/dist/shared/lib/drive/manifest-ops.js +9 -4
  283. package/dist/shared/lib/drive/manifest-pack.d.ts +65 -0
  284. package/dist/shared/lib/drive/manifest-pack.js +287 -0
  285. package/dist/shared/lib/drive/manifest-settings.d.ts +113 -0
  286. package/dist/shared/lib/drive/manifest-settings.js +87 -6
  287. package/dist/shared/lib/drive/name-conflict.d.ts +76 -0
  288. package/dist/shared/lib/drive/rebuild-verify.d.ts +73 -0
  289. package/dist/shared/lib/drive/rebuild-verify.js +112 -0
  290. package/dist/shared/lib/drive/unique-name.d.ts +9 -0
  291. package/dist/shared/lib/drive/zstd.d.ts +27 -0
  292. package/dist/shared/lib/drive/zstd.js +74 -0
  293. package/dist/shared/lib/extend/epochs.d.ts +205 -0
  294. package/dist/shared/lib/net/retry-budget.d.ts +79 -0
  295. package/dist/shared/lib/share/shared-file-info.d.ts +21 -0
  296. package/dist/shared/lib/storage-control/chain.d.ts +57 -0
  297. package/dist/shared/lib/storage-control/chain.js +82 -0
  298. package/dist/shared/lib/storage-control/plan.d.ts +40 -0
  299. package/dist/shared/lib/storage-control/plan.js +72 -0
  300. package/dist/shared/lib/storage-control/reuse.d.ts +72 -0
  301. package/dist/shared/lib/storage-control/reuse.js +95 -0
  302. package/dist/shared/lib/storage-network.d.ts +25 -0
  303. package/dist/shared/lib/upload/part-plan.d.ts +24 -0
  304. package/dist/shared/lib/wallet/activity.d.ts +138 -0
  305. package/dist/shared/lib/wallet/activity.js +208 -0
  306. package/dist/shared/lib/wallet/send-rules.d.ts +68 -0
  307. package/dist/shared/lib/wallet/send-rules.js +116 -0
  308. package/dist/shared/lib/wallet/swap-rules.d.ts +115 -0
  309. package/dist/shared/lib/wallet/swap-rules.js +199 -0
  310. package/dist/shared/lib/wallet/tip.d.ts +14 -0
  311. package/dist/shared/lib/wallet/tip.js +34 -0
  312. package/dist/shared/lib/wallet/venue-ids.d.ts +23 -0
  313. package/dist/shared/lib/wallet/venue-ids.js +53 -0
  314. package/dist/standing-tip.d.ts +24 -0
  315. package/dist/standing-tip.js +52 -0
  316. package/dist/stdout.d.ts +38 -0
  317. package/dist/storage-control-chain.d.ts +38 -0
  318. package/dist/storage-control-chain.js +78 -0
  319. package/dist/sui-rpc.d.ts +15 -0
  320. package/dist/sui-rpc.js +59 -0
  321. package/dist/support-attach.d.ts +24 -0
  322. package/dist/support-attach.js +72 -0
  323. package/dist/support-copy.d.ts +42 -0
  324. package/dist/support-copy.js +109 -0
  325. package/dist/support-wire.d.ts +49 -0
  326. package/dist/support-wire.js +194 -0
  327. package/dist/trash-sweep.d.ts +55 -0
  328. package/dist/units.d.ts +2 -0
  329. package/dist/update-check.d.ts +50 -0
  330. package/dist/update-source.d.ts +63 -0
  331. package/dist/upload-api.d.ts +3 -0
  332. package/dist/upload-file.d.ts +97 -0
  333. package/dist/upload-file.js +3 -2
  334. package/dist/upload-price.d.ts +50 -0
  335. package/dist/upload-steps.d.ts +26 -0
  336. package/dist/upload-steps.js +29 -9
  337. package/dist/upload-store.d.ts +182 -0
  338. package/dist/upload-wallet-chain.d.ts +54 -0
  339. package/dist/upload-wallet-chain.js +203 -0
  340. package/dist/upload-wallet-plan.d.ts +128 -0
  341. package/dist/upload-wallet-plan.js +184 -0
  342. package/dist/upload-wallet.d.ts +24 -0
  343. package/dist/upload-wallet.js +208 -0
  344. package/dist/upload-wire.d.ts +244 -0
  345. package/dist/upload.d.ts +18 -0
  346. package/dist/upload.js +10 -0
  347. package/dist/usage-report.d.ts +35 -0
  348. package/dist/wallet-activity-chain.d.ts +5 -0
  349. package/dist/wallet-activity-chain.js +31 -0
  350. package/dist/wallet-chain.d.ts +19 -0
  351. package/dist/wallet-chain.js +2 -2
  352. package/dist/wallet-grant.d.ts +50 -0
  353. package/dist/wallet-grant.js +218 -0
  354. package/dist/wallet-send-chain.d.ts +24 -0
  355. package/dist/wallet-send-chain.js +49 -0
  356. package/dist/wallet-sign.d.ts +133 -0
  357. package/dist/wallet-sign.js +317 -0
  358. package/dist/wallet-storage-chain.d.ts +3 -0
  359. package/dist/wallet-storage-chain.js +20 -0
  360. package/dist/wallet-swap-chain.d.ts +52 -0
  361. package/dist/wallet-swap-chain.js +186 -0
  362. package/dist/wallet-swap-quote.d.ts +22 -0
  363. package/dist/wallet-swap-quote.js +126 -0
  364. package/dist/wallet.d.ts +135 -0
  365. package/dist/wallet.js +5 -5
  366. package/dist/walrus-write.d.ts +56 -0
  367. package/dist/walrus-write.js +5 -4
  368. package/dist/walrus.d.ts +86 -0
  369. package/dist/walrus.js +48 -10
  370. package/dist/zstd-node.d.ts +11 -0
  371. package/dist/zstd-node.js +71 -0
  372. package/docs/commands/accept-terms.md +15 -0
  373. package/docs/commands/create.md +17 -0
  374. package/docs/commands/credits.md +34 -0
  375. package/docs/commands/delete-account.md +14 -0
  376. package/docs/commands/deposit.md +27 -0
  377. package/docs/commands/devices.md +9 -0
  378. package/docs/commands/documents.md +10 -0
  379. package/docs/commands/env.md +21 -0
  380. package/docs/commands/extend.md +27 -0
  381. package/docs/commands/folders.md +10 -0
  382. package/docs/commands/get.md +14 -0
  383. package/docs/commands/key.md +14 -0
  384. package/docs/commands/login.md +23 -0
  385. package/docs/commands/logout.md +11 -0
  386. package/docs/commands/losses.md +13 -0
  387. package/docs/commands/ls.md +16 -0
  388. package/docs/commands/marks.md +9 -0
  389. package/docs/commands/mcp.md +33 -0
  390. package/docs/commands/mode.md +29 -0
  391. package/docs/commands/on-collision.md +13 -0
  392. package/docs/commands/padding.md +13 -0
  393. package/docs/commands/public-code.md +9 -0
  394. package/docs/commands/pull.md +9 -0
  395. package/docs/commands/push.md +12 -0
  396. package/docs/commands/put.md +36 -0
  397. package/docs/commands/rebuild.md +13 -0
  398. package/docs/commands/recovery.md +18 -0
  399. package/docs/commands/s3.md +17 -0
  400. package/docs/commands/share.md +15 -0
  401. package/docs/commands/support.md +16 -0
  402. package/docs/commands/tip.md +21 -0
  403. package/docs/commands/trash.md +25 -0
  404. package/docs/commands/trial.md +12 -0
  405. package/docs/commands/unlock.md +25 -0
  406. package/docs/commands/update.md +14 -0
  407. package/docs/commands/usage.md +14 -0
  408. package/docs/commands/verify.md +18 -0
  409. package/docs/commands/wallet.md +67 -0
  410. package/docs/commands/whoami.md +12 -0
  411. package/package.json +67 -8
  412. package/server.json +28 -0
  413. package/vendor/nmts-crypto/nmts_crypto_wasm.d.ts +23 -2
  414. package/vendor/nmts-crypto/nmts_crypto_wasm.js +44 -2
  415. package/vendor/nmts-crypto/nmts_crypto_wasm_bg.wasm +0 -0
  416. package/vendor/nmts-crypto/nmts_crypto_wasm_bg.wasm.d.ts +1 -0
  417. package/vendor/nmts-crypto/package.json +1 -1
  418. package/dist/commands/consent.js +0 -77
  419. package/dist/extend-sign.js +0 -130
@@ -0,0 +1,205 @@
1
+ /** One blob's lease, as the chain currently has it. */
2
+ export interface BlobLease {
3
+ /** Sui object id of the blob. */
4
+ objectId: string;
5
+ /** Unencoded size in bytes (Blob.size) — what the storage price is computed from. */
6
+ size: number;
7
+ /** The epoch the lease runs out at (Blob.storage.end_epoch). THE authoritative expiry. */
8
+ endEpoch: number;
9
+ }
10
+ /** Where the network is now, how far ahead anyone may buy, and how long an epoch lasts. */
11
+ export interface EpochWindow {
12
+ /** The epoch the network is in. */
13
+ current: number;
14
+ /**
15
+ * How many epochs ahead of `current` a lease may reach — the protocol's
16
+ * `storage_accounting::max_epochs_ahead`, read as the future-accounting ring length (that is
17
+ * exactly what the Move function returns). Measured 53 on testnet, 2026-07-27.
18
+ */
19
+ maxAhead: number;
20
+ /** One epoch's length in milliseconds (testnet 1 day · mainnet 14 days — read, not assumed). */
21
+ durationMs: number;
22
+ /**
23
+ * When the current epoch began, in ms. Null while the network is mid-epoch-change, in which case
24
+ * no date is shown at all — a wrong date on a screen about deletion is worse than no date.
25
+ */
26
+ startedMs: number | null;
27
+ }
28
+ /**
29
+ * The wall-clock moment an epoch is reached, from the network's own epoch clock. Null when there
30
+ * is no anchor to measure from.
31
+ *
32
+ * ⚠ An ESTIMATE, and labelled as one wherever it is shown: epoch changes can run late, and the
33
+ * measured history proves it (epoch 471 began 9 days later than `first_epoch_start` plus 470 × the
34
+ * epoch length would put it). Never present this as the exact deletion time.
35
+ */
36
+ export declare function epochDate(window: LeaseClock, epoch: number): Date | null;
37
+ /**
38
+ * The window an epoch can arrive in — an answer even when the clock is only APPROXIMATE.
39
+ *
40
+ * ⚠ The two ends are clamped at "now" only on the approximate branch, where a negative bound is an
41
+ * artefact of not knowing how far into the current epoch we are. An anchored date that lands in the
42
+ * past is a real answer (the lease ended on that day) and is returned as it is.
43
+ */
44
+ export declare function epochDateBounds(clock: LeaseClock, epoch: number, nowMs: number): {
45
+ earliest: Date;
46
+ latest: Date;
47
+ exact: boolean;
48
+ } | null;
49
+ /**
50
+ * Warn from here on. Two stages: a plain note, then a red one.
51
+ *
52
+ * ⭐ THEY LIVE HERE, NOT IN THE COMPONENT THAT DRAWS THE BANNER (moved 2026-07-30). Two surfaces
53
+ * now read them — the drive-wide banner (`ExpiryNotice`) and every file row's own status
54
+ * (`lib/drive/file-status.ts`). A copy in each is how a banner ends up shouting "extend now" over
55
+ * a list of rows that all say "sealed", with neither file looking wrong on its own.
56
+ * ⚠ A `.tsx` cannot hold them either: `node --test` reads plain `.ts` and not `.tsx`, so a constant
57
+ * parked in a component is a constant no pure test can check.
58
+ *
59
+ * Both stages are a floor in DAYS and a floor in EPOCHS, and the wider one wins (see
60
+ * `warningEpochs`). The epoch figures are what mainnet is really sized by: 3 epochs is six weeks of
61
+ * runway there, and 1 epoch — the urgent stage — is the last two weeks in which extending is still
62
+ * possible at all.
63
+ */
64
+ export declare const NOTICE_DAYS = 14;
65
+ export declare const NOTICE_EPOCHS = 3;
66
+ export declare const URGENT_DAYS = 3;
67
+ export declare const URGENT_EPOCHS = 1;
68
+ /**
69
+ * How far ahead the expiry warning starts, in epochs: a floor in DAYS and a floor in EPOCHS, wider
70
+ * one wins.
71
+ *
72
+ * Counted in days alone, mainnet's 14-day epoch made the whole warning exactly ONE epoch wide, so
73
+ * someone who opens the app monthly missed it entirely. Counted in epochs alone, testnet's 1-day
74
+ * epoch would have shrunk the window from 14 days to 3. Taking whichever is longer never narrows
75
+ * either network's warning — and the day-count rounds UP, because arriving a tick late is the
76
+ * quiet failure this whole surface exists to prevent.
77
+ */
78
+ export declare function warningEpochs(days: number, floorEpochs: number, durationMs: number): number;
79
+ /** The part of the epoch clock that turns an end epoch into a number of days. */
80
+ export interface LeaseClock {
81
+ /** The epoch the network is in. */
82
+ current: number;
83
+ /** One epoch's length in ms — 1 day on testnet, 14 on mainnet. Read, never assumed. */
84
+ durationMs: number;
85
+ /**
86
+ * When the current epoch began, when the network said so (`EpochChangeDone`). Absent or null ⇒
87
+ * there is no anchor, and every figure derived from this clock is a FLOOR rather than a
88
+ * measurement. Optional so a caller with only the two numbers above still type-checks; the real
89
+ * clock (`EpochWindow`) always carries it.
90
+ */
91
+ startedMs?: number | null;
92
+ }
93
+ /** Whole days until a lease ends, and whether that number is a measurement or a floor. */
94
+ export interface DaysLeft {
95
+ /** Rounded DOWN. Negative is a real answer — the epoch is already behind us. */
96
+ days: number;
97
+ /** False ⇒ `days` is a LOWER BOUND and the words beside it must say "or more". */
98
+ exact: boolean;
99
+ }
100
+ /**
101
+ * Whole days from now until `epoch` is reached, by the network's own epoch clock.
102
+ *
103
+ * ⛔ THE SAFE EDGE, NOT THE OPTIMISTIC ONE (fixed 2026-08-16). This used to be
104
+ * `(epoch − current) × epochLength`, which ignores the time already spent inside the current epoch
105
+ * — on mainnet that overstates the runway by up to fourteen days, and it did: 28 shown where the
106
+ * chain said 23. Without an anchor the answer is now the floor of `epochArrival`'s `minMs`, and
107
+ * `exact: false` tells the surface to say "N days or more" instead of making a flat claim.
108
+ *
109
+ * ⛔ Never substitute `NETWORK.epochDays` for the clock here. That constant is the MAINNET basis
110
+ * (14); using it on testnet, where an epoch is one day, would report 196 days over a file with
111
+ * fourteen days to live.
112
+ *
113
+ * Null when the clock carries no usable epoch length — the caller says the period is unread rather
114
+ * than counting days from a constant.
115
+ */
116
+ export declare function daysLeftUntilEpoch(epoch: number, clock: LeaseClock, nowMs: number): DaysLeft | null;
117
+ /** How much time is left, broken into the units a person reads off a clock. */
118
+ export interface TimeLeft {
119
+ /** Whole days. */
120
+ days: number;
121
+ /** 0–23. */
122
+ hours: number;
123
+ /** 0–59. */
124
+ minutes: number;
125
+ /** 0–59. */
126
+ seconds: number;
127
+ /** Total milliseconds, floored at zero. */
128
+ totalMs: number;
129
+ /** False ⇒ this is a LOWER BOUND — the real moment is later, by up to one epoch. */
130
+ exact: boolean;
131
+ }
132
+ /**
133
+ * The same answer `daysLeftUntilEpoch` gives, down to the second.
134
+ *
135
+ * ⭐ WHY THIS EXISTS: a day count is the right thing to glance at and the wrong thing to plan by
136
+ * on the last day. "1 day left" covers everything from twenty-four hours to one minute, and by
137
+ * then the only question left is whether there is time to deal with it tonight.
138
+ *
139
+ * ⛔ IT IS THE SAME EDGE AS THE DAY COUNT, on purpose. Both take `epochArrival`'s `minMs`, so the
140
+ * two can never disagree: a countdown reading three hours under a label reading "2 days left"
141
+ * would be two numbers about one fact, and a person believes the reassuring one.
142
+ *
143
+ * ⚠ EVEN EXACT IS AN ESTIMATE, and the direction is known: an epoch change can run LATE, never
144
+ * early, so this can only be early. Measured on mainnet 2026-08-25 — 36 epochs after the first,
145
+ * the accumulated drift was nine minutes.
146
+ *
147
+ * Null on the same input as `daysLeftUntilEpoch`: no usable epoch length.
148
+ */
149
+ export declare function timeLeftUntilEpoch(epoch: number, clock: LeaseClock, nowMs: number): TimeLeft | null;
150
+ /**
151
+ * The largest number of epochs these leases can ALL be extended by.
152
+ *
153
+ * The ceiling is per-blob: a lease may not end more than `maxAhead` epochs past the current one,
154
+ * so the blob that already reaches furthest into the future is the binding one. Returns 0 when
155
+ * nothing more can be bought yet — which is a real answer ("already paid as far ahead as the
156
+ * network allows"), not an error.
157
+ */
158
+ export declare function headroom(leases: readonly BlobLease[], window: EpochWindow): number;
159
+ /**
160
+ * The enum cases of the network's `epoch_state` that carry WHEN THE CURRENT EPOCH BEGAN.
161
+ *
162
+ * ⛔ THERE ARE TWO OF THEM, AND READING ONLY THE FIRST COST US A FORTNIGHT OF PRECISION. The Move
163
+ * enum has three cases: `EpochChangeSync` (a node count — a small integer, NOT a moment),
164
+ * `EpochChangeDone` (the moment this epoch's change happened), and `NextParamsSelected` (the
165
+ * same moment, kept after the next epoch's parameters are chosen). A network settles into the
166
+ * LAST of those and stays there, so an implementation that accepted `EpochChangeDone` alone
167
+ * threw the anchor away nearly always. Measured on mainnet 2026-08-25: epoch 37 reported
168
+ * `NextParamsSelected` holding 2026-08-11T15:08:58Z — exactly one epoch before its end. Without
169
+ * it `epochArrival` falls back to a range ONE WHOLE EPOCH wide (fourteen days on mainnet), and
170
+ * every surface that counts down to a deletion then says "as early as N days" — honest, and
171
+ * useless to somebody deciding whether to pay for more time.
172
+ *
173
+ * ⛔ THIS IS AN ALLOW-LIST, NOT A DENY-LIST. `EpochChangeSync` carries a `u16`, which is finite and
174
+ * would happily become a date in 1970; and a case this code has not been taught must report NO
175
+ * anchor rather than guess. Losing precision costs a warning that comes early. Guessing costs a
176
+ * deleted file.
177
+ */
178
+ export declare const EPOCH_START_VARIANTS: readonly string[];
179
+ /**
180
+ * When the current epoch began, in ms — or null when this reading cannot say.
181
+ *
182
+ * ⭐ ONE OF IT, ON PURPOSE. Both the browser and the command-line tool read the same enum for the
183
+ * same reason, and a second narrowing elsewhere would be a second answer to "has this epoch
184
+ * settled" — the two would drift the day the protocol renames a case, and drift here is a wrong
185
+ * deletion date on a screen where somebody spends money.
186
+ *
187
+ * Read by name rather than cast: a shape change in the protocol has to surface as "no anchor",
188
+ * which costs precision, instead of as a NaN that becomes a date.
189
+ */
190
+ export declare function epochStartedMs(epochState: unknown): number | null;
191
+ /**
192
+ * When a file actually runs out: the SOONEST end epoch across the blobs it rides on. Null when
193
+ * there is no lease to read.
194
+ *
195
+ * ⚠ NULL IS NOT A ZERO AND NOT "NOW" (2026-07-28). The sheet that shows this used to
196
+ * substitute the CURRENT epoch when the list was empty, and so printed today's date under "expires
197
+ * on" above the sentence "after this date the file is deleted and cannot be recovered" —
198
+ * telling someone their file dies today. The empty case is reached by real files: every part on
199
+ * treasury-paid storage, or parts old enough to carry no on-chain object id, produce no targets
200
+ * and therefore no leases. There is no epoch to report for those, so this reports none and the
201
+ * caller shows nothing rather than a number it invented.
202
+ *
203
+ * SOONEST, not furthest: one expired blob is enough to make the file unreadable.
204
+ */
205
+ export declare function soonestEnd(leases: readonly BlobLease[]): number | null;
@@ -0,0 +1,79 @@
1
+ /** First wait after a failure, before jitter. */
2
+ export declare const RETRY_BASE_MS = 1000;
3
+ /**
4
+ * The longest single wait. Without a ceiling the ninth backoff is eight minutes, and a person
5
+ * watching a progress bar cannot tell that from a program that has stopped.
6
+ */
7
+ export declare const RETRY_MAX_WAIT_MS = 30000;
8
+ /**
9
+ * How long to go on retrying while the network is reachable and the far side keeps failing.
10
+ *
11
+ * ⚠ THIS IS THE UPLOAD-SHAPED DEFAULT: money is already spent, the work resumes where it stopped,
12
+ * and nobody is staring at it. A surface where none of that is true passes its own (`budgetMs`).
13
+ */
14
+ export declare const RETRY_BUDGET_MS: number;
15
+ /**
16
+ * The budget for something a person is watching and can simply ask for again — a download.
17
+ *
18
+ * ⚠ It is not small because failing is fine; it is small because ten minutes of "still trying" is
19
+ * indistinguishable from a program that has stopped, and pressing again costs nothing here.
20
+ */
21
+ export declare const WATCHED_RETRY_BUDGET_MS = 60000;
22
+ /** The matching offline bound for a watched surface. */
23
+ export declare const WATCHED_OFFLINE_BUDGET_MS: number;
24
+ /** How long to go on waiting while there is no network at all. Longer, because waiting is free. */
25
+ export declare const OFFLINE_BUDGET_MS: number;
26
+ /** How often to look again while offline. The `online` event is the real signal; this is the net. */
27
+ export declare const OFFLINE_POLL_MS = 2000;
28
+ /** What the caller should do next. */
29
+ export interface NextAttempt {
30
+ /** False ⇒ the budget is spent. Report the failure honestly and stop. */
31
+ readonly again: boolean;
32
+ /** How long to wait first, in ms. */
33
+ readonly waitMs: number;
34
+ /**
35
+ * True ⇒ this wait is for the network to come back, not for a busy server.
36
+ *
37
+ * ⛔ The caller must NOT add this wait to `elapsedOnlineMs`, and the screen must say
38
+ * 「waiting for the network」 rather than 「retrying」 — those are different facts, and only
39
+ * one of them is something the person can do anything about.
40
+ */
41
+ readonly waitingForNetwork: boolean;
42
+ }
43
+ export interface AttemptInput {
44
+ /** 1-based number of the attempt that just failed. */
45
+ readonly attempt: number;
46
+ /** Wall clock spent retrying WHILE ONLINE, in ms. Offline waiting is not counted here. */
47
+ readonly elapsedOnlineMs: number;
48
+ /** Wall clock spent waiting for a network, in ms. */
49
+ readonly elapsedOfflineMs: number;
50
+ /** What the browser says about having a network. Believed only when it says no. */
51
+ readonly online: boolean;
52
+ /** A number in [0, 1). Passed in so the jitter is reproducible in a test. */
53
+ readonly random: number;
54
+ /**
55
+ * How long to go on retrying while online. Defaults to {@link RETRY_BUDGET_MS}.
56
+ *
57
+ * ⛔ IT IS NOT ONE NUMBER FOR EVERYTHING, because the two sides are not the same bargain. An
58
+ * upload has money already spent on it and resumes where it stopped, so waiting is cheap and
59
+ * giving up is expensive. A download has nothing at stake and the person is watching it — ten
60
+ * minutes of "still trying" there is a program that looks broken, and pressing it again costs
61
+ * nothing. So the caller says.
62
+ */
63
+ readonly budgetMs?: number;
64
+ /** How long to go on waiting for a network. Defaults to {@link OFFLINE_BUDGET_MS}. */
65
+ readonly offlineBudgetMs?: number;
66
+ }
67
+ /**
68
+ * What to do after one failed attempt.
69
+ *
70
+ * ⛔ THE ORDER OF THE TWO CHECKS MATTERS. Offline is decided first, because a failure that
71
+ * happened because there is no network must not spend the online budget — otherwise a tunnel
72
+ * long enough to exhaust it turns into a failed upload the moment the network returns.
73
+ */
74
+ export declare function nextAttempt(input: AttemptInput): NextAttempt;
75
+ /**
76
+ * How much of the budget is left, as a fraction — for a screen that wants to say how long it will
77
+ * go on trying. Null when nothing has been spent on this kind of waiting yet.
78
+ */
79
+ export declare function budgetLeft(elapsedMs: number, waitingForNetwork: boolean): number;
@@ -0,0 +1,21 @@
1
+ /** What a recipient learns about a shared file before fetching a byte of it. */
2
+ export interface SharedFileInfo {
3
+ /** Plaintext file name, exactly as the sender's drive spells it. */
4
+ name: string;
5
+ /**
6
+ * The file's REAL plaintext length. Absent for a share sealed before this document existed.
7
+ *
8
+ * Absent must be read as "not recorded", never as "zero" and never as "unpadded": what makes an
9
+ * older share safe is the content hash, not this field.
10
+ */
11
+ size?: number;
12
+ }
13
+ /** The string to seal as `name_share_ct`. */
14
+ export declare function encodeSharedFileInfo(info: SharedFileInfo): string;
15
+ /**
16
+ * Read what the sender sealed. Never throws: a name that cannot be parsed IS the name.
17
+ *
18
+ * The refusal to throw is deliberate. This runs while painting a list of everything shared with a
19
+ * person, and one row whose document is malformed must not take the other rows' names down with it.
20
+ */
21
+ export declare function decodeSharedFileInfo(sealed: string): SharedFileInfo;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The slice of a Sui RPC client this file uses. Structural on purpose: the browser hands in its
3
+ * Walrus-extended client and the command-line tool its plain JSON-RPC client, and neither has to
4
+ * be named here.
5
+ */
6
+ export interface StorageChainReader {
7
+ getObject(input: {
8
+ id: string;
9
+ options: {
10
+ showType: true;
11
+ };
12
+ }): Promise<{
13
+ data?: {
14
+ type?: string | null;
15
+ } | null;
16
+ }>;
17
+ getOwnedObjects(input: {
18
+ owner: string;
19
+ filter: {
20
+ StructType: string;
21
+ };
22
+ options: {
23
+ showContent: true;
24
+ };
25
+ cursor?: string;
26
+ }): Promise<{
27
+ data?: readonly unknown[] | null;
28
+ hasNextPage?: boolean;
29
+ nextCursor?: string | null;
30
+ }>;
31
+ }
32
+ /** One storage resource — the chain's `Storage { id, start_epoch, end_epoch, storage_size }` as is. */
33
+ export interface StorageResource {
34
+ /** The Sui object id. */
35
+ readonly objectId: string;
36
+ /** The epoch from which this resource can be used. */
37
+ readonly startEpoch: number;
38
+ /** The epoch at which it ends. */
39
+ readonly endEpoch: number;
40
+ /** How much it can hold AFTER encoding, in bytes. ⚠ Not a plaintext size. */
41
+ readonly sizeBytes: number;
42
+ }
43
+ /**
44
+ * This network's storage-resource type name, derived from the system object.
45
+ *
46
+ * ⛔ `showType` only — the content is not needed, and asking for it returns a large answer.
47
+ */
48
+ export declare function readStorageType(client: StorageChainReader, systemObjectId: string): Promise<string>;
49
+ /** One object response as a storage resource. A different shape gives null — it quietly leaves the list. */
50
+ export declare function toStorageResource(node: unknown): StorageResource | null;
51
+ /**
52
+ * Every storage resource this address holds.
53
+ *
54
+ * ⚠ Follows the pages to the end. Reading only the first would show a person with many resources
55
+ * SOME OF THEM AS IF THEY WERE ALL, which is a worse lie than "none".
56
+ */
57
+ export declare function readOwnedStorage(client: StorageChainReader, owner: string, storageType: string, maxPages?: number): Promise<StorageResource[]>;
@@ -0,0 +1,82 @@
1
+ // Storage resources — the "size × time" a wallet holds, read from the chain. ⚠ PUBLISHED —
2
+ // copied byte-for-byte into the `nmts` command-line package; keep comments self-contained English.
3
+ //
4
+ // ⛔ WHY THIS EXISTS (owner directive 2026-08-10, pressed again 2026-08-27). What the storage
5
+ // network sells is not a file but an OBJECT WITH A SIZE AND A PERIOD. Deleting a file gives
6
+ // that object BACK TO ITS OWNER — and until this, the product had nowhere to see what came
7
+ // back, nor to use it: the erase path sent it to the person's address and stopped, so paid-for
8
+ // space sat there unseen.
9
+ //
10
+ // ⛔ THE TYPE NAME IS NOT WRITTEN AS A CONSTANT. When Walrus upgrades its contract the package
11
+ // address changes, but a Move type carries the package that FIRST defined it. So the name is cut
12
+ // from the system object's own type — an object that survives upgrades (the same judgement the
13
+ // wallet configuration makes). ⚠ Written by hand, the list would fall to "none" — not to an
14
+ // error — on the day of the next upgrade.
15
+ //
16
+ // ⛔ EVERYTHING HERE IS A READ. Splitting, fusing and transferring need a signature and are not here.
17
+ //
18
+ // FAILURE MODES: what cannot be read THROWS — it is not flattened to "0 resources". Having none and
19
+ // failing to read are different facts to a person, and drawing both as one screen is a defect this
20
+ // product has stepped on more than once.
21
+ /**
22
+ * This network's storage-resource type name, derived from the system object.
23
+ *
24
+ * ⛔ `showType` only — the content is not needed, and asking for it returns a large answer.
25
+ */
26
+ export async function readStorageType(client, systemObjectId) {
27
+ const res = await client.getObject({ id: systemObjectId, options: { showType: true } });
28
+ const type = res.data?.type;
29
+ if (typeof type !== "string" || !type.includes("::")) {
30
+ throw new Error("The storage network's system object did not say its type.");
31
+ }
32
+ return `${type.split("::")[0]}::storage_resource::Storage`;
33
+ }
34
+ /** One object response as a storage resource. A different shape gives null — it quietly leaves the list. */
35
+ export function toStorageResource(node) {
36
+ if (typeof node !== "object" || node === null)
37
+ return null;
38
+ const data = Reflect.get(node, "data");
39
+ if (typeof data !== "object" || data === null)
40
+ return null;
41
+ const objectId = Reflect.get(data, "objectId");
42
+ const content = Reflect.get(data, "content");
43
+ if (typeof objectId !== "string" || typeof content !== "object" || content === null)
44
+ return null;
45
+ const fields = Reflect.get(content, "fields");
46
+ if (typeof fields !== "object" || fields === null)
47
+ return null;
48
+ const start = Number(Reflect.get(fields, "start_epoch"));
49
+ const end = Number(Reflect.get(fields, "end_epoch"));
50
+ const size = Number(Reflect.get(fields, "storage_size"));
51
+ if (!Number.isFinite(start) || !Number.isFinite(end) || !Number.isFinite(size))
52
+ return null;
53
+ return { objectId, startEpoch: start, endEpoch: end, sizeBytes: size };
54
+ }
55
+ /**
56
+ * Every storage resource this address holds.
57
+ *
58
+ * ⚠ Follows the pages to the end. Reading only the first would show a person with many resources
59
+ * SOME OF THEM AS IF THEY WERE ALL, which is a worse lie than "none".
60
+ */
61
+ export async function readOwnedStorage(client, owner, storageType, maxPages = 20) {
62
+ const out = [];
63
+ let cursor = null;
64
+ for (let page = 0; page < maxPages; page += 1) {
65
+ const res = await client.getOwnedObjects({
66
+ owner,
67
+ filter: { StructType: storageType },
68
+ options: { showContent: true },
69
+ ...(cursor === null ? {} : { cursor }),
70
+ });
71
+ for (const node of res.data ?? []) {
72
+ const one = toStorageResource(node);
73
+ if (one !== null)
74
+ out.push(one);
75
+ }
76
+ if (res.hasNextPage !== true || typeof res.nextCursor !== "string")
77
+ return out;
78
+ cursor = res.nextCursor;
79
+ }
80
+ // ⛔ Hitting the page ceiling is SAID. Cutting quietly would make the screen claim "this is all".
81
+ throw new Error("Too many storage resources to read in one go.");
82
+ }
@@ -0,0 +1,40 @@
1
+ import type { StorageResource } from "./chain.ts";
2
+ /** Whether two resources can be fused, and if not, why. */
3
+ export type FuseVerdict = {
4
+ readonly can: true;
5
+ readonly kind: "amount" | "periods";
6
+ } | {
7
+ readonly can: false;
8
+ readonly why: "differentPeriod" | "differentSize" | "notAdjacent" | "same";
9
+ };
10
+ /**
11
+ * Whether the contract will fuse these two.
12
+ *
13
+ * ⚠ Written so the order does not matter — the order a person picks them in means nothing.
14
+ */
15
+ export declare function canFuse(a: StorageResource, b: StorageResource): FuseVerdict;
16
+ /**
17
+ * Where a resource stands against the current epoch.
18
+ *
19
+ * ⛔ "Ended" is decided by COMPARING EPOCHS, not dates — the rule this product learned from its
20
+ * expiry display, for the same reason here.
21
+ */
22
+ export declare function statusOf(resource: StorageResource, currentEpoch: number): "lapsed" | "notYet" | "usable";
23
+ /** Usable ones first, largest first. The order a list shows before anything else. */
24
+ export declare function usableFirst(resources: readonly StorageResource[], currentEpoch: number): StorageResource[];
25
+ /**
26
+ * Whether a file of `encodedBytes` that must last until `needUntilEpoch` fits in this resource.
27
+ *
28
+ * ⚠ `encodedBytes` is the size AFTER the storage network's encoding, not the plaintext size.
29
+ */
30
+ export declare function fits(resource: StorageResource, encodedBytes: number, needUntilEpoch: number): boolean;
31
+ /**
32
+ * What is left of the resource after that file goes in.
33
+ *
34
+ * ⛔ Registration DOES NOT GIVE THE REMAINDER BACK — putting 500 MB into a 1 GB resource binds
35
+ * the whole gigabyte. That is why this number is shown: it is what a person chooses "cut to
36
+ * fit" or "use whole" on.
37
+ */
38
+ export declare function leftoverBytes(resource: StorageResource, encodedBytes: number): number;
39
+ /** The sizes of the usable resources added up — the "space held right now" line. */
40
+ export declare function totalUsableBytes(resources: readonly StorageResource[], currentEpoch: number): number;
@@ -0,0 +1,72 @@
1
+ // What can be done with a storage resource — pure judgement. Touches no chain and no screen.
2
+ // ⚠ PUBLISHED — copied byte-for-byte into the `nmts` command-line package; keep comments
3
+ // self-contained English.
4
+ //
5
+ // ⛔ ONLY WHAT THE CONTRACT ALLOWS IS ALLOWED (`storage_resource.move`, read verbatim 2026-08-11):
6
+ // · `fuse_amount` — the periods must be IDENTICAL for the sizes to add;
7
+ // · `fuse_periods` — the sizes must be equal and the periods ADJACENT for the periods to join;
8
+ // · `split_by_size` / `split_by_epoch` — cut by size, or by period.
9
+ // ⛔ No other combination fuses. Leaving a button alive and letting the chain refuse it leaves
10
+ // the person having PAID GAS with no idea why. So the answer is given here, first.
11
+ //
12
+ // ⛔ The reason it cannot be done is returned with the verdict. A greyed-out button alone is a
13
+ // shape this product has already forbidden (the final approval never stands grey and silent).
14
+ /**
15
+ * Whether the contract will fuse these two.
16
+ *
17
+ * ⚠ Written so the order does not matter — the order a person picks them in means nothing.
18
+ */
19
+ export function canFuse(a, b) {
20
+ if (a.objectId === b.objectId)
21
+ return { can: false, why: "same" };
22
+ const samePeriod = a.startEpoch === b.startEpoch && a.endEpoch === b.endEpoch;
23
+ if (samePeriod)
24
+ return { can: true, kind: "amount" };
25
+ const sameSize = a.sizeBytes === b.sizeBytes;
26
+ if (!sameSize)
27
+ return { can: false, why: "differentSize" };
28
+ const adjacent = a.endEpoch === b.startEpoch || b.endEpoch === a.startEpoch;
29
+ return adjacent ? { can: true, kind: "periods" } : { can: false, why: "notAdjacent" };
30
+ }
31
+ /**
32
+ * Where a resource stands against the current epoch.
33
+ *
34
+ * ⛔ "Ended" is decided by COMPARING EPOCHS, not dates — the rule this product learned from its
35
+ * expiry display, for the same reason here.
36
+ */
37
+ export function statusOf(resource, currentEpoch) {
38
+ if (resource.endEpoch <= currentEpoch)
39
+ return "lapsed";
40
+ if (resource.startEpoch > currentEpoch)
41
+ return "notYet";
42
+ return "usable";
43
+ }
44
+ /** Usable ones first, largest first. The order a list shows before anything else. */
45
+ export function usableFirst(resources, currentEpoch) {
46
+ const rank = (r) => ({ usable: 0, notYet: 1, lapsed: 2 })[statusOf(r, currentEpoch)];
47
+ return [...resources].sort((x, y) => rank(x) - rank(y) || y.sizeBytes - x.sizeBytes || y.endEpoch - x.endEpoch);
48
+ }
49
+ /**
50
+ * Whether a file of `encodedBytes` that must last until `needUntilEpoch` fits in this resource.
51
+ *
52
+ * ⚠ `encodedBytes` is the size AFTER the storage network's encoding, not the plaintext size.
53
+ */
54
+ export function fits(resource, encodedBytes, needUntilEpoch) {
55
+ return resource.sizeBytes >= encodedBytes && resource.endEpoch >= needUntilEpoch;
56
+ }
57
+ /**
58
+ * What is left of the resource after that file goes in.
59
+ *
60
+ * ⛔ Registration DOES NOT GIVE THE REMAINDER BACK — putting 500 MB into a 1 GB resource binds
61
+ * the whole gigabyte. That is why this number is shown: it is what a person chooses "cut to
62
+ * fit" or "use whole" on.
63
+ */
64
+ export function leftoverBytes(resource, encodedBytes) {
65
+ return Math.max(0, resource.sizeBytes - encodedBytes);
66
+ }
67
+ /** The sizes of the usable resources added up — the "space held right now" line. */
68
+ export function totalUsableBytes(resources, currentEpoch) {
69
+ return resources
70
+ .filter((r) => statusOf(r, currentEpoch) === "usable")
71
+ .reduce((sum, r) => sum + r.sizeBytes, 0);
72
+ }
@@ -0,0 +1,72 @@
1
+ import { Transaction } from "@mysten/sui/transactions";
2
+ /** Whether one resource CERTAINLY holds this file — true means it does; false means "unknown", not "it cannot". */
3
+ export interface FitInput {
4
+ /** The space the resource holds (bytes AFTER encoding) — the chain's `storage_size`. */
5
+ readonly resourceSizeBytes: number;
6
+ /** The BEFORE-encoding size of the file this resource used to hold. Absent = defer the judgement. */
7
+ readonly heldRawBytes?: number;
8
+ /** The BEFORE-encoding size of the file about to go in. */
9
+ readonly newRawBytes: number;
10
+ /** The epoch the resource ends at. */
11
+ readonly resourceEndEpoch: number;
12
+ /** The current epoch. */
13
+ readonly currentEpoch: number;
14
+ }
15
+ /**
16
+ * Only "it certainly fits" is true.
17
+ *
18
+ * ⛔ THE ENCODED LENGTH IS NOT COMPUTED HERE. That arithmetic is the protocol's and lives inside
19
+ * the SDK (unexported); a copy kept here would be wrong the day they change it, and only we
20
+ * would not know. ▶ Instead MONOTONICITY alone is used: the encoded length never shrinks as the
21
+ * raw length grows, so a new file no larger than the one the resource held certainly fits.
22
+ * ⚠ This is therefore a SUFFICIENT condition. When it is false the real answer comes from a dry
23
+ * run — resources carry a 63 MiB floor, so a slightly larger file fitting a small file's slot
24
+ * is common in practice.
25
+ */
26
+ export declare function surelyFits(input: FitInput): boolean;
27
+ export interface RegisterIntoInput {
28
+ /** The Walrus system object. */
29
+ readonly systemObjectId: string;
30
+ /** The package to CALL — the system object's `package_id` field. ⛔ Not the type's prefix. */
31
+ readonly walrusPackageId: string;
32
+ /** The full type name of the WAL coin. */
33
+ readonly walType: string;
34
+ /** The resource already held. */
35
+ readonly storageObjectId: string;
36
+ /** What the encoder produced. */
37
+ readonly blobIdAsInt: bigint;
38
+ readonly rootHash: Uint8Array;
39
+ readonly rawBytes: number;
40
+ /** The write cost for this size, in FROST (WAL base units). */
41
+ readonly writeCost: bigint;
42
+ readonly deletable: boolean;
43
+ /** Where the created blob object goes. */
44
+ readonly owner: string;
45
+ }
46
+ /** A registration that uses ONE held storage resource as it is. */
47
+ export declare function registerIntoStorage(input: RegisterIntoInput, transaction?: Transaction): Transaction;
48
+ export interface SplitToFitInput {
49
+ /** The package to CALL — the system object's `package_id`, as above. */
50
+ readonly walrusPackageId: string;
51
+ /** The resource to cut. After this call it is exactly `keepBytes` large. */
52
+ readonly storageObjectId: string;
53
+ /** The encoded size the file needs — what the cut resource keeps. */
54
+ readonly keepBytes: number;
55
+ /** Where the remainder — a NEW resource object — goes. */
56
+ readonly owner: string;
57
+ }
58
+ /**
59
+ * "Cut to fit": shrink a held resource to exactly what the file needs, so the rest stays a free
60
+ * resource instead of being bound inside the blob. The owner's rule: the person chooses between
61
+ * cutting and binding whole, and is shown the leftover in bytes — no default is chosen for them.
62
+ *
63
+ * ⛔ WHICH HALF IS WHICH IS THE CONTRACT'S CHOICE, read from `storage_resource.move`: `split_by_size`
64
+ * MODIFIES the given resource down to `split_size` and RETURNS a new object holding the rest.
65
+ * So the object id the caller already holds is the one that registers the blob afterwards, and
66
+ * the returned object is the leftover — which must be transferred, or the transaction is
67
+ * refused at assembly for an unused value.
68
+ *
69
+ * ⚠ `keepBytes` must be the ENCODED size (the chain's `encoded_blob_length`), never the raw one:
70
+ * registration checks `encoded_size <= storage_size` and a resource cut to the raw size fails it.
71
+ */
72
+ export declare function splitStorageToFit(input: SplitToFitInput, transaction?: Transaction): Transaction;