@ar-agents/treasury 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/manteca.ts","../src/ripio.ts","../src/mural.ts","../src/afip.ts","../src/index.ts"],"names":["num"],"mappings":";AA4EO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EACzC,WAAA,CACE,OAAA,EACS,MAAA,EACA,IAAA,EACT;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHJ,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAGT,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AAAA,EACd;AAAA,EALW,MAAA;AAAA,EACA,IAAA;AAKb;AAEO,IAAM,gBAAA,GAAN,cAA+B,eAAA,CAAgB;AAAA,EACpD,WAAA,CAAY,OAAA,EAAiB,MAAA,EAAgB,IAAA,EAAgB;AAC3D,IAAA,KAAA,CAAM,OAAA,EAAS,QAAQ,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AAAA,EACd;AACF;AAEO,IAAM,qBAAA,GAAN,cAAoC,eAAA,CAAgB;AAAA,EACzD,WAAA,CAAY,OAAA,EAAiB,MAAA,EAAgB,IAAA,EAAgB;AAC3D,IAAA,KAAA,CAAM,OAAA,EAAS,QAAQ,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,uBAAA;AAAA,EACd;AACF;AAEA,IAAM,gBAAA,GAAmB,yBAAA;AAGzB,SAAS,IAAI,CAAA,EAAgC;AAC3C,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,QAAA,CAAS,CAAC,GAAG,OAAO,CAAA;AACxD,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,IAAA,EAAK,KAAM,EAAA,IAAM,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC,CAAA,EAAG;AAC1E,IAAA,OAAO,OAAO,CAAC,CAAA;AAAA,EACjB;AACA,EAAA,OAAO,MAAA;AACT;AAOO,SAAS,gBAAA,CAAiB,MAAe,MAAA,EAAoC;AAClF,EAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAmC;AAClD,IAAA,MAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AACpB,IAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AACjC,IAAA,IAAI,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,EAAU;AAC9B,MAAA,MAAM,GAAA,GAAM,CAAA;AACZ,MAAA,KAAA,MAAW,CAAA,IAAK,CAAC,MAAA,EAAQ,KAAA,EAAO,SAAS,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,MAAM,CAAA,EAAG;AACvE,QAAA,MAAM,CAAA,GAAI,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA;AACpB,QAAA,IAAI,CAAA,KAAM,QAAW,OAAO,CAAA;AAAA,MAC9B;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AACA,EAAA,MAAM,GAAA,GAAM,IAAA;AACZ,EAAA,OAAO,QAAQ,GAAA,GAAM,MAAM,CAAC,CAAA,IAAK,QAAQ,IAAI,CAAA;AAC/C;AAGO,SAAS,uBAAuB,GAAA,EAAwC;AAC7E,EAAA,MAAM,CAAA,GAAA,CAAK,GAAA,IAAO,EAAA,EAAI,WAAA,EAAY;AAClC,EAAA,IAAI,CAAC,aAAa,UAAA,EAAY,MAAA,EAAQ,WAAW,SAAA,EAAW,UAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA;AAChF,IAAA,OAAO,WAAA;AACT,EAAA,IAAI,CAAC,UAAU,SAAA,EAAW,OAAA,EAAS,YAAY,WAAA,EAAa,UAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA;AAChF,IAAA,OAAO,QAAA;AACT,EAAA,IAAI,CAAC,cAAc,aAAA,EAAe,YAAA,EAAc,WAAW,SAAS,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9E,IAAA,OAAO,YAAA;AACT,EAAA,IAAI,CAAC,SAAA,EAAW,SAAA,EAAW,KAAA,EAAO,QAAA,EAAU,SAAS,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,EAAG,OAAO,SAAA;AAC3E,EAAA,OAAO,SAAA;AACT;AAEO,IAAM,wBAAN,MAAsD;AAAA,EAQ3D,YAA6B,MAAA,EAAuB;AAAvB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAC3B,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,IAAI,MAAM,kCAAkC,CAAA;AACtE,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,IAAI,MAAM,kCAAkC,CAAA;AACtE,IAAA,IAAI,CAAC,MAAA,CAAO,aAAA;AACV,MAAA,MAAM,IAAI,MAAM,yCAAyC,CAAA;AAC3D,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,OAAA,IAAW,gBAAA,EAAkB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACtE,IAAA,IAAA,CAAK,SAAA,GAAY,OAAO,SAAA,IAAa,MAAA;AACrC,IAAA,IAAA,CAAK,SAAA,GAAY,OAAO,SAAA,IAAa,KAAA;AACrC,IAAA,IAAA,CAAK,MAAA,GAAS,OAAO,MAAA,IAAU,CAAA,EAAG,KAAK,SAAS,CAAA,CAAA,EAAI,KAAK,SAAS,CAAA,CAAA;AAClE,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,SAAA,IAAa,UAAA,CAAW,KAAA;AACzC,IAAA,IAAI,CAAC,CAAA,EAAG,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAC1E,IAAA,IAAA,CAAK,SAAA,GAAY,CAAA;AACjB,IAAA,IAAA,CAAK,GAAA,GAAM,MAAA,CAAO,GAAA,IAAO,IAAA,CAAK,GAAA;AAAA,EAChC;AAAA,EAb6B,MAAA;AAAA,EAPZ,OAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAA;AAAA,EAiBjB,MAAc,OAAA,CACZ,MAAA,EACA,IAAA,EACA,IAAA,EACY;AACZ,IAAA,MAAM,IAAA,GAAoB;AAAA,MACxB,MAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,YAAA,EAAc,KAAK,MAAA,CAAO,MAAA;AAAA,QAC1B,cAAA,EAAgB,kBAAA;AAAA,QAChB,MAAA,EAAQ;AAAA;AACV,KACF;AACA,IAAA,IAAI,SAAS,MAAA,EAAW,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AACvD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,KAAK,SAAA,CAAU,CAAA,EAAG,KAAK,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA;AAAA,IAC3D,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,eAAA;AAAA,QACR,WAAW,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,kBAAA,EAAqB,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAAA,QAC3D;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,MAAA,GAAkB,MAAA;AACtB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MAC1B,CAAA,CAAA,MAAQ;AACN,QAAA,MAAA,GAAS,IAAA;AAAA,MACX;AAAA,IACF;AACA,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,MAAM,CAAA,QAAA,EAAW,MAAM,IAAI,IAAI,CAAA,IAAA,EAAO,IAAI,MAAM,CAAA,CAAA;AACtD,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,IAAO,GAAA,CAAI,MAAA,KAAW,GAAA;AACvC,QAAA,MAAM,IAAI,gBAAA,CAAiB,GAAA,EAAK,GAAA,CAAI,QAAQ,MAAM,CAAA;AACpD,MAAA,IAAI,IAAI,MAAA,KAAW,GAAA;AACjB,QAAA,MAAM,IAAI,qBAAA,CAAsB,GAAA,EAAK,GAAA,CAAI,QAAQ,MAAM,CAAA;AACzD,MAAA,MAAM,IAAI,eAAA,CAAgB,GAAA,EAAK,GAAA,CAAI,QAAQ,MAAM,CAAA;AAAA,IACnD;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,MAAM,SAAA,EAAuC;AACjD,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,KAAA;AAAA,MACA,CAAA,kBAAA,EAAqB,kBAAA,CAAmB,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,KACtD;AACA,IAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA;AAC/C,IAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,IAAQ,CAAA,EAAG;AACnC,MAAA,MAAM,IAAI,eAAA;AAAA,QACR,CAAA,0CAAA,EAA6C,KAAK,MAAM,CAAA,CAAA;AAAA,QACxD,GAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAIA,IAAA,OAAO,EAAE,SAAA,EAAW,MAAA,EAAQ,YAAY,IAAA,EAAM,IAAA,EAAM,QAAQ,CAAA,EAAE;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAA,CACJ,SAAA,EACA,IAAA,EACyB;AACzB,IAAA,IAAI,CAAC,IAAA,EAAM,UAAA;AACT,MAAA,MAAM,IAAI,MAAM,yEAAyE,CAAA;AAC3F,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACpC,IAAA,MAAM,aAAa,IAAA,CAAK,UAAA;AACxB,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,OAAA;AAAA,MAC3B,MAAA;AAAA,MACA,yBAAA;AAAA,MACA;AAAA,QACE,MAAA,EAAQ,KAAK,MAAA,CAAO,MAAA;AAAA,QACpB,UAAA,EAAY,OAAO,SAAS,CAAA;AAAA,QAC5B,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,eAAe,IAAA,CAAK,SAAA;AAAA,QACpB,aAAA,EAAe,KAAK,MAAA,CAAO,aAAA;AAAA,QAC3B;AAAA;AACF,KACF;AACA,IAAA,MAAM,IAAA,GAAO,SAAA,CAAU,EAAA,IAAM,SAAA,CAAU,GAAA;AACvC,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,eAAA;AAAA,QACR,gDAAA;AAAA,QACA,GAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO,EAAE,WAAW,WAAA,EAAa,CAAA,CAAE,QAAQ,IAAA,EAAM,CAAA,CAAE,MAAM,IAAA,EAAK;AAAA,EAChE;AAAA;AAAA,EAGA,MAAM,UAAU,IAAA,EAA4C;AAC1D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,KAAA;AAAA,MACA,CAAA,eAAA,EAAkB,kBAAA,CAAmB,IAAI,CAAC,CAAA;AAAA,KAC5C;AACA,IAAA,MAAM,SAAA,GACH,OAAO,IAAA,CAAK,MAAA,KAAW,QAAA,IAAY,IAAA,CAAK,MAAA,IACxC,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,IAAY,IAAA,CAAK,KAAA,IACxC,MAAA;AACF,IAAA,MAAM,UAAA,GACJ,GAAA,CAAI,IAAA,CAAK,cAAc,CAAA,IACvB,GAAA,CAAI,IAAA,CAAK,UAAU,CAAA,IACnB,GAAA,CAAI,IAAA,CAAK,SAAS,CAAA,IAClB,MAAA;AACF,IAAA,MAAM,MAAA,GAA8B;AAAA,MAClC,IAAA;AAAA,MACA,MAAA,EAAQ,uBAAuB,SAAS;AAAA,KAC1C;AACA,IAAA,IAAI,SAAA,KAAc,MAAA,EAAW,MAAA,CAAO,GAAA,GAAM,SAAA;AAC1C,IAAA,IAAI,UAAA,KAAe,MAAA,EAAW,MAAA,CAAO,UAAA,GAAa,UAAA;AAClD,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAoB,KAAA,EAG2B;AACnD,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,MAAA;AAAA,MACA,yCAAA;AAAA,MACA;AAAA,QACE,MAAA,EAAQ,KAAK,MAAA,CAAO,MAAA;AAAA,QACpB,eAAe,KAAA,CAAM,eAAA;AAAA,QACrB,WAAA,EAAa,MAAM,KAAA,IAAS;AAAA;AAC9B,KACF;AACA,IAAA,MAAM,KACH,OAAO,IAAA,CAAK,OAAO,QAAA,IAAY,IAAA,CAAK,MACpC,OAAO,IAAA,CAAK,GAAA,KAAQ,QAAA,IAAY,KAAK,GAAA,IACrC,OAAO,KAAK,aAAA,KAAkB,QAAA,IAAY,KAAK,aAAA,IAChD,EAAA;AACF,IAAA,OAAO,EAAE,aAAA,EAAe,EAAA,EAAI,GAAA,EAAK,IAAA,EAAK;AAAA,EACxC;AACF;;;AChRO,IAAM,aAAA,GAAgB;AACtB,IAAM,UAAA,GAAa;AAuBnB,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EACvC,WAAA,CAAY,OAAA,EAA0B,MAAA,EAAyB,IAAA,EAAgB;AAC7E,IAAA,KAAA,CAAM,OAAO,CAAA;AADuB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAyB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAE7D,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AAAA,EAHsC,MAAA;AAAA,EAAyB,IAAA;AAIjE;AACO,IAAM,cAAA,GAAN,cAA6B,aAAA,CAAc;AAAA,EAChD,WAAA,CAAY,OAAA,EAAiB,MAAA,EAAgB,IAAA,EAAgB;AAC3D,IAAA,KAAA,CAAM,OAAA,EAAS,QAAQ,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AAAA,EACd;AACF;AACO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAA,EACrD,WAAA,CAAY,OAAA,EAAiB,MAAA,EAAgB,IAAA,EAAgB;AAC3D,IAAA,KAAA,CAAM,OAAA,EAAS,QAAQ,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF;AAEA,SAASA,KAAI,CAAA,EAAgC;AAC3C,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,QAAA,CAAS,CAAC,GAAG,OAAO,CAAA;AACxD,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,MAAK,KAAM,EAAA,IAAM,MAAA,CAAO,QAAA,CAAS,OAAO,CAAC,CAAC,CAAA,EAAG,OAAO,OAAO,CAAC,CAAA;AAC3F,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,qBAAqB,GAAA,EAAwC;AAC3E,EAAA,MAAM,CAAA,GAAA,CAAK,GAAA,IAAO,EAAA,EAAI,WAAA,EAAY;AAClC,EAAA,IAAI,CAAC,WAAA,EAAa,UAAA,EAAY,MAAA,EAAQ,SAAA,EAAW,WAAW,UAAA,EAAY,MAAM,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA;AACxF,IAAA,OAAO,WAAA;AACT,EAAA,IAAI,CAAC,QAAA,EAAU,SAAA,EAAW,OAAA,EAAS,UAAA,EAAY,aAAa,UAAA,EAAY,SAAS,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA;AAC3F,IAAA,OAAO,QAAA;AACT,EAAA,IAAI,CAAC,cAAc,aAAA,EAAe,YAAA,EAAc,WAAW,SAAA,EAAW,YAAY,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA;AAC5F,IAAA,OAAO,YAAA;AACT,EAAA,IAAI,CAAC,SAAA,EAAW,SAAA,EAAW,KAAA,EAAO,QAAA,EAAU,WAAW,MAAA,EAAQ,kBAAkB,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA;AAC3F,IAAA,OAAO,SAAA;AACT,EAAA,OAAO,SAAA;AACT;AAEO,IAAM,sBAAN,MAAoD;AAAA,EAUzD,YAA6B,MAAA,EAAqB;AAArB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAC3B,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,IAAY,CAAC,MAAA,CAAO,YAAA;AAC9B,MAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAClE,IAAA,IAAI,CAAC,MAAA,CAAO,UAAA,EAAY,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAC5E,IAAA,IAAI,CAAC,MAAA,CAAO,aAAA,EAAe,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAClF,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,OAAA,IAAW,aAAA,EAAe,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACnE,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAO,KAAA,IAAS,MAAA;AAC7B,IAAA,IAAA,CAAK,YAAA,GAAe,OAAO,YAAA,IAAgB,MAAA;AAC3C,IAAA,IAAA,CAAK,UAAA,GAAa,OAAO,UAAA,IAAc,KAAA;AACvC,IAAA,IAAA,CAAK,iBAAA,GAAoB,OAAO,iBAAA,IAAqB,eAAA;AACrD,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,SAAA,IAAa,UAAA,CAAW,KAAA;AACzC,IAAA,IAAI,CAAC,CAAA,EAAG,MAAM,IAAI,MAAM,gDAAgD,CAAA;AACxE,IAAA,IAAA,CAAK,SAAA,GAAY,CAAA;AACjB,IAAA,IAAA,CAAK,GAAA,GAAM,MAAA,CAAO,GAAA,IAAO,IAAA,CAAK,GAAA;AAAA,EAChC;AAAA,EAd6B,MAAA;AAAA,EATZ,OAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAA;AAAA,EACT,KAAA,GAAuD,IAAA;AAAA,EAkB/D,MAAc,QAAA,GAA4B;AACxC,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,IAAA,CAAK,SAAS,IAAA,CAAK,KAAA,CAAM,cAAc,GAAA,GAAM,GAAA,EAAQ,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA;AAC3E,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,CAAO,YAAY,CAAA,CAAE,CAAA;AACxE,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,cAAA,CAAA,EAAkB;AAAA,QAC1D,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,aAAA,EAAe,SAAS,KAAK,CAAA,CAAA;AAAA,UAC7B,cAAA,EAAgB,mCAAA;AAAA,UAChB,MAAA,EAAQ;AAAA,SACV;AAAA,QACA,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,6BAAA,EAAgC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAA;AAAA,IAC5E;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,MAAA,GAAkB,MAAA;AACtB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MAC1B,CAAA,CAAA,MAAQ;AACN,QAAA,MAAA,GAAS,IAAA;AAAA,MACX;AAAA,IACF;AACA,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,IAAI,cAAA,CAAe,CAAA,eAAA,EAAkB,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AACxF,IAAA,MAAM,IAAA,GAAO,MAAA;AACb,IAAA,IAAI,CAAC,KAAK,YAAA,EAAc,MAAM,IAAI,cAAA,CAAe,8BAAA,EAAgC,KAAK,MAAM,CAAA;AAC5F,IAAA,IAAA,CAAK,KAAA,GAAQ;AAAA,MACX,OAAO,IAAA,CAAK,YAAA;AAAA,MACZ,WAAA,EAAa,GAAA,GAAA,CAAO,IAAA,CAAK,UAAA,IAAc,IAAA,IAAQ;AAAA,KACjD;AACA,IAAA,OAAO,KAAK,KAAA,CAAM,KAAA;AAAA,EACpB;AAAA,EAEA,MAAc,OAAA,CAAW,MAAA,EAAwB,IAAA,EAAc,IAAA,EAA4B;AACzF,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,QAAA,EAAS;AAClC,IAAA,MAAM,IAAA,GAAoB;AAAA,MACxB,MAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,UAAU,KAAK,CAAA,CAAA;AAAA,QAC9B,cAAA,EAAgB,kBAAA;AAAA,QAChB,MAAA,EAAQ;AAAA;AACV,KACF;AACA,IAAA,IAAI,SAAS,MAAA,EAAW,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AACvD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,KAAK,SAAA,CAAU,CAAA,EAAG,KAAK,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA;AAAA,IAC3D,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,MAAA,EAAS,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,kBAAA,EAAqB,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA;AAAA,IACxF;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,MAAA,GAAkB,MAAA;AACtB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MAC1B,CAAA,CAAA,MAAQ;AACN,QAAA,MAAA,GAAS,IAAA;AAAA,MACX;AAAA,IACF;AACA,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,MAAM,CAAA,MAAA,EAAS,MAAM,IAAI,IAAI,CAAA,IAAA,EAAO,IAAI,MAAM,CAAA,CAAA;AACpD,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,IAAO,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,MAAM,IAAI,cAAA,CAAe,GAAA,EAAK,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AAC9F,MAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK,MAAM,IAAI,mBAAA,CAAoB,GAAA,EAAK,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AAC7E,MAAA,MAAM,IAAI,aAAA,CAAc,GAAA,EAAK,GAAA,CAAI,QAAQ,MAAM,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAAA,EAAuC;AACjD,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA,CAAiC,QAAQ,iBAAA,EAAmB;AAAA,MAClF,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,UAAA,EAAY,OAAO,SAAS,CAAA;AAAA,MAC5B,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,mBAAmB,IAAA,CAAK;AAAA,KACzB,CAAA;AACD,IAAA,MAAM,SAASA,IAAAA,CAAI,IAAA,CAAK,aAAa,CAAA,IAAKA,IAAAA,CAAI,KAAK,QAAQ,CAAA;AAC3D,IAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,IAAU,CAAA,EAAG;AACvC,MAAA,MAAM,IAAI,aAAA,CAAc,uCAAA,EAAyC,GAAA,EAAK,IAAI,CAAA;AAAA,IAC5E;AACA,IAAA,MAAM,IAAA,GAAOA,IAAAA,CAAI,IAAA,CAAK,IAAI,KAAK,MAAA,GAAS,SAAA;AACxC,IAAA,OAAO,EAAE,SAAA,EAAW,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAA,EAAE;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAA,CAAQ,SAAA,EAAgB,IAAA,EAAuD;AACnF,IAAA,IAAI,CAAC,IAAA,EAAM,UAAA;AACT,MAAA,MAAM,IAAI,MAAM,uEAAuE,CAAA;AACzF,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACpC,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA;AAAA,MACzB,MAAA;AAAA,MACA,yBAAA;AAAA,MACA;AAAA,QACE,aAAA,EAAe,KAAK,MAAA,CAAO,aAAA;AAAA,QAC3B,cAAc,IAAA,CAAK,YAAA;AAAA,QACnB,YAAY,IAAA,CAAK,UAAA;AAAA,QACjB,UAAA,EAAY,OAAO,SAAS,CAAA;AAAA,QAC5B,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,YAAY,IAAA,CAAK;AAAA;AACnB,KACF;AACA,IAAA,MAAM,IAAA,GACH,OAAO,OAAA,CAAQ,SAAA,KAAc,QAAA,IAAY,OAAA,CAAQ,SAAA,IACjD,OAAO,OAAA,CAAQ,EAAA,KAAO,QAAA,IAAY,OAAA,CAAQ,EAAA,IAC3C,EAAA;AACF,IAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,aAAA,CAAc,qCAAA,EAAuC,KAAK,OAAO,CAAA;AAEtF,IAAA,MAAM,OAAA,GAA0B;AAAA,MAC9B,SAAA;AAAA,MACA,aAAa,CAAA,CAAE,MAAA;AAAA,MACf,MAAM,CAAA,CAAE,IAAA;AAAA,MACR;AAAA,KACF;AACA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,kBAAA,CAAmB,OAAA,CAAQ,gBAAgB,CAAA;AAChE,IAAA,IAAI,OAAA,UAAiB,cAAA,GAAiB,OAAA;AACtC,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEQ,mBAAmB,GAAA,EAAkC;AAC3D,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,GAAG,OAAO,MAAA;AAChC,IAAA,MAAM,OAAA,GAAU,GAAA;AAChB,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAA,CAAO,CAAA,CAAE,KAAA,IAAS,EAAA,EAAI,WAAA,EAAY,KAAM,IAAA,CAAK,KAAA,CAAM,aAAa,CAAA;AAC5F,IAAA,OAAA,CAAQ,KAAA,IAAS,OAAA,CAAQ,CAAC,CAAA,GAAI,OAAA;AAAA,EAChC;AAAA,EAEA,MAAM,UAAU,IAAA,EAA4C;AAC1D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,KAAA;AAAA,MACA,CAAA,uBAAA,EAA0B,kBAAA,CAAmB,IAAI,CAAC,CAAA;AAAA,KACpD;AACA,IAAA,MAAM,SAAA,GACH,OAAO,IAAA,CAAK,MAAA,KAAW,QAAA,IAAY,IAAA,CAAK,MAAA,IACxC,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,IAAY,IAAA,CAAK,KAAA,IACxC,MAAA;AACF,IAAA,MAAM,UAAA,GAAaA,IAAAA,CAAI,IAAA,CAAK,aAAa,CAAA,IAAKA,IAAAA,CAAI,IAAA,CAAK,QAAQ,CAAA,IAAKA,IAAAA,CAAI,IAAA,CAAK,SAAS,CAAA;AACtF,IAAA,MAAM,MAAA,GAA8B;AAAA,MAClC,IAAA;AAAA,MACA,MAAA,EAAQ,qBAAqB,SAAS;AAAA,KACxC;AACA,IAAA,IAAI,SAAA,KAAc,MAAA,EAAW,MAAA,CAAO,GAAA,GAAM,SAAA;AAC1C,IAAA,IAAI,UAAA,KAAe,MAAA,EAAW,MAAA,CAAO,UAAA,GAAa,UAAA;AAClD,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAAoB,KAAA,EAE2B;AACnD,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA,CAAiC,QAAQ,uBAAA,EAAyB;AAAA,MACxF,UAAA,EAAY,KAAK,MAAA,CAAO,UAAA;AAAA,MACxB,mBAAmB,IAAA,CAAK,iBAAA;AAAA,MACxB,aAAA,EAAe,EAAE,wBAAA,EAA0B,KAAA,CAAM,eAAA;AAAgB,KAClE,CAAA;AACD,IAAA,MAAM,EAAA,GACH,OAAO,IAAA,CAAK,EAAA,KAAO,QAAA,IAAY,IAAA,CAAK,EAAA,IACpC,OAAO,IAAA,CAAK,aAAA,KAAkB,QAAA,IAAY,IAAA,CAAK,aAAA,IAChD,EAAA;AACF,IAAA,OAAO,EAAE,aAAA,EAAe,EAAA,EAAI,GAAA,EAAK,IAAA,EAAK;AAAA,EACxC;AACF;;;AC/PO,IAAM,UAAA,GAAa;AACnB,IAAM,aAAA,GAAgB;AA6CtB,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EACvC,WAAA,CACE,OAAA,EACS,MAAA,EACA,IAAA,EACT;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHJ,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAGT,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AAAA,EALW,MAAA;AAAA,EACA,IAAA;AAKb;AAEO,IAAM,cAAA,GAAN,cAA6B,aAAA,CAAc;AAAA,EAChD,WAAA,CAAY,OAAA,EAAiB,MAAA,EAAgB,IAAA,EAAgB;AAC3D,IAAA,KAAA,CAAM,OAAA,EAAS,QAAQ,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AAAA,EACd;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAA,EACrD,WAAA,CAAY,OAAA,EAAiB,MAAA,EAAgB,IAAA,EAAgB;AAC3D,IAAA,KAAA,CAAM,OAAA,EAAS,QAAQ,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF;AAGA,SAASA,KAAI,CAAA,EAAgC;AAC3C,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,QAAA,CAAS,CAAC,GAAG,OAAO,CAAA;AACxD,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,MAAK,KAAM,EAAA,IAAM,MAAA,CAAO,QAAA,CAAS,OAAO,CAAC,CAAC,CAAA,EAAG,OAAO,OAAO,CAAC,CAAA;AAC3F,EAAA,OAAO,MAAA;AACT;AASO,SAAS,oBAAA,CACd,eACA,cAAA,EACe;AACf,EAAA,MAAM,CAAA,GAAA,CAAK,cAAA,IAAkB,EAAA,EAAI,WAAA,EAAY;AAC7C,EAAA,IAAI,CAAA,EAAG;AACL,IAAA,IAAI,CAAA,KAAM,aAAa,OAAO,WAAA;AAC9B,IAAA,IAAI,MAAM,QAAA,IAAY,CAAA,KAAM,UAAA,IAAc,CAAA,KAAM,aAAa,OAAO,QAAA;AACpE,IAAA,IAAI,CAAA,KAAM,WAAW,OAAO,SAAA;AAC5B,IAAA,IAAI,CAAC,WAAW,SAAA,EAAW,kBAAA,EAAoB,UAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,EAAG,OAAO,YAAA;AAAA,EACjF;AACA,EAAA,MAAM,CAAA,GAAA,CAAK,aAAA,IAAiB,EAAA,EAAI,WAAA,EAAY;AAC5C,EAAA,IAAI,CAAA,KAAM,UAAA,IAAc,CAAA,KAAM,SAAA,EAAW,OAAO,YAAA;AAChD,EAAA,IAAI,CAAA,KAAM,sBAAsB,OAAO,SAAA;AACvC,EAAA,IAAI,MAAM,QAAA,IAAY,CAAA,KAAM,UAAA,IAAc,CAAA,KAAM,aAAa,OAAO,QAAA;AACpE,EAAA,OAAO,SAAA;AACT;AAEO,IAAM,sBAAN,MAAoD;AAAA,EAOzD,YAA6B,MAAA,EAAqB;AAArB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAC3B,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,IAAI,MAAM,gCAAgC,CAAA;AACpE,IAAA,IAAI,CAAC,MAAA,CAAO,cAAA,EAAgB,MAAM,IAAI,MAAM,wCAAwC,CAAA;AACpF,IAAA,IAAI,CAAC,MAAA,CAAO,eAAA,EAAiB,MAAM,IAAI,MAAM,yCAAyC,CAAA;AACtF,IAAA,IAAI,CAAC,MAAA,CAAO,GAAA,EAAK,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAC9D,IAAA,IAAI,CAAC,MAAA,CAAO,cAAA,EAAgB,MAAM,IAAI,MAAM,wCAAwC,CAAA;AACpF,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,OAAA,IAAW,UAAA,EAAY,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAChE,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,MAAA;AACzC,IAAA,IAAA,CAAK,YAAA,GAAe,OAAO,YAAA,IAAgB,KAAA;AAC3C,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,SAAA,IAAa,UAAA,CAAW,KAAA;AACzC,IAAA,IAAI,CAAC,CAAA,EAAG,MAAM,IAAI,MAAM,gDAAgD,CAAA;AACxE,IAAA,IAAA,CAAK,SAAA,GAAY,CAAA;AACjB,IAAA,IAAA,CAAK,GAAA,GAAM,MAAA,CAAO,GAAA,IAAO,IAAA,CAAK,GAAA;AAAA,EAChC;AAAA,EAb6B,MAAA;AAAA,EANZ,OAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAA;AAAA,EAiBjB,MAAc,OAAA,CACZ,MAAA,EACA,IAAA,EACA,MACA,YAAA,EACY;AACZ,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,MAC3C,cAAA,EAAgB,kBAAA;AAAA,MAChB,MAAA,EAAQ,kBAAA;AAAA,MACR,GAAI,IAAA,CAAK,MAAA,CAAO,cAAA,GAAiB,EAAE,gBAAgB,IAAA,CAAK,MAAA,CAAO,cAAA,EAAe,GAAI,EAAC;AAAA,MACnF,GAAG;AAAA,KACL;AACA,IAAA,MAAM,IAAA,GAAoB,EAAE,MAAA,EAAQ,OAAA,EAAQ;AAC5C,IAAA,IAAI,SAAS,MAAA,EAAW,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AACvD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,KAAK,SAAA,CAAU,CAAA,EAAG,KAAK,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA;AAAA,IAC3D,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,MAAA,EAAS,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,kBAAA,EAAqB,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA;AAAA,IACxF;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,MAAA,GAAkB,MAAA;AACtB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MAC1B,CAAA,CAAA,MAAQ;AACN,QAAA,MAAA,GAAS,IAAA;AAAA,MACX;AAAA,IACF;AACA,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,MAAM,CAAA,MAAA,EAAS,MAAM,IAAI,IAAI,CAAA,IAAA,EAAO,IAAI,MAAM,CAAA,CAAA;AACpD,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,IAAO,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,MAAM,IAAI,cAAA,CAAe,GAAA,EAAK,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AAC9F,MAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK,MAAM,IAAI,mBAAA,CAAoB,GAAA,EAAK,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AAC7E,MAAA,MAAM,IAAI,aAAA,CAAc,GAAA,EAAK,GAAA,CAAI,QAAQ,MAAM,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,MAAM,SAAA,EAAuC;AACjD,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,gBAAA,EAAkB;AAAA,QAChB;AAAA,UACE,QAAQ,EAAE,WAAA,EAAa,SAAA,EAAW,WAAA,EAAa,KAAK,WAAA,EAAY;AAAA,UAChE,iBAAiB,IAAA,CAAK;AAAA;AACxB;AACF,KACF;AACA,IAAA,MAAM,MAAM,MAAM,IAAA,CAAK,OAAA,CAAiB,MAAA,EAAQ,mCAAmC,IAAI,CAAA;AACvF,IAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAK,GAAA,CAAI,CAAC,CAAA,GAAgC,MAAA;AACzE,IAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,aAAA,CAAc,4BAAA,EAA8B,KAAK,GAAG,CAAA;AAC1E,IAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC1B,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,kBAAA,EAAqB,MAAA,CAAO,KAAA,CAAM,WAAW,SAAS,CAAC,CAAA,CAAA,EAAI,GAAA,EAAK,KAAK,CAAA;AAAA,IAC/F;AACA,IAAA,MAAM,MAAM,KAAA,CAAM,mBAAA;AAClB,IAAA,MAAM,MAAA,GAASA,IAAAA,CAAI,GAAA,EAAK,UAAU,CAAA;AAClC,IAAA,MAAM,IAAA,GAAOA,IAAAA,CAAI,KAAA,CAAM,YAAY,CAAA;AACnC,IAAA,IAAI,MAAA,KAAW,MAAA,IAAa,IAAA,KAAS,MAAA,IAAa,QAAQ,CAAA,EAAG;AAC3D,MAAA,MAAM,IAAI,aAAA,CAAc,2CAAA,EAA6C,GAAA,EAAK,KAAK,CAAA;AAAA,IACjF;AACA,IAAA,MAAM,MAAA,GAASA,IAAAA,CAAI,KAAA,CAAM,qBAAqB,CAAA,IAAK,CAAA;AACnD,IAAA,OAAO,EAAE,SAAA,EAAW,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAO;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAA,CAAQ,SAAA,EAAgB,IAAA,EAAuD;AACnF,IAAA,IAAI,CAAC,IAAA,EAAM,UAAA;AACT,MAAA,MAAM,IAAI,MAAM,uEAAuE,CAAA;AACzF,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACpC,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,MAAM,UAAA,GAAA,CAAc,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,QAAQ,UAAA,MAAgB,UAAA;AAClE,IAAA,MAAM,gBAAgB,UAAA,GAClB;AAAA,MACE,IAAA,EAAM,UAAA;AAAA,MACN,MAAM,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,IAAA,IAAQ,KAAK,MAAA,CAAO,gBAAA;AAAA,MAChD,GAAI,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,KAAA,GAAQ,EAAE,KAAA,EAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,KAAA,EAAM,GAAI,EAAC;AAAA,MAC5E,eAAA,EAAiB,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU;AAAA,KACzC,GACA;AAAA,MACE,IAAA,EAAM,YAAA;AAAA,MACN,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,SAAA;AAAA,MACjC,QAAA,EAAU,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,QAAA;AAAA,MAChC,GAAI,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,KAAA,GAAQ,EAAE,KAAA,EAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,KAAA,EAAM,GAAI,EAAC;AAAA,MAC5E,eAAA,EAAiB,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU;AAAA,KACzC;AAEJ,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA;AAAA,MACzB,MAAA;AAAA,MACA,qBAAA;AAAA,MACA;AAAA,QACE,eAAA,EAAiB,KAAK,MAAA,CAAO,eAAA;AAAA,QAC7B,IAAA;AAAA,QACA,OAAA,EAAS;AAAA,UACP;AAAA,YACE,QAAQ,EAAE,WAAA,EAAa,SAAA,EAAW,WAAA,EAAa,KAAK,WAAA,EAAY;AAAA,YAChE,aAAA,EAAe;AAAA,cACb,IAAA,EAAM,MAAA;AAAA,cACN,QAAA,EAAU,KAAK,MAAA,CAAO,QAAA;AAAA,cACtB,gBAAA,EAAkB,KAAK,MAAA,CAAO,gBAAA;AAAA,cAC9B,kBAAA,EAAoB;AAAA,gBAClB,IAAA,EAAM,KAAA;AAAA,gBACN,MAAA,EAAQ,KAAA;AAAA,gBACR,iBAAA,EAAmB,KAAK,MAAA,CAAO,GAAA;AAAA,gBAC/B,cAAA,EAAgB,KAAK,MAAA,CAAO,cAAA;AAAA,gBAC5B,qBAAA,EAAuB,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW;AAAA;AAChD,aACF;AAAA,YACA;AAAA;AACF;AACF;AACF,KACF;AACA,IAAA,MAAM,KAAK,OAAA,CAAQ,EAAA;AACnB,IAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,aAAA,CAAc,kCAAA,EAAoC,KAAK,OAAO,CAAA;AAEjF,IAAA,MAAM,IAAA,CAAK,OAAA;AAAA,MACT,MAAA;AAAA,MACA,CAAA,oBAAA,EAAuB,kBAAA,CAAmB,EAAE,CAAC,CAAA,QAAA,CAAA;AAAA,MAC7C,MAAA;AAAA,MACA,EAAE,kBAAA,EAAoB,IAAA,CAAK,MAAA,CAAO,cAAA;AAAe,KACnD;AAEA,IAAA,OAAO,EAAE,WAAW,WAAA,EAAa,CAAA,CAAE,QAAQ,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,IAAA,EAAM,EAAA,EAAG;AAAA,EACpE;AAAA;AAAA,EAGA,MAAM,UAAU,IAAA,EAA4C;AAC1D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,KAAA;AAAA,MACA,CAAA,oBAAA,EAAuB,kBAAA,CAAmB,IAAI,CAAC,CAAA;AAAA,KACjD;AACA,IAAA,MAAM,gBAAgB,OAAO,IAAA,CAAK,MAAA,KAAW,QAAA,GAAW,KAAK,MAAA,GAAS,MAAA;AACtE,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,GAAI,IAAA,CAAK,UAAU,EAAC;AAC9D,IAAA,MAAM,KAAA,GAAQ,QAAQ,CAAC,CAAA;AACvB,IAAA,MAAM,UAAU,KAAA,EAAO,OAAA;AACvB,IAAA,MAAM,aAAa,OAAA,EAAS,gBAAA;AAC5B,IAAA,MAAM,WAAW,OAAO,UAAA,EAAY,IAAA,KAAS,QAAA,GAAW,WAAW,IAAA,GAAO,MAAA;AAC1E,IAAA,MAAM,aAAa,OAAA,EAAS,UAAA;AAC5B,IAAA,MAAM,aACJ,QAAA,KAAa,WAAA,GAAcA,IAAAA,CAAI,UAAA,EAAY,UAAU,CAAA,GAAI,MAAA;AAE3D,IAAA,MAAM,MAAA,GAA8B;AAAA,MAClC,IAAA;AAAA,MACA,MAAA,EAAQ,oBAAA,CAAqB,aAAA,EAAe,QAAQ;AAAA,KACtD;AACA,IAAA,MAAM,MAAM,QAAA,IAAY,aAAA;AACxB,IAAA,IAAI,GAAA,KAAQ,MAAA,EAAW,MAAA,CAAO,GAAA,GAAM,GAAA;AACpC,IAAA,IAAI,UAAA,KAAe,MAAA,EAAW,MAAA,CAAO,UAAA,GAAa,UAAA;AAClD,IAAA,OAAO,MAAA;AAAA,EACT;AACF;;;ACjTO,IAAM,uBAAA,GACX;AAcK,IAAM,2BAAA,GAA8B;AAmBpC,IAAM,gBAAA,GAA8C;AAAA,EACzD,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,QAAA,EAAW,WAAA,EAAa,QAAA,EAAW,UAAA,EAAY,KAAA,EAAM;AAAA,EACnH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,QAAA,EAAW,WAAA,EAAa,QAAA,EAAW,UAAA,EAAY,KAAA,EAAM;AAAA,EACnH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,QAAA,EAAW,WAAA,EAAa,QAAA,EAAW,UAAA,EAAY,KAAA,EAAM;AAAA,EACnH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,OAAA,EAAW,WAAA,EAAa,QAAA,EAAW,UAAA,EAAY,KAAA,EAAM;AAAA,EACnH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,SAAA,EAAY,WAAA,EAAa,QAAA,EAAW,UAAA,EAAY,KAAA,EAAM;AAAA,EACpH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,SAAA,EAAY,WAAA,EAAa,SAAA,EAAY,UAAA,EAAY,KAAA,EAAM;AAAA,EACrH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,SAAA,EAAY,WAAA,EAAa,SAAA,EAAY,UAAA,EAAY,KAAA,EAAM;AAAA,EACrH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,SAAA,EAAY,WAAA,EAAa,QAAA,EAAY,UAAA,EAAY,KAAA,EAAM;AAAA,EACrH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,aAAA,EAAe,gBAAgB,SAAA,EAAY,WAAA,EAAa,SAAA,EAAY,UAAA,EAAY,IAAA,EAAK;AAAA,EACpH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,YAAA,EAAe,gBAAgB,SAAA,EAAY,WAAA,EAAa,SAAA,EAAY,UAAA,EAAY,IAAA,EAAK;AAAA,EACpH,EAAE,QAAA,EAAU,GAAA,EAAK,YAAA,EAAc,cAAA,EAAgB,gBAAgB,WAAA,EAAc,WAAA,EAAa,SAAA,EAAY,UAAA,EAAY,IAAA;AACpH;AAGO,SAAS,gBAAA,CACd,UACA,QAAA,EACK;AACL,EAAA,MAAM,MAAM,gBAAA,CAAiB,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,QAAQ,CAAA;AAChE,EAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,QAAQ,CAAA,CAAE,CAAA;AACrE,EAAA,IAAI,GAAA,CAAI,UAAA,IAAc,QAAA,KAAa,WAAA,EAAa;AAC9C,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,YAAY,QAAQ,CAAA,4DAAA;AAAA,KACtB;AAAA,EACF;AACA,EAAA,OAAO,QAAA,KAAa,WAAA,GAAc,GAAA,CAAI,cAAA,GAAiB,GAAA,CAAI,WAAA;AAC7D;AAOO,SAAS,uBAAA,CACd,WACA,QAAA,EAC4B;AAC5B,EAAA,MAAM,OAAO,gBAAA,CAAiB,MAAA;AAAA,IAC5B,CAAC,CAAA,KAAM,QAAA,KAAa,QAAA,IAAY,CAAC,CAAA,CAAE;AAAA,GACrC;AACA,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,IAAI,SAAA,IAAa,CAAA,CAAE,YAAA,EAAc,OAAO,CAAA,CAAE,QAAA;AAAA,EAC5C;AACA,EAAA,OAAO,IAAA;AACT;AAyCO,SAAS,cAAA,CACd,YACA,MAAA,EACgB;AAChB,EAAA,MAAM,IAAA,GAAO;AAAA,IACX,WAAW,UAAA,CAAW,SAAA;AAAA,IACtB,SAAS,UAAA,CAAW,OAAA;AAAA,IACpB,cAAA,EAAgB;AAAA,GAClB;AACA,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,mBAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,IAAA;AAAA,QACH,MAAA;AAAA,QACA,QAAA,EAAU,SAAA;AAAA,QACV,aACE,0BAAA,GACA,UAAA,CAAW,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,GAC9B,mFAAA;AAAA,QACF,YAAA,EACE;AAAA,OACJ;AAAA,IACF,KAAK,YAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,IAAA;AAAA,QACH,MAAA;AAAA,QACA,QAAA,EAAU,gBAAA;AAAA,QACV,WAAA,EACE,yKAAA;AAAA,QACF,YAAA,EAAc;AAAA,OAChB;AAAA,IACF,KAAK,WAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,IAAA;AAAA,QACH,MAAA;AAAA,QACA,QAAA,EAAU,gBAAA;AAAA,QACV,WAAA,EACE,+JAAA;AAAA,QACF,YAAA,EAAc;AAAA,OAChB;AAAA;AAEN;;;AC1JO,IAAM,aAA4B,EAAE,GAAA,EAAK,GAAG,GAAA,EAAK,CAAA,EAAG,iBAAiB,CAAA;AAQrE,IAAM,YAAA,GAA6C,EAAE,GAAA,EAAK,IAAA,EAAM,SAAS,IAAA;AAMzE,SAAS,UAAA,CACd,SAAA,EACA,eAAA,EACA,MAAA,EACA,QAAsB,KAAA,EACjB;AACL,EAAA,MAAM,WAAW,SAAA,GAAY,MAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,YAAY,eAAA,GAAkB,MAAA;AAC3C,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAW,IAAI,CAAA;AACxC,EAAA,OAAO,IAAA,GAAO,aAAa,KAAK,CAAA;AAClC;AAiBO,SAAS,cAAA,CAAe,aAA2B,KAAA,EAAkC;AAC1F,EAAA,MAAM,WAAW,WAAA,CACd,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,OAAA,IAAW,KAAK,CAAA,CAChC,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,OAAA,GAAU,EAAE,OAAO,CAAA;AACvC,EAAA,OAAO,QAAA,CAAS,CAAC,CAAA,IAAK,IAAA;AACxB;AAMO,SAAS,iBAAA,CACd,WAAA,EACA,KAAA,EACA,SAAA,EACA,SAAS,GAAA,EACJ;AACL,EAAA,MAAM,GAAA,GAAM,WAAA,CAAY,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,OAAA,IAAW,KAAA,IAAS,CAAA,CAAE,OAAA,IAAW,KAAA,GAAQ,SAAS,CAAA;AAC1F,EAAA,MAAM,KAAA,GAAQ,IAAI,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AACzD,EAAA,OAAO,KAAA,GAAQ,MAAA;AACjB;AAoBO,SAAS,cAAA,CACd,KAAA,EACA,WAAA,EACA,MAAA,EACA,SAAS,IAAA,EACO;AAChB,EAAA,MAAM,SAAA,GAAY,cAAc,KAAA,CAAM,GAAA;AACtC,EAAA,IAAI,aAAa,CAAA,EAAG;AAClB,IAAA,OAAO,EAAE,UAAA,EAAY,CAAA,EAAG,WAAA,EAAa,CAAA,EAAG,QAAQ,uBAAA,EAAwB;AAAA,EAC1E;AACA,EAAA,MAAM,aAAA,GAAgB,UAAU,CAAA,GAAI,MAAA,CAAA;AACpC,EAAA,IAAI,aAAA,IAAiB,CAAA,IAAK,KAAA,CAAM,GAAA,IAAO,CAAA,EAAG;AACxC,IAAA,OAAO,EAAE,UAAA,EAAY,CAAA,EAAG,WAAA,EAAa,CAAA,EAAG,QAAQ,kCAAA,EAAmC;AAAA,EACrF;AACA,EAAA,MAAM,YAAY,SAAA,GAAY,aAAA;AAC9B,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,MAAM,GAAG,CAAA;AAChD,EAAA,MAAM,cAAc,UAAA,GAAa,aAAA;AACjC,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA,EAAQ,UAAA,GAAa,SAAA,GAAY,2CAAA,GAA8C;AAAA,GACjF;AACF;AAqBO,SAAS,eAAA,CAAgB,OAAsB,OAAA,EAAwC;AAC5F,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,KAAA,CAAM,GAAA,GAAM,OAAA,CAAQ,SAAA;AAAA,IACzB,GAAA,EAAK,KAAA,CAAM,GAAA,GAAM,OAAA,CAAQ,WAAA;AAAA,IACzB,iBAAiB,KAAA,CAAM;AAAA,GACzB;AACF;AAGO,SAAS,YAAA,CAAa,OAAsB,SAAA,EAA+B;AAChF,EAAA,IAAI,SAAA,GAAY,MAAM,GAAA,EAAK;AACzB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,uBAAA,EAA0B,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAC,UAAU,KAAA,CAAM,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,KAC9E;AAAA,EACF;AACA,EAAA,OAAO,EAAE,GAAG,KAAA,EAAO,GAAA,EAAK,KAAA,CAAM,MAAM,SAAA,EAAU;AAChD;AAyDO,IAAM,yBAAN,MAAuD;AAAA,EAE5D,WAAA,CACmB,IAAA,EACA,MAAA,GAAS,IAAA,EAC1B;AAFiB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAChB;AAAA,EAFgB,IAAA;AAAA,EACA,MAAA;AAAA,EAHF,OAAA,uBAAc,GAAA,EAA4B;AAAA,EAM3D,MAAM,MAAM,SAAA,EAAuC;AACjD,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,MAAA,EAAQ,SAAA,GAAY,IAAA,CAAK,IAAA,IAAQ,IAAI,IAAA,CAAK,MAAA,CAAA;AAAA,MAC1C,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,QAAQ,IAAA,CAAK;AAAA,KACf;AAAA,EACF;AAAA,EAEA,MAAM,OAAA,CAAQ,SAAA,EAAgB,IAAA,EAAuD;AACnF,IAAA,IAAI,CAAC,IAAA,EAAM,UAAA;AACT,MAAA,MAAM,IAAI,MAAM,0EAA0E,CAAA;AAC5F,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,UAAU,CAAA;AAC/C,IAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACpC,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,SAAA;AAAA,MACA,aAAa,CAAA,CAAE,MAAA;AAAA,MACf,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,CAAA,GAAI,IAAA,CAAK,MAAA,CAAA;AAAA,MAC5B,IAAA,EAAM,CAAA,IAAA,EAAO,IAAA,CAAK,UAAU,CAAA;AAAA,KAC9B;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,UAAA,EAAY,OAAO,CAAA;AACzC,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,UAAU,IAAA,EAA4C;AAC1D,IAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAA,EAAa,KAAK,WAAA,EAAY;AAAA,EACvD;AACF;AASA,eAAsB,cAAc,IAAA,EAgBkD;AACpF,EAAA,MAAM,QAAA,GAAW,kBAAkB,IAAA,CAAK,WAAA,EAAa,KAAK,KAAA,EAAO,IAAA,CAAK,SAAA,EAAW,IAAA,CAAK,MAAM,CAAA;AAC5F,EAAA,MAAM,IAAA,GAAO,eAAe,IAAA,CAAK,KAAA,EAAO,UAAU,IAAA,CAAK,MAAA,EAAQ,KAAK,MAAM,CAAA;AAC1E,EAAA,IAAI,IAAA,CAAK,UAAA,IAAc,CAAA,IAAK,CAAC,KAAK,OAAA,EAAS;AACzC,IAAA,OAAO,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM;AAAA,EACnC;AACA,EAAA,MAAM,UAAA,GACJ,KAAK,UAAA,IACL,CAAA,KAAA,EAAQ,KAAK,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,EAAI,KAAK,UAAA,CAAW,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,QAAQ,IAAA,CAAK,UAAA,EAAY,EAAE,UAAA,EAAY,CAAA;AAC1E,EAAA,OAAO,EAAE,MAAM,OAAA,EAAS,KAAA,EAAO,gBAAgB,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA,EAAE;AACtE","file":"index.js","sourcesContent":["/**\n * MantecaOffRampAdapter — the real PSAV off-ramp behind the treasury rail.\n *\n * Manteca (manteca.dev) is an Argentine crypto-fiat infrastructure provider. We\n * integrate it as a registered-PSAV off-ramp; we never custody the conversion\n * ourselves (CNV RG 1058/2025). This is a thin, typed client over Manteca's\n * documented v2 API.\n *\n * GROUNDING — what is verified vs. what to confirm at onboarding\n * ─────────────────────────────────────────────────────────────\n * VERIFIED from docs.manteca.dev / developers.manteca.dev (jun-2026):\n * - Auth header is `md-api-key`.\n * - GET /v2/prices/direct/{ticker} (a direct pair price)\n * - POST /v2/price-locks {userAnyId,side,asset,against} -> {code,price}\n * - POST /v2/synthetics/ramp-off {userId,sellAmount,sellAsset,withdrawAsset,\n * bankAccountId,externalId?} -> {id,status,stages[],...}\n * - GET /v2/synthetics/{id} (synthetic status)\n * - POST /v2/onboarding-actions/add-bank-account (register a CBU/CVU/alias; needs legalId)\n * - 429 responses carry internalStatus: \"RATE_LIMITED\".\n * - `externalId` is the idempotency key on synthetics/orders/withdraws.\n *\n * CONFIRM with your account before going to prod (all are config, one-line fixes):\n * - `baseUrl`: defaults to https://api.manteca.dev. The PUBLIC DOCS host is\n * developers.manteca.dev; the live API host ships with your credentials.\n * - `ticker`: defaults to \"USDC_ARS\"; confirm the exact pair string.\n * - The JSON shape of the price response and the synthetic status enum — both\n * are parsed DEFENSIVELY here and normalized; verify against a sandbox call.\n *\n * NOT yet integration-tested: Manteca onboarding is sales-gated (no self-serve\n * keys), so this client is unit-tested against mocked HTTP (the request contract\n * is pinned exactly). LIVE-PROBED 2026-06-24: api.manteca.dev is reachable but the\n * live API host + price path ship per-account (GET /v2/prices/direct/USDC_ARS ->\n * 404 unauth), so there is no public proving surface — confirm the host + ticker\n * at onboarding. Going live = set the 3 config items above. See\n * ../../TREASURY-FISCAL-RAIL.md §5. Run: `scripts/live-offramp.mjs manteca`.\n */\n\nimport type {\n Ars,\n OffRampAdapter,\n OffRampQuote,\n OffRampReceipt,\n OffRampStatus,\n OffRampStatusReport,\n Usd,\n} from \"./index\";\n\nexport interface MantecaConfig {\n /** API key, sent as the `md-api-key` header. */\n apiKey: string;\n /** Manteca user/company id that owns the crypto balance + the bank account. */\n userId: string;\n /** Registered destination bank account id (the society's CVU) for ARS payout. */\n bankAccountId: string;\n /**\n * API base URL. Default https://api.manteca.dev. CONFIRM at onboarding — the\n * public docs live at developers.manteca.dev; the live API host comes with\n * your credentials.\n */\n baseUrl?: string;\n /** Crypto asset sold. Default \"USDC\". */\n sellAsset?: string;\n /** Fiat received + withdrawn. Default \"ARS\". */\n fiatAsset?: string;\n /**\n * Pair ticker for quote(). Default `${sellAsset}_${fiatAsset}` (\"USDC_ARS\").\n * Confirm the exact string accepted by /v2/prices/direct for your account.\n */\n ticker?: string;\n /** Injectable fetch (tests / non-global-fetch runtimes). Default global fetch. */\n fetchImpl?: typeof fetch;\n /** Injectable clock for the externalId fallback. Default Date.now. */\n now?: () => number;\n}\n\n/** A non-2xx (or transport) failure from the Manteca API. */\nexport class MantecaApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(message);\n this.name = \"MantecaApiError\";\n }\n}\n/** 401/403 — bad or unauthorized api key. */\nexport class MantecaAuthError extends MantecaApiError {\n constructor(message: string, status: number, body?: unknown) {\n super(message, status, body);\n this.name = \"MantecaAuthError\";\n }\n}\n/** 429 — per-user rate limit (internalStatus RATE_LIMITED). */\nexport class MantecaRateLimitError extends MantecaApiError {\n constructor(message: string, status: number, body?: unknown) {\n super(message, status, body);\n this.name = \"MantecaRateLimitError\";\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://api.manteca.dev\";\n\n/** Coerce a number-ish value (Manteca returns amounts as strings). */\nfunction num(v: unknown): number | undefined {\n if (typeof v === \"number\" && Number.isFinite(v)) return v;\n if (typeof v === \"string\" && v.trim() !== \"\" && Number.isFinite(Number(v))) {\n return Number(v);\n }\n return undefined;\n}\n\n/**\n * Pull the sell-side price out of a direct-price response. The off-ramp SELLS\n * crypto for ARS, so we prefer the sell/bid side. Handles a flat `{price}`, a\n * `{sell,buy}` spread, or a ticker-keyed `{ [ticker]: {...} }` envelope.\n */\nexport function parseDirectPrice(body: unknown, ticker: string): number | undefined {\n const fromObj = (o: unknown): number | undefined => {\n const direct = num(o);\n if (direct !== undefined) return direct;\n if (o && typeof o === \"object\") {\n const rec = o as Record<string, unknown>;\n for (const k of [\"sell\", \"bid\", \"price\", \"ask\", \"buy\", \"value\", \"rate\"]) {\n const v = num(rec[k]);\n if (v !== undefined) return v;\n }\n }\n return undefined;\n };\n const env = body as Record<string, unknown> | null | undefined;\n return fromObj(env?.[ticker]) ?? fromObj(body);\n}\n\n/** Normalize Manteca's synthetic status string into our cross-PSAV enum. */\nexport function normalizeMantecaStatus(raw: string | undefined): OffRampStatus {\n const s = (raw ?? \"\").toUpperCase();\n if ([\"COMPLETED\", \"COMPLETE\", \"DONE\", \"SETTLED\", \"SUCCESS\", \"FINISHED\"].includes(s))\n return \"COMPLETED\";\n if ([\"FAILED\", \"FAILURE\", \"ERROR\", \"REJECTED\", \"CANCELLED\", \"CANCELED\"].includes(s))\n return \"FAILED\";\n if ([\"PROCESSING\", \"IN_PROGRESS\", \"INPROGRESS\", \"RUNNING\", \"PARTIAL\"].includes(s))\n return \"PROCESSING\";\n if ([\"PENDING\", \"CREATED\", \"NEW\", \"QUEUED\", \"WAITING\"].includes(s)) return \"PENDING\";\n return \"UNKNOWN\";\n}\n\nexport class MantecaOffRampAdapter implements OffRampAdapter {\n private readonly baseUrl: string;\n private readonly sellAsset: string;\n private readonly fiatAsset: string;\n private readonly ticker: string;\n private readonly fetchImpl: typeof fetch;\n private readonly now: () => number;\n\n constructor(private readonly config: MantecaConfig) {\n if (!config.apiKey) throw new Error(\"MantecaConfig.apiKey is required\");\n if (!config.userId) throw new Error(\"MantecaConfig.userId is required\");\n if (!config.bankAccountId)\n throw new Error(\"MantecaConfig.bankAccountId is required\");\n this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.sellAsset = config.sellAsset ?? \"USDC\";\n this.fiatAsset = config.fiatAsset ?? \"ARS\";\n this.ticker = config.ticker ?? `${this.sellAsset}_${this.fiatAsset}`;\n const f = config.fetchImpl ?? globalThis.fetch;\n if (!f) throw new Error(\"no fetch available; pass MantecaConfig.fetchImpl\");\n this.fetchImpl = f;\n this.now = config.now ?? Date.now;\n }\n\n private async request<T>(\n method: \"GET\" | \"POST\",\n path: string,\n body?: unknown,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: {\n \"md-api-key\": this.config.apiKey,\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n let res: Response;\n try {\n res = await this.fetchImpl(`${this.baseUrl}${path}`, init);\n } catch (cause) {\n throw new MantecaApiError(\n `manteca ${method} ${path} transport error: ${String(cause)}`,\n 0,\n );\n }\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n if (!res.ok) {\n const msg = `manteca ${method} ${path} -> ${res.status}`;\n if (res.status === 401 || res.status === 403)\n throw new MantecaAuthError(msg, res.status, parsed);\n if (res.status === 429)\n throw new MantecaRateLimitError(msg, res.status, parsed);\n throw new MantecaApiError(msg, res.status, parsed);\n }\n return parsed as T;\n }\n\n /** Quote a USDC->ARS off-ramp using the direct sell-side price. */\n async quote(amountUsd: Usd): Promise<OffRampQuote> {\n const body = await this.request<unknown>(\n \"GET\",\n `/v2/prices/direct/${encodeURIComponent(this.ticker)}`,\n );\n const rate = parseDirectPrice(body, this.ticker);\n if (rate === undefined || rate <= 0) {\n throw new MantecaApiError(\n `manteca: could not parse a sell price for ${this.ticker}`,\n 200,\n body,\n );\n }\n // Manteca's price already includes its spread; we report spread: 0 and the\n // executable rate. The just-in-time planner accounts for slippage via its\n // own safety multiple.\n return { amountUsd, arsOut: amountUsd * rate, rate, spread: 0 };\n }\n\n /**\n * Fire the off-ramp synthetic: sell `amountUsd` of crypto and withdraw the ARS\n * to the configured CVU. IRREVERSIBLE — gate behind requireConfirmation (RFC-001)\n * and write to the signed audit log. Returns immediately with the synthetic id;\n * the ARS settles asynchronously (poll getStatus). `arsReceived` is the EXPECTED\n * amount at submission (from a fresh quote); the settled figure comes from getStatus.\n */\n async convert(\n amountUsd: Usd,\n opts: { externalId: string },\n ): Promise<OffRampReceipt> {\n if (!opts?.externalId)\n throw new Error(\"MantecaOffRampAdapter.convert: externalId (idempotency key) is required\");\n const q = await this.quote(amountUsd);\n const externalId = opts.externalId;\n const synthetic = await this.request<{ id?: string; _id?: string }>(\n \"POST\",\n \"/v2/synthetics/ramp-off\",\n {\n userId: this.config.userId,\n sellAmount: String(amountUsd),\n sellAsset: this.sellAsset,\n withdrawAsset: this.fiatAsset,\n bankAccountId: this.config.bankAccountId,\n externalId,\n },\n );\n const txId = synthetic.id ?? synthetic._id;\n if (!txId) {\n throw new MantecaApiError(\n \"manteca ramp-off: response had no synthetic id\",\n 200,\n synthetic,\n );\n }\n return { amountUsd, arsReceived: q.arsOut, rate: q.rate, txId };\n }\n\n /** Poll a ramp-off synthetic and normalize its settlement state. */\n async getStatus(txId: string): Promise<OffRampStatusReport> {\n const body = await this.request<Record<string, unknown>>(\n \"GET\",\n `/v2/synthetics/${encodeURIComponent(txId)}`,\n );\n const rawStatus =\n (typeof body.status === \"string\" && body.status) ||\n (typeof body.state === \"string\" && body.state) ||\n undefined;\n const arsSettled =\n num(body.withdrawAmount) ??\n num(body.fiatAmount) ??\n num(body.arsAmount) ??\n undefined;\n const report: OffRampStatusReport = {\n txId,\n status: normalizeMantecaStatus(rawStatus),\n };\n if (rawStatus !== undefined) report.raw = rawStatus;\n if (arsSettled !== undefined) report.arsSettled = arsSettled as Ars;\n return report;\n }\n\n /**\n * One-time onboarding helper: register the society's CBU/CVU/alias as a payout\n * destination. The Manteca user must have `legalId` set first. Returns the\n * created account id to use as `bankAccountId`.\n */\n async registerBankAccount(input: {\n cbuOrCvuOrAlias: string;\n label?: string;\n }): Promise<{ bankAccountId: string; raw: unknown }> {\n const body = await this.request<Record<string, unknown>>(\n \"POST\",\n \"/v2/onboarding-actions/add-bank-account\",\n {\n userId: this.config.userId,\n accountNumber: input.cbuOrCvuOrAlias,\n description: input.label ?? \"Sociedad Automatizada CVU\",\n },\n );\n const id =\n (typeof body.id === \"string\" && body.id) ||\n (typeof body._id === \"string\" && body._id) ||\n (typeof body.bankAccountId === \"string\" && body.bankAccountId) ||\n \"\";\n return { bankAccountId: id, raw: body };\n }\n}\n","/**\n * RipioOffRampAdapter — the second registered-PSAV off-ramp behind the treasury\n * rail, proving the OffRampAdapter interface is provider-agnostic (no single-PSAV\n * lock-in). Ripio's operating entity (Moonbird SRL) is a CNV-registered PSAV.\n *\n * Ripio's off-ramp is a SESSION model (unlike Manteca's sell-from-balance): you\n * create a session bound to a fiat account (the society's CVU), Ripio returns a\n * deposit ADDRESS, the society sends USDC there, and Ripio converts + pays ARS to\n * the CVU. So convert() creates the session and returns the deposit address (on\n * the receipt); completion needs an on-chain transfer the society makes from its\n * wallet, then getStatus() tracks it.\n *\n * GROUNDING (docs.ripio.com, jun-2026):\n * - Auth: OAuth2 client-credentials. POST /oauth2/token/ with\n * `Authorization: Basic base64(clientId:clientSecret)` + body\n * `grant_type=client_credentials` -> { access_token, token_type, expires_in }.\n * Then `Authorization: Bearer <token>`.\n * - POST /api/v1/quotes/ { fromCurrency, toCurrency, fromAmount, chain, paymentMethodType }\n * -> { quoteId, rate, toAmount, finalToAmount, fees[], expiration }\n * - POST /api/v1/fiatAccounts/ { customerId, paymentMethodType, accountFields:{ alias_or_cvu_destination } }\n * -> { id, status } (one-time CVU registration)\n * - POST /api/v1/offrampSession/ { fiatAccountId, ... } -> { sessionId, depositAddresses:[{chain,address}], ... }\n * - GET /api/v1/offrampSession/{id} -> session status\n *\n * CONFIRM at onboarding (all config, sales-gated credentials):\n * - baseUrl: defaults to the sandbox; pass prod to go live.\n * - `chain`: defaults to \"BASE\" — Ripio's public docs only enumerate ETHEREUM\n * in static examples; confirm Base/USDC is enabled via GET /api/v1/depositNetworks/.\n * - The exact offrampSession request body + status enum (parsed defensively here).\n *\n * Request contract pinned + unit-tested vs mocked HTTP. LIVE-PROBED 2026-06-24:\n * the sandbox host is up and `POST /oauth2/token/` returns `{error:\"invalid_client\"}`\n * (401) while `POST /api/v1/quotes/` returns 401 — the exact wire + error shapes\n * this adapter handles (RipioAuthError), verified up to the credential boundary.\n * Only sales-gated client creds remain; Ripio is the soonest path to a full live\n * run (open sandbox + deposit simulation). Run: `scripts/live-offramp.mjs ripio`.\n */\n\nimport type {\n Ars,\n OffRampAdapter,\n OffRampQuote,\n OffRampReceipt,\n OffRampStatus,\n OffRampStatusReport,\n Usd,\n} from \"./index\";\n\nexport const RIPIO_SANDBOX = \"https://sandbox-b2b.ripio.com\";\nexport const RIPIO_PROD = \"https://b2b-api.ripio.com\";\n\nexport interface RipioConfig {\n clientId: string;\n clientSecret: string;\n /** Ripio B2B customer id (the KYC'd society). */\n customerId: string;\n /** Pre-registered fiat account id (the society's CVU). See registerFiatAccount. */\n fiatAccountId: string;\n /** API base URL. Default = sandbox. Pass RIPIO_PROD for live. */\n baseUrl?: string;\n /** Settlement chain. Default \"BASE\". CONFIRM Base is enabled for your account. */\n chain?: string;\n /** Crypto sold. Default \"USDC\". */\n fromCurrency?: string;\n /** Fiat received. Default \"ARS\". */\n toCurrency?: string;\n /** Default \"bank_transfer\". */\n paymentMethodType?: string;\n fetchImpl?: typeof fetch;\n now?: () => number;\n}\n\nexport class RipioApiError extends Error {\n constructor(message: string, readonly status: number, readonly body?: unknown) {\n super(message);\n this.name = \"RipioApiError\";\n }\n}\nexport class RipioAuthError extends RipioApiError {\n constructor(message: string, status: number, body?: unknown) {\n super(message, status, body);\n this.name = \"RipioAuthError\";\n }\n}\nexport class RipioRateLimitError extends RipioApiError {\n constructor(message: string, status: number, body?: unknown) {\n super(message, status, body);\n this.name = \"RipioRateLimitError\";\n }\n}\n\nfunction num(v: unknown): number | undefined {\n if (typeof v === \"number\" && Number.isFinite(v)) return v;\n if (typeof v === \"string\" && v.trim() !== \"\" && Number.isFinite(Number(v))) return Number(v);\n return undefined;\n}\n\n/** Normalize Ripio's off-ramp session status into our cross-PSAV enum. */\nexport function normalizeRipioStatus(raw: string | undefined): OffRampStatus {\n const s = (raw ?? \"\").toUpperCase();\n if ([\"COMPLETED\", \"COMPLETE\", \"DONE\", \"SETTLED\", \"SUCCESS\", \"FINISHED\", \"PAID\"].includes(s))\n return \"COMPLETED\";\n if ([\"FAILED\", \"FAILURE\", \"ERROR\", \"REJECTED\", \"CANCELLED\", \"CANCELED\", \"EXPIRED\"].includes(s))\n return \"FAILED\";\n if ([\"PROCESSING\", \"IN_PROGRESS\", \"INPROGRESS\", \"RUNNING\", \"PARTIAL\", \"CONFIRMING\"].includes(s))\n return \"PROCESSING\";\n if ([\"PENDING\", \"CREATED\", \"NEW\", \"QUEUED\", \"WAITING\", \"OPEN\", \"AWAITING_DEPOSIT\"].includes(s))\n return \"PENDING\";\n return \"UNKNOWN\";\n}\n\nexport class RipioOffRampAdapter implements OffRampAdapter {\n private readonly baseUrl: string;\n private readonly chain: string;\n private readonly fromCurrency: string;\n private readonly toCurrency: string;\n private readonly paymentMethodType: string;\n private readonly fetchImpl: typeof fetch;\n private readonly now: () => number;\n private token: { value: string; expiresAtMs: number } | null = null;\n\n constructor(private readonly config: RipioConfig) {\n if (!config.clientId || !config.clientSecret)\n throw new Error(\"RipioConfig.clientId/clientSecret are required\");\n if (!config.customerId) throw new Error(\"RipioConfig.customerId is required\");\n if (!config.fiatAccountId) throw new Error(\"RipioConfig.fiatAccountId is required\");\n this.baseUrl = (config.baseUrl ?? RIPIO_SANDBOX).replace(/\\/+$/, \"\");\n this.chain = config.chain ?? \"BASE\";\n this.fromCurrency = config.fromCurrency ?? \"USDC\";\n this.toCurrency = config.toCurrency ?? \"ARS\";\n this.paymentMethodType = config.paymentMethodType ?? \"bank_transfer\";\n const f = config.fetchImpl ?? globalThis.fetch;\n if (!f) throw new Error(\"no fetch available; pass RipioConfig.fetchImpl\");\n this.fetchImpl = f;\n this.now = config.now ?? Date.now;\n }\n\n private async getToken(): Promise<string> {\n const now = this.now();\n if (this.token && this.token.expiresAtMs > now + 30_000) return this.token.value;\n const basic = btoa(`${this.config.clientId}:${this.config.clientSecret}`);\n let res: Response;\n try {\n res = await this.fetchImpl(`${this.baseUrl}/oauth2/token/`, {\n method: \"POST\",\n headers: {\n authorization: `Basic ${basic}`,\n \"content-type\": \"application/x-www-form-urlencoded\",\n accept: \"application/json\",\n },\n body: \"grant_type=client_credentials\",\n });\n } catch (cause) {\n throw new RipioApiError(`ripio token transport error: ${String(cause)}`, 0);\n }\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n if (!res.ok) throw new RipioAuthError(`ripio token -> ${res.status}`, res.status, parsed);\n const body = parsed as { access_token?: string; expires_in?: number };\n if (!body.access_token) throw new RipioAuthError(\"ripio token: no access_token\", 200, parsed);\n this.token = {\n value: body.access_token,\n expiresAtMs: now + (body.expires_in ?? 3600) * 1000,\n };\n return this.token.value;\n }\n\n private async request<T>(method: \"GET\" | \"POST\", path: string, body?: unknown): Promise<T> {\n const token = await this.getToken();\n const init: RequestInit = {\n method,\n headers: {\n authorization: `Bearer ${token}`,\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n let res: Response;\n try {\n res = await this.fetchImpl(`${this.baseUrl}${path}`, init);\n } catch (cause) {\n throw new RipioApiError(`ripio ${method} ${path} transport error: ${String(cause)}`, 0);\n }\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n if (!res.ok) {\n const msg = `ripio ${method} ${path} -> ${res.status}`;\n if (res.status === 401 || res.status === 403) throw new RipioAuthError(msg, res.status, parsed);\n if (res.status === 429) throw new RipioRateLimitError(msg, res.status, parsed);\n throw new RipioApiError(msg, res.status, parsed);\n }\n return parsed as T;\n }\n\n async quote(amountUsd: Usd): Promise<OffRampQuote> {\n const body = await this.request<Record<string, unknown>>(\"POST\", \"/api/v1/quotes/\", {\n fromCurrency: this.fromCurrency,\n toCurrency: this.toCurrency,\n fromAmount: String(amountUsd),\n chain: this.chain,\n paymentMethodType: this.paymentMethodType,\n });\n const arsOut = num(body.finalToAmount) ?? num(body.toAmount);\n if (arsOut === undefined || arsOut <= 0) {\n throw new RipioApiError(\"ripio quote: could not parse toAmount\", 200, body);\n }\n const rate = num(body.rate) ?? arsOut / amountUsd;\n return { amountUsd, arsOut, rate, spread: 0 };\n }\n\n /**\n * Create an off-ramp session for `amountUsd`. Returns a receipt whose\n * `depositAddress` is where the society must send the USDC to complete the\n * payout; `txId` is the session id for getStatus. `arsReceived` is the EXPECTED\n * amount (from a fresh quote); the settled figure comes from getStatus.\n */\n async convert(amountUsd: Usd, opts: { externalId: string }): Promise<OffRampReceipt> {\n if (!opts?.externalId)\n throw new Error(\"RipioOffRampAdapter.convert: externalId (idempotency key) is required\");\n const q = await this.quote(amountUsd);\n const session = await this.request<Record<string, unknown>>(\n \"POST\",\n \"/api/v1/offrampSession/\",\n {\n fiatAccountId: this.config.fiatAccountId,\n fromCurrency: this.fromCurrency,\n toCurrency: this.toCurrency,\n fromAmount: String(amountUsd),\n chain: this.chain,\n externalId: opts.externalId,\n },\n );\n const txId =\n (typeof session.sessionId === \"string\" && session.sessionId) ||\n (typeof session.id === \"string\" && session.id) ||\n \"\";\n if (!txId) throw new RipioApiError(\"ripio offrampSession: no session id\", 200, session);\n\n const receipt: OffRampReceipt = {\n amountUsd,\n arsReceived: q.arsOut,\n rate: q.rate,\n txId,\n };\n const deposit = this.pickDepositAddress(session.depositAddresses);\n if (deposit) receipt.depositAddress = deposit;\n return receipt;\n }\n\n private pickDepositAddress(raw: unknown): string | undefined {\n if (!Array.isArray(raw)) return undefined;\n const entries = raw as Array<{ chain?: string; address?: string }>;\n const match = entries.find((e) => (e.chain ?? \"\").toUpperCase() === this.chain.toUpperCase());\n return (match ?? entries[0])?.address;\n }\n\n async getStatus(txId: string): Promise<OffRampStatusReport> {\n const body = await this.request<Record<string, unknown>>(\n \"GET\",\n `/api/v1/offrampSession/${encodeURIComponent(txId)}`,\n );\n const rawStatus =\n (typeof body.status === \"string\" && body.status) ||\n (typeof body.state === \"string\" && body.state) ||\n undefined;\n const arsSettled = num(body.finalToAmount) ?? num(body.toAmount) ?? num(body.arsAmount);\n const report: OffRampStatusReport = {\n txId,\n status: normalizeRipioStatus(rawStatus),\n };\n if (rawStatus !== undefined) report.raw = rawStatus;\n if (arsSettled !== undefined) report.arsSettled = arsSettled as Ars;\n return report;\n }\n\n /**\n * One-time onboarding helper: register the society's CBU/CVU/alias as a fiat\n * account payout destination. Returns the id to use as `fiatAccountId`.\n */\n async registerFiatAccount(input: {\n cbuOrCvuOrAlias: string;\n }): Promise<{ fiatAccountId: string; raw: unknown }> {\n const body = await this.request<Record<string, unknown>>(\"POST\", \"/api/v1/fiatAccounts/\", {\n customerId: this.config.customerId,\n paymentMethodType: this.paymentMethodType,\n accountFields: { alias_or_cvu_destination: input.cbuOrCvuOrAlias },\n });\n const id =\n (typeof body.id === \"string\" && body.id) ||\n (typeof body.fiatAccountId === \"string\" && body.fiatAccountId) ||\n \"\";\n return { fiatAccountId: id, raw: body };\n }\n}\n","/**\n * MuralOffRampAdapter — the self-onboard off-ramp behind the treasury rail.\n *\n * Mural (muralpay.com) is a stablecoin->fiat payouts API with deep LatAm rails.\n * Unlike a sell-from-balance exchange (Manteca) or a deposit-session PSAV (Ripio),\n * Mural is a PAYOUT model: you fund a Mural Account with USDC (on Base), then\n * create + execute a Payout Request that converts USDC->ARS and pays a bank\n * account (CBU/CVU/alias). We integrate it as the off-ramp; we never custody the\n * conversion ourselves. Chosen as the proving path because onboarding is\n * self-driven KYB (no sales gate) and it covers the full USDC->ARS-to-bank loop.\n *\n * GROUNDING — verified against Mural's OpenAPI spec + docs (jun-2026):\n * - Base URLs: prod https://api.muralpay.com ; sandbox https://api-staging.muralpay.com\n * - Auth: `authorization: Bearer <apiKey>` on all calls; `transfer-api-key:\n * <transferApiKey>` additionally on /execute (and /cancel). `on-behalf-of:\n * <organizationId>` scopes org operations.\n * - POST /api/payouts/fees/token-to-fiat { tokenFeeRequests:[{amount:{tokenAmount,\n * tokenSymbol},fiatAndRailCode:\"ars\"}] } -> [{type:\"success\",exchangeRate,\n * exchangeFeePercentage,estimatedFiatAmount:{fiatAmount,fiatCurrencyCode},\n * feeTotal:{tokenAmount,tokenSymbol},...} | {type:\"error\",message,...}]\n * - POST /api/payouts/payout { sourceAccountId, memo, payouts:[{amount:{tokenAmount,\n * tokenSymbol:\"USDC\"}, payoutDetails:{type:\"fiat\",bankName,bankAccountOwner,\n * fiatAndRailDetails:{type:\"ars\",symbol:\"ARS\",bankAccountNumber,documentNumber,\n * bankAccountNumberType:\"CVU\"|\"CBU\"|\"ALIAS\"}}, recipientInfo:{type:\"business\"|\n * \"individual\",...,physicalAddress}}] } -> { id, status:\"AWAITING_EXECUTION\" }\n * - POST /api/payouts/payout/{id}/execute (transfer-api-key) -> status PENDING\n * - GET /api/payouts/payout/{id} -> { status:AWAITING_EXECUTION|PENDING|EXECUTED|\n * FAILED|CANCELED, payouts:[{details:{fiatPayoutStatus:{type},fiatAmount:{fiatAmount}}}] }\n * - USDC fund chain enum includes BASE; ARS rail code = \"ars\".\n *\n * CONFIRM at onboarding (config, one-line fixes):\n * - baseUrl: defaults to prod; set the sandbox while testing.\n * - The exact `recipientInfo.physicalAddress` shape your account requires\n * (passed through verbatim) and whether `on-behalf-of` is needed on payouts.\n * - Whether the fees `amount` field wants the {tokenAmount,tokenSymbol} object\n * (sent here) or a bare number — parsed/sent defensively; verify in sandbox.\n *\n * NOT yet live-integration-tested: Mural API keys need a Mural Organization +\n * self-driven KYB (no self-serve key minting, but no sales gate either). Going\n * live = KYB -> keys -> set the config -> run scripts/live-offramp.mjs mural.\n * convert() moves real money; gate behind requireConfirmation (RFC-001).\n */\n\nimport type {\n Ars,\n OffRampAdapter,\n OffRampQuote,\n OffRampReceipt,\n OffRampStatus,\n OffRampStatusReport,\n Usd,\n} from \"./index\";\n\nexport const MURAL_PROD = \"https://api.muralpay.com\";\nexport const MURAL_SANDBOX = \"https://api-staging.muralpay.com\";\n\nexport interface MuralConfig {\n /** General API key — sent as `authorization: Bearer`. */\n apiKey: string;\n /** Transfer API key — sent as `transfer-api-key`, required to execute payouts. */\n transferApiKey: string;\n /** Mural Account id holding the USDC balance (the payout source). */\n sourceAccountId: string;\n /** Organization id; sent as `on-behalf-of` when present. */\n organizationId?: string;\n /** Destination bank (the society's ARS account). */\n bankName: string;\n bankAccountOwner: string;\n /** CBU / CVU / alias value -> `bankAccountNumber`. */\n cvu: string;\n /** How `cvu` is identified. Default \"CVU\". */\n cvuType?: \"CVU\" | \"CBU\" | \"ALIAS\";\n /** Recipient tax/ID number (e.g. the society's CUIT) -> `documentNumber`. */\n documentNumber: string;\n /** Recipient identity for the payout (the society). */\n recipient: {\n type?: \"business\" | \"individual\";\n /** Business name (type=business). */\n name?: string;\n /** Person name (type=individual). */\n firstName?: string;\n lastName?: string;\n email?: string;\n /** Passed through verbatim as recipientInfo.physicalAddress. */\n physicalAddress: unknown;\n };\n /** API base URL. Default = prod. Pass MURAL_SANDBOX while testing. */\n baseUrl?: string;\n /** Crypto sold. Default \"USDC\". */\n tokenSymbol?: string;\n /** Fiat rail code. Default \"ars\". */\n fiatRailCode?: string;\n /** Injectable fetch (tests / non-global-fetch runtimes). */\n fetchImpl?: typeof fetch;\n /** Injectable clock for the externalId fallback. Default Date.now. */\n now?: () => number;\n}\n\n/** A non-2xx (or transport) failure from the Mural API. */\nexport class MuralApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(message);\n this.name = \"MuralApiError\";\n }\n}\n/** 401/403 — bad or unauthorized api key (or ToS not accepted). */\nexport class MuralAuthError extends MuralApiError {\n constructor(message: string, status: number, body?: unknown) {\n super(message, status, body);\n this.name = \"MuralAuthError\";\n }\n}\n/** 429 — rate limited. */\nexport class MuralRateLimitError extends MuralApiError {\n constructor(message: string, status: number, body?: unknown) {\n super(message, status, body);\n this.name = \"MuralRateLimitError\";\n }\n}\n\n/** Coerce a number-ish value (amounts may arrive as strings). */\nfunction num(v: unknown): number | undefined {\n if (typeof v === \"number\" && Number.isFinite(v)) return v;\n if (typeof v === \"string\" && v.trim() !== \"\" && Number.isFinite(Number(v))) return Number(v);\n return undefined;\n}\n\n/**\n * Normalize Mural's status into our cross-PSAV enum. Prefers the per-payout\n * `fiatPayoutStatus.type` (created/pending/on-hold/completed/failed/canceled/\n * refund*) when present; else falls back to the request-level status. Note: a\n * request status of EXECUTED only means the on-chain leg ran — the fiat may still\n * be settling, so EXECUTED maps to PROCESSING unless the fiat leg is completed.\n */\nexport function normalizeMuralStatus(\n requestStatus: string | undefined,\n fiatPayoutType?: string,\n): OffRampStatus {\n const f = (fiatPayoutType ?? \"\").toLowerCase();\n if (f) {\n if (f === \"completed\") return \"COMPLETED\";\n if (f === \"failed\" || f === \"canceled\" || f === \"cancelled\") return \"FAILED\";\n if (f === \"created\") return \"PENDING\";\n if ([\"pending\", \"on-hold\", \"refundinprogress\", \"refunded\"].includes(f)) return \"PROCESSING\";\n }\n const s = (requestStatus ?? \"\").toUpperCase();\n if (s === \"EXECUTED\" || s === \"PENDING\") return \"PROCESSING\";\n if (s === \"AWAITING_EXECUTION\") return \"PENDING\";\n if (s === \"FAILED\" || s === \"CANCELED\" || s === \"CANCELLED\") return \"FAILED\";\n return \"UNKNOWN\";\n}\n\nexport class MuralOffRampAdapter implements OffRampAdapter {\n private readonly baseUrl: string;\n private readonly tokenSymbol: string;\n private readonly fiatRailCode: string;\n private readonly fetchImpl: typeof fetch;\n private readonly now: () => number;\n\n constructor(private readonly config: MuralConfig) {\n if (!config.apiKey) throw new Error(\"MuralConfig.apiKey is required\");\n if (!config.transferApiKey) throw new Error(\"MuralConfig.transferApiKey is required\");\n if (!config.sourceAccountId) throw new Error(\"MuralConfig.sourceAccountId is required\");\n if (!config.cvu) throw new Error(\"MuralConfig.cvu is required\");\n if (!config.documentNumber) throw new Error(\"MuralConfig.documentNumber is required\");\n this.baseUrl = (config.baseUrl ?? MURAL_PROD).replace(/\\/+$/, \"\");\n this.tokenSymbol = config.tokenSymbol ?? \"USDC\";\n this.fiatRailCode = config.fiatRailCode ?? \"ars\";\n const f = config.fetchImpl ?? globalThis.fetch;\n if (!f) throw new Error(\"no fetch available; pass MuralConfig.fetchImpl\");\n this.fetchImpl = f;\n this.now = config.now ?? Date.now;\n }\n\n private async request<T>(\n method: \"GET\" | \"POST\",\n path: string,\n body?: unknown,\n extraHeaders?: Record<string, string>,\n ): Promise<T> {\n const headers: Record<string, string> = {\n authorization: `Bearer ${this.config.apiKey}`,\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n ...(this.config.organizationId ? { \"on-behalf-of\": this.config.organizationId } : {}),\n ...extraHeaders,\n };\n const init: RequestInit = { method, headers };\n if (body !== undefined) init.body = JSON.stringify(body);\n let res: Response;\n try {\n res = await this.fetchImpl(`${this.baseUrl}${path}`, init);\n } catch (cause) {\n throw new MuralApiError(`mural ${method} ${path} transport error: ${String(cause)}`, 0);\n }\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n if (!res.ok) {\n const msg = `mural ${method} ${path} -> ${res.status}`;\n if (res.status === 401 || res.status === 403) throw new MuralAuthError(msg, res.status, parsed);\n if (res.status === 429) throw new MuralRateLimitError(msg, res.status, parsed);\n throw new MuralApiError(msg, res.status, parsed);\n }\n return parsed as T;\n }\n\n /** Quote a USDC->ARS off-ramp via the token-to-fiat fees endpoint. */\n async quote(amountUsd: Usd): Promise<OffRampQuote> {\n const body = {\n tokenFeeRequests: [\n {\n amount: { tokenAmount: amountUsd, tokenSymbol: this.tokenSymbol },\n fiatAndRailCode: this.fiatRailCode,\n },\n ],\n };\n const res = await this.request<unknown>(\"POST\", \"/api/payouts/fees/token-to-fiat\", body);\n const first = Array.isArray(res) ? (res[0] as Record<string, unknown>) : undefined;\n if (!first) throw new MuralApiError(\"mural fees: empty response\", 200, res);\n if (first.type === \"error\") {\n throw new MuralApiError(`mural fees error: ${String(first.message ?? \"unknown\")}`, 200, first);\n }\n const est = first.estimatedFiatAmount as Record<string, unknown> | undefined;\n const arsOut = num(est?.fiatAmount);\n const rate = num(first.exchangeRate);\n if (arsOut === undefined || rate === undefined || rate <= 0) {\n throw new MuralApiError(\"mural fees: could not parse rate/estimate\", 200, first);\n }\n const spread = num(first.exchangeFeePercentage) ?? 0;\n return { amountUsd, arsOut, rate, spread };\n }\n\n /**\n * Create + execute the off-ramp payout: convert `amountUsd` USDC and pay ARS to\n * the configured CBU/CVU. IRREVERSIBLE — gate behind requireConfirmation (RFC-001)\n * and write to the signed audit log. Returns the payout-request id as txId;\n * `arsReceived` is the EXPECTED amount (from a fresh quote), the settled figure\n * comes from getStatus.\n */\n async convert(amountUsd: Usd, opts: { externalId: string }): Promise<OffRampReceipt> {\n if (!opts?.externalId)\n throw new Error(\"MuralOffRampAdapter.convert: externalId (idempotency key) is required\");\n const q = await this.quote(amountUsd);\n const memo = opts.externalId;\n const isBusiness = (this.config.recipient.type ?? \"business\") === \"business\";\n const recipientInfo = isBusiness\n ? {\n type: \"business\",\n name: this.config.recipient.name ?? this.config.bankAccountOwner,\n ...(this.config.recipient.email ? { email: this.config.recipient.email } : {}),\n physicalAddress: this.config.recipient.physicalAddress,\n }\n : {\n type: \"individual\",\n firstName: this.config.recipient.firstName,\n lastName: this.config.recipient.lastName,\n ...(this.config.recipient.email ? { email: this.config.recipient.email } : {}),\n physicalAddress: this.config.recipient.physicalAddress,\n };\n\n const created = await this.request<{ id?: string; status?: string }>(\n \"POST\",\n \"/api/payouts/payout\",\n {\n sourceAccountId: this.config.sourceAccountId,\n memo,\n payouts: [\n {\n amount: { tokenAmount: amountUsd, tokenSymbol: this.tokenSymbol },\n payoutDetails: {\n type: \"fiat\",\n bankName: this.config.bankName,\n bankAccountOwner: this.config.bankAccountOwner,\n fiatAndRailDetails: {\n type: \"ars\",\n symbol: \"ARS\",\n bankAccountNumber: this.config.cvu,\n documentNumber: this.config.documentNumber,\n bankAccountNumberType: this.config.cvuType ?? \"CVU\",\n },\n },\n recipientInfo,\n },\n ],\n },\n );\n const id = created.id;\n if (!id) throw new MuralApiError(\"mural payout: response had no id\", 200, created);\n\n await this.request<unknown>(\n \"POST\",\n `/api/payouts/payout/${encodeURIComponent(id)}/execute`,\n undefined,\n { \"transfer-api-key\": this.config.transferApiKey },\n );\n\n return { amountUsd, arsReceived: q.arsOut, rate: q.rate, txId: id };\n }\n\n /** Poll a payout request and normalize its settlement state. */\n async getStatus(txId: string): Promise<OffRampStatusReport> {\n const body = await this.request<Record<string, unknown>>(\n \"GET\",\n `/api/payouts/payout/${encodeURIComponent(txId)}`,\n );\n const requestStatus = typeof body.status === \"string\" ? body.status : undefined;\n const payouts = Array.isArray(body.payouts) ? body.payouts : [];\n const first = payouts[0] as Record<string, unknown> | undefined;\n const details = first?.details as Record<string, unknown> | undefined;\n const fiatStatus = details?.fiatPayoutStatus as Record<string, unknown> | undefined;\n const fiatType = typeof fiatStatus?.type === \"string\" ? fiatStatus.type : undefined;\n const fiatAmount = details?.fiatAmount as Record<string, unknown> | undefined;\n const arsSettled =\n fiatType === \"completed\" ? num(fiatAmount?.fiatAmount) : undefined;\n\n const report: OffRampStatusReport = {\n txId,\n status: normalizeMuralStatus(requestStatus, fiatType),\n };\n const raw = fiatType ?? requestStatus;\n if (raw !== undefined) report.raw = raw;\n if (arsSettled !== undefined) report.arsSettled = arsSettled as Ars;\n return report;\n }\n}\n","/**\n * The AFIP/ARCA fiscal layer of the treasury rail.\n *\n * (ARCA = Agencia de Recaudación y Control Aduanero, the continuator of AFIP per\n * Decreto 953/2024, eff. 5-nov-2024. afip.gob.ar URLs still resolve.)\n *\n * THE HONEST FINDING (verified jun-2026): there is NO fully-autonomous, official\n * channel for a private entity to pay its taxes at pay-time. So this module does\n * NOT pretend to \"pay AFIP.\" It does the parts that are real:\n * 1. Compute the obligation (monotributo cuota here; cedular lives in index.ts).\n * 2. Describe the settlement honestly — what is automatable vs. human-required.\n * The treasury brain (index.ts) sizes + funds the ARS buffer so that whatever\n * settlement rail the society configured can succeed on time.\n *\n * Why no autonomy (all verified against ARCA + MercadoPago official docs):\n * - WSCREATEVEP (create a VEP via web service) is enabled ONLY for public\n * organisms, not private taxpayers. Do not build on it.\n * - Monotributo débito automático CANNOT be enrolled via API — it is a one-time\n * portal/bank step. Once enrolled it runs PASSIVELY (the monthly cuota debits\n * itself). The agent cannot trigger it; it can only ensure the CVU is funded.\n * - There is NO MercadoPago API to pay a VEP — it is a manual in-app flow\n * (scan QR, or enter CUIT + VEP number).\n * Full sourcing: ../../TREASURY-FISCAL-RAIL.md §3.\n */\n\nimport type { Ars, Obligation } from \"./index\";\n\n/**\n * Guard constant: documents (so nobody re-adds it) why WSCREATEVEP is unusable.\n */\nexport const WSCREATEVEP_IS_GOV_ONLY =\n \"AFIP/ARCA WSCREATEVEP is enabled only for public organisms (organismos \" +\n \"recaudadores), not private taxpayers. Do not build VEP creation on it. \" +\n \"See TREASURY-FISCAL-RAIL.md §3.\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Monotributo — the cleanest automatable (passive) path for a small operator.\n// Values per ARCA \"Valores de aplicación desde el 1/02/2026\". IPC-indexed ~every\n// 6 months: re-verify against https://www.afip.gob.ar/monotributo/categorias.asp.\n// Categories I/J/K require venta de bienes; a servicios taxpayer caps at H.\n// NOTE: monotributo is for personas humanas. A SAS/SRL/SA is in the general\n// regime (Ganancias + IVA + IIBB) — compute those via @ar-agents/facturacion +\n// sicore; this table is for a monotributista operator.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const MONOTRIBUTO_TABLE_EFFECTIVE = \"2026-02-01\";\n\nexport type MonotributoCategory =\n | \"A\" | \"B\" | \"C\" | \"D\" | \"E\" | \"F\" | \"G\" | \"H\" | \"I\" | \"J\" | \"K\";\n\nexport type MonotributoActivity = \"servicios\" | \"bienes\";\n\nexport interface MonotributoRow {\n category: MonotributoCategory;\n /** Annual gross-income ceiling for the category, ARS. */\n annualCapArs: Ars;\n /** Monthly total cuota for a services taxpayer, ARS. */\n cuotaServicios: Ars;\n /** Monthly total cuota for a goods taxpayer, ARS. */\n cuotaBienes: Ars;\n /** I/J/K are only available when selling goods. */\n bienesOnly: boolean;\n}\n\nexport const MONOTRIBUTO_2026: readonly MonotributoRow[] = [\n { category: \"A\", annualCapArs: 10_277_988.13, cuotaServicios: 42_386.74, cuotaBienes: 42_386.74, bienesOnly: false },\n { category: \"B\", annualCapArs: 15_058_447.71, cuotaServicios: 48_250.78, cuotaBienes: 48_250.78, bienesOnly: false },\n { category: \"C\", annualCapArs: 21_113_696.52, cuotaServicios: 56_501.85, cuotaBienes: 55_227.06, bienesOnly: false },\n { category: \"D\", annualCapArs: 26_212_853.42, cuotaServicios: 72_414.10, cuotaBienes: 70_661.26, bienesOnly: false },\n { category: \"E\", annualCapArs: 30_833_964.37, cuotaServicios: 102_537.97, cuotaBienes: 92_658.35, bienesOnly: false },\n { category: \"F\", annualCapArs: 38_642_048.36, cuotaServicios: 129_045.32, cuotaBienes: 111_198.27, bienesOnly: false },\n { category: \"G\", annualCapArs: 46_211_109.37, cuotaServicios: 197_108.23, cuotaBienes: 135_918.34, bienesOnly: false },\n { category: \"H\", annualCapArs: 70_113_407.33, cuotaServicios: 447_346.93, cuotaBienes: 272_063.40, bienesOnly: false },\n { category: \"I\", annualCapArs: 78_479_211.62, cuotaServicios: 824_802.26, cuotaBienes: 406_512.05, bienesOnly: true },\n { category: \"J\", annualCapArs: 89_872_640.30, cuotaServicios: 999_007.65, cuotaBienes: 497_059.41, bienesOnly: true },\n { category: \"K\", annualCapArs: 108_357_084.05, cuotaServicios: 1_381_687.90, cuotaBienes: 600_879.51, bienesOnly: true },\n];\n\n/** Monthly monotributo cuota for a category + activity, ARS. */\nexport function monotributoCuota(\n category: MonotributoCategory,\n activity: MonotributoActivity,\n): Ars {\n const row = MONOTRIBUTO_2026.find((r) => r.category === category);\n if (!row) throw new Error(`unknown monotributo category: ${category}`);\n if (row.bienesOnly && activity === \"servicios\") {\n throw new Error(\n `category ${category} is only available for venta de bienes (servicios caps at H)`,\n );\n }\n return activity === \"servicios\" ? row.cuotaServicios : row.cuotaBienes;\n}\n\n/**\n * The category an annual gross income falls into, for the given activity. A\n * services taxpayer caps at H; returns null if income exceeds the regime ceiling\n * (the taxpayer must move to the general regime).\n */\nexport function categoryForAnnualIncome(\n annualArs: Ars,\n activity: MonotributoActivity,\n): MonotributoCategory | null {\n const rows = MONOTRIBUTO_2026.filter(\n (r) => activity === \"bienes\" || !r.bienesOnly,\n );\n for (const r of rows) {\n if (annualArs <= r.annualCapArs) return r.category;\n }\n return null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Settlement model — HOW an obligation actually gets paid. The honest core:\n// NO method lets the agent settle autonomously at pay-time (canAutoExecute is\n// the literal type `false`). They differ in whether a one-time human setup makes\n// payment PASSIVE thereafter, or whether a human is needed every time.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type SettlementMethod = \"debito_automatico\" | \"vep_manual\" | \"mp_manual\";\n\n/**\n * - `passive`: a one-time human enrolment makes future payments run themselves;\n * the agent only has to keep the CVU funded (débito automático).\n * - `human-required`: a human must act for THIS payment (generate + pay a VEP).\n */\nexport type SettlementAutonomy = \"passive\" | \"human-required\";\n\nexport interface SettlementPlan {\n method: SettlementMethod;\n autonomy: SettlementAutonomy;\n /**\n * Whether the agent can settle with zero human action at pay-time. Typed as the\n * literal `false`: in jun-2026 NO official channel allows fully-autonomous tax\n * payment by a private entity. The rail funds + instructs; it does not pay.\n */\n canAutoExecute: false;\n amountArs: Ars;\n /** Epoch ms the obligation is due. */\n dueAtMs: number;\n /** What must happen for this obligation to actually be paid. */\n instruction: string;\n /** One-time human setup this method needs (empty string if none). */\n oneTimeSetup: string;\n}\n\n/**\n * Describe how a given obligation gets settled under the chosen method. Pure +\n * honest: the agent's autonomous part is funding the CVU (see index.ts\n * fundTaxBuffer); the settlement itself is passive (débito) or human (VEP/MP).\n */\nexport function settlementPlan(\n obligation: Obligation,\n method: SettlementMethod,\n): SettlementPlan {\n const base = {\n amountArs: obligation.amountArs,\n dueAtMs: obligation.dueAtMs,\n canAutoExecute: false as const,\n };\n switch (method) {\n case \"debito_automatico\":\n return {\n ...base,\n method,\n autonomy: \"passive\",\n instruction:\n \"Mantené al menos ARS \" +\n obligation.amountArs.toFixed(2) +\n \" en el CVU antes del vencimiento; el débito automático cobra la cuota solo.\",\n oneTimeSetup:\n \"Adherí el CBU/CVU al débito automático en el Portal Monotributo de ARCA (paso único, no hay API; el alta debe estar antes del día 20 para el débito del día 7 siguiente).\",\n };\n case \"vep_manual\":\n return {\n ...base,\n method,\n autonomy: \"human-required\",\n instruction:\n \"Generá el VEP/QR en ARCA (Mis Aplicaciones) y pagalo escaneando el QR o ingresando CUIT + número de VEP en tu billetera. El agente no puede pagar el VEP por API.\",\n oneTimeSetup: \"\",\n };\n case \"mp_manual\":\n return {\n ...base,\n method,\n autonomy: \"human-required\",\n instruction:\n \"Generá el VEP en ARCA y pagalo en Mercado Pago (Cuentas y servicios → AFIP VEP, o escaneá el QR). No existe API de Mercado Pago para pagar un VEP.\",\n oneTimeSetup: \"\",\n };\n }\n}\n","/**\n * @ar-agents/treasury — the fiscal/treasury rail for a Sociedad Automatizada.\n *\n * The moat half of the crypto<->fiat bridge: an autonomous society earns in\n * crypto (USDC on Base) but must pay AFIP in pesos. This module is the pure,\n * deterministic BRAIN of that loop: track balances, size the peso tax buffer,\n * plan a just-in-time USDC->ARS conversion, and account for the Ganancias\n * cedular tax on each disposal. The actual off-ramp (USDC->ARS payout to a CVU)\n * is done by an OffRampAdapter wrapping a registered PSAV (Manteca / Ripio B2B);\n * we integrate one, we do not become one (CNV RG 1058/2025).\n *\n * Pure functions (clock + fx injected, never read) so they are unit-testable and\n * deterministic. Irreversible moves (convert, pay) must be gated by the agent's\n * requireConfirmation (RFC-001) and written to the signed audit log by the caller.\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Money + state\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Stablecoin balance, USDC (the society earns here). */\nexport type Usd = number;\n/** Peso balance, ARS (held in a CVU; what AFIP is paid from). */\nexport type Ars = number;\n\nexport interface TreasuryState {\n /** USDC balance (on Base). */\n usd: Usd;\n /** ARS balance (in the society's CVU). */\n ars: Ars;\n /**\n * Average USD cost basis per USDC unit currently held. For USDC ~= 1, but the\n * society may have acquired crypto that appreciated; cedular is on the gain.\n */\n costBasisPerUsd: number;\n}\n\nexport const ZERO_STATE: TreasuryState = { usd: 0, ars: 0, costBasisPerUsd: 1 };\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Ganancias cedular on a crypto disposal (verified: 5% ARS / 15% foreign, on the\n// GAIN; crypto is IVA-exempt; holding + own-wallet transfers are not taxable).\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type Denomination = \"ARS\" | \"FOREIGN\";\nexport const CEDULAR_RATE: Record<Denomination, number> = { ARS: 0.05, FOREIGN: 0.15 };\n\n/**\n * Cedular tax owed (in ARS) on disposing `amountUsd` of crypto with the given\n * per-unit cost basis, at `fxRate` (ARS per USD). Taxed on the gain only; 0 if no gain.\n */\nexport function cedularTax(\n amountUsd: Usd,\n costBasisPerUsd: number,\n fxRate: number,\n denom: Denomination = \"ARS\",\n): Ars {\n const proceeds = amountUsd * fxRate;\n const cost = amountUsd * costBasisPerUsd * fxRate;\n const gain = Math.max(0, proceeds - cost);\n return gain * CEDULAR_RATE[denom];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Obligations (what the society owes AFIP / fisco) + the peso buffer\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type ObligationKind = \"monotributo\" | \"vep\" | \"iibb\" | \"cedular\";\n\nexport interface Obligation {\n id: string;\n kind: ObligationKind;\n amountArs: Ars;\n /** Epoch ms when it is due. */\n dueAtMs: number;\n}\n\n/** The next obligation due at/after `nowMs`, or null. */\nexport function nextObligation(obligations: Obligation[], nowMs: number): Obligation | null {\n const upcoming = obligations\n .filter((o) => o.dueAtMs >= nowMs)\n .sort((a, b) => a.dueAtMs - b.dueAtMs);\n return upcoming[0] ?? null;\n}\n\n/**\n * ARS needed to cover every obligation due within `horizonMs` from now, times a\n * safety multiple (default 1.1) so a small fx move does not leave AFIP short.\n */\nexport function requiredArsBuffer(\n obligations: Obligation[],\n nowMs: number,\n horizonMs: number,\n safety = 1.1,\n): Ars {\n const due = obligations.filter((o) => o.dueAtMs >= nowMs && o.dueAtMs <= nowMs + horizonMs);\n const total = due.reduce((sum, o) => sum + o.amountArs, 0);\n return total * safety;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Just-in-time conversion policy\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ConversionPlan {\n /** How much USDC to convert now (0 = do nothing). */\n convertUsd: Usd;\n /** ARS expected from that conversion, net of spread. */\n expectedArs: Ars;\n reason: string;\n}\n\n/**\n * Plan a just-in-time conversion: if the ARS balance is below `requiredArs`,\n * convert only enough USDC (at `fxRate` net of `spread`) to top the buffer back\n * up, capped by available USDC. Never over-converts (minimizes taxable disposals\n * + fx exposure). Pure.\n */\nexport function planConversion(\n state: TreasuryState,\n requiredArs: Ars,\n fxRate: number,\n spread = 0.01,\n): ConversionPlan {\n const shortfall = requiredArs - state.ars;\n if (shortfall <= 0) {\n return { convertUsd: 0, expectedArs: 0, reason: \"ars buffer sufficient\" };\n }\n const effectiveRate = fxRate * (1 - spread);\n if (effectiveRate <= 0 || state.usd <= 0) {\n return { convertUsd: 0, expectedArs: 0, reason: \"no usd available or invalid rate\" };\n }\n const neededUsd = shortfall / effectiveRate;\n const convertUsd = Math.min(neededUsd, state.usd);\n const expectedArs = convertUsd * effectiveRate;\n return {\n convertUsd,\n expectedArs,\n reason: convertUsd < neededUsd ? \"partial: usd insufficient for full buffer\" : \"top up to buffer\",\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pure state transitions (apply a conversion / a payment)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface OffRampReceipt {\n amountUsd: Usd;\n arsReceived: Ars;\n /** ARS per USD actually realized (net of spread). */\n rate: number;\n txId: string;\n /**\n * Set by session-model PSAVs (Ripio): the on-chain address the society must\n * send `amountUsd` USDC to in order to complete the off-ramp. Manteca (which\n * sells from the platform balance) leaves it undefined.\n */\n depositAddress?: string;\n}\n\n/** Apply a completed off-ramp conversion to the state (USDC down, ARS up). */\nexport function applyConversion(state: TreasuryState, receipt: OffRampReceipt): TreasuryState {\n return {\n usd: state.usd - receipt.amountUsd,\n ars: state.ars + receipt.arsReceived,\n costBasisPerUsd: state.costBasisPerUsd,\n };\n}\n\n/** Apply a tax/obligation payment (ARS down). Throws if it would overdraw the CVU. */\nexport function applyPayment(state: TreasuryState, amountArs: Ars): TreasuryState {\n if (amountArs > state.ars) {\n throw new Error(\n `insufficient ARS: need ${amountArs.toFixed(2)}, have ${state.ars.toFixed(2)}`,\n );\n }\n return { ...state, ars: state.ars - amountArs };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OffRampAdapter — integrate a registered PSAV (Manteca first, Ripio B2B alt).\n// We never custody the conversion ourselves; we orchestrate on top of a PSAV.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface OffRampQuote {\n amountUsd: Usd;\n arsOut: Ars;\n /** Gross ARS per USD before spread. */\n rate: number;\n spread: number;\n}\n\n/** Settlement state of an off-ramp, normalized across PSAVs. */\nexport type OffRampStatus =\n | \"PENDING\"\n | \"PROCESSING\"\n | \"COMPLETED\"\n | \"FAILED\"\n | \"UNKNOWN\";\n\nexport interface OffRampStatusReport {\n txId: string;\n status: OffRampStatus;\n /** ARS actually settled to the CVU once COMPLETED, if the PSAV reports it. */\n arsSettled?: Ars;\n /** Provider-native status string, kept for the signed audit log / forensics. */\n raw?: string;\n}\n\nexport interface OffRampAdapter {\n /** Quote a USDC->ARS conversion (net of spread). No side effects. */\n quote(amountUsd: Usd): Promise<OffRampQuote>;\n /**\n * Execute the conversion + payout of ARS to the society's CVU. IRREVERSIBLE:\n * the caller MUST gate this behind requireConfirmation (RFC-001) and log it.\n * `opts.externalId` is a REQUIRED idempotency key — a STABLE id derived from the\n * payment (e.g. obligation id + period + amount). Reuse the SAME key on retry so\n * the PSAV deduplicates it and a retried convert never double-spends.\n */\n convert(amountUsd: Usd, opts: { externalId: string }): Promise<OffRampReceipt>;\n /**\n * Poll the settlement of a prior convert(). A real off-ramp is ASYNCHRONOUS:\n * the PSAV sells the crypto, then settles ARS to the CVU over seconds-to-minutes\n * (Manteca models this as a multi-stage \"synthetic\"). Optional because the\n * in-memory adapter settles instantly.\n */\n getStatus?(txId: string): Promise<OffRampStatusReport>;\n}\n\n/**\n * Deterministic in-memory off-ramp for tests/dev (no network, no PSAV). A real\n * adapter wraps Manteca's API Cripto / API Rampa (or Ripio B2B): fund a wallet\n * with USDC -> POST a conversion -> ARS settles to the CVU -> webhook confirms.\n */\nexport class InMemoryOffRampAdapter implements OffRampAdapter {\n private readonly settled = new Map<string, OffRampReceipt>();\n constructor(\n private readonly rate: number,\n private readonly spread = 0.01,\n ) {}\n\n async quote(amountUsd: Usd): Promise<OffRampQuote> {\n return {\n amountUsd,\n arsOut: amountUsd * this.rate * (1 - this.spread),\n rate: this.rate,\n spread: this.spread,\n };\n }\n\n async convert(amountUsd: Usd, opts: { externalId: string }): Promise<OffRampReceipt> {\n if (!opts?.externalId)\n throw new Error(\"InMemoryOffRampAdapter.convert: externalId (idempotency key) is required\");\n const cached = this.settled.get(opts.externalId);\n if (cached) return cached; // idempotent: a retry with the same key returns the same receipt\n const q = await this.quote(amountUsd);\n const receipt = {\n amountUsd,\n arsReceived: q.arsOut,\n rate: this.rate * (1 - this.spread),\n txId: `mem-${opts.externalId}`,\n };\n this.settled.set(opts.externalId, receipt);\n return receipt;\n }\n\n /** The in-memory adapter settles instantly: any tx it issued is COMPLETED. */\n async getStatus(txId: string): Promise<OffRampStatusReport> {\n return { txId, status: \"COMPLETED\", raw: \"in-memory\" };\n }\n}\n\n/**\n * One-shot helper: given the current state, the obligations, and an off-ramp,\n * compute + (optionally) execute the conversion needed to fund the buffer. Returns\n * the plan; if `offramp` is provided it also performs the conversion and returns\n * the receipt + the resulting state. The convert() call is irreversible: only pass\n * `offramp` from a path already behind requireConfirmation.\n */\nexport async function fundTaxBuffer(args: {\n state: TreasuryState;\n obligations: Obligation[];\n nowMs: number;\n horizonMs: number;\n fxRate: number;\n spread?: number;\n safety?: number;\n offramp?: OffRampAdapter;\n /**\n * Idempotency key for the off-ramp convert. Defaults to a deterministic id from\n * the obligations being funded + the amount, so a retried fundTaxBuffer with the\n * same inputs is deduplicated by the PSAV and never double-spends. Pass an\n * explicit stable id to override.\n */\n externalId?: string;\n}): Promise<{ plan: ConversionPlan; receipt?: OffRampReceipt; state: TreasuryState }> {\n const required = requiredArsBuffer(args.obligations, args.nowMs, args.horizonMs, args.safety);\n const plan = planConversion(args.state, required, args.fxRate, args.spread);\n if (plan.convertUsd <= 0 || !args.offramp) {\n return { plan, state: args.state };\n }\n const externalId =\n args.externalId ??\n `fund-${args.obligations.map((o) => o.id).join(\"+\")}-${plan.convertUsd.toFixed(2)}`;\n const receipt = await args.offramp.convert(plan.convertUsd, { externalId });\n return { plan, receipt, state: applyConversion(args.state, receipt) };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Concrete PSAV adapter (Manteca) + the AFIP fiscal layer. Re-exported so the\n// pure core and the real-world rails share one import. These are still ai/zod-\n// free; only `@ar-agents/treasury/tools` pulls in the Vercel AI SDK.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport {\n MantecaOffRampAdapter,\n type MantecaConfig,\n MantecaApiError,\n MantecaAuthError,\n MantecaRateLimitError,\n} from \"./manteca\";\n\nexport {\n RipioOffRampAdapter,\n type RipioConfig,\n RipioApiError,\n RipioAuthError,\n RipioRateLimitError,\n normalizeRipioStatus,\n RIPIO_SANDBOX,\n RIPIO_PROD,\n} from \"./ripio\";\n\nexport {\n MuralOffRampAdapter,\n type MuralConfig,\n MuralApiError,\n MuralAuthError,\n MuralRateLimitError,\n normalizeMuralStatus,\n MURAL_PROD,\n MURAL_SANDBOX,\n} from \"./mural\";\n\nexport {\n MONOTRIBUTO_2026,\n MONOTRIBUTO_TABLE_EFFECTIVE,\n type MonotributoCategory,\n type MonotributoActivity,\n type MonotributoRow,\n monotributoCuota,\n categoryForAnnualIncome,\n type SettlementMethod,\n type SettlementAutonomy,\n type SettlementPlan,\n settlementPlan,\n WSCREATEVEP_IS_GOV_ONLY,\n} from \"./afip\";\n"]}
package/dist/tools.cjs ADDED
@@ -0,0 +1,278 @@
1
+ 'use strict';
2
+
3
+ var ai = require('ai');
4
+ var zod = require('zod');
5
+
6
+ // src/tools.ts
7
+
8
+ // src/afip.ts
9
+ var MONOTRIBUTO_TABLE_EFFECTIVE = "2026-02-01";
10
+ var MONOTRIBUTO_2026 = [
11
+ { category: "A", annualCapArs: 1027798813e-2, cuotaServicios: 42386.74, cuotaBienes: 42386.74, bienesOnly: false },
12
+ { category: "B", annualCapArs: 1505844771e-2, cuotaServicios: 48250.78, cuotaBienes: 48250.78, bienesOnly: false },
13
+ { category: "C", annualCapArs: 2111369652e-2, cuotaServicios: 56501.85, cuotaBienes: 55227.06, bienesOnly: false },
14
+ { category: "D", annualCapArs: 2621285342e-2, cuotaServicios: 72414.1, cuotaBienes: 70661.26, bienesOnly: false },
15
+ { category: "E", annualCapArs: 3083396437e-2, cuotaServicios: 102537.97, cuotaBienes: 92658.35, bienesOnly: false },
16
+ { category: "F", annualCapArs: 3864204836e-2, cuotaServicios: 129045.32, cuotaBienes: 111198.27, bienesOnly: false },
17
+ { category: "G", annualCapArs: 4621110937e-2, cuotaServicios: 197108.23, cuotaBienes: 135918.34, bienesOnly: false },
18
+ { category: "H", annualCapArs: 7011340733e-2, cuotaServicios: 447346.93, cuotaBienes: 272063.4, bienesOnly: false },
19
+ { category: "I", annualCapArs: 7847921162e-2, cuotaServicios: 824802.26, cuotaBienes: 406512.05, bienesOnly: true },
20
+ { category: "J", annualCapArs: 898726403e-1, cuotaServicios: 999007.65, cuotaBienes: 497059.41, bienesOnly: true },
21
+ { category: "K", annualCapArs: 10835708405e-2, cuotaServicios: 13816879e-1, cuotaBienes: 600879.51, bienesOnly: true }
22
+ ];
23
+ function monotributoCuota(category, activity) {
24
+ const row = MONOTRIBUTO_2026.find((r) => r.category === category);
25
+ if (!row) throw new Error(`unknown monotributo category: ${category}`);
26
+ if (row.bienesOnly && activity === "servicios") {
27
+ throw new Error(
28
+ `category ${category} is only available for venta de bienes (servicios caps at H)`
29
+ );
30
+ }
31
+ return activity === "servicios" ? row.cuotaServicios : row.cuotaBienes;
32
+ }
33
+ function categoryForAnnualIncome(annualArs, activity) {
34
+ const rows = MONOTRIBUTO_2026.filter(
35
+ (r) => activity === "bienes" || !r.bienesOnly
36
+ );
37
+ for (const r of rows) {
38
+ if (annualArs <= r.annualCapArs) return r.category;
39
+ }
40
+ return null;
41
+ }
42
+ function settlementPlan(obligation, method) {
43
+ const base = {
44
+ amountArs: obligation.amountArs,
45
+ dueAtMs: obligation.dueAtMs,
46
+ canAutoExecute: false
47
+ };
48
+ switch (method) {
49
+ case "debito_automatico":
50
+ return {
51
+ ...base,
52
+ method,
53
+ autonomy: "passive",
54
+ instruction: "Manten\xE9 al menos ARS " + obligation.amountArs.toFixed(2) + " en el CVU antes del vencimiento; el d\xE9bito autom\xE1tico cobra la cuota solo.",
55
+ oneTimeSetup: "Adher\xED el CBU/CVU al d\xE9bito autom\xE1tico en el Portal Monotributo de ARCA (paso \xFAnico, no hay API; el alta debe estar antes del d\xEDa 20 para el d\xE9bito del d\xEDa 7 siguiente)."
56
+ };
57
+ case "vep_manual":
58
+ return {
59
+ ...base,
60
+ method,
61
+ autonomy: "human-required",
62
+ instruction: "Gener\xE1 el VEP/QR en ARCA (Mis Aplicaciones) y pagalo escaneando el QR o ingresando CUIT + n\xFAmero de VEP en tu billetera. El agente no puede pagar el VEP por API.",
63
+ oneTimeSetup: ""
64
+ };
65
+ case "mp_manual":
66
+ return {
67
+ ...base,
68
+ method,
69
+ autonomy: "human-required",
70
+ instruction: "Gener\xE1 el VEP en ARCA y pagalo en Mercado Pago (Cuentas y servicios \u2192 AFIP VEP, o escane\xE1 el QR). No existe API de Mercado Pago para pagar un VEP.",
71
+ oneTimeSetup: ""
72
+ };
73
+ }
74
+ }
75
+
76
+ // src/index.ts
77
+ var CEDULAR_RATE = { ARS: 0.05, FOREIGN: 0.15 };
78
+ function cedularTax(amountUsd, costBasisPerUsd, fxRate, denom = "ARS") {
79
+ const proceeds = amountUsd * fxRate;
80
+ const cost = amountUsd * costBasisPerUsd * fxRate;
81
+ const gain = Math.max(0, proceeds - cost);
82
+ return gain * CEDULAR_RATE[denom];
83
+ }
84
+ function nextObligation(obligations, nowMs) {
85
+ const upcoming = obligations.filter((o) => o.dueAtMs >= nowMs).sort((a, b) => a.dueAtMs - b.dueAtMs);
86
+ return upcoming[0] ?? null;
87
+ }
88
+ function requiredArsBuffer(obligations, nowMs, horizonMs, safety = 1.1) {
89
+ const due = obligations.filter((o) => o.dueAtMs >= nowMs && o.dueAtMs <= nowMs + horizonMs);
90
+ const total = due.reduce((sum, o) => sum + o.amountArs, 0);
91
+ return total * safety;
92
+ }
93
+ function planConversion(state, requiredArs, fxRate, spread = 0.01) {
94
+ const shortfall = requiredArs - state.ars;
95
+ if (shortfall <= 0) {
96
+ return { convertUsd: 0, expectedArs: 0, reason: "ars buffer sufficient" };
97
+ }
98
+ const effectiveRate = fxRate * (1 - spread);
99
+ if (effectiveRate <= 0 || state.usd <= 0) {
100
+ return { convertUsd: 0, expectedArs: 0, reason: "no usd available or invalid rate" };
101
+ }
102
+ const neededUsd = shortfall / effectiveRate;
103
+ const convertUsd = Math.min(neededUsd, state.usd);
104
+ const expectedArs = convertUsd * effectiveRate;
105
+ return {
106
+ convertUsd,
107
+ expectedArs,
108
+ reason: convertUsd < neededUsd ? "partial: usd insufficient for full buffer" : "top up to buffer"
109
+ };
110
+ }
111
+
112
+ // src/tools.ts
113
+ var TREASURY_TOOL_SIDE_EFFECTS = {
114
+ treasury_offramp_convert: "irreversible",
115
+ treasury_offramp_quote: "network read",
116
+ treasury_offramp_status: "network read",
117
+ treasury_tax_estimate: "none",
118
+ treasury_monotributo: "none",
119
+ treasury_buffer_status: "none",
120
+ treasury_plan_conversion: "none",
121
+ treasury_settlement_plan: "none"
122
+ };
123
+ function treasurySideEffectsFor(toolName) {
124
+ return TREASURY_TOOL_SIDE_EFFECTS[toolName];
125
+ }
126
+ var DAY_MS = 864e5;
127
+ var obligationSchema = zod.z.object({
128
+ id: zod.z.string(),
129
+ kind: zod.z.enum(["monotributo", "vep", "iibb", "cedular"]),
130
+ amountArs: zod.z.number(),
131
+ dueAtMs: zod.z.number().describe("Epoch ms the obligation is due.")
132
+ });
133
+ function treasuryTools(options = {}) {
134
+ const now = options.now ?? Date.now;
135
+ const offramp = options.offramp;
136
+ const noOfframp = {
137
+ available: false,
138
+ reason: "No off-ramp configured. Set MANTECA_API_KEY (+ user/bank-account) to enable USDC->ARS conversion."
139
+ };
140
+ return {
141
+ treasury_tax_estimate: ai.tool({
142
+ description: "Estimate the Impuesto a las Ganancias cedular owed (in ARS) on disposing crypto. Use before converting USDC->ARS so the society reserves the tax. Rate is 5% when sold in pesos without adjustment clause, 15% in foreign currency, on the GAIN only (0 if no gain). Crypto is IVA-exempt; holding + own-wallet transfers are not taxable. Pure, no side effects.",
143
+ inputSchema: zod.z.object({
144
+ amountUsd: zod.z.number().positive(),
145
+ costBasisPerUsd: zod.z.number().default(1).describe("Acquisition cost per USDC unit (\u22481 for stablecoins)."),
146
+ fxRate: zod.z.number().positive().describe("ARS per USD at disposal."),
147
+ denom: zod.z.enum(["ARS", "FOREIGN"]).default("ARS").describe("Sale denominated in pesos (5%) or foreign currency (15%).")
148
+ }),
149
+ execute: async ({ amountUsd, costBasisPerUsd, fxRate, denom }) => {
150
+ const taxArs = cedularTax(amountUsd, costBasisPerUsd, fxRate, denom);
151
+ const proceeds = amountUsd * fxRate;
152
+ const gainArs = Math.max(0, proceeds - amountUsd * costBasisPerUsd * fxRate);
153
+ return {
154
+ taxArs,
155
+ gainArs,
156
+ ratePct: denom === "ARS" ? 5 : 15,
157
+ denom,
158
+ note: "Cedular sobre la ganancia. Cripto exento de IVA."
159
+ };
160
+ }
161
+ }),
162
+ treasury_monotributo: ai.tool({
163
+ description: "Look up the monthly monotributo cuota (ARS) and/or the category for an annual income. Pass `category` to get its cuota, or `annualIncomeArs` to resolve the category. Values eff. " + MONOTRIBUTO_TABLE_EFFECTIVE + " (IPC-indexed ~6mo). Monotributo is for a persona-humana operator; a SAS/SRL is in the general regime. Pure.",
164
+ inputSchema: zod.z.object({
165
+ activity: zod.z.enum(["servicios", "bienes"]),
166
+ category: zod.z.enum(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"]).optional(),
167
+ annualIncomeArs: zod.z.number().nonnegative().optional()
168
+ }),
169
+ execute: async ({ activity, category, annualIncomeArs }) => {
170
+ let cat = category ?? null;
171
+ if (!cat && annualIncomeArs !== void 0) {
172
+ cat = categoryForAnnualIncome(annualIncomeArs, activity);
173
+ }
174
+ if (!cat) {
175
+ return {
176
+ available: false,
177
+ reason: annualIncomeArs !== void 0 ? "Income exceeds the monotributo ceiling; move to the general regime." : "Provide `category` or `annualIncomeArs`."
178
+ };
179
+ }
180
+ return {
181
+ category: cat,
182
+ activity,
183
+ cuotaArs: monotributoCuota(cat, activity),
184
+ tableEffective: MONOTRIBUTO_TABLE_EFFECTIVE
185
+ };
186
+ }
187
+ }),
188
+ treasury_buffer_status: ai.tool({
189
+ description: "Given the current ARS balance and upcoming AFIP obligations, compute the peso buffer needed within a horizon (with a safety multiple) and any shortfall. Use to decide whether to convert crypto. Pure (clock injected).",
190
+ inputSchema: zod.z.object({
191
+ arsBalance: zod.z.number().nonnegative(),
192
+ obligations: zod.z.array(obligationSchema),
193
+ horizonDays: zod.z.number().positive().default(30),
194
+ safety: zod.z.number().min(1).default(1.1)
195
+ }),
196
+ execute: async ({ arsBalance, obligations, horizonDays, safety }) => {
197
+ const t = now();
198
+ const obs = obligations;
199
+ const requiredArs = requiredArsBuffer(obs, t, horizonDays * DAY_MS, safety);
200
+ const next = nextObligation(obs, t);
201
+ return {
202
+ requiredArs,
203
+ arsBalance,
204
+ shortfallArs: Math.max(0, requiredArs - arsBalance),
205
+ funded: arsBalance >= requiredArs,
206
+ horizonDays,
207
+ nextObligation: next ? { id: next.id, kind: next.kind, amountArs: next.amountArs, dueAtMs: next.dueAtMs } : null
208
+ };
209
+ }
210
+ }),
211
+ treasury_plan_conversion: ai.tool({
212
+ description: "Plan a just-in-time USDC->ARS conversion: how much USDC to convert to top the ARS buffer to `requiredArs`, net of spread, capped by available USDC. Never over-converts (minimizes taxable disposals + fx exposure). Returns convertUsd=0 if the buffer is already met. Pure \u2014 this PLANS, it does not execute (use treasury_offramp_convert for that).",
213
+ inputSchema: zod.z.object({
214
+ usd: zod.z.number().nonnegative().describe("USDC available."),
215
+ ars: zod.z.number().nonnegative().describe("Current ARS balance."),
216
+ costBasisPerUsd: zod.z.number().default(1),
217
+ requiredArs: zod.z.number().nonnegative(),
218
+ fxRate: zod.z.number().positive(),
219
+ spread: zod.z.number().min(0).max(1).default(0.01)
220
+ }),
221
+ execute: async ({ usd, ars, costBasisPerUsd, requiredArs, fxRate, spread }) => {
222
+ return planConversion({ usd, ars}, requiredArs, fxRate, spread);
223
+ }
224
+ }),
225
+ treasury_settlement_plan: ai.tool({
226
+ description: "Describe HOW a tax obligation actually gets paid under a chosen method, honestly. IMPORTANT: no method lets the agent pay autonomously at pay-time (canAutoExecute is always false). 'debito_automatico' is passive after a one-time human enrolment (the agent just keeps the CVU funded); 'vep_manual'/'mp_manual' need a human each time. Use to tell the operator exactly what to do. Pure.",
227
+ inputSchema: zod.z.object({
228
+ amountArs: zod.z.number().nonnegative(),
229
+ dueAtMs: zod.z.number(),
230
+ kind: zod.z.enum(["monotributo", "vep", "iibb", "cedular"]).default("monotributo"),
231
+ method: zod.z.enum(["debito_automatico", "vep_manual", "mp_manual"])
232
+ }),
233
+ execute: async ({ amountArs, dueAtMs, kind, method }) => {
234
+ return settlementPlan({ amountArs, dueAtMs }, method);
235
+ }
236
+ }),
237
+ treasury_offramp_quote: ai.tool({
238
+ description: "Get a live USDC->ARS quote from the configured registered-PSAV off-ramp (e.g. Manteca). Read-only, no side effects. Returns {available:false} if no off-ramp is configured.",
239
+ inputSchema: zod.z.object({ amountUsd: zod.z.number().positive() }),
240
+ execute: async ({ amountUsd }) => {
241
+ if (!offramp) return noOfframp;
242
+ const q = await offramp.quote(amountUsd);
243
+ return { available: true, ...q };
244
+ }
245
+ }),
246
+ treasury_offramp_convert: ai.tool({
247
+ description: "EXECUTE an off-ramp: sell USDC and pay out ARS to the society's CVU via the registered PSAV. IRREVERSIBLE \u2014 moves real money. Only call after a human approval (RFC-001); the call is also hard-gated by the kill-switch. Settlement is asynchronous; confirm with treasury_offramp_status. Returns {available:false} if no off-ramp is configured.",
248
+ inputSchema: zod.z.object({
249
+ amountUsd: zod.z.number().positive(),
250
+ externalId: zod.z.string().min(1).describe(
251
+ "REQUIRED stable idempotency key tied to the payment (e.g. the obligation id + period). Reuse the EXACT same key on any retry, or the off-ramp will double-spend."
252
+ )
253
+ }),
254
+ execute: async ({ amountUsd, externalId }) => {
255
+ if (!offramp) return noOfframp;
256
+ const receipt = await offramp.convert(amountUsd, { externalId });
257
+ return { available: true, ...receipt };
258
+ }
259
+ }),
260
+ treasury_offramp_status: ai.tool({
261
+ description: "Poll the settlement status of a prior treasury_offramp_convert by its txId. Use to confirm the ARS actually landed in the CVU before marking an obligation funded. Returns {available:false} if no off-ramp (or it does not support status polling).",
262
+ inputSchema: zod.z.object({ txId: zod.z.string() }),
263
+ execute: async ({ txId }) => {
264
+ if (!offramp) return noOfframp;
265
+ if (!offramp.getStatus)
266
+ return { available: false, reason: "Off-ramp does not support status polling." };
267
+ const report = await offramp.getStatus(txId);
268
+ return { available: true, ...report };
269
+ }
270
+ })
271
+ };
272
+ }
273
+
274
+ exports.TREASURY_TOOL_SIDE_EFFECTS = TREASURY_TOOL_SIDE_EFFECTS;
275
+ exports.treasurySideEffectsFor = treasurySideEffectsFor;
276
+ exports.treasuryTools = treasuryTools;
277
+ //# sourceMappingURL=tools.cjs.map
278
+ //# sourceMappingURL=tools.cjs.map