@artblocks/abx-cli 0.1.0-alpha.40 → 0.1.0-alpha.42

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 (77) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/assets/renderer-scaffold/README.md +12 -0
  3. package/assets/renderer-scaffold/foundry.toml +4 -0
  4. package/assets/renderer-scaffold/script/Preview.s.sol +99 -0
  5. package/dist/capabilities.d.ts +9 -4
  6. package/dist/capabilities.d.ts.map +1 -1
  7. package/dist/capabilities.js +13 -4
  8. package/dist/capabilities.js.map +1 -1
  9. package/dist/commands/deploy.d.ts +51 -1
  10. package/dist/commands/deploy.d.ts.map +1 -1
  11. package/dist/commands/deploy.js +1008 -172
  12. package/dist/commands/deploy.js.map +1 -1
  13. package/dist/commands/maintenance.d.ts +4 -0
  14. package/dist/commands/maintenance.d.ts.map +1 -0
  15. package/dist/commands/maintenance.js +114 -0
  16. package/dist/commands/maintenance.js.map +1 -0
  17. package/dist/commands/project.d.ts +175 -3
  18. package/dist/commands/project.d.ts.map +1 -1
  19. package/dist/commands/project.js +359 -29
  20. package/dist/commands/project.js.map +1 -1
  21. package/dist/commands/reads.d.ts +21 -0
  22. package/dist/commands/reads.d.ts.map +1 -1
  23. package/dist/commands/reads.js +171 -4
  24. package/dist/commands/reads.js.map +1 -1
  25. package/dist/commands/scaffold.d.ts.map +1 -1
  26. package/dist/commands/scaffold.js +5 -0
  27. package/dist/commands/scaffold.js.map +1 -1
  28. package/dist/commands/service.d.ts.map +1 -1
  29. package/dist/commands/service.js +7 -0
  30. package/dist/commands/service.js.map +1 -1
  31. package/dist/commands/storage.d.ts.map +1 -1
  32. package/dist/commands/storage.js +32 -3
  33. package/dist/commands/storage.js.map +1 -1
  34. package/dist/commands/submit-app.d.ts +43 -0
  35. package/dist/commands/submit-app.d.ts.map +1 -1
  36. package/dist/commands/submit-app.js +115 -6
  37. package/dist/commands/submit-app.js.map +1 -1
  38. package/dist/config.d.ts +16 -1
  39. package/dist/config.d.ts.map +1 -1
  40. package/dist/config.js +73 -7
  41. package/dist/config.js.map +1 -1
  42. package/dist/deploy-plan.d.ts +221 -0
  43. package/dist/deploy-plan.d.ts.map +1 -0
  44. package/dist/deploy-plan.js +20 -0
  45. package/dist/deploy-plan.js.map +1 -0
  46. package/dist/flag-allowlists.d.ts.map +1 -1
  47. package/dist/flag-allowlists.js +5 -1
  48. package/dist/flag-allowlists.js.map +1 -1
  49. package/dist/flags.d.ts +6 -0
  50. package/dist/flags.d.ts.map +1 -1
  51. package/dist/flags.js +14 -0
  52. package/dist/flags.js.map +1 -1
  53. package/dist/jsonout.d.ts.map +1 -1
  54. package/dist/jsonout.js +11 -0
  55. package/dist/jsonout.js.map +1 -1
  56. package/dist/main.js +62 -13
  57. package/dist/main.js.map +1 -1
  58. package/dist/ownerops.d.ts +139 -1
  59. package/dist/ownerops.d.ts.map +1 -1
  60. package/dist/ownerops.js +382 -19
  61. package/dist/ownerops.js.map +1 -1
  62. package/dist/riskgate.d.ts +36 -0
  63. package/dist/riskgate.d.ts.map +1 -1
  64. package/dist/riskgate.js +91 -17
  65. package/dist/riskgate.js.map +1 -1
  66. package/dist/script-chunks.d.ts +1 -1
  67. package/dist/script-chunks.d.ts.map +1 -1
  68. package/dist/script-chunks.js +2 -2
  69. package/dist/script-chunks.js.map +1 -1
  70. package/package.json +6 -6
  71. package/skill/SKILL.md +6 -4
  72. package/skill/reference/code.md +31 -8
  73. package/skill/reference/deploy.md +9 -2
  74. package/skill/reference/diagnose.md +15 -2
  75. package/skill/reference/hosting.md +26 -0
  76. package/skill/reference/operate.md +55 -4
  77. package/skill/reference/setup.md +14 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ownerops.d.ts","sourceRoot":"","sources":["../src/ownerops.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EA4CL,KAAK,kBAAkB,EAavB,KAAK,eAAe,EAapB,KAAK,MAAM,EAIX,KAAK,OAAO,EACZ,KAAK,GAAG,EACR,KAAK,iBAAiB,EAMtB,mBAAmB,EAEnB,0BAA0B,EAC1B,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAElB,KAAK,QAAQ,EACb,KAAK,WAAW,EAEjB,MAAM,oBAAoB,CAAC;AAoC5B,OAAO,EAAsD,KAAK,aAAa,EAAC,MAAM,aAAa,CAAC;AAKpG,OAAO,EAAmC,KAAK,YAAY,EAAC,MAAM,aAAa,CAAC;AAKhF,OAAO,EAAC,0BAA0B,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,KAAK,QAAQ,EAAC,CAAC;AASzI,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAYhD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CA4BvD;AAmCD;;gGAEgG;AAChG,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMnE;AAiGD;sGACsG;AACtG,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB1E;AAID;;;;;;;;GAQG;AACH;;;4GAG4G;AAC5G;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAiBrG;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGhH;AAGD,QAAA,MAAM,UAAU,+CAAgD,CAAC;AACjE,KAAK,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAQ5C,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAMnE;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA2E/F;AAOD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB/G;AAED;uEACuE;AACvE,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAItG;AAED;+FAC+F;AAC/F,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBvH;AAED,uGAAuG;AACvG,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAMlG;AAED;;;;;gDAKgD;AAChD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5F;AAED;;;;gEAIgE;AAChE,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAmChG;AAGD;iGACiG;AACjG,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvE;AAED;oGACoG;AACpG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBvD;AAUD,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAuFtF;AAMD;2EAC2E;AAC3E,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3F;AAED,oGAAoG;AACpG,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBnG;AAGD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA8C9F;AAOD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBzF;AAED,iFAAiF;AACjF,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvF;AAED,oEAAoE;AACpE,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzF;AAGD;;;;mFAImF;AACnF,eAAO,MAAM,wBAAwB,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAK1F,CAAC;AAEF;sFACsF;AACtF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,iBAAiB,EAAE,CAI1E;AAOD;oGACoG;AACpG,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,iBAAiB,EAAE,CAYvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE,KAAK,GACX;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,CAQnC;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC5F;AAED,+EAA+E;AAC/E,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjG;AAmBD,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCzF;AAGD,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA2C1F;AAMD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAW7F;AAID,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhG;AAGD;;;mDAGmD;AACnD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASnD;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5F;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B/F;AAaD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAC,GAC/D,OAAO,CAkCT;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DtH;AAYD;;;;;6BAK6B;AAC7B,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAC,GAC3C,OAAO,CAuBT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,GAAG,KAAK,CAyCnH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAyD/G;AAUD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAI7D;AAgCD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAIzC;AAED;;qGAEqG;AACrG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAEnE;AAgBD,+FAA+F;AAC/F,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,CAAC,CAS9F;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,CAAC,EAAE;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,GAAG,SAAS,GAAG,IAAI,CAExG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuCxF;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAGjF;AAqED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAQrF;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAYhG;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAC,CAQnD;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,CAAC,CAgBxD;AA+BD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CAuCrF;AASD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B3E;AAgBD,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK;AACZ,0DAA0D;AAC1D,KAAK,GAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAsE,GAC3G,OAAO,CAAC,IAAI,CAAC,CAoBf;AAQD,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgG1F;AAiDD;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA8I3E;AAwCD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAa3F;AAGD;;;6EAG6E;AAC7E,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB7F;AAGD;;;8FAG8F;AAC9F,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAazF;AAGD,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1F;AAoHD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAwHjG;AAED;;sGAEsG;AACtG,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA0F5F;AAED;;;oEAGoE;AACpE,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAqD3F;AAUD;+FAC+F;AAC/F,wBAAgB,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,EAAE,CAiBxF;AAED;iEACiE;AACjE,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAkE3F;AAgBD,2FAA2F;AAC3F,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB7G"}
