@routstr/sdk 0.1.5 → 0.1.7

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../core/errors.ts","../../discovery/ModelManager.ts","../../discovery/MintDiscovery.ts"],"names":["event"],"mappings":";;;;;AAiHO,IAAM,sBAAA,GAAN,cAAqC,KAAA,CAAM;AAAA,EAChD,WAAA,CACS,iBACP,OAAA,EACA;AACA,IAAA,KAAA;AAAA,MACE,OAAA,IAAW,CAAA,sCAAA,EAAyC,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KAChF;AALO,IAAA,IAAA,CAAA,eAAA,GAAA,eAAA;AAMP,IAAA,IAAA,CAAK,IAAA,GAAO,wBAAA;AAAA,EACd;AACF,CAAA;AAKO,IAAM,yBAAA,GAAN,cAAwC,KAAA,CAAM;AAAA,EACnD,WAAA,GAAc;AACZ,IAAA,KAAA,CAAM,gDAAgD,CAAA;AACtD,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AAAA,EACd;AACF,CAAA;ACnGO,IAAM,YAAA,GAAN,MAAM,aAAA,CAAa;AAAA,EAMxB,WAAA,CACU,OAAA,EACR,MAAA,GAA6B,EAAC,EAC9B;AAFQ,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGR,IAAA,IAAA,CAAK,oBAAA,GACH,OAAO,oBAAA,IAAwB,uCAAA;AACjC,IAAA,IAAA,CAAK,QAAA,GAAW,MAAA,CAAO,QAAA,IAAY,GAAA,GAAM,EAAA,GAAK,GAAA;AAC9C,IAAA,IAAA,CAAK,mBAAA,GAAsB,MAAA,CAAO,mBAAA,IAAuB,EAAC;AAC1D,IAAA,IAAA,CAAK,mBAAA,GAAsB,MAAA,CAAO,mBAAA,IAAuB,EAAC;AAAA,EAC5D;AAAA,EAdiB,QAAA;AAAA,EACA,oBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBjB,WAAA,GAAwB;AACtB,IAAA,OAAO,IAAA,CAAK,QAAQ,eAAA,EAAgB;AAAA,EACtC;AAAA,EAEA,aAAa,KACX,OAAA,EACA,MAAA,GAA6B,EAAC,EAC9B,OAAA,GAAyD,EAAC,EACnC;AACvB,IAAA,MAAM,OAAA,GAAU,IAAI,aAAA,CAAa,OAAA,EAAS,MAAM,CAAA;AAChD,IAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,KAAA;AACnC,IAAA,MAAM,YAAA,GAAe,QAAQ,YAAA,IAAgB,KAAA;AAC7C,IAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,kBAAA,CAAmB,OAAO,CAAA;AAC1D,IAAA,MAAM,OAAA,CAAQ,WAAA,CAAY,SAAA,EAAW,YAAY,CAAA;AACjD,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,kBAAA,CAAmB,OAAA,GAAmB,KAAA,EAA0B;AAEpE,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,eAAA,EAAgB;AAChD,IAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,qBAAA,EAAsB;AACtD,MAAA,MAAM,aAAa,UAAA,IAAc,IAAA,CAAK,GAAA,EAAI,GAAI,cAAc,IAAA,CAAK,QAAA;AACjE,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,MAAM,KAAK,oBAAA,EAAqB;AAChC,QAAA,OAAO,IAAA,CAAK,oBAAA,CAAqB,UAAA,EAAY,OAAO,CAAA;AAAA,MACtD;AAAA,IACF;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,cAAA,GAAiB,MAAM,IAAA,CAAK,kBAAA,CAAmB,OAAO,OAAO,CAAA;AACnE,MAAA,IAAI,cAAA,CAAe,SAAS,CAAA,EAAG;AAC7B,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,oBAAA,CAAqB,cAAA,EAAgB,OAAO,CAAA;AAClE,QAAA,IAAA,CAAK,OAAA,CAAQ,gBAAgB,QAAQ,CAAA;AACrC,QAAA,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAA,CAAK,GAAA,EAAK,CAAA;AAC7C,QAAA,MAAM,KAAK,oBAAA,EAAqB;AAChC,QAAA,OAAO,QAAA;AAAA,MACT;AAAA,IACF,SAAS,CAAA,EAAG;AACV,MAAA,OAAA,CAAQ,IAAA,CAAK,iDAAiD,CAAC,CAAA;AAAA,IACjE;AAGA,IAAA,OAAO,IAAA,CAAK,kBAAkB,OAAO,CAAA;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,kBAAA,CACZ,IAAA,EACA,OAAA,EACmB;AACnB,IAAA,MAAM,cAAA,GAAiB;AAAA,MACrB,wBAAA;AAAA,MACA,eAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,MAAM,IAAA,GAAO,IAAI,SAAA,EAAU;AAC3B,IAAA,MAAM,eAAA,GAAkB,IAAI,UAAA,EAAW;AAEvC,IAAA,MAAM,SAAA,GAAY,GAAA;AAElB,IAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACnC,MAAA,IAAA,CACG,IAAI,cAAA,EAAgB;AAAA,QACnB,KAAA,EAAO,CAAC,IAAI,CAAA;AAAA,QACZ,KAAA,EAAO;AAAA,OACR,CAAA,CACA,IAAA;AAAA,QACC,UAAA,EAAW;AAAA,QACX,GAAA,CAAI,CAAC,KAAA,KAAU;AACb,UAAA,eAAA,CAAgB,IAAI,KAAK,CAAA;AAAA,QAC3B,CAAC;AAAA,QAEF,SAAA,CAAU;AAAA,QACT,UAAU,MAAM;AACd,UAAA,OAAA,EAAQ;AAAA,QACV;AAAA,OACD,CAAA;AAEH,MAAA,UAAA,CAAW,MAAM;AACf,QAAA,OAAA,EAAQ;AAAA,MACV,GAAG,SAAS,CAAA;AAAA,IACd,CAAC,CAAA;AAED,IAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,CAAY,EAAE,OAAO,CAAC,IAAI,GAAG,CAAA;AAE9D,IAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAE9B,IAAA,KAAA,MAAW,SAAS,QAAA,EAAU;AAC5B,MAAA,MAAM,YAAsB,EAAC;AAE7B,MAAA,KAAA,MAAW,GAAA,IAAO,MAAM,IAAA,EAAM;AAC5B,QAAA,IAAI,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,IAAO,OAAO,GAAA,CAAI,CAAC,MAAM,QAAA,EAAU;AAChD,UAAA,SAAA,CAAU,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,QACvB;AAAA,MACF;AAEA,MAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACxB,QAAA,KAAA,MAAW,OAAO,SAAA,EAAW;AAC3B,UAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,GAAG,CAAA;AACxC,UAAA,IAAI,CAAC,OAAA,IAAW,UAAA,CAAW,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC7C,YAAA,KAAA,CAAM,IAAI,UAAU,CAAA;AAAA,UACtB;AAAA,QACF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,OAAO,CAAA;AACxC,QAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,OAAO,IACnC,OAAA,GACA,OAAA,CAAQ,aAAa,EAAC;AAE1B,QAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,UAAA,MAAM,SAAA,GAAY,IAAA,CAAK,oBAAA,CAAqB,CAAA,EAAG,OAAO,CAAA;AACtD,UAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,YAAA,KAAA,CAAM,IAAI,QAAQ,CAAA;AAAA,UACpB;AAAA,QACF;AAAA,MACF,CAAA,CAAA,MAAQ;AACN,QAAA,IAAI;AACF,UAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,OAAO,CAAA;AAC1C,UAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC5B,YAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,cAAA,MAAM,SAAA,GAAY,IAAA,CAAK,oBAAA,CAAqB,CAAA,EAAG,OAAO,CAAA;AACtD,cAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,gBAAA,KAAA,CAAM,IAAI,QAAQ,CAAA;AAAA,cACpB;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAA,CAAA,MAAQ;AACN,UAAA,OAAA,CAAQ,IAAA;AAAA,YACN,uDAAA;AAAA,YACA,KAAA,CAAM;AAAA,WACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,KAAA,MAAW,GAAA,IAAO,KAAK,mBAAA,EAAqB;AAC1C,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,GAAG,CAAA;AACxC,MAAA,IAAI,CAAC,OAAA,IAAW,UAAA,CAAW,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC7C,QAAA,KAAA,CAAM,IAAI,UAAU,CAAA;AAAA,MACtB;AAAA,IACF;AAEA,IAAA,MAAM,WAAW,IAAI,GAAA;AAAA,MACnB,IAAA,CAAK,oBAAoB,GAAA,CAAI,CAAC,QAAQ,IAAA,CAAK,YAAA,CAAa,GAAG,CAAC;AAAA,KAC9D;AAEA,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,CAAE,MAAA,CAAO,CAAC,IAAA,KAAS,CAAC,QAAA,CAAS,GAAA,CAAI,IAAI,CAAC,CAAA;AAErE,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,kBAAkB,OAAA,EAAqC;AACnE,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,IAAA,CAAK,oBAAoB,CAAA;AACjD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,MAC5D;AAEA,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,IAAA,EAAM,SAAS,CAAA,GAAI,IAAA,CAAK,YAAY,EAAC;AAErE,MAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,MAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,QAAA,MAAM,SAAA,GAAY,IAAA,CAAK,oBAAA,CAAqB,CAAA,EAAG,OAAO,CAAA;AACtD,QAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,UAAA,KAAA,CAAM,IAAI,QAAQ,CAAA;AAAA,QACpB;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,GAAA,IAAO,KAAK,mBAAA,EAAqB;AAC1C,QAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,GAAG,CAAA;AACxC,QAAA,IAAI,CAAC,OAAA,IAAW,UAAA,CAAW,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC7C,UAAA,KAAA,CAAM,IAAI,UAAU,CAAA;AAAA,QACtB;AAAA,MACF;AAEA,MAAA,MAAM,WAAW,IAAI,GAAA;AAAA,QACnB,IAAA,CAAK,oBAAoB,GAAA,CAAI,CAAC,QAAQ,IAAA,CAAK,YAAA,CAAa,GAAG,CAAC;AAAA,OAC9D;AAEA,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,CAAE,MAAA,CAAO,CAAC,IAAA,KAAS,CAAC,QAAA,CAAS,GAAA,CAAI,IAAI,CAAC,CAAA;AAEnE,MAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,QAAA,IAAA,CAAK,OAAA,CAAQ,gBAAgB,IAAI,CAAA;AACjC,QAAA,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAA,CAAK,GAAA,EAAK,CAAA;AAC7C,QAAA,MAAM,KAAK,oBAAA,EAAqB;AAAA,MAClC;AAEA,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,CAAA,EAAG;AACV,MAAA,OAAA,CAAQ,KAAA,CAAM,iCAAiC,CAAC,CAAA;AAChD,MAAA,MAAM,IAAI,sBAAA,CAAuB,EAAC,EAAG,CAAA,2BAAA,EAA8B,CAAC,CAAA,CAAE,CAAA;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAA,CACJ,QAAA,EACA,YAAA,GAAwB,KAAA,EACN;AAClB,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,MAAA,MAAM,IAAI,yBAAA,EAA0B;AAAA,IACtC;AAEA,IAAA,MAAM,QAAA,uBAAe,GAAA,EAA4C;AACjE,IAAA,MAAM,yBAAkD,EAAC;AACzD,IAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,OAAA,CAAQ,oBAAA,EAAqB;AAG5D,IAAA,MAAM,eAAA,GAAkB,CAAC,CAAA,KAAqB;AAC5C,MAAA,OAAO,CAAA,EAAG,cAAc,UAAA,IAAc,CAAA;AAAA,IACxC,CAAA;AAGA,IAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,GAAA,CAAI,OAAO,GAAA,KAAQ;AAChD,MAAA,MAAM,OAAO,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,GAAA,GAAM,GAAG,GAAG,CAAA,CAAA,CAAA;AAC7C,MAAA,IAAI;AAEF,QAAA,IAAI,IAAA;AAEJ,QAAA,IAAI,CAAC,YAAA,EAAc;AACjB,UAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAI,CAAA;AAC1D,UAAA,MAAM,aACJ,UAAA,IAAc,IAAA,CAAK,GAAA,EAAI,GAAI,cAAc,IAAA,CAAK,QAAA;AAEhD,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,eAAA,EAAgB;AAClD,YAAA,MAAM,UAAA,GAAa,YAAA,CAAa,IAAI,CAAA,IAAK,EAAC;AAC1C,YAAA,IAAA,GAAO,UAAA;AAAA,UACT,CAAA,MAAO;AAEL,YAAA,IAAA,GAAO,MAAM,IAAA,CAAK,uBAAA,CAAwB,IAAI,CAAA;AAAA,UAChD;AAAA,QACF,CAAA,MAAO;AAEL,UAAA,IAAA,GAAO,MAAM,IAAA,CAAK,uBAAA,CAAwB,IAAI,CAAA;AAAA,QAChD;AAEA,QAAA,sBAAA,CAAuB,IAAI,CAAA,GAAI,IAAA;AAC/B,QAAA,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAA,EAAM,IAAA,CAAK,KAAK,CAAA;AAGnD,QAAA,IAAI,CAAC,iBAAA,CAAkB,QAAA,CAAS,IAAI,CAAA,EAAG;AACrC,UAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,YAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA;AAGlC,YAAA,IAAI,CAAC,EAAE,YAAA,EAAc;AAErB,YAAA,IAAI,CAAC,QAAA,EAAU;AACb,cAAA,QAAA,CAAS,IAAI,CAAA,CAAE,EAAA,EAAI,EAAE,KAAA,EAAO,CAAA,EAAG,MAAM,CAAA;AACrC,cAAA;AAAA,YACF;AAGA,YAAA,MAAM,WAAA,GAAc,gBAAgB,CAAC,CAAA;AACrC,YAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,QAAA,CAAS,KAAK,CAAA;AACnD,YAAA,IAAI,WAAA,GAAc,YAAA,IAAgB,CAAA,CAAE,YAAA,EAAc;AAChD,cAAA,QAAA,CAAS,IAAI,CAAA,CAAE,EAAA,EAAI,EAAE,KAAA,EAAO,CAAA,EAAG,MAAM,CAAA;AAAA,YACvC;AAAA,UACF;AAAA,QACF;AAEA,QAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,IAAA,EAAK;AAAA,MACrC,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,IAAA,CAAK,mBAAA,CAAoB,KAAK,CAAA,EAAG;AACnC,UAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,SAAA,EAAY,IAAI,CAAA,mBAAA,CAAqB,CAAA;AAAA,QACpD,CAAA,MAAO;AACL,UAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,4BAAA,EAA+B,IAAI,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QAC5D;AACA,QAAA,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAA,EAAM,IAAA,CAAK,KAAK,CAAA;AACnD,QAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,IAAA,EAAK;AAAA,MAChC;AAAA,IACF,CAAC,CAAA;AAGD,IAAA,MAAM,OAAA,CAAQ,WAAW,aAAa,CAAA;AAGtC,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,OAAA,CAAQ,eAAA,EAAgB;AACnD,IAAA,IAAA,CAAK,QAAQ,eAAA,CAAgB;AAAA,MAC3B,GAAG,aAAA;AAAA,MACH,GAAG;AAAA,KACJ,CAAA;AAGD,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAA;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,wBAAwB,OAAA,EAAmC;AACvE,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,SAAA,CAAW,CAAA;AAC7C,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IACzD;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,EAAM,IAAI,IACjC,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,MAAc;AAAA,MAC3B,GAAG,CAAA;AAAA,MACH,EAAA,EAAI,EAAE,EAAA,CAAG,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,MAAS,CAAA,CAAE;AAAA,KACjC,CAAE,IACF,EAAC;AAEL,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEQ,oBAAoB,KAAA,EAAyB;AACnD,IAAA,IAAI,EAAE,KAAA,YAAiB,KAAA,CAAA,EAAQ,OAAO,KAAA;AACtC,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,WAAA,EAAY;AACtC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,cAAc,CAAA,EAAG,OAAO,IAAA;AACzC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,IAAA;AAChC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,IAAA;AAChC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,IAAA;AAChC,IAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,IAAA,OAAO,OAAO,IAAA,KAAS,WAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAA,GAA8C;AAC5C,IAAA,OAAO,IAAA,CAAK,QAAQ,eAAA,EAAgB;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAmB,OAAA,EAAuB;AACxC,IAAA,MAAM,OAAO,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,GAAI,OAAA,GAAU,GAAG,OAAO,CAAA,CAAA,CAAA;AACzD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,eAAA,EAAgB;AAC5C,IAAA,OAAO,OAAO,IAAI,CAAA;AAClB,IAAA,IAAA,CAAK,OAAA,CAAQ,gBAAgB,MAAM,CAAA;AACnC,IAAA,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAA,EAAM,CAAC,CAAA;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,OAAA,CAAQ,eAAA,CAAgB,EAAE,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAA,CAAqB,UAAoB,OAAA,EAA4B;AACnE,IAAA,IAAI,CAAC,OAAA,EAAS;AAEZ,MAAA,OAAO,QAAA,CAAS,OAAO,CAAC,GAAA,KAAQ,CAAC,GAAA,CAAI,QAAA,CAAS,QAAQ,CAAC,CAAA;AAAA,IACzD;AAEA,IAAA,OAAO,SAAS,MAAA,CAAO,CAAC,QAAQ,GAAA,CAAI,QAAA,CAAS,QAAQ,CAAC,CAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,oBAAA,CAAqB,UAAe,OAAA,EAA4B;AACtE,IAAA,MAAM,YAAsB,EAAC;AAE7B,IAAA,IAAI,OAAA,IAAW,SAAS,SAAA,EAAW;AACjC,MAAA,SAAA,CAAU,IAAA,CAAK,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,SAAS,CAAC,CAAA;AAAA,IACtD,CAAA,MAAA,IAAW,SAAS,YAAA,EAAc;AAChC,MAAA,SAAA,CAAU,IAAA,CAAK,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,YAAY,CAAC,CAAA;AAAA,IACzD;AAEA,IAAA,OAAO,SAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,aAAa,GAAA,EAAqB;AACxC,IAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAC3B,MAAA,GAAA,GAAM,WAAW,GAAG,CAAA,CAAA;AAAA,IACtB;AACA,IAAA,OAAO,IAAI,QAAA,CAAS,GAAG,CAAA,GAAI,GAAA,GAAM,GAAG,GAAG,CAAA,CAAA,CAAA;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAA,CAAqB,YAAA,GAAwB,KAAA,EAA0B;AAE3E,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,kBAAA,EAAmB;AACrD,IAAA,IAAI,CAAC,YAAA,IAAgB,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG;AAC5C,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,4BAAA,EAA6B;AAC7D,MAAA,MAAM,aAAa,UAAA,IAAc,IAAA,CAAK,GAAA,EAAI,GAAI,cAAc,IAAA,CAAK,QAAA;AACjE,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,OAAO,YAAA;AAAA,MACT;AAAA,IACF;AAEA,IAAA,MAAM,cAAA,GAAiB;AAAA,MACrB,wBAAA;AAAA,MACA,eAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,MAAM,IAAA,GAAO,IAAI,SAAA,EAAU;AAC3B,IAAA,MAAM,eAAA,GAAkB,IAAI,UAAA,EAAW;AAEvC,IAAA,MAAM,SAAA,GAAY,GAAA;AAElB,IAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACnC,MAAA,IAAA,CACG,IAAI,cAAA,EAAgB;AAAA,QACnB,KAAA,EAAO,CAAC,KAAK,CAAA;AAAA,QACb,IAAA,EAAM,CAAC,mBAAmB,CAAA;AAAA,QAC1B,KAAA,EAAO,CAAA;AAAA,QACP,OAAA,EAAS;AAAA,UACP;AAAA;AACF,OACD,CAAA,CACA,IAAA;AAAA,QACC,UAAA,EAAW;AAAA,QACX,GAAA,CAAI,CAACA,MAAAA,KAAU;AACb,UAAA,eAAA,CAAgB,IAAIA,MAAK,CAAA;AAAA,QAC3B,CAAC;AAAA,QAEF,SAAA,CAAU;AAAA,QACT,UAAU,MAAM;AACd,UAAA,OAAA,EAAQ;AAAA,QACV;AAAA,OACD,CAAA;AAEH,MAAA,UAAA,CAAW,MAAM;AACf,QAAA,OAAA,EAAQ;AAAA,MACV,GAAG,SAAS,CAAA;AAAA,IACd,CAAC,CAAA;AAED,IAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,CAAY,EAAE,OAAO,CAAC,KAAK,GAAG,CAAA;AAE/D,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,MAAA,OAAO,YAAA,CAAa,MAAA,GAAS,CAAA,GAAI,YAAA,GAAe,EAAC;AAAA,IACnD;AAEA,IAAA,MAAM,KAAA,GAAQ,SAAS,CAAC,CAAA;AAExB,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,OAAO,CAAA;AACxC,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,EAAS,MAAM,CAAA,GAAI,OAAA,CAAQ,SAAS,EAAC;AAClE,MAAA,IAAA,CAAK,OAAA,CAAQ,mBAAmB,MAAM,CAAA;AACtC,MAAA,IAAA,CAAK,OAAA,CAAQ,4BAAA,CAA6B,IAAA,CAAK,GAAA,EAAK,CAAA;AACpD,MAAA,OAAO,MAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,wDAAA;AAAA,QACA,KAAA,CAAM;AAAA,OACR;AACA,MAAA,OAAO,YAAA,CAAa,MAAA,GAAS,CAAA,GAAI,YAAA,GAAe,EAAC;AAAA,IACnD;AAAA,EACF;AACF;;;ACxhBO,IAAM,gBAAN,MAAoB;AAAA,EAGzB,WAAA,CACU,OAAA,EACR,MAAA,GAA8B,EAAC,EAC/B;AAFQ,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGR,IAAA,IAAA,CAAK,QAAA,GAAW,MAAA,CAAO,QAAA,IAAY,EAAA,GAAK,EAAA,GAAK,GAAA;AAAA,EAC/C;AAAA,EAPiB,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAejB,MAAM,aAAA,CACJ,QAAA,EACA,OAAA,GAAsC,EAAC,EAItC;AACD,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,MAAA,OAAO,EAAE,kBAAA,EAAoB,EAAC,EAAG,iBAAA,EAAmB,EAAC,EAAE;AAAA,IACzD;AAEA,IAAA,MAAM,wBAAkD,EAAC;AACzD,IAAA,MAAM,uBAAqD,EAAC;AAC5D,IAAA,MAAM,YAAA,GAAe,QAAQ,YAAA,IAAgB,KAAA;AAG7C,IAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,GAAA,CAAI,OAAO,GAAA,KAAQ;AAChD,MAAA,MAAM,OAAO,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,GAAA,GAAM,GAAG,GAAG,CAAA,CAAA,CAAA;AAC7C,MAAA,IAAI;AACF,QAAA,IAAI,CAAC,YAAA,EAAc;AACjB,UAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAI,CAAA;AAC1D,UAAA,MAAM,aACJ,UAAA,IAAc,IAAA,CAAK,GAAA,EAAI,GAAI,cAAc,IAAA,CAAK,QAAA;AAChD,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,MAAM,cAAc,IAAA,CAAK,OAAA,CAAQ,gBAAe,CAAE,IAAI,KAAK,EAAC;AAC5D,YAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,qBAAA,GAAwB,IAAI,CAAA;AAC5D,YAAA,qBAAA,CAAsB,IAAI,CAAA,GAAI,WAAA;AAC9B,YAAA,IAAI,UAAA,EAAY;AACd,cAAA,oBAAA,CAAqB,IAAI,CAAA,GAAI,UAAA;AAAA,YAC/B;AACA,YAAA,OAAO;AAAA,cACL,OAAA,EAAS,IAAA;AAAA,cACT,IAAA;AAAA,cACA,KAAA,EAAO,WAAA;AAAA,cACP,IAAA,EAAM;AAAA,aACR;AAAA,UACF;AAAA,QACF;AAEA,QAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,IAAI,CAAA,OAAA,CAAS,CAAA;AACxC,QAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,QACvD;AAEA,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAG5B,QAAA,MAAM,KAAA,GAAkB,MAAM,OAAA,CAAQ,IAAA,EAAM,KAAK,CAAA,GAAI,IAAA,CAAK,QAAQ,EAAC;AAGnE,QAAA,MAAM,kBAAkB,KAAA,CAAM,GAAA;AAAA,UAAI,CAAC,IAAA,KACjC,IAAA,CAAK,QAAA,CAAS,GAAG,IAAI,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI;AAAA,SAC3C;AAGA,QAAA,qBAAA,CAAsB,IAAI,CAAA,GAAI,eAAA;AAC9B,QAAA,oBAAA,CAAqB,IAAI,CAAA,GAAI,IAAA;AAC7B,QAAA,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAA,EAAM,IAAA,CAAK,KAAK,CAAA;AAEnD,QAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,MAAM,KAAA,EAAO,eAAA,EAAiB,MAAM,IAAA,EAAK;AAAA,MACnE,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,IAAA,EAAM,IAAA,CAAK,KAAK,CAAA;AACnD,QAAA,IAAI,IAAA,CAAK,mBAAA,CAAoB,KAAK,CAAA,EAAG;AACnC,UAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,SAAA,EAAY,IAAI,CAAA,mBAAA,CAAqB,CAAA;AAAA,QACpD,CAAA,MAAO;AACL,UAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,2BAAA,EAA8B,IAAI,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QAC3D;AACA,QAAA,OAAO,EAAE,SAAS,KAAA,EAAO,IAAA,EAAM,OAAO,EAAC,EAAG,MAAM,IAAA,EAAK;AAAA,MACvD;AAAA,IACF,CAAC,CAAA;AAGD,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,UAAA,CAAW,aAAa,CAAA;AAGtD,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,MAAA,CAAO,WAAW,WAAA,EAAa;AACjC,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,KAAS,MAAA,CAAO,KAAA;AACrC,QAAA,qBAAA,CAAsB,IAAI,CAAA,GAAI,KAAA;AAC9B,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,oBAAA,CAAqB,IAAI,CAAA,GAAI,IAAA;AAAA,QAC/B;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,OAAA,CAAQ,KAAA,CAAM,uBAAA,EAAyB,MAAA,CAAO,MAAM,CAAA;AAAA,MACtD;AAAA,IACF;AAGA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,OAAA,CAAQ,eAAe,qBAAqB,CAAA;AACjD,MAAA,IAAA,CAAK,OAAA,CAAQ,sBAAsB,oBAAoB,CAAA;AAAA,IACzD,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAAA,IAC9D;AAEA,IAAA,OAAO;AAAA,MACL,kBAAA,EAAoB,qBAAA;AAAA,MACpB,iBAAA,EAAmB;AAAA,KACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAA,GAA2C;AACzC,IAAA,OAAO,IAAA,CAAK,QAAQ,cAAA,EAAe;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBAAA,GAAsD;AACpD,IAAA,OAAO,IAAA,CAAK,QAAQ,qBAAA,EAAsB;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAiB,OAAA,EAA2B;AAC1C,IAAA,MAAM,aAAa,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,GAAI,OAAA,GAAU,GAAG,OAAO,CAAA,CAAA,CAAA;AAC/D,IAAA,MAAM,QAAA,GAAW,KAAK,cAAA,EAAe;AACrC,IAAA,OAAO,QAAA,CAAS,UAAU,CAAA,IAAK,EAAC;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgB,OAAA,EAAsC;AACpD,IAAA,MAAM,aAAa,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,GAAI,OAAA,GAAU,GAAG,OAAO,CAAA,CAAA,CAAA;AAC/D,IAAA,MAAM,OAAA,GAAU,KAAK,qBAAA,EAAsB;AAC3C,IAAA,OAAO,OAAA,CAAQ,UAAU,CAAA,IAAK,IAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,OAAA,EAAuB;AAC5C,IAAA,MAAM,aAAa,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,GAAI,OAAA,GAAU,GAAG,OAAO,CAAA,CAAA,CAAA;AAE/D,IAAA,MAAM,KAAA,GAAQ,KAAK,cAAA,EAAe;AAClC,IAAA,OAAO,MAAM,UAAU,CAAA;AACvB,IAAA,IAAA,CAAK,OAAA,CAAQ,eAAe,KAAK,CAAA;AAEjC,IAAA,MAAM,IAAA,GAAO,KAAK,qBAAA,EAAsB;AACxC,IAAA,OAAO,KAAK,UAAU,CAAA;AACtB,IAAA,IAAA,CAAK,OAAA,CAAQ,sBAAsB,IAAI,CAAA;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,OAAA,CAAQ,cAAA,CAAe,EAAE,CAAA;AAC9B,IAAA,IAAA,CAAK,OAAA,CAAQ,qBAAA,CAAsB,EAAE,CAAA;AAAA,EACvC;AAAA,EAEQ,oBAAoB,KAAA,EAAyB;AACnD,IAAA,IAAI,EAAE,KAAA,YAAiB,KAAA,CAAA,EAAQ,OAAO,KAAA;AACtC,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,WAAA,EAAY;AACtC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,cAAc,CAAA,EAAG,OAAO,IAAA;AACzC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,IAAA;AAChC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,IAAA;AAChC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,IAAA;AAChC,IAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,IAAA,IAAI,KAAA,EAAO,IAAA,KAAS,WAAA,EAAa,OAAO,IAAA;AACxC,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"index.mjs","sourcesContent":["/**\n * Custom error classes for the Routstr SDK\n * Provides specific error types for different failure modes\n */\n\n/**\n * Error thrown when balance is insufficient for an operation\n */\nexport class InsufficientBalanceError extends Error {\n constructor(\n public required: number,\n public available: number,\n public maxMintBalance: number = 0,\n public maxMintUrl: string = \"\"\n ) {\n super(\n `Insufficient balance: need ${required} sats, have ${available} sats available. ` +\n (maxMintBalance > 0\n ? `Largest mint balance: ${maxMintBalance} sats from ${maxMintUrl}`\n : \"\")\n );\n this.name = \"InsufficientBalanceError\";\n }\n}\n\n/**\n * Error thrown when a provider returns an error response\n */\nexport class ProviderError extends Error {\n constructor(\n public baseUrl: string,\n public statusCode: number,\n message: string,\n public requestId?: string\n ) {\n super(\n `Provider ${baseUrl} returned ${statusCode}: ${message}` +\n (requestId ? ` (Request ID: ${requestId})` : \"\")\n );\n this.name = \"ProviderError\";\n }\n}\n\n/**\n * Error thrown when a mint is unreachable\n */\nexport class MintUnreachableError extends Error {\n constructor(public mintUrl: string) {\n super(\n `Your mint ${mintUrl} is unreachable or is blocking your IP. Please try again later or switch mints.`\n );\n this.name = \"MintUnreachableError\";\n }\n}\n\n/**\n * Error thrown when a token operation fails\n */\nexport class TokenOperationError extends Error {\n constructor(\n message: string,\n public operation: \"send\" | \"receive\" | \"refund\",\n public mintUrl?: string\n ) {\n super(message);\n this.name = \"TokenOperationError\";\n }\n}\n\n/**\n * Error thrown when provider failover fails\n */\nexport class FailoverError extends Error {\n constructor(\n public originalProvider: string,\n public failedProviders: string[],\n message?: string\n ) {\n super(\n message ||\n `All providers failed. Original: ${originalProvider}, Failed: ${failedProviders.join(\", \")}`\n );\n this.name = \"FailoverError\";\n }\n}\n\n/**\n * Error thrown when streaming response processing fails\n */\nexport class StreamingError extends Error {\n constructor(\n message: string,\n public finishReason?: string,\n public accumulatedContent?: string\n ) {\n super(message);\n this.name = \"StreamingError\";\n }\n}\n\n/**\n * Error thrown when model is not found on a provider\n */\nexport class ModelNotFoundError extends Error {\n constructor(public modelId: string, public baseUrl: string) {\n super(`Model '${modelId}' not found on provider ${baseUrl}`);\n this.name = \"ModelNotFoundError\";\n }\n}\n\n/**\n * Error thrown when provider bootstrap fails\n */\nexport class ProviderBootstrapError extends Error {\n constructor(\n public failedProviders: string[],\n message?: string\n ) {\n super(\n message || `Failed to bootstrap providers. Tried: ${failedProviders.join(\", \")}`\n );\n this.name = \"ProviderBootstrapError\";\n }\n}\n\n/**\n * Error thrown when no providers are available\n */\nexport class NoProvidersAvailableError extends Error {\n constructor() {\n super(\"No providers are available for model discovery\");\n this.name = \"NoProvidersAvailableError\";\n }\n}\n\n/**\n * Error thrown when mint discovery fails\n */\nexport class MintDiscoveryError extends Error {\n constructor(\n public baseUrl: string,\n message?: string\n ) {\n super(message || `Failed to discover mints from provider ${baseUrl}`);\n this.name = \"MintDiscoveryError\";\n }\n}\n","/**\n * ModelManager class for discovering, fetching, and managing models from providers\n * Core responsibility: fetching models from providers, caching them, and selecting the best option\n * (lowest cost) across multiple providers\n */\n\nimport type { Model } from \"../core/types\";\nimport type { DiscoveryAdapter, ProviderInfo } from \"./interfaces\";\nimport {\n NoProvidersAvailableError,\n ProviderBootstrapError,\n} from \"../core/errors\";\nimport { onlyEvents, RelayPool } from \"applesauce-relay\";\nimport { EventStore } from \"applesauce-core\";\nimport { tap } from \"rxjs\";\n\n/**\n * Configuration for ModelManager\n */\nexport interface ModelManagerConfig {\n /** URL to fetch provider directory from */\n providerDirectoryUrl?: string;\n /** Additional provider base URLs to include */\n includeProviderUrls?: string[];\n /** Provider base URLs to exclude */\n excludeProviderUrls?: string[];\n /** Cache TTL in milliseconds (default: 21 minutes) */\n cacheTTL?: number;\n}\n\n/**\n * ModelManager handles all model discovery and caching logic\n * Abstracts away storage details via DiscoveryAdapter\n */\nexport class ModelManager {\n private readonly cacheTTL: number;\n private readonly providerDirectoryUrl: string;\n private readonly includeProviderUrls: string[];\n private readonly excludeProviderUrls: string[];\n\n constructor(\n private adapter: DiscoveryAdapter,\n config: ModelManagerConfig = {}\n ) {\n this.providerDirectoryUrl =\n config.providerDirectoryUrl || \"https://api.routstr.com/v1/providers/\";\n this.cacheTTL = config.cacheTTL || 210 * 60 * 1000; // 21 minutes\n this.includeProviderUrls = config.includeProviderUrls || [];\n this.excludeProviderUrls = config.excludeProviderUrls || [];\n }\n\n /**\n * Get the list of bootstrapped provider base URLs\n * @returns Array of provider base URLs\n */\n getBaseUrls(): string[] {\n return this.adapter.getBaseUrlsList();\n }\n\n static async init(\n adapter: DiscoveryAdapter,\n config: ModelManagerConfig = {},\n options: { torMode?: boolean; forceRefresh?: boolean } = {}\n ): Promise<ModelManager> {\n const manager = new ModelManager(adapter, config);\n const torMode = options.torMode ?? false;\n const forceRefresh = options.forceRefresh ?? false;\n const providers = await manager.bootstrapProviders(torMode);\n await manager.fetchModels(providers, forceRefresh);\n return manager;\n }\n\n /**\n * Bootstrap provider list from the provider directory\n * First tries to fetch from Nostr (kind 30421), falls back to HTTP\n * @param torMode Whether running in Tor context\n * @returns Array of provider base URLs\n * @throws ProviderBootstrapError if all providers fail to fetch\n */\n async bootstrapProviders(torMode: boolean = false): Promise<string[]> {\n // First try cache\n const cachedUrls = this.adapter.getBaseUrlsList();\n if (cachedUrls.length > 0) {\n const lastUpdate = this.adapter.getBaseUrlsLastUpdate();\n const cacheValid = lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;\n if (cacheValid) {\n await this.fetchRoutstr21Models();\n return this.filterBaseUrlsForTor(cachedUrls, torMode);\n }\n }\n\n // Try Nostr first (kind 38421)\n try {\n const nostrProviders = await this.bootstrapFromNostr(38421, torMode);\n if (nostrProviders.length > 0) {\n const filtered = this.filterBaseUrlsForTor(nostrProviders, torMode);\n this.adapter.setBaseUrlsList(filtered);\n this.adapter.setBaseUrlsLastUpdate(Date.now());\n await this.fetchRoutstr21Models();\n return filtered;\n }\n } catch (e) {\n console.warn(\"Nostr bootstrap failed, falling back to HTTP:\", e);\n }\n\n // Fall back to HTTP\n return this.bootstrapFromHttp(torMode);\n }\n\n /**\n * Bootstrap providers from Nostr network (kind 30421)\n * @param kind The Nostr kind to fetch\n * @param torMode Whether running in Tor context\n * @returns Array of provider base URLs\n */\n private async bootstrapFromNostr(\n kind: number,\n torMode: boolean\n ): Promise<string[]> {\n const DEFAULT_RELAYS = [\n \"wss://relay.primal.net\",\n \"wss://nos.lol\",\n \"wss://relay.routstr.com\",\n ];\n\n const pool = new RelayPool();\n const localEventStore = new EventStore();\n\n const timeoutMs = 5000;\n\n await new Promise<void>((resolve) => {\n pool\n .req(DEFAULT_RELAYS, {\n kinds: [kind],\n limit: 100,\n })\n .pipe(\n onlyEvents(),\n tap((event) => {\n localEventStore.add(event);\n })\n )\n .subscribe({\n complete: () => {\n resolve();\n },\n });\n\n setTimeout(() => {\n resolve();\n }, timeoutMs);\n });\n\n const timeline = localEventStore.getTimeline({ kinds: [kind] });\n\n const bases = new Set<string>();\n\n for (const event of timeline) {\n const eventUrls: string[] = [];\n\n for (const tag of event.tags) {\n if (tag[0] === \"u\" && typeof tag[1] === \"string\") {\n eventUrls.push(tag[1]);\n }\n }\n\n if (eventUrls.length > 0) {\n for (const url of eventUrls) {\n const normalized = this.normalizeUrl(url);\n if (!torMode || normalized.includes(\".onion\")) {\n bases.add(normalized);\n }\n }\n continue;\n }\n\n try {\n const content = JSON.parse(event.content);\n const providers = Array.isArray(content)\n ? content\n : content.providers || [];\n\n for (const p of providers) {\n const endpoints = this.getProviderEndpoints(p, torMode);\n for (const endpoint of endpoints) {\n bases.add(endpoint);\n }\n }\n } catch {\n try {\n const providers = JSON.parse(event.content);\n if (Array.isArray(providers)) {\n for (const p of providers) {\n const endpoints = this.getProviderEndpoints(p, torMode);\n for (const endpoint of endpoints) {\n bases.add(endpoint);\n }\n }\n }\n } catch {\n console.warn(\n \"[NostrBootstrap] Failed to parse Nostr event content:\",\n event.id\n );\n }\n }\n }\n\n // Add additional configured providers\n for (const url of this.includeProviderUrls) {\n const normalized = this.normalizeUrl(url);\n if (!torMode || normalized.includes(\".onion\")) {\n bases.add(normalized);\n }\n }\n\n const excluded = new Set(\n this.excludeProviderUrls.map((url) => this.normalizeUrl(url))\n );\n\n const result = Array.from(bases).filter((base) => !excluded.has(base));\n\n return result;\n }\n\n /**\n * Bootstrap providers from HTTP endpoint\n * @param torMode Whether running in Tor context\n * @returns Array of provider base URLs\n */\n private async bootstrapFromHttp(torMode: boolean): Promise<string[]> {\n try {\n const res = await fetch(this.providerDirectoryUrl);\n if (!res.ok) {\n throw new Error(`Failed to fetch providers: ${res.status}`);\n }\n\n const data = await res.json();\n const providers = Array.isArray(data?.providers) ? data.providers : [];\n\n const bases = new Set<string>();\n for (const p of providers) {\n const endpoints = this.getProviderEndpoints(p, torMode);\n for (const endpoint of endpoints) {\n bases.add(endpoint);\n }\n }\n\n for (const url of this.includeProviderUrls) {\n const normalized = this.normalizeUrl(url);\n if (!torMode || normalized.includes(\".onion\")) {\n bases.add(normalized);\n }\n }\n\n const excluded = new Set(\n this.excludeProviderUrls.map((url) => this.normalizeUrl(url))\n );\n\n const list = Array.from(bases).filter((base) => !excluded.has(base));\n\n if (list.length > 0) {\n this.adapter.setBaseUrlsList(list);\n this.adapter.setBaseUrlsLastUpdate(Date.now());\n await this.fetchRoutstr21Models();\n }\n\n return list;\n } catch (e) {\n console.error(\"Failed to bootstrap providers\", e);\n throw new ProviderBootstrapError([], `Provider bootstrap failed: ${e}`);\n }\n }\n\n /**\n * Fetch models from all providers and select best-priced options\n * Uses cache if available and not expired\n * @param baseUrls List of provider base URLs to fetch from\n * @param forceRefresh Ignore cache and fetch fresh data\n * @returns Array of unique models with best prices selected\n */\n async fetchModels(\n baseUrls: string[],\n forceRefresh: boolean = false\n ): Promise<Model[]> {\n if (baseUrls.length === 0) {\n throw new NoProvidersAvailableError();\n }\n\n const bestById = new Map<string, { model: Model; base: string }>();\n const modelsFromAllProviders: Record<string, Model[]> = {};\n const disabledProviders = this.adapter.getDisabledProviders();\n\n // Helper to estimate minimum cost for a model\n const estimateMinCost = (m: Model): number => {\n return m?.sats_pricing?.completion ?? 0;\n };\n\n // Fetch from all providers in parallel\n const fetchPromises = baseUrls.map(async (url) => {\n const base = url.endsWith(\"/\") ? url : `${url}/`;\n try {\n // Check cache if not forcing refresh\n let list: Model[];\n\n if (!forceRefresh) {\n const lastUpdate = this.adapter.getProviderLastUpdate(base);\n const cacheValid =\n lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;\n\n if (cacheValid) {\n const cachedModels = this.adapter.getCachedModels();\n const cachedList = cachedModels[base] || [];\n list = cachedList;\n } else {\n // Cache expired or doesn't exist, fetch fresh\n list = await this.fetchModelsFromProvider(base);\n }\n } else {\n // Force refresh\n list = await this.fetchModelsFromProvider(base);\n }\n\n modelsFromAllProviders[base] = list;\n this.adapter.setProviderLastUpdate(base, Date.now());\n\n // Update best-priced models if provider not disabled\n if (!disabledProviders.includes(base)) {\n for (const m of list) {\n const existing = bestById.get(m.id);\n\n // Skip models without sats pricing\n if (!m.sats_pricing) continue;\n\n if (!existing) {\n bestById.set(m.id, { model: m, base });\n continue;\n }\n\n // Replace if this provider has lower cost\n const currentCost = estimateMinCost(m);\n const existingCost = estimateMinCost(existing.model);\n if (currentCost < existingCost && m.sats_pricing) {\n bestById.set(m.id, { model: m, base });\n }\n }\n }\n\n return { success: true, base, list };\n } catch (error) {\n if (this.isProviderDownError(error)) {\n console.warn(`Provider ${base} is down right now.`);\n } else {\n console.warn(`Failed to fetch models from ${base}:`, error);\n }\n this.adapter.setProviderLastUpdate(base, Date.now());\n return { success: false, base };\n }\n });\n\n // Wait for all to complete\n await Promise.allSettled(fetchPromises);\n\n // Cache all provider results\n const existingCache = this.adapter.getCachedModels();\n this.adapter.setCachedModels({\n ...existingCache,\n ...modelsFromAllProviders,\n });\n\n // Return combined models array\n return Array.from(bestById.values()).map((v) => v.model);\n }\n\n /**\n * Fetch models from a single provider\n * @param baseUrl Provider base URL\n * @returns Array of models from provider\n */\n private async fetchModelsFromProvider(baseUrl: string): Promise<Model[]> {\n const res = await fetch(`${baseUrl}v1/models`);\n if (!res.ok) {\n throw new Error(`Failed to fetch models: ${res.status}`);\n }\n\n const json = await res.json();\n const list = Array.isArray(json?.data)\n ? json.data.map((m: Model) => ({\n ...m,\n id: m.id.split(\"/\").pop() || m.id,\n }))\n : [];\n\n return list;\n }\n\n private isProviderDownError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n if (msg.includes(\"fetch failed\")) return true;\n if (msg.includes(\"502\")) return true;\n if (msg.includes(\"503\")) return true;\n if (msg.includes(\"504\")) return true;\n const cause = error.cause as { code?: string } | undefined;\n return cause?.code === \"ENOTFOUND\";\n }\n\n /**\n * Get all cached models from all providers\n * @returns Record mapping baseUrl -> models\n */\n getAllCachedModels(): Record<string, Model[]> {\n return this.adapter.getCachedModels();\n }\n\n /**\n * Clear cache for a specific provider\n * @param baseUrl Provider base URL\n */\n clearProviderCache(baseUrl: string): void {\n const base = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const cached = this.adapter.getCachedModels();\n delete cached[base];\n this.adapter.setCachedModels(cached);\n this.adapter.setProviderLastUpdate(base, 0);\n }\n\n /**\n * Clear all model caches\n */\n clearAllCache(): void {\n this.adapter.setCachedModels({});\n }\n\n /**\n * Filter base URLs based on Tor context\n * @param baseUrls Provider URLs to filter\n * @param torMode Whether in Tor context\n * @returns Filtered URLs appropriate for Tor mode\n */\n filterBaseUrlsForTor(baseUrls: string[], torMode: boolean): string[] {\n if (!torMode) {\n // In normal mode, exclude onion URLs\n return baseUrls.filter((url) => !url.includes(\".onion\"));\n }\n // In Tor mode, only include onion URLs\n return baseUrls.filter((url) => url.includes(\".onion\"));\n }\n\n /**\n * Get provider endpoints from provider info\n * @param provider Provider object from directory\n * @param torMode Whether in Tor context\n * @returns Array of endpoint URLs\n */\n private getProviderEndpoints(provider: any, torMode: boolean): string[] {\n const endpoints: string[] = [];\n\n if (torMode && provider.onion_url) {\n endpoints.push(this.normalizeUrl(provider.onion_url));\n } else if (provider.endpoint_url) {\n endpoints.push(this.normalizeUrl(provider.endpoint_url));\n }\n\n return endpoints;\n }\n\n /**\n * Normalize provider URL with trailing slash\n * @param url URL to normalize\n * @returns Normalized URL\n */\n private normalizeUrl(url: string): string {\n if (!url.startsWith(\"http\")) {\n url = `https://${url}`;\n }\n return url.endsWith(\"/\") ? url : `${url}/`;\n }\n\n /**\n * Fetch routstr21 models from Nostr network (kind 38423)\n * Uses cache if available and not expired\n * @returns Array of model IDs or empty array if not found\n */\n async fetchRoutstr21Models(forceRefresh: boolean = false): Promise<string[]> {\n // Check cache first\n const cachedModels = this.adapter.getRoutstr21Models();\n if (!forceRefresh && cachedModels.length > 0) {\n const lastUpdate = this.adapter.getRoutstr21ModelsLastUpdate();\n const cacheValid = lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;\n if (cacheValid) {\n return cachedModels;\n }\n }\n\n const DEFAULT_RELAYS = [\n \"wss://relay.primal.net\",\n \"wss://nos.lol\",\n \"wss://relay.routstr.com\",\n ];\n\n const pool = new RelayPool();\n const localEventStore = new EventStore();\n\n const timeoutMs = 5000;\n\n await new Promise<void>((resolve) => {\n pool\n .req(DEFAULT_RELAYS, {\n kinds: [38423],\n \"#d\": [\"routstr-21-models\"],\n limit: 1,\n authors: [\n \"4ad6fa2d16e2a9b576c863b4cf7404a70d4dc320c0c447d10ad6ff58993eacc8\",\n ],\n })\n .pipe(\n onlyEvents(),\n tap((event) => {\n localEventStore.add(event);\n })\n )\n .subscribe({\n complete: () => {\n resolve();\n },\n });\n\n setTimeout(() => {\n resolve();\n }, timeoutMs);\n });\n\n const timeline = localEventStore.getTimeline({ kinds: [38423] });\n\n if (timeline.length === 0) {\n return cachedModels.length > 0 ? cachedModels : [];\n }\n\n const event = timeline[0];\n\n try {\n const content = JSON.parse(event.content);\n const models = Array.isArray(content?.models) ? content.models : [];\n this.adapter.setRoutstr21Models(models);\n this.adapter.setRoutstr21ModelsLastUpdate(Date.now());\n return models;\n } catch {\n console.warn(\n \"[Routstr21Models] Failed to parse Nostr event content:\",\n event.id\n );\n return cachedModels.length > 0 ? cachedModels : [];\n }\n }\n}\n","/**\n * MintDiscovery class for discovering mints and provider info\n * Core responsibility: fetching mint information from providers and caching it\n */\n\nimport type { DiscoveryAdapter, ProviderInfo } from \"./interfaces\";\n\n/**\n * Configuration for MintDiscovery\n */\nexport interface MintDiscoveryConfig {\n /** Cache TTL in milliseconds (default: 21 minutes) */\n cacheTTL?: number;\n}\n\n/**\n * MintDiscovery handles mint and provider info discovery\n * Abstracts away storage details via DiscoveryAdapter\n */\nexport class MintDiscovery {\n private readonly cacheTTL: number;\n\n constructor(\n private adapter: DiscoveryAdapter,\n config: MintDiscoveryConfig = {}\n ) {\n this.cacheTTL = config.cacheTTL || 21 * 60 * 1000; // 21 minutes\n }\n\n /**\n * Fetch mints from all providers via their /v1/info endpoints\n * Caches mints and full provider info for later access\n * @param baseUrls List of provider base URLs to fetch from\n * @returns Object with mints and provider info from all providers\n */\n async discoverMints(\n baseUrls: string[],\n options: { forceRefresh?: boolean } = {}\n ): Promise<{\n mintsFromProviders: Record<string, string[]>;\n infoFromProviders: Record<string, ProviderInfo>;\n }> {\n if (baseUrls.length === 0) {\n return { mintsFromProviders: {}, infoFromProviders: {} };\n }\n\n const mintsFromAllProviders: Record<string, string[]> = {};\n const infoFromAllProviders: Record<string, ProviderInfo> = {};\n const forceRefresh = options.forceRefresh ?? false;\n\n // Fetch info from each provider\n const fetchPromises = baseUrls.map(async (url) => {\n const base = url.endsWith(\"/\") ? url : `${url}/`;\n try {\n if (!forceRefresh) {\n const lastUpdate = this.adapter.getProviderLastUpdate(base);\n const cacheValid =\n lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;\n if (cacheValid) {\n const cachedMints = this.adapter.getCachedMints()[base] || [];\n const cachedInfo = this.adapter.getCachedProviderInfo()[base];\n mintsFromAllProviders[base] = cachedMints;\n if (cachedInfo) {\n infoFromAllProviders[base] = cachedInfo;\n }\n return {\n success: true,\n base,\n mints: cachedMints,\n info: cachedInfo,\n };\n }\n }\n\n const res = await fetch(`${base}v1/info`);\n if (!res.ok) {\n throw new Error(`Failed to fetch info: ${res.status}`);\n }\n\n const json = await res.json();\n\n // Extract mints array from response\n const mints: string[] = Array.isArray(json?.mints) ? json.mints : [];\n\n // Normalize mint URLs (remove trailing slashes for consistency)\n const normalizedMints = mints.map((mint) =>\n mint.endsWith(\"/\") ? mint.slice(0, -1) : mint\n );\n\n // Save provider mints and full info\n mintsFromAllProviders[base] = normalizedMints;\n infoFromAllProviders[base] = json;\n this.adapter.setProviderLastUpdate(base, Date.now());\n\n return { success: true, base, mints: normalizedMints, info: json };\n } catch (error) {\n this.adapter.setProviderLastUpdate(base, Date.now());\n if (this.isProviderDownError(error)) {\n console.warn(`Provider ${base} is down right now.`);\n } else {\n console.warn(`Failed to fetch mints from ${base}:`, error);\n }\n return { success: false, base, mints: [], info: null };\n }\n });\n\n // Wait for all to complete (but allow individual failures)\n const results = await Promise.allSettled(fetchPromises);\n\n // Handle results\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n const { base, mints, info } = result.value;\n mintsFromAllProviders[base] = mints;\n if (info) {\n infoFromAllProviders[base] = info;\n }\n } else {\n // Log but don't throw - continue with partial results\n console.error(\"Mint discovery error:\", result.reason);\n }\n }\n\n // Cache all results\n try {\n this.adapter.setCachedMints(mintsFromAllProviders);\n this.adapter.setCachedProviderInfo(infoFromAllProviders);\n } catch (error) {\n console.error(\"Error caching mint discovery results:\", error);\n }\n\n return {\n mintsFromProviders: mintsFromAllProviders,\n infoFromProviders: infoFromAllProviders,\n };\n }\n\n /**\n * Get cached mints from all providers\n * @returns Record mapping baseUrl -> mint URLs\n */\n getCachedMints(): Record<string, string[]> {\n return this.adapter.getCachedMints();\n }\n\n /**\n * Get cached provider info from all providers\n * @returns Record mapping baseUrl -> provider info\n */\n getCachedProviderInfo(): Record<string, ProviderInfo> {\n return this.adapter.getCachedProviderInfo();\n }\n\n /**\n * Get mints for a specific provider\n * @param baseUrl Provider base URL\n * @returns Array of mint URLs for the provider\n */\n getProviderMints(baseUrl: string): string[] {\n const normalized = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const allMints = this.getCachedMints();\n return allMints[normalized] || [];\n }\n\n /**\n * Get info for a specific provider\n * @param baseUrl Provider base URL\n * @returns Provider info object or null if not found\n */\n getProviderInfo(baseUrl: string): ProviderInfo | null {\n const normalized = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const allInfo = this.getCachedProviderInfo();\n return allInfo[normalized] || null;\n }\n\n /**\n * Clear mint cache for a specific provider\n * @param baseUrl Provider base URL\n */\n clearProviderMintCache(baseUrl: string): void {\n const normalized = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\n const mints = this.getCachedMints();\n delete mints[normalized];\n this.adapter.setCachedMints(mints);\n\n const info = this.getCachedProviderInfo();\n delete info[normalized];\n this.adapter.setCachedProviderInfo(info);\n }\n\n /**\n * Clear all mint caches\n */\n clearAllCache(): void {\n this.adapter.setCachedMints({});\n this.adapter.setCachedProviderInfo({});\n }\n\n private isProviderDownError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n if (msg.includes(\"fetch failed\")) return true;\n if (msg.includes(\"502\")) return true;\n if (msg.includes(\"503\")) return true;\n if (msg.includes(\"504\")) return true;\n const cause = error.cause as { code?: string } | undefined;\n if (cause?.code === \"ENOTFOUND\") return true;\n return false;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../core/errors.ts","../../discovery/ModelManager.ts","../../discovery/MintDiscovery.ts"],"names":["event"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Custom error classes for the Routstr SDK\n * Provides specific error types for different failure modes\n */\n\n/**\n * Error thrown when balance is insufficient for an operation\n */\nexport class InsufficientBalanceError extends Error {\n constructor(\n public required: number,\n public available: number,\n public maxMintBalance: number = 0,\n public maxMintUrl: string = \"\"\n ) {\n super(\n `Insufficient balance: need ${required} sats, have ${available} sats available. ` +\n (maxMintBalance > 0\n ? `Largest mint balance: ${maxMintBalance} sats from ${maxMintUrl}`\n : \"\")\n );\n this.name = \"InsufficientBalanceError\";\n }\n}\n\n/**\n * Error thrown when a provider returns an error response\n */\nexport class ProviderError extends Error {\n constructor(\n public baseUrl: string,\n public statusCode: number,\n message: string,\n public requestId?: string\n ) {\n super(\n `Provider ${baseUrl} returned ${statusCode}: ${message}` +\n (requestId ? ` (Request ID: ${requestId})` : \"\")\n );\n this.name = \"ProviderError\";\n }\n}\n\n/**\n * Error thrown when a mint is unreachable\n */\nexport class MintUnreachableError extends Error {\n constructor(public mintUrl: string) {\n super(\n `Your mint ${mintUrl} is unreachable or is blocking your IP. Please try again later or switch mints.`\n );\n this.name = \"MintUnreachableError\";\n }\n}\n\n/**\n * Error thrown when a token operation fails\n */\nexport class TokenOperationError extends Error {\n constructor(\n message: string,\n public operation: \"send\" | \"receive\" | \"refund\",\n public mintUrl?: string\n ) {\n super(message);\n this.name = \"TokenOperationError\";\n }\n}\n\n/**\n * Error thrown when provider failover fails\n */\nexport class FailoverError extends Error {\n constructor(\n public originalProvider: string,\n public failedProviders: string[],\n message?: string\n ) {\n super(\n message ||\n `All providers failed. Original: ${originalProvider}, Failed: ${failedProviders.join(\", \")}`\n );\n this.name = \"FailoverError\";\n }\n}\n\n/**\n * Error thrown when streaming response processing fails\n */\nexport class StreamingError extends Error {\n constructor(\n message: string,\n public finishReason?: string,\n public accumulatedContent?: string\n ) {\n super(message);\n this.name = \"StreamingError\";\n }\n}\n\n/**\n * Error thrown when model is not found on a provider\n */\nexport class ModelNotFoundError extends Error {\n constructor(public modelId: string, public baseUrl: string) {\n super(`Model '${modelId}' not found on provider ${baseUrl}`);\n this.name = \"ModelNotFoundError\";\n }\n}\n\n/**\n * Error thrown when provider bootstrap fails\n */\nexport class ProviderBootstrapError extends Error {\n constructor(\n public failedProviders: string[],\n message?: string\n ) {\n super(\n message || `Failed to bootstrap providers. Tried: ${failedProviders.join(\", \")}`\n );\n this.name = \"ProviderBootstrapError\";\n }\n}\n\n/**\n * Error thrown when no providers are available\n */\nexport class NoProvidersAvailableError extends Error {\n constructor() {\n super(\"No providers are available for model discovery\");\n this.name = \"NoProvidersAvailableError\";\n }\n}\n\n/**\n * Error thrown when mint discovery fails\n */\nexport class MintDiscoveryError extends Error {\n constructor(\n public baseUrl: string,\n message?: string\n ) {\n super(message || `Failed to discover mints from provider ${baseUrl}`);\n this.name = \"MintDiscoveryError\";\n }\n}\n","/**\n * ModelManager class for discovering, fetching, and managing models from providers\n * Core responsibility: fetching models from providers, caching them, and selecting the best option\n * (lowest cost) across multiple providers\n */\n\nimport type { Model } from \"../core/types\";\nimport type { DiscoveryAdapter, ProviderInfo } from \"./interfaces\";\nimport {\n NoProvidersAvailableError,\n ProviderBootstrapError,\n} from \"../core/errors\";\nimport { onlyEvents, RelayPool } from \"applesauce-relay\";\nimport { EventStore } from \"applesauce-core\";\nimport { tap } from \"rxjs\";\n\n/**\n * Configuration for ModelManager\n */\nexport interface ModelManagerConfig {\n /** URL to fetch provider directory from */\n providerDirectoryUrl?: string;\n /** Additional provider base URLs to include */\n includeProviderUrls?: string[];\n /** Provider base URLs to exclude */\n excludeProviderUrls?: string[];\n /** Cache TTL in milliseconds (default: 21 minutes) */\n cacheTTL?: number;\n}\n\n/**\n * ModelManager handles all model discovery and caching logic\n * Abstracts away storage details via DiscoveryAdapter\n */\nexport class ModelManager {\n private readonly cacheTTL: number;\n private readonly providerDirectoryUrl: string;\n private readonly includeProviderUrls: string[];\n private readonly excludeProviderUrls: string[];\n\n constructor(\n private adapter: DiscoveryAdapter,\n config: ModelManagerConfig = {}\n ) {\n this.providerDirectoryUrl =\n config.providerDirectoryUrl || \"https://api.routstr.com/v1/providers/\";\n this.cacheTTL = config.cacheTTL || 210 * 60 * 1000; // 21 minutes\n this.includeProviderUrls = config.includeProviderUrls || [];\n this.excludeProviderUrls = config.excludeProviderUrls || [];\n }\n\n /**\n * Get the list of bootstrapped provider base URLs\n * @returns Array of provider base URLs\n */\n getBaseUrls(): string[] {\n return this.adapter.getBaseUrlsList();\n }\n\n static async init(\n adapter: DiscoveryAdapter,\n config: ModelManagerConfig = {},\n options: { torMode?: boolean; forceRefresh?: boolean } = {}\n ): Promise<ModelManager> {\n const manager = new ModelManager(adapter, config);\n const torMode = options.torMode ?? false;\n const forceRefresh = options.forceRefresh ?? false;\n const providers = await manager.bootstrapProviders(torMode, forceRefresh);\n await manager.fetchModels(providers, forceRefresh);\n return manager;\n }\n\n /**\n * Bootstrap provider list from the provider directory\n * First tries to fetch from Nostr (kind 30421), falls back to HTTP\n * @param torMode Whether running in Tor context\n * @param forceRefresh Ignore provider cache and refresh provider sources\n * @returns Array of provider base URLs\n * @throws ProviderBootstrapError if all providers fail to fetch\n */\n async bootstrapProviders(\n torMode: boolean = false,\n forceRefresh: boolean = false\n ): Promise<string[]> {\n // First try cache\n if (!forceRefresh) {\n const cachedUrls = this.adapter.getBaseUrlsList();\n if (cachedUrls.length > 0) {\n const lastUpdate = this.adapter.getBaseUrlsLastUpdate();\n const cacheValid =\n lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;\n if (cacheValid) {\n await this.fetchRoutstr21Models(forceRefresh);\n return this.filterBaseUrlsForTor(cachedUrls, torMode);\n }\n }\n }\n\n // Try Nostr first (kind 38421)\n try {\n const nostrProviders = await this.bootstrapFromNostr(38421, torMode);\n if (nostrProviders.length > 0) {\n const filtered = this.filterBaseUrlsForTor(nostrProviders, torMode);\n this.adapter.setBaseUrlsList(filtered);\n this.adapter.setBaseUrlsLastUpdate(Date.now());\n await this.fetchRoutstr21Models(forceRefresh);\n return filtered;\n }\n } catch (e) {\n console.warn(\"Nostr bootstrap failed, falling back to HTTP:\", e);\n }\n\n // Fall back to HTTP\n return this.bootstrapFromHttp(torMode, forceRefresh);\n }\n\n /**\n * Bootstrap providers from Nostr network (kind 30421)\n * @param kind The Nostr kind to fetch\n * @param torMode Whether running in Tor context\n * @returns Array of provider base URLs\n */\n private async bootstrapFromNostr(\n kind: number,\n torMode: boolean\n ): Promise<string[]> {\n const DEFAULT_RELAYS = [\n \"wss://relay.primal.net\",\n \"wss://nos.lol\",\n \"wss://relay.routstr.com\",\n ];\n\n const pool = new RelayPool();\n const localEventStore = new EventStore();\n\n const timeoutMs = 5000;\n\n await new Promise<void>((resolve) => {\n pool\n .req(DEFAULT_RELAYS, {\n kinds: [kind],\n limit: 100,\n })\n .pipe(\n onlyEvents(),\n tap((event) => {\n localEventStore.add(event);\n })\n )\n .subscribe({\n complete: () => {\n resolve();\n },\n });\n\n setTimeout(() => {\n resolve();\n }, timeoutMs);\n });\n\n const timeline = localEventStore.getTimeline({ kinds: [kind] });\n\n const bases = new Set<string>();\n\n for (const event of timeline) {\n const eventUrls: string[] = [];\n\n for (const tag of event.tags) {\n if (tag[0] === \"u\" && typeof tag[1] === \"string\") {\n eventUrls.push(tag[1]);\n }\n }\n\n if (eventUrls.length > 0) {\n for (const url of eventUrls) {\n const normalized = this.normalizeUrl(url);\n if (!torMode || normalized.includes(\".onion\")) {\n bases.add(normalized);\n }\n }\n continue;\n }\n\n try {\n const content = JSON.parse(event.content);\n const providers = Array.isArray(content)\n ? content\n : content.providers || [];\n\n for (const p of providers) {\n const endpoints = this.getProviderEndpoints(p, torMode);\n for (const endpoint of endpoints) {\n bases.add(endpoint);\n }\n }\n } catch {\n try {\n const providers = JSON.parse(event.content);\n if (Array.isArray(providers)) {\n for (const p of providers) {\n const endpoints = this.getProviderEndpoints(p, torMode);\n for (const endpoint of endpoints) {\n bases.add(endpoint);\n }\n }\n }\n } catch {\n console.warn(\n \"[NostrBootstrap] Failed to parse Nostr event content:\",\n event.id\n );\n }\n }\n }\n\n // Add additional configured providers\n for (const url of this.includeProviderUrls) {\n const normalized = this.normalizeUrl(url);\n if (!torMode || normalized.includes(\".onion\")) {\n bases.add(normalized);\n }\n }\n\n const excluded = new Set(\n this.excludeProviderUrls.map((url) => this.normalizeUrl(url))\n );\n\n const result = Array.from(bases).filter((base) => !excluded.has(base));\n\n return result;\n }\n\n /**\n * Bootstrap providers from HTTP endpoint\n * @param torMode Whether running in Tor context\n * @param forceRefresh Ignore routstr21 cache and fetch fresh data\n * @returns Array of provider base URLs\n */\n private async bootstrapFromHttp(\n torMode: boolean,\n forceRefresh: boolean = false\n ): Promise<string[]> {\n try {\n const res = await fetch(this.providerDirectoryUrl);\n if (!res.ok) {\n throw new Error(`Failed to fetch providers: ${res.status}`);\n }\n\n const data = await res.json();\n const providers = Array.isArray(data?.providers) ? data.providers : [];\n\n const bases = new Set<string>();\n for (const p of providers) {\n const endpoints = this.getProviderEndpoints(p, torMode);\n for (const endpoint of endpoints) {\n bases.add(endpoint);\n }\n }\n\n for (const url of this.includeProviderUrls) {\n const normalized = this.normalizeUrl(url);\n if (!torMode || normalized.includes(\".onion\")) {\n bases.add(normalized);\n }\n }\n\n const excluded = new Set(\n this.excludeProviderUrls.map((url) => this.normalizeUrl(url))\n );\n\n const list = Array.from(bases).filter((base) => !excluded.has(base));\n\n if (list.length > 0) {\n this.adapter.setBaseUrlsList(list);\n this.adapter.setBaseUrlsLastUpdate(Date.now());\n await this.fetchRoutstr21Models(forceRefresh);\n }\n\n return list;\n } catch (e) {\n console.error(\"Failed to bootstrap providers\", e);\n throw new ProviderBootstrapError([], `Provider bootstrap failed: ${e}`);\n }\n }\n\n /**\n * Fetch models from all providers and select best-priced options\n * Uses cache if available and not expired\n * @param baseUrls List of provider base URLs to fetch from\n * @param forceRefresh Ignore cache and fetch fresh data\n * @returns Array of unique models with best prices selected\n */\n async fetchModels(\n baseUrls: string[],\n forceRefresh: boolean = false\n ): Promise<Model[]> {\n if (baseUrls.length === 0) {\n throw new NoProvidersAvailableError();\n }\n\n const bestById = new Map<string, { model: Model; base: string }>();\n const modelsFromAllProviders: Record<string, Model[]> = {};\n const disabledProviders = this.adapter.getDisabledProviders();\n\n // Helper to estimate minimum cost for a model\n const estimateMinCost = (m: Model): number => {\n return m?.sats_pricing?.completion ?? 0;\n };\n\n // Fetch from all providers in parallel\n const fetchPromises = baseUrls.map(async (url) => {\n const base = url.endsWith(\"/\") ? url : `${url}/`;\n try {\n // Check cache if not forcing refresh\n let list: Model[];\n\n if (!forceRefresh) {\n const lastUpdate = this.adapter.getProviderLastUpdate(base);\n const cacheValid =\n lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;\n\n if (cacheValid) {\n const cachedModels = this.adapter.getCachedModels();\n const cachedList = cachedModels[base] || [];\n list = cachedList;\n } else {\n // Cache expired or doesn't exist, fetch fresh\n list = await this.fetchModelsFromProvider(base);\n }\n } else {\n // Force refresh\n list = await this.fetchModelsFromProvider(base);\n }\n\n modelsFromAllProviders[base] = list;\n this.adapter.setProviderLastUpdate(base, Date.now());\n\n // Update best-priced models if provider not disabled\n if (!disabledProviders.includes(base)) {\n for (const m of list) {\n const existing = bestById.get(m.id);\n\n // Skip models without sats pricing\n if (!m.sats_pricing) continue;\n\n if (!existing) {\n bestById.set(m.id, { model: m, base });\n continue;\n }\n\n // Replace if this provider has lower cost\n const currentCost = estimateMinCost(m);\n const existingCost = estimateMinCost(existing.model);\n if (currentCost < existingCost && m.sats_pricing) {\n bestById.set(m.id, { model: m, base });\n }\n }\n }\n\n return { success: true, base, list };\n } catch (error) {\n if (this.isProviderDownError(error)) {\n console.warn(`Provider ${base} is down right now.`);\n } else {\n console.warn(`Failed to fetch models from ${base}:`, error);\n }\n this.adapter.setProviderLastUpdate(base, Date.now());\n return { success: false, base };\n }\n });\n\n // Wait for all to complete\n await Promise.allSettled(fetchPromises);\n\n // Cache all provider results\n const existingCache = this.adapter.getCachedModels();\n this.adapter.setCachedModels({\n ...existingCache,\n ...modelsFromAllProviders,\n });\n\n // Return combined models array\n return Array.from(bestById.values()).map((v) => v.model);\n }\n\n /**\n * Fetch models from a single provider\n * @param baseUrl Provider base URL\n * @returns Array of models from provider\n */\n private async fetchModelsFromProvider(baseUrl: string): Promise<Model[]> {\n const res = await fetch(`${baseUrl}v1/models`);\n if (!res.ok) {\n throw new Error(`Failed to fetch models: ${res.status}`);\n }\n\n const json = await res.json();\n const list = Array.isArray(json?.data)\n ? json.data.map((m: Model) => ({\n ...m,\n id: m.id.split(\"/\").pop() || m.id,\n }))\n : [];\n\n return list;\n }\n\n private isProviderDownError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n if (msg.includes(\"fetch failed\")) return true;\n if (msg.includes(\"502\")) return true;\n if (msg.includes(\"503\")) return true;\n if (msg.includes(\"504\")) return true;\n const cause = error.cause as { code?: string } | undefined;\n return cause?.code === \"ENOTFOUND\";\n }\n\n /**\n * Get all cached models from all providers\n * @returns Record mapping baseUrl -> models\n */\n getAllCachedModels(): Record<string, Model[]> {\n return this.adapter.getCachedModels();\n }\n\n /**\n * Clear cache for a specific provider\n * @param baseUrl Provider base URL\n */\n clearProviderCache(baseUrl: string): void {\n const base = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const cached = this.adapter.getCachedModels();\n delete cached[base];\n this.adapter.setCachedModels(cached);\n this.adapter.setProviderLastUpdate(base, 0);\n }\n\n /**\n * Clear all model caches\n */\n clearAllCache(): void {\n this.adapter.setCachedModels({});\n }\n\n /**\n * Filter base URLs based on Tor context\n * @param baseUrls Provider URLs to filter\n * @param torMode Whether in Tor context\n * @returns Filtered URLs appropriate for Tor mode\n */\n filterBaseUrlsForTor(baseUrls: string[], torMode: boolean): string[] {\n if (!torMode) {\n // In normal mode, exclude onion URLs\n return baseUrls.filter((url) => !url.includes(\".onion\"));\n }\n // In Tor mode, only include onion URLs\n return baseUrls.filter((url) => url.includes(\".onion\"));\n }\n\n /**\n * Get provider endpoints from provider info\n * @param provider Provider object from directory\n * @param torMode Whether in Tor context\n * @returns Array of endpoint URLs\n */\n private getProviderEndpoints(provider: any, torMode: boolean): string[] {\n const endpoints: string[] = [];\n\n if (torMode && provider.onion_url) {\n endpoints.push(this.normalizeUrl(provider.onion_url));\n } else if (provider.endpoint_url) {\n endpoints.push(this.normalizeUrl(provider.endpoint_url));\n }\n\n return endpoints;\n }\n\n /**\n * Normalize provider URL with trailing slash\n * @param url URL to normalize\n * @returns Normalized URL\n */\n private normalizeUrl(url: string): string {\n if (!url.startsWith(\"http\")) {\n url = `https://${url}`;\n }\n return url.endsWith(\"/\") ? url : `${url}/`;\n }\n\n /**\n * Fetch routstr21 models from Nostr network (kind 38423)\n * Uses cache if available and not expired\n * @returns Array of model IDs or empty array if not found\n */\n async fetchRoutstr21Models(forceRefresh: boolean = false): Promise<string[]> {\n // Check cache first\n const cachedModels = this.adapter.getRoutstr21Models();\n if (!forceRefresh && cachedModels.length > 0) {\n const lastUpdate = this.adapter.getRoutstr21ModelsLastUpdate();\n const cacheValid = lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;\n if (cacheValid) {\n return cachedModels;\n }\n }\n\n const DEFAULT_RELAYS = [\n \"wss://relay.primal.net\",\n \"wss://nos.lol\",\n \"wss://relay.routstr.com\",\n ];\n\n const pool = new RelayPool();\n const localEventStore = new EventStore();\n\n const timeoutMs = 5000;\n\n await new Promise<void>((resolve) => {\n pool\n .req(DEFAULT_RELAYS, {\n kinds: [38423],\n \"#d\": [\"routstr-21-models\"],\n limit: 1,\n authors: [\n \"4ad6fa2d16e2a9b576c863b4cf7404a70d4dc320c0c447d10ad6ff58993eacc8\",\n ],\n })\n .pipe(\n onlyEvents(),\n tap((event) => {\n localEventStore.add(event);\n })\n )\n .subscribe({\n complete: () => {\n resolve();\n },\n });\n\n setTimeout(() => {\n resolve();\n }, timeoutMs);\n });\n\n const timeline = localEventStore.getTimeline({ kinds: [38423] });\n\n if (timeline.length === 0) {\n return cachedModels.length > 0 ? cachedModels : [];\n }\n\n const event = timeline[0];\n\n try {\n const content = JSON.parse(event.content);\n const models = Array.isArray(content?.models) ? content.models : [];\n this.adapter.setRoutstr21Models(models);\n this.adapter.setRoutstr21ModelsLastUpdate(Date.now());\n return models;\n } catch {\n console.warn(\n \"[Routstr21Models] Failed to parse Nostr event content:\",\n event.id\n );\n return cachedModels.length > 0 ? cachedModels : [];\n }\n }\n}\n","/**\n * MintDiscovery class for discovering mints and provider info\n * Core responsibility: fetching mint information from providers and caching it\n */\n\nimport type { DiscoveryAdapter, ProviderInfo } from \"./interfaces\";\n\n/**\n * Configuration for MintDiscovery\n */\nexport interface MintDiscoveryConfig {\n /** Cache TTL in milliseconds (default: 21 minutes) */\n cacheTTL?: number;\n}\n\n/**\n * MintDiscovery handles mint and provider info discovery\n * Abstracts away storage details via DiscoveryAdapter\n */\nexport class MintDiscovery {\n private readonly cacheTTL: number;\n\n constructor(\n private adapter: DiscoveryAdapter,\n config: MintDiscoveryConfig = {}\n ) {\n this.cacheTTL = config.cacheTTL || 21 * 60 * 1000; // 21 minutes\n }\n\n /**\n * Fetch mints from all providers via their /v1/info endpoints\n * Caches mints and full provider info for later access\n * @param baseUrls List of provider base URLs to fetch from\n * @returns Object with mints and provider info from all providers\n */\n async discoverMints(\n baseUrls: string[],\n options: { forceRefresh?: boolean } = {}\n ): Promise<{\n mintsFromProviders: Record<string, string[]>;\n infoFromProviders: Record<string, ProviderInfo>;\n }> {\n if (baseUrls.length === 0) {\n return { mintsFromProviders: {}, infoFromProviders: {} };\n }\n\n const mintsFromAllProviders: Record<string, string[]> = {};\n const infoFromAllProviders: Record<string, ProviderInfo> = {};\n const forceRefresh = options.forceRefresh ?? false;\n\n // Fetch info from each provider\n const fetchPromises = baseUrls.map(async (url) => {\n const base = url.endsWith(\"/\") ? url : `${url}/`;\n try {\n if (!forceRefresh) {\n const lastUpdate = this.adapter.getProviderLastUpdate(base);\n const cacheValid =\n lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;\n if (cacheValid) {\n const cachedMints = this.adapter.getCachedMints()[base] || [];\n const cachedInfo = this.adapter.getCachedProviderInfo()[base];\n mintsFromAllProviders[base] = cachedMints;\n if (cachedInfo) {\n infoFromAllProviders[base] = cachedInfo;\n }\n return {\n success: true,\n base,\n mints: cachedMints,\n info: cachedInfo,\n };\n }\n }\n\n const res = await fetch(`${base}v1/info`);\n if (!res.ok) {\n throw new Error(`Failed to fetch info: ${res.status}`);\n }\n\n const json = await res.json();\n\n // Extract mints array from response\n const mints: string[] = Array.isArray(json?.mints) ? json.mints : [];\n\n // Normalize mint URLs (remove trailing slashes for consistency)\n const normalizedMints = mints.map((mint) =>\n mint.endsWith(\"/\") ? mint.slice(0, -1) : mint\n );\n\n // Save provider mints and full info\n mintsFromAllProviders[base] = normalizedMints;\n infoFromAllProviders[base] = json;\n this.adapter.setProviderLastUpdate(base, Date.now());\n\n return { success: true, base, mints: normalizedMints, info: json };\n } catch (error) {\n this.adapter.setProviderLastUpdate(base, Date.now());\n if (this.isProviderDownError(error)) {\n console.warn(`Provider ${base} is down right now.`);\n } else {\n console.warn(`Failed to fetch mints from ${base}:`, error);\n }\n return { success: false, base, mints: [], info: null };\n }\n });\n\n // Wait for all to complete (but allow individual failures)\n const results = await Promise.allSettled(fetchPromises);\n\n // Handle results\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n const { base, mints, info } = result.value;\n mintsFromAllProviders[base] = mints;\n if (info) {\n infoFromAllProviders[base] = info;\n }\n } else {\n // Log but don't throw - continue with partial results\n console.error(\"Mint discovery error:\", result.reason);\n }\n }\n\n // Cache all results\n try {\n this.adapter.setCachedMints(mintsFromAllProviders);\n this.adapter.setCachedProviderInfo(infoFromAllProviders);\n } catch (error) {\n console.error(\"Error caching mint discovery results:\", error);\n }\n\n return {\n mintsFromProviders: mintsFromAllProviders,\n infoFromProviders: infoFromAllProviders,\n };\n }\n\n /**\n * Get cached mints from all providers\n * @returns Record mapping baseUrl -> mint URLs\n */\n getCachedMints(): Record<string, string[]> {\n return this.adapter.getCachedMints();\n }\n\n /**\n * Get cached provider info from all providers\n * @returns Record mapping baseUrl -> provider info\n */\n getCachedProviderInfo(): Record<string, ProviderInfo> {\n return this.adapter.getCachedProviderInfo();\n }\n\n /**\n * Get mints for a specific provider\n * @param baseUrl Provider base URL\n * @returns Array of mint URLs for the provider\n */\n getProviderMints(baseUrl: string): string[] {\n const normalized = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const allMints = this.getCachedMints();\n return allMints[normalized] || [];\n }\n\n /**\n * Get info for a specific provider\n * @param baseUrl Provider base URL\n * @returns Provider info object or null if not found\n */\n getProviderInfo(baseUrl: string): ProviderInfo | null {\n const normalized = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const allInfo = this.getCachedProviderInfo();\n return allInfo[normalized] || null;\n }\n\n /**\n * Clear mint cache for a specific provider\n * @param baseUrl Provider base URL\n */\n clearProviderMintCache(baseUrl: string): void {\n const normalized = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\n const mints = this.getCachedMints();\n delete mints[normalized];\n this.adapter.setCachedMints(mints);\n\n const info = this.getCachedProviderInfo();\n delete info[normalized];\n this.adapter.setCachedProviderInfo(info);\n }\n\n /**\n * Clear all mint caches\n */\n clearAllCache(): void {\n this.adapter.setCachedMints({});\n this.adapter.setCachedProviderInfo({});\n }\n\n private isProviderDownError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n if (msg.includes(\"fetch failed\")) return true;\n if (msg.includes(\"502\")) return true;\n if (msg.includes(\"503\")) return true;\n if (msg.includes(\"504\")) return true;\n const cause = error.cause as { code?: string } | undefined;\n if (cause?.code === \"ENOTFOUND\") return true;\n return false;\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -125,7 +125,7 @@ var ModelManager = class _ModelManager {
125
125
  const manager = new _ModelManager(adapter, config);
126
126
  const torMode = options.torMode ?? false;
127
127
  const forceRefresh = options.forceRefresh ?? false;
128
- const providers = await manager.bootstrapProviders(torMode);
128
+ const providers = await manager.bootstrapProviders(torMode, forceRefresh);
129
129
  await manager.fetchModels(providers, forceRefresh);
130
130
  return manager;
131
131
  }
@@ -133,17 +133,20 @@ var ModelManager = class _ModelManager {
133
133
  * Bootstrap provider list from the provider directory
134
134
  * First tries to fetch from Nostr (kind 30421), falls back to HTTP
135
135
  * @param torMode Whether running in Tor context
136
+ * @param forceRefresh Ignore provider cache and refresh provider sources
136
137
  * @returns Array of provider base URLs
137
138
  * @throws ProviderBootstrapError if all providers fail to fetch
138
139
  */
139
- async bootstrapProviders(torMode = false) {
140
- const cachedUrls = this.adapter.getBaseUrlsList();
141
- if (cachedUrls.length > 0) {
142
- const lastUpdate = this.adapter.getBaseUrlsLastUpdate();
143
- const cacheValid = lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;
144
- if (cacheValid) {
145
- await this.fetchRoutstr21Models();
146
- return this.filterBaseUrlsForTor(cachedUrls, torMode);
140
+ async bootstrapProviders(torMode = false, forceRefresh = false) {
141
+ if (!forceRefresh) {
142
+ const cachedUrls = this.adapter.getBaseUrlsList();
143
+ if (cachedUrls.length > 0) {
144
+ const lastUpdate = this.adapter.getBaseUrlsLastUpdate();
145
+ const cacheValid = lastUpdate && Date.now() - lastUpdate <= this.cacheTTL;
146
+ if (cacheValid) {
147
+ await this.fetchRoutstr21Models(forceRefresh);
148
+ return this.filterBaseUrlsForTor(cachedUrls, torMode);
149
+ }
147
150
  }
148
151
  }
149
152
  try {
@@ -152,13 +155,13 @@ var ModelManager = class _ModelManager {
152
155
  const filtered = this.filterBaseUrlsForTor(nostrProviders, torMode);
153
156
  this.adapter.setBaseUrlsList(filtered);
154
157
  this.adapter.setBaseUrlsLastUpdate(Date.now());
155
- await this.fetchRoutstr21Models();
158
+ await this.fetchRoutstr21Models(forceRefresh);
156
159
  return filtered;
157
160
  }
158
161
  } catch (e) {
159
162
  console.warn("Nostr bootstrap failed, falling back to HTTP:", e);
160
163
  }
161
- return this.bootstrapFromHttp(torMode);
164
+ return this.bootstrapFromHttp(torMode, forceRefresh);
162
165
  }
163
166
  /**
164
167
  * Bootstrap providers from Nostr network (kind 30421)
@@ -254,9 +257,10 @@ var ModelManager = class _ModelManager {
254
257
  /**
255
258
  * Bootstrap providers from HTTP endpoint
256
259
  * @param torMode Whether running in Tor context
260
+ * @param forceRefresh Ignore routstr21 cache and fetch fresh data
257
261
  * @returns Array of provider base URLs
258
262
  */
259
- async bootstrapFromHttp(torMode) {
263
+ async bootstrapFromHttp(torMode, forceRefresh = false) {
260
264
  try {
261
265
  const res = await fetch(this.providerDirectoryUrl);
262
266
  if (!res.ok) {
@@ -284,7 +288,7 @@ var ModelManager = class _ModelManager {
284
288
  if (list.length > 0) {
285
289
  this.adapter.setBaseUrlsList(list);
286
290
  this.adapter.setBaseUrlsLastUpdate(Date.now());
287
- await this.fetchRoutstr21Models();
291
+ await this.fetchRoutstr21Models(forceRefresh);
288
292
  }
289
293
  return list;
290
294
  } catch (e) {
@@ -1818,6 +1822,14 @@ var BalanceManager = class {
1818
1822
  console.log(response.status);
1819
1823
  const data = await response.json();
1820
1824
  console.log("FAILED ", data);
1825
+ const isInvalidApiKey = response.status === 401 && data?.code === "invalid_api_key" && data?.message?.includes("proofs already spent");
1826
+ return {
1827
+ amount: -1,
1828
+ reserved: data.reserved ?? 0,
1829
+ unit: "msat",
1830
+ apiKey: data.api_key,
1831
+ isInvalidApiKey
1832
+ };
1821
1833
  }
1822
1834
  } catch (error) {
1823
1835
  console.error("ERRORR IN RESTPONSE", error);
@@ -2766,7 +2778,8 @@ var RoutstrClient = class {
2766
2778
  response.status,
2767
2779
  requestId,
2768
2780
  this.mode === "xcashu" ? response.headers.get("x-cashu") ?? void 0 : void 0,
2769
- bodyText
2781
+ bodyText,
2782
+ params.retryCount ?? 0
2770
2783
  );
2771
2784
  }
2772
2785
  return response;
@@ -2775,8 +2788,12 @@ var RoutstrClient = class {
2775
2788
  return await this._handleErrorResponse(
2776
2789
  params,
2777
2790
  token,
2778
- -1
2791
+ -1,
2779
2792
  // just for Network Error to skip all statuses
2793
+ void 0,
2794
+ void 0,
2795
+ void 0,
2796
+ params.retryCount ?? 0
2780
2797
  );
2781
2798
  }
2782
2799
  throw error;
@@ -2785,7 +2802,8 @@ var RoutstrClient = class {
2785
2802
  /**
2786
2803
  * Handle error responses with failover
2787
2804
  */
2788
- async _handleErrorResponse(params, token, status, requestId, xCashuRefundToken, responseBody) {
2805
+ async _handleErrorResponse(params, token, status, requestId, xCashuRefundToken, responseBody, retryCount = 0) {
2806
+ const MAX_RETRIES_PER_PROVIDER = 2;
2789
2807
  const { path, method, body, selectedModel, baseUrl, mintUrl } = params;
2790
2808
  let tryNextProvider = false;
2791
2809
  this._log(
@@ -2855,8 +2873,7 @@ var RoutstrClient = class {
2855
2873
  );
2856
2874
  }
2857
2875
  }
2858
- if ((status === 402 || status === 413 && responseBody?.includes("Insufficient balance")) && !tryNextProvider && (this.mode === "apikeys" || this.mode === "lazyrefund")) {
2859
- console.log("RESPONSFE ", responseBody);
2876
+ if (status === 402 && !tryNextProvider && (this.mode === "apikeys" || this.mode === "lazyrefund")) {
2860
2877
  const topupResult = await this.balanceManager.topUp({
2861
2878
  mintUrl,
2862
2879
  baseUrl,
@@ -2892,12 +2909,83 @@ var RoutstrClient = class {
2892
2909
  `[RoutstrClient] _handleErrorResponse: Topup successful, will retry with new token`
2893
2910
  );
2894
2911
  }
2895
- if (!tryNextProvider)
2912
+ if (!tryNextProvider) {
2913
+ if (retryCount < MAX_RETRIES_PER_PROVIDER) {
2914
+ this._log(
2915
+ "DEBUG",
2916
+ `[RoutstrClient] _handleErrorResponse: Retrying 402 (attempt ${retryCount + 1}/${MAX_RETRIES_PER_PROVIDER})`
2917
+ );
2918
+ return this._makeRequest({
2919
+ ...params,
2920
+ token: params.token,
2921
+ headers: this._withAuthHeader(params.baseHeaders, params.token),
2922
+ retryCount: retryCount + 1
2923
+ });
2924
+ } else {
2925
+ this._log(
2926
+ "DEBUG",
2927
+ `[RoutstrClient] _handleErrorResponse: 402 retry limit reached (${retryCount}/${MAX_RETRIES_PER_PROVIDER}), failing over to next provider`
2928
+ );
2929
+ tryNextProvider = true;
2930
+ }
2931
+ }
2932
+ }
2933
+ const isInsufficientBalance413 = status === 413 && responseBody?.includes("Insufficient balance");
2934
+ if (isInsufficientBalance413 && !tryNextProvider && this.mode === "apikeys") {
2935
+ let retryToken = params.token;
2936
+ try {
2937
+ const latestBalanceInfo = await this.balanceManager.getTokenBalance(
2938
+ params.token,
2939
+ baseUrl
2940
+ );
2941
+ if (latestBalanceInfo.isInvalidApiKey) {
2942
+ this._log(
2943
+ "DEBUG",
2944
+ `[RoutstrClient] _handleErrorResponse: Invalid API key (proofs already spent), removing for ${baseUrl}`
2945
+ );
2946
+ this.storageAdapter.removeApiKey(baseUrl);
2947
+ tryNextProvider = true;
2948
+ } else {
2949
+ const latestTokenBalance = latestBalanceInfo.unit === "msat" ? latestBalanceInfo.amount / 1e3 : latestBalanceInfo.amount;
2950
+ if (latestBalanceInfo.apiKey) {
2951
+ const storedApiKeyEntry = this.storageAdapter.getApiKey(baseUrl);
2952
+ if (storedApiKeyEntry?.key !== latestBalanceInfo.apiKey) {
2953
+ if (storedApiKeyEntry) {
2954
+ this.storageAdapter.removeApiKey(baseUrl);
2955
+ }
2956
+ this.storageAdapter.setApiKey(baseUrl, latestBalanceInfo.apiKey);
2957
+ }
2958
+ retryToken = latestBalanceInfo.apiKey;
2959
+ }
2960
+ if (latestTokenBalance >= 0) {
2961
+ this.storageAdapter.updateApiKeyBalance(baseUrl, latestTokenBalance);
2962
+ }
2963
+ }
2964
+ } catch (error) {
2965
+ this._log(
2966
+ "WARN",
2967
+ `[RoutstrClient] _handleErrorResponse: Failed to refresh API key after 413 insufficient balance for ${baseUrl}`,
2968
+ error
2969
+ );
2970
+ }
2971
+ if (retryCount < MAX_RETRIES_PER_PROVIDER) {
2972
+ this._log(
2973
+ "DEBUG",
2974
+ `[RoutstrClient] _handleErrorResponse: Retrying 413 (attempt ${retryCount + 1}/${MAX_RETRIES_PER_PROVIDER})`
2975
+ );
2896
2976
  return this._makeRequest({
2897
2977
  ...params,
2898
- token: params.token,
2899
- headers: this._withAuthHeader(params.baseHeaders, params.token)
2978
+ token: retryToken,
2979
+ headers: this._withAuthHeader(params.baseHeaders, retryToken),
2980
+ retryCount: retryCount + 1
2900
2981
  });
2982
+ } else {
2983
+ this._log(
2984
+ "DEBUG",
2985
+ `[RoutstrClient] _handleErrorResponse: 413 retry limit reached (${retryCount}/${MAX_RETRIES_PER_PROVIDER}), failing over to next provider`
2986
+ );
2987
+ tryNextProvider = true;
2988
+ }
2901
2989
  }
2902
2990
  if ((status === 401 || status === 403 || status === 413 || status === 400 || status === 500 || status === 502 || status === 503 || status === 504 || status === 521) && !tryNextProvider) {
2903
2991
  this._log(
@@ -3013,7 +3101,8 @@ var RoutstrClient = class {
3013
3101
  selectedModel: newModel,
3014
3102
  token: spendResult.token,
3015
3103
  requiredSats: newRequiredSats,
3016
- headers: this._withAuthHeader(params.baseHeaders, spendResult.token)
3104
+ headers: this._withAuthHeader(params.baseHeaders, spendResult.token),
3105
+ retryCount: 0
3017
3106
  });
3018
3107
  }
3019
3108
  throw new FailoverError(baseUrl, Array.from(this.providerManager));
@@ -3648,7 +3737,7 @@ var SDK_STORAGE_KEYS = {
3648
3737
 
3649
3738
  // storage/store.ts
3650
3739
  var normalizeBaseUrl = (baseUrl) => baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
3651
- var getTokenBalance = (token) => {
3740
+ var getCashuTokenBalance = (token) => {
3652
3741
  try {
3653
3742
  const decoded = cashuTs.getDecodedToken(token);
3654
3743
  const unitDivisor = decoded.unit === "msat" ? 1e3 : 1;
@@ -3741,7 +3830,7 @@ var createSdkStore = async ({
3741
3830
  const cachedTokens = rawCachedTokens.map((entry) => ({
3742
3831
  ...entry,
3743
3832
  baseUrl: normalizeBaseUrl(entry.baseUrl),
3744
- balance: typeof entry.balance === "number" ? entry.balance : getTokenBalance(entry.token),
3833
+ balance: typeof entry.balance === "number" ? entry.balance : getCashuTokenBalance(entry.token),
3745
3834
  lastUsed: entry.lastUsed ?? null
3746
3835
  }));
3747
3836
  const apiKeys = rawApiKeys.map((entry) => ({
@@ -3845,7 +3934,7 @@ var createSdkStore = async ({
3845
3934
  const normalized = updates.map((entry) => ({
3846
3935
  ...entry,
3847
3936
  baseUrl: normalizeBaseUrl(entry.baseUrl),
3848
- balance: typeof entry.balance === "number" ? entry.balance : getTokenBalance(entry.token),
3937
+ balance: typeof entry.balance === "number" ? entry.balance : getCashuTokenBalance(entry.token),
3849
3938
  lastUsed: entry.lastUsed ?? null
3850
3939
  }));
3851
3940
  void driver.setItem(SDK_STORAGE_KEYS.LOCAL_CASHU_TOKENS, normalized);
@@ -3944,7 +4033,7 @@ var createStorageAdapterFromStore = (store) => ({
3944
4033
  setToken: (baseUrl, token) => {
3945
4034
  const normalized = normalizeBaseUrl(baseUrl);
3946
4035
  const tokens = store.getState().cachedTokens;
3947
- const balance = getTokenBalance(token);
4036
+ const balance = getCashuTokenBalance(token);
3948
4037
  const existingIndex = tokens.findIndex(
3949
4038
  (entry) => entry.baseUrl === normalized
3950
4039
  );