1
+ {"version":3,"file":"ownerops.d.ts","sourceRoot":"","sources":["../src/ownerops.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EA4CL,KAAK,kBAAkB,EAavB,KAAK,eAAe,EAapB,KAAK,MAAM,EAIX,KAAK,OAAO,EACZ,KAAK,GAAG,EACR,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAMtB,mBAAmB,EAEnB,0BAA0B,EAC1B,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAElB,KAAK,QAAQ,EACb,KAAK,WAAW,EAEjB,MAAM,oBAAoB,CAAC;AA6C5B,OAAO,EAAsD,KAAK,aAAa,EAAC,MAAM,aAAa,CAAC;AAKpG,OAAO,EAAmC,KAAK,YAAY,EAAC,MAAM,aAAa,CAAC;AAKhF,OAAO,EAAC,0BAA0B,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,KAAK,QAAQ,EAAC,CAAC;AAUzI,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAYhD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CA4BvD;AAmCD;;gGAEgG;AAChG,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMnE;AAiGD;sGACsG;AACtG,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB1E;AAID;;;;;;;;GAQG;AACH;;;4GAG4G;AAC5G;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAiBrG;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGhH;AAGD,QAAA,MAAM,UAAU,+CAAgD,CAAC;AACjE,KAAK,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAQ5C,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAMnE;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA2E/F;AAOD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB/G;AAED;uEACuE;AACvE,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAItG;AAED;+FAC+F;AAC/F,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBvH;AAED,uGAAuG;AACvG,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAMlG;AAED;;;;;gDAKgD;AAChD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5F;AAuED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAoG/F;AAED;;;;gEAIgE;AAChE,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAmChG;AAGD;iGACiG;AACjG,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvE;AAED;oGACoG;AACpG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBvD;AAUD,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAuFtF;AAMD;2EAC2E;AAC3E,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3F;AAED,oGAAoG;AACpG,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBnG;AAGD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA8C9F;AAOD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBzF;AAED,iFAAiF;AACjF,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvF;AAED,oEAAoE;AACpE,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzF;AAGD;;;;mFAImF;AACnF,eAAO,MAAM,wBAAwB,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAK1F,CAAC;AAEF;sFACsF;AACtF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,iBAAiB,EAAE,CAI1E;AAOD;oGACoG;AACpG,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,iBAAiB,EAAE,CAYvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE,KAAK,GACX;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,CAQnC;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC5F;AAED,+EAA+E;AAC/E,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjG;AAmBD,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCzF;AAGD,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA2C1F;AAMD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAW7F;AAID,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhG;AAGD;;;mDAGmD;AACnD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASnD;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5F;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B/F;AAaD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAC,GAC/D,OAAO,CAkCT;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DtH;AAYD;;;;;6BAK6B;AAC7B,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAC,GAC3C,OAAO,CAuBT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,GAAG,KAAK,CAyCnH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAyD/G;AAUD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAI7D;AAgCD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAIzC;AAED;;qGAEqG;AACrG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAEnE;AAgBD,+FAA+F;AAC/F,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,CAAC,CAS9F;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,CAAC,EAAE;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,GAAG,SAAS,GAAG,IAAI,CAExG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuCxF;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAGjF;AAqED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAQrF;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAYhG;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAC,CAQnD;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,CAAC,CAgBxD;AA+BD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CAuCrF;AASD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B3E;AAgBD,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK;AACZ,0DAA0D;AAC1D,KAAK,GAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAsE,GAC3G,OAAO,CAAC,IAAI,CAAC,CAoBf;AAQD,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAgG1F;AAiDD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,GAAG,MAAM,CAIzI;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB,GAAG,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAAC,CAQ7D;AAGD;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA+K3E;AAwCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAQpC;AAED;kGACkG;AAClG,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB;AACD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,YAAY,CAAC;AAEpD;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,cAAc,GACrB;IAAC,SAAS,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAC,GAAG,IAAI,CAI5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE;IAAC,SAAS,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAC,EAC7D,IAAI,EAAE;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GACxE;IAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CA2B9C;AAqBD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAe3F;AAGD;;;6EAG6E;AAC7E,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB7F;AAGD;;;8FAG8F;AAC9F,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAazF;AAGD,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1F;AAoHD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAwHjG;AAED;;sGAEsG;AACtG,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA0F5F;AAED;;;oEAGoE;AACpE,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAqD3F;AAUD;+FAC+F;AAC/F,wBAAgB,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,EAAE,CAiBxF;AAED;iEACiE;AACjE,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAkE3F;AAgBD,2FAA2F;AAC3F,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB7G"}
package/dist/ownerops.js CHANGED
@@ -10,15 +10,18 @@ import { MAX_ROYALTY_BPS, assertChainId, ensureChunkStore as sdkEnsureChunkStore
10
10
  import { encodeScalarParam, encodeTag as encodeTagSdk, isAccepted, prepareConfigureTokenParam, prepareConfigureTokenParamData, prepareSetContractParam, prepareSetContractParamData, seriesCodeAbi, tryReadContract, } from '@artblocks/abx-sdk';
11
11
  import { hasParamEnumeration, GATEWAY_FIELD, GATEWAY_FLOOR, gatewayPrefixFrom, readCollectionPolicy, readEnv } from '@artblocks/abx-sdk';
12
12
  import { decodeFieldRenderer, encodeFieldRenderer, resolveGenerator, DEP_RESOLUTION, parseDependencyRef, prepareLockDependencies, prepareLockParamHooks, prepareLockScript, prepareRemoveLastDependency, prepareSetDependency, prepareSetDependencyRegistry, } from '@artblocks/abx-sdk';
13
+ import { planScriptReplace, prepareRemoveLastScriptChunk, prepareSetScriptChunk, verifyScriptReplace, } from '@artblocks/abx-sdk';
13
14
  import { contentTypeFromPath } from '@artblocks/abx-storage';
14
15
  import { toHex as toHexSdk } from 'viem';
15
- import { readFileSync } from 'node:fs';
16
+ import { existsSync, readFileSync } from 'node:fs';
16
17
  import { basename, resolve as resolvePath } from 'node:path';
17
18
  import { gzipSync } from 'node:zlib';
18
- import { formatEther, getAddress, isAddress, parseEther, toHex, zeroAddress } from 'viem';
19
+ import { formatEther, getAddress, hexToBytes, isAddress, parseEther, toHex, zeroAddress } from 'viem';
19
20
  import { backendResolution, CHAIN, chainId, fixedPriceMinterAddress, fixedPriceMinter1155Address, localIndexer } from './config.js';
20
21
  import { CliError } from './errors.js';
21
- import { detectTokenKind, isEditionContract, assertHasParamsSurface } from './kind.js';
22
+ import { detectTokenKind, isEditionContract, assertHasParamsSurface, hasParamsSurface } from './kind.js';
23
+ import { planOnChainScript } from './script-chunks.js';
24
+ import { fetchServedTokenUri, servedOk } from './served.js';
22
25
  import { openWalletSession } from './signer.js';
23
26
  import { gatedSend, laneFromFlags } from './riskgate.js';
24
27
  import { withJson } from './jsonout.js';
@@ -30,11 +33,12 @@ import { parseSchemaSpecs, describeSchema } from './schema.js';
30
33
  // definition below).
31
34
  export { ONCHAIN_PROJECT_SOFT_LIMIT, ONCHAIN_READ_WARN_BYTES, ETH_CALL_GAS_FLOOR, tokenUriGasEstimate, readableBytesAtGas };
32
35
  // ── ANSI (local) ─────────────────────────────────────────────────────────────
33
- const C = { reset: '\x1b[0m', dim: '\x1b[2m', bold: '\x1b[1m', green: '\x1b[38;5;115m', yellow: '\x1b[38;5;221m' };
36
+ const C = { reset: '\x1b[0m', dim: '\x1b[2m', bold: '\x1b[1m', green: '\x1b[38;5;115m', yellow: '\x1b[38;5;221m', red: '\x1b[31m' };
34
37
  const dim = (s) => `${C.dim}${s}${C.reset}`;
35
38
  const green = (s) => `${C.green}${s}${C.reset}`;
36
39
  const yellow = (s) => `${C.yellow}${s}${C.reset}`;
37
40
  const bold = (s) => `${C.bold}${s}${C.reset}`;
41
+ const red = (s) => `${C.red}${s}${C.reset}`;
38
42
  // ── data plane: attach files, and the keys you can't set by hand ──────────────
39
43
  // A token anchors named, typed files ("artifacts"). The served JSON's `artifacts` list is the
40
44
  // COMPLETE set — but it's COMPUTED by the resolver/renderer from the token's fields + effect
@@ -532,6 +536,189 @@ export async function cmdLockScript(address, flags) {
532
536
  console.log(dim(' that is not the same as a frozen OUTPUT: params stay writable and a Registry dependency is re-fetched live, so say "locked metadata" to a buyer, not "immutable".'));
533
537
  await runWrite(contract, prepareLockScript({ contract, chainId: chainId() }), flags, owner);
534
538
  }
539
+ /** Flags `abx replace-script` recognizes — anything else warns (non-fatal). */
540
+ const REPLACE_SCRIPT_FLAGS = [...SHARED_WRITE_FLAGS, 'script', 'chunk-size'];
541
+ /** A `ScriptChunkReader` backed by a real chain read — the only place `replace-script` touches
542
+ * `seriesCodeAbi` directly, so `planScriptReplace`/`verifyScriptReplace` themselves stay chain-free
543
+ * and testable (see packages/sdk/src/script-chunks.ts). `scriptChunk` returns `null` on a revert
544
+ * (an index at/past the CURRENT on-chain count) rather than throwing — exactly what both SDK
545
+ * functions expect for "nothing stored here yet". */
546
+ function chainScriptReader(contract) {
547
+ const client = makePublicClient({ chainKey: CHAIN });
548
+ return {
549
+ scriptChunkCount: async () => Number(await client.readContract({ address: contract, abi: seriesCodeAbi, functionName: 'scriptChunkCount' })),
550
+ scriptChunk: async (index) => {
551
+ try {
552
+ return (await client.readContract({ address: contract, abi: seriesCodeAbi, functionName: 'scriptChunk', args: [BigInt(index)] }));
553
+ }
554
+ catch {
555
+ return null;
556
+ }
557
+ },
558
+ };
559
+ }
560
+ /**
561
+ * The `gasFloor` `replace-script` restates for its batched multicall (see the call site's own
562
+ * comment for WHY it restates rather than sums the per-op values `prepareSetScriptChunk` already
563
+ * computes). This used to be `writeByteCounts.reduce((sum, n) => sum + n * 200, 0)` — code-deposit
564
+ * cost alone, mirroring `prepareSetScriptChunk`'s own per-chunk floor exactly.
565
+ *
566
+ * A funded on-chain sweep found that number 49% below what a real replace-script send actually
567
+ * needed, and the send failed after passing a `--dry-run` that called it "would succeed" (see
568
+ * riskgate.ts's `simulateDryRun`, fixed alongside this for the OTHER half of that finding: the dry
569
+ * run never checked gas/cost at all, floor included). Investigating this specific number: the
570
+ * deposit-only floor was never WRONG about what it claims — it is still a true lower bound — but it
571
+ * was radically INCOMPLETE for a multi-chunk replacement, because it omits two costs that are just as
572
+ * unconditionally "physics" as the 200 gas/byte deposit, and are not "an invented estimate" the
573
+ * codebase's own philosophy (see execute.ts's `pinGas` doc) warns against including:
574
+ *
575
+ * - `Gcreate` = 32,000 gas per `setScriptChunk` WRITE. `OnChainScript.setScriptChunk` stores its
576
+ * bytes via `SSTORE2.write`, which is one `CREATE` per call — a fixed opcode cost incurred
577
+ * regardless of chain state, chunk size, or whether the index already held something. A replace
578
+ * that (say) uses a small `--chunk-size` to spread one program over many chunks pays this 32,000
579
+ * once per chunk; the old floor counted 0 of it, so the gap grows with chunk COUNT, not just
580
+ * total bytes — exactly the shape a small-`--chunk-size` multi-chunk replacement produces.
581
+ * - The intrinsic cost of the multicall's own calldata — 16 gas per non-zero byte, 4 gas per zero
582
+ * byte (EIP-2028), plus the flat 21,000 base every transaction pays (EIP-2) — computed from the
583
+ * REAL encoded `data`, not approximated from chunk byte counts. `eth_estimateGas` (what `pinGas`
584
+ * compares the floor against) always includes both; the old floor included neither, so it could
585
+ * never clear this amount even for a single-chunk replacement with no removes at all.
586
+ *
587
+ * Deliberately still NOT included, because — unlike the two above — they genuinely depend on
588
+ * on-chain state this function doesn't read, and a floor that could overstate the true minimum stops
589
+ * being a floor: the SSTORE cost of the chunk-pointer mapping and the chunk-count counter (cold vs.
590
+ * warm, zero-vs-nonzero all vary by what's on chain now), `removeLastScriptChunk`'s own cost, and any
591
+ * gas refund (refunds apply AFTER execution and never reduce what a transaction must be GIVEN to
592
+ * avoid running out mid-execution, so they could only ever justify a LOWER floor, working against the
593
+ * "never send an under-funded tx" goal this exists for). So this remains a floor, not an estimate —
594
+ * `simulateDryRun`'s new `estimatedGas`/`estimatedCostWei` (from `pinGas`'s real `eth_estimateGas`,
595
+ * the same call the send itself makes) is the number to trust for cost guidance; this is only ever
596
+ * the threshold that flags an implausible one.
597
+ */
598
+ function replaceScriptGasFloor(finalCalldata, writeByteCounts) {
599
+ const bytes = hexToBytes(finalCalldata);
600
+ let calldataGas = 0n;
601
+ for (const b of bytes)
602
+ calldataGas += b === 0 ? 4n : 16n;
603
+ const createBase = BigInt(writeByteCounts.length) * 32000n;
604
+ const depositGas = writeByteCounts.reduce((sum, n) => sum + BigInt(n) * 200n, 0n);
605
+ return 21000n + calldataGas + createBase + depositGas;
606
+ }
607
+ /**
608
+ * `abx replace-script <address> --script <path>` — the safe, first-class way to replace an
609
+ * UNLOCKED code project's on-chain program (#119). `OnChainScript.sol` permits `setScriptChunk`/
610
+ * `removeLastScriptChunk` right up until `lock-script` — but before this command the only writer
611
+ * was `deploy-code` (its initial setup, or its `--resume` leg for a setup that never landed).
612
+ * Neither is "replace a program that's already live and correct on-chain", which is the gap this
613
+ * closes: a creator iterating on a generative project pre-lock had no supported way to ship a fix.
614
+ *
615
+ * Safety properties, in the order they're enforced:
616
+ * 1. REFUSE outright — never warn-and-proceed — on a locked script or a non-code target. Both are
617
+ * "there is nothing here for this command to safely do", not "proceed with caution".
618
+ * 2. Diff by CONTENT against what's on-chain now ({@link planScriptReplace}, mirroring
619
+ * `resume.ts`'s script-chunk leg) so an index that already matches is never re-sent — SSTORE2
620
+ * deposit is 200 gas/byte, so a needless re-store is the most expensive way to be "safe".
621
+ * 3. Every write AND every remove rides in ONE atomic `multicall` (`batchOps`, the same primitive
622
+ * `abx attach` uses for its own all-or-nothing guarantee). This is what makes "half-applied"
623
+ * structurally impossible from this command's own send: a revert undoes everything, a success
624
+ * lands everything. Writes are ordered before removes — the retained indices get their correct
625
+ * content before the tail is trimmed, so the intermediate calldata sequence never shrinks the
626
+ * script before it's right (the two groups touch disjoint indices, so this is a documentation
627
+ * choice about intent, not a correctness requirement of the atomic call itself).
628
+ * 4. After a real send, READ THE SCRIPT BACK and verify it reassembles EXACTLY to the source file
629
+ * ({@link verifyScriptReplace}) before reporting success. A transaction not reverting proves the
630
+ * EVM accepted each call; it does not prove the final program is what was intended. This is the
631
+ * step that actually justifies the command existing — skip it and "replace-script" is just
632
+ * "send some txs and hope".
633
+ *
634
+ * `--dry-run`/`--sign`/`--unsigned` all route through the shared `runWrite`/`gatedSend` choke point
635
+ * (the same one every owner-op uses), so a dry run sends nothing, per the house invariant.
636
+ */
637
+ export async function cmdReplaceScript(address, flags) {
638
+ const usage = 'abx replace-script <address> --script <path> [--chunk-size <bytes>] [--sign|--unsigned] [--dry-run]';
639
+ const contract = requireAddress(address, usage);
640
+ warnStrayFlags(flags, new Set(REPLACE_SCRIPT_FLAGS), 'replace-script');
641
+ const scriptPath = requireFlag(flags, 'script', usage);
642
+ if (!existsSync(scriptPath)) {
643
+ throw new Error(`no file at ${scriptPath} — pass the path to the replacement program (the same --script a deploy-code would take).`);
644
+ }
645
+ const source = readFileSync(scriptPath, 'utf8');
646
+ // REFUSE (not warn) on a target this command cannot safely act on — before any signing prompt.
647
+ const publicClient = makePublicClient({ chainKey: CHAIN });
648
+ const kind = await detectTokenKind(publicClient, contract);
649
+ if (!hasParamsSurface(kind)) {
650
+ throw new Error(`${contract} is a ${kind.label} — replace-script only applies to a SeriesCode/EditionCode on-chain program ` +
651
+ `(the OnChainScript extension). ${kind.label} has no script to replace.`);
652
+ }
653
+ const scriptLocked = (await publicClient.readContract({ address: contract, abi: seriesCodeAbi, functionName: 'scriptLocked' }));
654
+ if (scriptLocked) {
655
+ throw new Error(`${contract}'s script is LOCKED (\`abx lock-script\` was already sent) — setScriptChunk/removeLastScriptChunk ` +
656
+ `revert forever, on-chain, for everyone. There is no way to replace it; that refusal IS the safety property ` +
657
+ `lock-script exists to guarantee, so this command does not attempt a workaround.`);
658
+ }
659
+ const owner = await read(contract, 'owner');
660
+ const chunkSize = flags['chunk-size'] !== undefined ? Number(flags['chunk-size']) : undefined;
661
+ if (chunkSize !== undefined && (!Number.isFinite(chunkSize) || chunkSize < 1)) {
662
+ throw new Error(`--chunk-size must be a positive integer, got "${flags['chunk-size']}"`);
663
+ }
664
+ const nextChunks = planOnChainScript(source, chunkSize);
665
+ if (nextChunks.length === 0) {
666
+ console.log(yellow(' ⚠ ') + `${scriptPath} is empty — this will REMOVE every existing script chunk, leaving no program on-chain. Ctrl-C now if that's not what you meant.`);
667
+ }
668
+ const reader = chainScriptReader(contract);
669
+ const plan = await planScriptReplace(reader, nextChunks);
670
+ console.log(` script: ${plan.currentCount} chunk(s) on-chain → ${plan.targetCount} chunk(s) in ${scriptPath}`);
671
+ if (plan.noop) {
672
+ console.log(` ${green('✓')} no-op — the on-chain script already matches ${scriptPath} byte-for-byte. Nothing to send.`);
673
+ return;
674
+ }
675
+ if (plan.toWrite.length) {
676
+ console.log(dim(` write ${plan.toWrite.length} chunk(s): index ${plan.toWrite.map((w) => w.index).join(', ')}`));
677
+ }
678
+ if (plan.toRemove) {
679
+ console.log(dim(` remove ${plan.toRemove} trailing chunk(s) — shrinking ${plan.currentCount} → ${plan.targetCount} (removeLastScriptChunk has no "remove N"; this is ${plan.toRemove} queued call(s))`));
680
+ }
681
+ // Writes before removes (see the function doc for why this ordering, not the reverse). Both
682
+ // groups fold into ONE multicall below — that's what makes a half-applied result impossible from
683
+ // this command's own send, not the ordering.
684
+ const ops = [
685
+ ...plan.toWrite.map((w) => prepareSetScriptChunk({ contract, index: w.index, chunk: w.hex, chainId: chainId() })),
686
+ ...Array.from({ length: plan.toRemove }, () => prepareRemoveLastScriptChunk({ contract, chainId: chainId() })),
687
+ ];
688
+ const batched = batchOps(ops);
689
+ if (batched.length !== 1) {
690
+ // Defensive: every op above targets the SAME contract and carries no value, so batchOps must
691
+ // fold them to exactly one multicall. If that ever changes, fail loudly rather than send N
692
+ // separate transactions with no atomicity — the one property this command exists to guarantee.
693
+ throw new Error(`replace-script expected to batch ${ops.length} op(s) into one transaction, got ${batched.length}`);
694
+ }
695
+ // `batchOps`/`prepareMulticall` don't sum a folded gasFloor from their sub-ops (each PER-CHUNK
696
+ // gasFloor is real physics — see prepareSetScriptChunk's own doc — but is dropped once several ops
697
+ // merge into one multicall PreparedTx). Restate it here — using the REAL final calldata, not an
698
+ // approximation — so the eth_estimateGas sanity check fires for any replacement that changes
699
+ // anything on-chain, writes or pure removes alike. See replaceScriptGasFloor's own doc for what
700
+ // changed here and why (a real sweep found the deposit-only version 49% under the true minimum).
701
+ const writeByteCounts = plan.toWrite.map((w) => (w.hex.length - 2) / 2);
702
+ const floor = replaceScriptGasFloor(batched[0].data, writeByteCounts);
703
+ const tx = { ...batched[0], gasFloor: `0x${floor.toString(16)}` };
704
+ const sent = await runWrite(contract, tx, flags, owner);
705
+ if (!sent)
706
+ return; // dry run, or the cold lane — nothing landed to verify yet
707
+ const verify = await verifyScriptReplace(reader, source);
708
+ if (!verify.ok) {
709
+ console.error(`\n ${red('✗')} VERIFICATION FAILED — the on-chain script does NOT reassemble to ${scriptPath} after this write.\n` +
710
+ ` on-chain now reports ${verify.chunkCount} chunk(s) (wanted ${plan.targetCount}). This can mean the write only\n` +
711
+ ` partially landed, or something else wrote to this contract concurrently — either way, DO NOT assume the\n` +
712
+ ` program is what you intended.\n` +
713
+ ` Way forward: re-run \`abx replace-script ${contract} --script ${scriptPath}\` — it re-diffs against whatever\n` +
714
+ ` is ACTUALLY on-chain now and sends only what's still missing or wrong; it will not resend what already matches.\n` +
715
+ ` Inspect by hand: abx tokenuri ${contract} --fetch (or scriptChunkCount/scriptChunk directly).\n`);
716
+ process.exitCode = 1;
717
+ return;
718
+ }
719
+ console.log(` ${green('✓')} verified — the on-chain script reassembles EXACTLY to ${scriptPath} (${verify.chunkCount} chunk(s), ${source.length} bytes).\n` +
720
+ dim(` this is the safety property \`abx lock-script ${contract}\` later makes permanent.`));
721
+ }
535
722
  /** `abx lock-param-hooks <address>` — freeze the three param-lifecycle hook addresses forever.
536
723
  * The sibling of lock-script/lock-dependencies/lock-uri, and the only one aimed at a BUYER rather
537
724
  * than at metadata: the transfer hook is a veto over transfers and mints, so an unlocked hook set
@@ -1977,6 +2164,42 @@ async function reportUriAfterFieldWrite(contract, collection, flags) {
1977
2164
  ` a field renderer must NEVER revert.`);
1978
2165
  }
1979
2166
  }
2167
+ // ── attach: the canonical fetch URL + a real reachability probe (#127) ────────
2168
+ /**
2169
+ * The exact, directly-fetchable URL for one attached key — `{base}/{chainId}/{address}[/{tokenId}]
2170
+ * /data/{key}`, the token-api route grammar (`packages/token-api/src/server.ts`'s `/t` and `/c`
2171
+ * routes). `base` already carries its OWN `/t` or `/c` prefix (see `TokenURI.sol`/`ContractURI.sol`
2172
+ * — `deploy-code`/`deploy`/etc. bake `tokenURIBase = "${host}/t"`), so this never re-adds one.
2173
+ * Exported so a creator or an agent never hand-assembles this from the docs — the exact gap #127
2174
+ * reported (`attach` produced a bare path, not a URL anyone could actually GET).
2175
+ */
2176
+ export function canonicalAttachmentUrl(opts) {
2177
+ const base = opts.uriBase.replace(/\/+$/, '');
2178
+ const coords = opts.tokenId === undefined ? `${opts.chainId}/${opts.contract}` : `${opts.chainId}/${opts.contract}/${opts.tokenId}`;
2179
+ return `${base}/${coords}/data/${encodeURIComponent(opts.key)}`;
2180
+ }
2181
+ /**
2182
+ * Is ANY resolver actually answering for this project right now — the precondition for an
2183
+ * attachment to ever become fetchable, and the check `attach` never ran before #127 (it warned on
2184
+ * an EMPTY resolver base, but a non-empty one that answered nothing got a silent, confident "listed
2185
+ * in this project's resolver artifacts"). Reuses `cmdVerifyRemote`'s own GET-and-classify shape
2186
+ * (`served.ts`'s `fetchServedTokenUri`) rather than a second HTTP client.
2187
+ *
2188
+ * Deliberately probes the token's (or collection's) OWN metadata document — NEVER the specific key
2189
+ * being attached. That document already exists for any minted token; the key being attached here
2190
+ * does not exist server-side until the write this gates on lands and the resolver re-indexes, so
2191
+ * probing it directly would 404 on a perfectly healthy resolver and cry wolf on every attach.
2192
+ */
2193
+ export async function probeResolverReachable(opts) {
2194
+ const base = opts.uriBase.replace(/\/+$/, '');
2195
+ const coords = opts.tokenId === undefined ? `${opts.chainId}/${opts.contract}` : `${opts.chainId}/${opts.contract}/${opts.tokenId}`;
2196
+ const url = `${base}/${coords}`;
2197
+ const served = await fetchServedTokenUri(url, { fetchFn: opts.fetchFn });
2198
+ if (servedOk(served))
2199
+ return { reachable: true, url, detail: `HTTP ${served.status}` };
2200
+ const detail = served.error ? `no response: ${served.error}` : served.status !== null ? `HTTP ${served.status}` : (served.skipped ?? 'unreachable');
2201
+ return { reachable: false, url, detail };
2202
+ }
1980
2203
  // ── attach (the data-plane verb: put a named file on a token) ─────────────────
1981
2204
  /**
1982
2205
  * `abx attach <address> <key> <uri>` — attach a named, typed file to a token (or the collection),
@@ -2085,24 +2308,46 @@ export async function cmdAttach(rest, flags) {
2085
2308
  for (const p of pairs) {
2086
2309
  console.log(` attaching ${bold(p.key)} ${dim(`(${p.mimeType}, ${p.representation})`)} to ${scope}: ${dim(p.uri)}`);
2087
2310
  }
2088
- // Where it surfaces. This used to be one dim line, and it read as a footnote rather than as a
2089
- // dependency: an integrator attached five audio stems to a fully-on-chain token, paid to store
2090
- // them, and found `tokenURI` listed none of them "paid for, stored on-chain, and invisible".
2091
- // The on-chain renderer deliberately omits locator-represented artifacts (they duplicate no
2092
- // on-chain type information see site/content/docs/protocol/data-plane.mdx), so the artifacts manifest comes
2093
- // from a RESOLVER. When the project has no resolver baked in, that is not a footnote, it is the
2094
- // difference between a feature working and not existing, so say it as a warning.
2095
- const uriBase = await read(contract, 'tokenURIBase').catch(() => '');
2096
- const artifactsPath = `/t/${chainId()}/${contract}/${flags.token ?? '0'}`;
2311
+ // Where it surfaces and whether anything can actually SERVE it (#127). This used to be one dim
2312
+ // line assuming a non-empty resolver base meant the artifact would be listed; it never checked.
2313
+ // An integrator attached five audio stems to a fully-on-chain token, paid to store them, and found
2314
+ // `tokenURI` listed none of them — "paid for, stored on-chain, and invisible". The on-chain
2315
+ // renderer deliberately omits locator-represented artifacts (they duplicate no on-chain type
2316
+ // information see site/content/docs/protocol/data-plane.mdx), so the complete artifacts manifest
2317
+ // comes from a RESOLVER and a resolver base baked on-chain is a CONFIGURATION, not proof one is
2318
+ // actually running and knows this project. `--collection` reads the collection-scope base
2319
+ // (`contractURIBase`); a token-scope attach reads `tokenURIBase` — these are two separate on-chain
2320
+ // fields (the earlier version of this always read `tokenURIBase`, silently wrong for --collection).
2321
+ const uriBase = await read(contract, collection ? 'contractURIBase' : 'tokenURIBase').catch(() => '');
2322
+ const tokenIdForUrl = collection ? undefined : BigInt(flags.token ?? '0');
2323
+ let reachability = null;
2097
2324
  if (uriBase && uriBase.trim() !== '') {
2098
- console.log(dim(` → listed in this project's resolver artifacts (${artifactsPath} and /data/<key>); a bare on-chain tokenURI carries reserved fields only (params are chain state read them with abx tokens).`));
2325
+ // The canonical fetch URL for every key, printed directlyno hand-assembling a resolver
2326
+ // route from the docs. A PROMISE, not yet a fact: the key doesn't exist server-side until the
2327
+ // write below lands and the resolver re-indexes, so it is printed here, never probed here.
2328
+ for (const p of pairs) {
2329
+ console.log(dim(` → fetch: ${canonicalAttachmentUrl({ uriBase, chainId: chainId(), contract, tokenId: tokenIdForUrl, key: p.key })}`));
2330
+ }
2331
+ // What CAN be checked before any write: does ANY resolver answer for this project at all right
2332
+ // now — the precondition for the URL(s) above to ever resolve. Same GET-and-classify shape
2333
+ // `cmdVerifyRemote` uses for its own reachability check (served.ts).
2334
+ reachability = await probeResolverReachable({ uriBase, chainId: chainId(), contract, tokenId: tokenIdForUrl });
2335
+ if (reachability.reachable) {
2336
+ console.log(dim(` resolver answers for this project (${reachability.detail}) — the URL(s) above start serving once this write lands and re-indexes.`));
2337
+ }
2338
+ else {
2339
+ console.log(yellow(' ⚠ ') +
2340
+ `the resolver base baked on-chain (${uriBase}) does not currently answer for ${scope} (${reachability.detail}) — ` +
2341
+ `the on-chain FIELD WRITE below will still succeed, but nothing is known to be able to SERVE ${pairs.map((p) => bold(p.key)).join(', ')} right now. ` +
2342
+ `Local: is ${bold('abx serve')} running, and is this project ${bold('abx add')}-ed + indexed? Hosted: ${bold(`abx add ${contract} --remote <name>`)} then ${bold(`abx index ${contract} --remote <name>`)}.`);
2343
+ }
2099
2344
  }
2100
2345
  else {
2101
2346
  console.log(yellow(' ⚠ ') +
2102
- `this project resolves ON-CHAIN (no resolver base baked in), and the on-chain document carries reserved fields only ` +
2103
- `so ${pairs.map((p) => bold(p.key)).join(', ')} will NOT appear in ${bold('tokenURI')}. The bytes are stored and provable, but nothing surfaces them to a marketplace or wallet. ` +
2347
+ `this project resolves ON-CHAIN (no resolver base baked in) — the on-chain FIELD WRITE below will still succeed, but there is NO off-chain serving path at all: the on-chain document carries reserved fields only, ` +
2348
+ `so ${pairs.map((p) => bold(p.key)).join(', ')} will NEVER appear in ${bold('tokenURI')} for ANY resolver. The bytes are stored and provable, but nothing surfaces them to a marketplace or wallet. ` +
2104
2349
  dim('(Params are chain state, readable with abx tokens and by any contract call — attachments are the surface that needs a resolver.)'));
2105
- console.log(dim(` to make attached artifacts visible, point the project at a resolver (${bold('abx deploy-resolver')}, or a managed one via ${bold('abx add <addr> --remote <name>')}) — it serves the listing at ${artifactsPath}.`));
2350
+ console.log(dim(` to make attached artifacts servable at all, point the project at a resolver (${bold('abx deploy-resolver')}, or a managed one via ${bold('abx add <addr> --remote <name>')}) — then re-run this.`));
2106
2351
  }
2107
2352
  // ONE transaction for the whole set. `batchOps` folds a same-target run into a `multicall` and
2108
2353
  // passes a lone op through untouched, so a single attach is byte-identical to before.
@@ -2122,7 +2367,16 @@ export async function cmdAttach(rest, flags) {
2122
2367
  if (sent) {
2123
2368
  const id = flags.token ?? '0';
2124
2369
  const names = pairs.map((p) => bold(p.key)).join(', ');
2125
- console.log(` ${green('✓')} attached ${names} join${pairs.length > 1 ? '' : 's'} ${scope}'s ${bold('artifacts')} manifest (stored on-chain, anchored).\n` +
2370
+ // The distinction #127 asked for: the on-chain FIELD WRITE succeeding (this line, always true
2371
+ // when we get here) is not the same fact as the artifact being SERVABLE — say both, separately,
2372
+ // rather than one "✓ attached" that a reader takes to mean "and it's live".
2373
+ const servingLine = !uriBase || uriBase.trim() === ''
2374
+ ? dim(` serving: NONE — this project resolves fully on-chain (see the warning above); the bytes are stored and provable, but no resolver will ever list them.\n`)
2375
+ : reachability?.reachable
2376
+ ? dim(` serving: a resolver answered for ${scope} just before this write (see above); fetch the URL(s) above once it re-indexes to confirm.\n`)
2377
+ : dim(` serving: NOT CONFIRMED — no resolver answered for ${scope} just before this write (see the warning above). The FIELD is on-chain now; SERVING it is a separate, still-unmet, concern.\n`);
2378
+ console.log(` ${green('✓')} on-chain field write succeeded — ${names} join${pairs.length > 1 ? '' : 's'} ${scope}'s ${bold('artifacts')} manifest (stored on-chain, anchored).\n` +
2379
+ servingLine +
2126
2380
  dim(` verify (a resolver serves the complete listing): `) +
2127
2381
  `abx tokenuri ${contract}${id === '0' ? '' : ` --token ${id}`} --fetch` +
2128
2382
  dim(` ${collection ? '' : `→ artifacts[].key ${pairs.map((p) => `"${p.key}"`).join(', ')}; /data/<key> fetches each`}\n`) +
@@ -2166,19 +2420,128 @@ async function refuseIfParamKey(contract, field) {
2166
2420
  `\`abx inspect ${contract}\`.)\n` +
2167
2421
  ` If you really did mean the metadata field "${field}" and not the param, re-run with --force-field.`);
2168
2422
  }
2423
+ /**
2424
+ * Which scope actually SERVES `field` right now — the same question `abx tokenuri`'s
2425
+ * `abx_provenance` line answers, and the one `lock-field` used not to ask (#F7, cold-agent sweep):
2426
+ * `lock-field --field description --token 0` reported "would succeed" — and DID succeed — on a
2427
+ * project where `description` is COLLECTION-scoped, freezing an empty token-scope slot while the
2428
+ * value every viewer actually sees (the collection one) stayed completely mutable. Every statement
2429
+ * the CLI made was true; together they promised a permanent freeze that never happened.
2430
+ *
2431
+ * Mirrors the renderer's own fallback (`AbxMetadataRenderer._field` / `fieldWithFallback` in
2432
+ * token-api/metadata.ts): a token-scope value wins when set; only when the token slot is empty does
2433
+ * the collection-scope value show through. Best-effort by design — a read that could not be
2434
+ * answered (RPC unreachable, or a contract predating the on-chain-metadata extension) returns
2435
+ * `null` rather than asserting a scope this call does not actually know, matching
2436
+ * `refuseIfParamKey`'s posture just above.
2437
+ *
2438
+ * Exported with an injected `client` (mirrors `readCollectionLocks` in project.ts) so a test can
2439
+ * exercise the real chain-read shape against a mocked `PublicClient` — no network, no live fixture.
2440
+ */
2441
+ export async function fieldScopePresence(client, contract, tokenId, field) {
2442
+ const tag = encodeTag(field);
2443
+ const [tokenEntry, collectionEntry] = await Promise.all([
2444
+ tryReadContract(client, { address: contract, abi: oneOfOneImageAbi, functionName: 'tokenField', args: [tokenId, tag] }),
2445
+ tryReadContract(client, { address: contract, abi: oneOfOneImageAbi, functionName: 'contractField', args: [tag] }),
2446
+ ]);
2447
+ if (!tokenEntry || !collectionEntry)
2448
+ return null;
2449
+ return { token: tokenEntry[1] !== '0x', collection: collectionEntry[1] !== '0x' };
2450
+ }
2451
+ /**
2452
+ * Pure decision core for the wrong-scope lock check (#F7, cold-agent sweep) — exported so it's
2453
+ * unit-testable with no chain at all, matching `computeAvailability`'s split (project.ts): the
2454
+ * chain read is a thin, low-risk passthrough; the judgment call belongs in a function a test can
2455
+ * call directly.
2456
+ *
2457
+ * Mirrors the renderer's own fallback (`AbxMetadataRenderer._field` / `fieldWithFallback` in
2458
+ * token-api/metadata.ts): a token-scope value wins over collection when both are set, so the scope
2459
+ * that's actually SERVED can differ from the scope the caller names. Returns `null` — nothing to
2460
+ * flag — when the chosen scope already IS what's served, or when genuinely neither scope carries a
2461
+ * value yet (locking a truly empty field is unambiguous: there's no "other" visible value this
2462
+ * command could fail to protect).
2463
+ */
2464
+ export function detectLockFieldScopeMismatch(presence, chosen) {
2465
+ const effective = presence.token ? 'token' : presence.collection ? 'collection' : 'none';
2466
+ if (effective === 'none' || effective === chosen)
2467
+ return null;
2468
+ return { effective, chosen };
2469
+ }
2470
+ /**
2471
+ * Refuse, or (under `--force-field`) loudly warn but proceed — the two allowed outcomes of a
2472
+ * detected mismatch, decided PURELY from the mismatch + whether the override flag was passed, so
2473
+ * this is unit-testable without a chain or a console.
2474
+ *
2475
+ * Deliberately does NOT refuse unconditionally with no escape hatch: pre-locking an empty slot so
2476
+ * it can never be filled — e.g. permanently guaranteeing one token can never diverge from the
2477
+ * collection default — is a legitimate, deliberate use of this same command, and an unconditional
2478
+ * refusal would just trade one bug (a silent no-op freeze) for another (a real, protocol-supported
2479
+ * shape the CLI now falsely claims is impossible — see "false refusal is a membrane defect").
2480
+ * `--force-field` is lock-field's existing general override for its own protective checks (see
2481
+ * `refuseIfParamKey` above); this reuses it rather than adding a second, narrower flag for the same
2482
+ * "yes, I really mean this" answer.
2483
+ */
2484
+ export function lockFieldScopeVerdict(mismatch, opts) {
2485
+ const { effective, chosen } = mismatch;
2486
+ const correctCmd = effective === 'collection'
2487
+ ? `abx lock-field ${opts.contract} --field ${opts.field} --collection`
2488
+ : `abx lock-field ${opts.contract} --field ${opts.field} --token ${opts.tokenId}`;
2489
+ const servedFrom = effective === 'collection' ? 'COLLECTION scope (shared across every token)' : `TOKEN #${opts.tokenId}'s own scope (a per-token override)`;
2490
+ const chosenDesc = chosen === 'collection' ? 'the COLLECTION scope' : `token #${opts.tokenId}'s scope`;
2491
+ if (!opts.forced) {
2492
+ return {
2493
+ action: 'refuse',
2494
+ message: `locking ${chosenDesc} would report "permanent" and DO NOTHING to freeze what's actually shown: '${opts.field}' for token #${opts.tokenId} ` +
2495
+ `is currently served from ${servedFrom}, not the scope you're about to lock. Lock the scope that's actually visible instead:\n` +
2496
+ ` ${correctCmd}\n` +
2497
+ ` If you deliberately want to freeze ${chosenDesc}'s slot forever anyway (e.g. guaranteeing this token can never diverge from the ` +
2498
+ `collection default), re-run with --force-field — it will proceed, with a loud warning that ${servedFrom} stays unfrozen.`,
2499
+ };
2500
+ }
2501
+ return {
2502
+ action: 'warn',
2503
+ message: `⚠⚠ LOCKING A SLOT THAT IS NOT WHAT'S DISPLAYED ⚠⚠\n` +
2504
+ ` '${opts.field}' for token #${opts.tokenId} is currently served from ${servedFrom} — THIS LOCK DOES NOT FREEZE THAT VALUE.\n` +
2505
+ ` You are about to PERMANENTLY lock ${chosenDesc}'s slot instead (proceeding because of --force-field). That value can never change again, ` +
2506
+ `but the value viewers actually see today is untouched by this operation and remains fully mutable.`,
2507
+ };
2508
+ }
2509
+ /**
2510
+ * Refuse (or, under `--force-field`, loudly warn but proceed) a `lock-field` whose CHOSEN scope is
2511
+ * not the scope actually serving `field` right now. Best-effort by design: a read that could not be
2512
+ * answered (RPC unreachable, or a contract predating the on-chain-metadata extension) skips the
2513
+ * check rather than asserting a scope this call does not actually know, matching
2514
+ * `refuseIfParamKey`'s posture above. Runs BEFORE `runWrite`, so `--dry-run` and a real send see
2515
+ * this identically.
2516
+ */
2517
+ async function warnOrRefuseWrongScope(contract, tokenId, field, collection, flags) {
2518
+ const presence = await fieldScopePresence(makePublicClient({ chainKey: CHAIN }), contract, tokenId, field);
2519
+ if (!presence)
2520
+ return; // couldn't determine either scope — don't block on a fact we don't have
2521
+ const chosen = collection ? 'collection' : 'token';
2522
+ const mismatch = detectLockFieldScopeMismatch(presence, chosen);
2523
+ if (!mismatch)
2524
+ return; // nothing to freeze, or the right scope
2525
+ const verdict = lockFieldScopeVerdict(mismatch, { contract, tokenId, field, forced: flags['force-field'] !== undefined });
2526
+ if (verdict.action === 'refuse')
2527
+ throw new Error(verdict.message);
2528
+ console.log(` ${red(verdict.message)}`);
2529
+ }
2169
2530
  export async function cmdLockField(address, flags) {
2170
2531
  const contract = requireAddress(address, 'abx lock-field <address> --field <name> [--collection | --token 0] [--sign|--unsigned]');
2171
2532
  const field = requireFlag(flags, 'field', 'abx lock-field <address> --field <name>');
2172
2533
  const collection = !!flags.collection;
2534
+ const tokenId = BigInt(flags.token ?? '0');
2173
2535
  // The metadata field and a same-named param are different things; only an explicit --force-field
2174
2536
  // says "yes, I mean the field". See refuseIfParamKey.
2175
2537
  if (flags['force-field'] === undefined)
2176
2538
  await refuseIfParamKey(contract, field);
2539
+ await warnOrRefuseWrongScope(contract, tokenId, field, collection, flags);
2177
2540
  const owner = await read(contract, 'owner');
2178
2541
  console.log(dim(` note: locking the '${field}' field is permanent and irreversible (freezes all its representations).`));
2179
2542
  const tx = collection
2180
2543
  ? prepareLockContractField({ contract, field, chainId: chainId() })
2181
- : prepareLockTokenField({ contract, tokenId: BigInt(flags.token ?? '0'), field, chainId: chainId() });
2544
+ : prepareLockTokenField({ contract, tokenId, field, chainId: chainId() });
2182
2545
  await runWrite(contract, tx, flags, owner);
2183
2546
  }
2184
2547
  // ── set-renderer (toggle on-chain URI resolution) ─────────────────────────────