@keetanetwork/anchor 0.0.33 → 0.0.35
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.
- package/lib/http-server/index.d.ts +7 -1
- package/lib/http-server/index.d.ts.map +1 -1
- package/lib/http-server/index.js +2 -0
- package/lib/http-server/index.js.map +1 -1
- package/lib/queue/common.d.ts +26 -0
- package/lib/queue/common.d.ts.map +1 -0
- package/lib/queue/common.js +47 -0
- package/lib/queue/common.js.map +1 -0
- package/lib/queue/drivers/queue_file.d.ts +17 -0
- package/lib/queue/drivers/queue_file.d.ts.map +1 -0
- package/lib/queue/drivers/queue_file.js +100 -0
- package/lib/queue/drivers/queue_file.js.map +1 -0
- package/lib/queue/drivers/queue_postgres.d.ts +28 -0
- package/lib/queue/drivers/queue_postgres.d.ts.map +1 -0
- package/lib/queue/drivers/queue_postgres.js +360 -0
- package/lib/queue/drivers/queue_postgres.js.map +1 -0
- package/lib/queue/drivers/queue_redis.d.ts +27 -0
- package/lib/queue/drivers/queue_redis.d.ts.map +1 -0
- package/lib/queue/drivers/queue_redis.js +359 -0
- package/lib/queue/drivers/queue_redis.js.map +1 -0
- package/lib/queue/drivers/queue_sqlite3.d.ts +28 -0
- package/lib/queue/drivers/queue_sqlite3.d.ts.map +1 -0
- package/lib/queue/drivers/queue_sqlite3.js +378 -0
- package/lib/queue/drivers/queue_sqlite3.js.map +1 -0
- package/lib/queue/index.d.ts +341 -0
- package/lib/queue/index.d.ts.map +1 -0
- package/lib/queue/index.js +946 -0
- package/lib/queue/index.js.map +1 -0
- package/lib/queue/internal.d.ts +20 -0
- package/lib/queue/internal.d.ts.map +1 -0
- package/lib/queue/internal.js +66 -0
- package/lib/queue/internal.js.map +1 -0
- package/lib/queue/pipeline.d.ts +152 -0
- package/lib/queue/pipeline.d.ts.map +1 -0
- package/lib/queue/pipeline.js +296 -0
- package/lib/queue/pipeline.js.map +1 -0
- package/lib/resolver.d.ts +1 -1
- package/lib/resolver.d.ts.map +1 -1
- package/lib/resolver.js.map +1 -1
- package/lib/utils/asleep.d.ts +2 -0
- package/lib/utils/asleep.d.ts.map +1 -0
- package/lib/utils/asleep.js +3 -0
- package/lib/utils/asleep.js.map +1 -0
- package/lib/utils/defer.d.ts +4 -0
- package/lib/utils/defer.d.ts.map +1 -0
- package/lib/utils/defer.js +3 -0
- package/lib/utils/defer.js.map +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/services/fx/client.d.ts +1 -1
- package/services/fx/client.d.ts.map +1 -1
- package/services/fx/client.js +2 -2
- package/services/fx/client.js.map +1 -1
- package/services/fx/common.d.ts +19 -4
- package/services/fx/common.d.ts.map +1 -1
- package/services/fx/common.js +8 -5
- package/services/fx/common.js.map +1 -1
- package/services/fx/server.d.ts +105 -8
- package/services/fx/server.d.ts.map +1 -1
- package/services/fx/server.js +609 -43
- package/services/fx/server.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/services/fx/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,qBAAqB,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACN,oBAAoB,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,kCAAkC,EAClC,yBAAyB,EACzB,MAAM,EACN,MAAM,aAAa,CAAC;AAWrB,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AA4DrD,CAAC;AAEF,KAAK,UAAU,mBAAmB,CAAC,aAAqD;IACvF,MAAM,MAAM,GAAqB;QAChC,aAAa,CAAC,OAAO,CAAC,IAAI;QAC1B,aAAa,CAAC,OAAO,CAAC,EAAE;QACxB,aAAa,CAAC,OAAO,CAAC,MAAM;QAC5B,aAAa,CAAC,OAAO,CAAC,QAAQ;QAC9B,aAAa,CAAC,OAAO;QACrB,aAAa,CAAC,eAAe;QAC7B,aAAa,CAAC,IAAI,CAAC,KAAK;QACxB,aAAa,CAAC,IAAI,CAAC,MAAM;KACzB,CAAC;IAEF,OAAM,CAAC,MAAM,CAAC,CAAC;AAgBhB,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,MAA+B,EAAE,aAAqD;IACxH,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAE7D,OAAM,CAAC;QACN,GAAG,aAAa;QAChB,MAAM,EAAE,MAAM;KACd,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAkC,EAAE,KAA6B;IAChG,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAEvD,OAAM,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,MAAiC,EAAE,OAAqC;IACxG,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACjH,IAAI,MAAM,GAAmC,IAAI,CAAC;IAClD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC1H,CAAC;IAED,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QAClD,MAAK,CAAC,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAA;IACvE,CAAC;IAED,OAAM,CAAC;QACN,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,OAAO;KAChB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,0BAA2B,SAAQ,qBAAqB,CAAC,wBAAmD;IAC/G,QAAQ,CAAqD;IAC7D,MAAM,CAAsC;IAC5C,OAAO,CAAuC;IAC9C,MAAM,CAAmD;IACzD,WAAW,CAA2C;IACtD,EAAE,CAAkC;IAE7C,YAAY,MAAiC;QAC5C,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACvC,CAAC;IAES,KAAK,CAAC,UAAU,CAAC,MAAiC;QAC3D,MAAM,MAAM,GAAiC,EAAE,CAAC;QAEhD;;WAEG;QACH,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;YAC1B,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK;gBACtB,IAAI,YAAoB,CAAC;gBACzB,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBACzC,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACP,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;wBACtB,MAAK,CAAC,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC;oBACnE,CAAC;oBAED,YAAY,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACxC,CAAC;gBAED,OAAM,CAAC;oBACN,MAAM,EAAE,YAAY;oBACpB,WAAW,EAAE,WAAW;iBACxB,CAAC,CAAC;YACJ,CAAC,CAAC;QACH,CAAC;QAED;;WAEG;QACH,MAAM,CAAC,uBAAuB,CAAC,GAAG,KAAK,WAAU,cAAc,EAAE,QAAQ;YACxE,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/C,MAAK,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAK,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;YAC/C,CAAC;YAED,MAAM,UAAU,GAAG,kCAAkC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACxE,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;YACvE,MAAM,gBAAgB,GAAkC;gBACvD,EAAE,EAAE,IAAI;gBACR,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC;oBAC1D,OAAO,EAAE,UAAU;oBACnB,eAAe,EAAE,UAAU,CAAC,eAAe;oBAC3C,YAAY,EAAE;wBACb,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM;wBAC3B,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM;wBAC3B,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK;qBAC5B;iBACD,CAAC;aACF,CAAC;YAEF,OAAM,CAAC;gBACN,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;aACxC,CAAC,CAAC;QACJ,CAAC,CAAA;QAED,MAAM,CAAC,oBAAoB,CAAC,GAAG,KAAK,WAAU,cAAc,EAAE,QAAQ;YACrE,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/C,MAAK,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAK,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;YAC/C,CAAC;YAED,MAAM,UAAU,GAAG,kCAAkC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACxE,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;YAEvE,MAAM,aAAa,GAA2C,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC;gBAC9G,OAAO,EAAE,UAAU;gBACnB,GAAG,UAAU;aACb,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;YACjF,MAAM,aAAa,GAA+B;gBACjD,EAAE,EAAE,IAAI;gBACR,KAAK,EAAE,WAAW;aAClB,CAAC;YAEF,OAAM,CAAC;gBACN,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;aACrC,CAAC,CAAC;QACJ,CAAC,CAAA;QAED,MAAM,CAAC,0BAA0B,CAAC,GAAG,KAAK,WAAU,cAAc,EAAE,QAAQ;YAC3E,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/C,MAAK,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAC3C,CAAC;YAED,IAAI,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAK,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;YAC/C,CAAC;YACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC7C,MAAK,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAC9C,CAAC;YAED,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;gBAC3B,MAAK,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;YACnD,CAAC;YACD,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAChE,MAAK,CAAC,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC,CAAC;YAChE,CAAC;YAED,MAAM,KAAK,GAAG,yBAAyB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACvD,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,YAAY,EAAE,CAAC;gBACnB,MAAK,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAC7C,CAAC;YAED,oDAAoD;YACpD,IAAI,MAAM,CAAC,EAAE,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;gBAC3C,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC1D,IAAI,CAAC,YAAY,EAAE,CAAC;oBACnB,MAAK,CAAC,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;gBAC3C,CAAC;YACF,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACpD,IAAI,UAA+B,CAAC;YACpC,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnD,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;YAC5B,CAAC;iBAAM,CAAC;gBACP,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAE3E,UAAU,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC;oBACpC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;oBAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;oBAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY;oBACxC,OAAO,EAAE,OAAO;oBAChB,MAAM,EAAE,MAAM;iBACd,CAAC,CAAC;YACJ,CAAC;YAED,kDAAkD;YAClD,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACnF,IAAI,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YACtH,uDAAuD;YACvD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnC,mJAAmJ;gBACnJ,IAAI,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtD,cAAc,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC7C,qFAAqF;gBACrF,CAAC;qBAAM,CAAC;oBACP,IAAI,mBAAmB,GAAG,KAAK,CAAC;oBAChC,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;wBAC1C,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;4BAC9D,MAAM,gBAAgB,GAAG,SAAS,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;4BACtE,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;4BACxE,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;4BACrE,IAAI,gBAAgB,IAAI,YAAY,IAAI,aAAa,EAAE,CAAC;gCACvD,mBAAmB,GAAG,IAAI,CAAC;4BAC5B,CAAC;wBACF,CAAC;oBACF,CAAC;oBACD,IAAI,CAAC,mBAAmB,EAAE,CAAC;wBAC1B,MAAK,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;oBACpD,CAAC;gBACF,CAAC;YACF,CAAC;YAED,uDAAuD;YACvD,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,EAAE,EAAC,CAAC,CAAC;YACpI,MAAM,cAAc,GAAqD,EAAE,CAAC;YAC5E,IAAI,UAAU,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACtD,cAAc,CAAC,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC;YACtE,CAAC;YACD,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;YACnF,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;gBAC5B,MAAK,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAC7C,CAAC;YACD,MAAM,gBAAgB,GAAkC;gBACvD,EAAE,EAAE,IAAI;gBACR,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE;aACjC,CAAC;YAEF,OAAM,CAAC;gBACN,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;aACxC,CAAC,CAAC;QACJ,CAAC,CAAA;QAED,MAAM,CAAC,gCAAgC,CAAC,GAAG,KAAK,WAAU,MAAM;YAC/D,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC7C,MAAK,CAAC,IAAI,oBAAoB,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACpD,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;gBACpC,MAAK,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;YAClD,CAAC;YACD,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YACzE,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;gBAC1B,MAAK,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACrC,CAAC;YACD,MAAM,gBAAgB,GAAkC;gBACvD,EAAE,EAAE,IAAI;gBACR,UAAU,EAAE,UAAU;aACtB,CAAC;YAEF,OAAM,CAAC;gBACN,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;aACxC,CAAC,CAAC;QACJ,CAAC,CAAA;QAED,OAAM,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACpB,MAAM,UAAU,GAAyE;YACxF,WAAW,EAAE,CAAC,IAAI,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;YAC/D,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;YACzD,cAAc,EAAE,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;YACrE,iBAAiB,EAAE,CAAC,IAAI,GAAG,CAAC,wBAAwB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,OAAO;SACrF,CAAC;QAEF,OAAM,CAAC;YACN,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE;YACxB,UAAU,EAAE,UAAU;SACtB,CAAC,CAAC;IACJ,CAAC;CACD","sourcesContent":["import * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';\nimport { KeetaNet } from '../../client/index.js';\nimport {\n\tKeetaAnchorUserError\n} from '../../lib/error.js';\nimport {\n\tassertConversionInputCanonicalJSON,\n\tassertConversionQuoteJSON,\n\tErrors\n} from './common.js';\nimport type {\n\tConversionInputCanonicalJSON,\n\tKeetaFXAnchorEstimateResponse,\n\tKeetaFXAnchorExchangeResponse,\n\tKeetaFXAnchorQuote,\n\tKeetaFXAnchorQuoteJSON,\n\tKeetaFXAnchorQuoteResponse,\n\tKeetaNetAccount,\n\tKeetaNetStorageAccount\n} from './common.ts';\nimport * as Signing from '../../lib/utils/signing.js';\nimport type { AssertNever } from '../../lib/utils/never.ts';\nimport type { ServiceMetadata } from '../../lib/resolver.js';\n\nexport interface KeetaAnchorFXServerConfig extends KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig {\n\t/**\n\t * The data to use for the index page (optional)\n\t */\n\thomepage?: string | (() => Promise<string> | string);\n\n\t/**\n\t * The account to use for performing swaps for a given pair\n\t *\n\t * This may be either a function or a KeetaNet Account instance.\n\t */\n\taccount: KeetaNetAccount | KeetaNetStorageAccount | ((request: ConversionInputCanonicalJSON) => Promise<KeetaNetAccount | KeetaNetStorageAccount> | KeetaNetAccount | KeetaNetStorageAccount);\n\t/**\n\t * Account which can be used to sign transactions\n\t * for the account above (if not supplied the\n\t * account will be used).\n\t *\n\t * This may be either a function or a KeetaNet Account instance.\n\t */\n\tsigner?: InstanceType<typeof KeetaNet.lib.Account> | ((request: ConversionInputCanonicalJSON) => Promise<InstanceType<typeof KeetaNet.lib.Account>> | InstanceType<typeof KeetaNet.lib.Account>);\n\n\t/**\n\t * Account which performs the signing and validation of quotes\n\t */\n\tquoteSigner: Signing.SignableAccount;\n\n\t/**\n\t * Configuration for FX handling\n\t */\n\tfx: {\n\t\t/**\n\t\t * Supported conversions\n\t\t */\n\t\tfrom?: NonNullable<ServiceMetadata['services']['fx']>[string]['from'];\n\t\t/**\n\t\t * Handle the conversion request of one token to another\n\t\t *\n\t\t * This is used to handle quotes and estimates\n\t\t */\n\t\tgetConversionRateAndFee: (request: ConversionInputCanonicalJSON) => Promise<Omit<KeetaFXAnchorQuote, 'request' | 'signed' >>;\n\t\t/**\n\t\t * Optional callback to validate a quote before completing an exchange\n\t\t *\n\t\t * This allows the FX Server operator to reject quotes that are no longer\n\t\t * acceptable (e.g., due to price changes, expiry, or other business logic)\n\t\t *\n\t\t * @param quote The quote to validate\n\t\t * @returns true to accept the quote and proceed with the exchange, false to reject it\n\t\t */\n\t\tvalidateQuote?: (quote: KeetaFXAnchorQuoteJSON) => Promise<boolean> | boolean;\n\t};\n\n\t/**\n\t * The network client to use for submitting blocks\n\t */\n\tclient: { client: KeetaNet.Client; network: bigint; networkAlias: typeof KeetaNet.Client.Config.networksArray[number] } | KeetaNet.UserClient;\n};\n\nasync function formatQuoteSignable(unsignedQuote: Omit<KeetaFXAnchorQuoteJSON, 'signed'>): Promise<Signing.Signable> {\n\tconst retval: Signing.Signable = [\n\t\tunsignedQuote.request.from,\n\t\tunsignedQuote.request.to,\n\t\tunsignedQuote.request.amount,\n\t\tunsignedQuote.request.affinity,\n\t\tunsignedQuote.account,\n\t\tunsignedQuote.convertedAmount,\n\t\tunsignedQuote.cost.token,\n\t\tunsignedQuote.cost.amount\n\t];\n\n\treturn(retval);\n\n\t/**\n\t * This is a static assertion to ensure that this function is updated\n\t * if new fields are added to the KeetaFXAnchorQuote type to ensure\n\t * that we are always signing all the fields.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\ttype _ignore_static_assert = AssertNever<\n\t\t// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n\t\tAssertNever<keyof Omit<typeof unsignedQuote['request'], 'from' | 'to' | 'amount' | 'affinity'>> &\n\t\t// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents,@typescript-eslint/no-duplicate-type-constituents\n\t\tAssertNever<keyof Omit<typeof unsignedQuote['cost'], 'token' | 'amount'>> &\n\t\t// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents,@typescript-eslint/no-duplicate-type-constituents\n\t\tAssertNever<keyof Omit<typeof unsignedQuote, 'request' | 'convertedAmount' | 'cost' | 'account'>>\n\t>;\n}\n\nasync function generateSignedQuote(signer: Signing.SignableAccount, unsignedQuote: Omit<KeetaFXAnchorQuoteJSON, 'signed'>): Promise<KeetaFXAnchorQuoteJSON> {\n\tconst signableQuote = await formatQuoteSignable(unsignedQuote);\n\tconst signed = await Signing.SignData(signer, signableQuote);\n\n\treturn({\n\t\t...unsignedQuote,\n\t\tsigned: signed\n\t});\n}\n\nasync function verifySignedData(signedBy: Signing.VerifableAccount, quote: KeetaFXAnchorQuoteJSON): Promise<boolean> {\n\tconst signableQuote = await formatQuoteSignable(quote);\n\n\treturn(await Signing.VerifySignedData(signedBy, signableQuote, quote.signed));\n}\n\nasync function requestToAccounts(config: KeetaAnchorFXServerConfig, request: ConversionInputCanonicalJSON): Promise<{ signer: Signing.SignableAccount; account: KeetaNetAccount | KeetaNetStorageAccount; }> {\n\tconst account = KeetaNet.lib.Account.isInstance(config.account) ? config.account : await config.account(request);\n\tlet signer: Signing.SignableAccount | null = null;\n\tif (config.signer !== undefined) {\n\t\tsigner = (KeetaNet.lib.Account.isInstance(config.signer) ? config.signer : await config.signer(request)).assertAccount();\n\t}\n\n\tif (signer === null) {\n\t\tsigner = account.assertAccount();\n\t}\n\n\tif (!account.isAccount() && !account.isStorage()) {\n\t\tthrow(new Error('FX Account should be an Account or Storage Account'))\n\t}\n\n\treturn({\n\t\tsigner: signer,\n\t\taccount: account\n\t});\n}\n\nexport class KeetaNetFXAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<KeetaAnchorFXServerConfig> implements Required<KeetaAnchorFXServerConfig> {\n\treadonly homepage: NonNullable<KeetaAnchorFXServerConfig['homepage']>;\n\treadonly client: KeetaAnchorFXServerConfig['client'];\n\treadonly account: KeetaAnchorFXServerConfig['account'];\n\treadonly signer: NonNullable<KeetaAnchorFXServerConfig['signer']>;\n\treadonly quoteSigner: KeetaAnchorFXServerConfig['quoteSigner'];\n\treadonly fx: KeetaAnchorFXServerConfig['fx'];\n\n\tconstructor(config: KeetaAnchorFXServerConfig) {\n\t\tsuper(config);\n\n\t\tthis.homepage = config.homepage ?? '';\n\t\tthis.client = config.client;\n\t\tthis.fx = config.fx;\n\t\tthis.account = config.account;\n\t\tthis.signer = config.signer ?? config.account;\n\t\tthis.quoteSigner = config.quoteSigner;\n\t}\n\n\tprotected async initRoutes(config: KeetaAnchorFXServerConfig): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = {};\n\n\t\t/**\n\t\t * If a homepage is provided, setup the route for it\n\t\t */\n\t\tif ('homepage' in config) {\n\t\t\troutes['GET /'] = async function() {\n\t\t\t\tlet homepageData: string;\n\t\t\t\tif (typeof config.homepage === 'string') {\n\t\t\t\t\thomepageData = config.homepage;\n\t\t\t\t} else {\n\t\t\t\t\tif (!config.homepage) {\n\t\t\t\t\t\tthrow(new Error('internal error: No homepage function provided'));\n\t\t\t\t\t}\n\n\t\t\t\t\thomepageData = await config.homepage();\n\t\t\t\t}\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: homepageData,\n\t\t\t\t\tcontentType: 'text/html'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\t/**\n\t\t * Setup the request handler for an estimate request\n\t\t */\n\t\troutes['POST /api/getEstimate'] = async function(_ignore_params, postData) {\n\t\t\tif (!postData || typeof postData !== 'object') {\n\t\t\t\tthrow(new Error('No POST data provided'));\n\t\t\t}\n\t\t\tif (!('request' in postData)) {\n\t\t\t\tthrow(new Error('POST data missing request'));\n\t\t\t}\n\n\t\t\tconst conversion = assertConversionInputCanonicalJSON(postData.request);\n\t\t\tconst rateAndFee = await config.fx.getConversionRateAndFee(conversion);\n\t\t\tconst estimateResponse: KeetaFXAnchorEstimateResponse = {\n\t\t\t\tok: true,\n\t\t\t\testimate: KeetaNet.lib.Utils.Conversion.toJSONSerializable({\n\t\t\t\t\trequest: conversion,\n\t\t\t\t\tconvertedAmount: rateAndFee.convertedAmount,\n\t\t\t\t\texpectedCost: {\n\t\t\t\t\t\tmin: rateAndFee.cost.amount,\n\t\t\t\t\t\tmax: rateAndFee.cost.amount,\n\t\t\t\t\t\ttoken: rateAndFee.cost.token\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t};\n\n\t\t\treturn({\n\t\t\t\toutput: JSON.stringify(estimateResponse)\n\t\t\t});\n\t\t}\n\n\t\troutes['POST /api/getQuote'] = async function(_ignore_params, postData) {\n\t\t\tif (!postData || typeof postData !== 'object') {\n\t\t\t\tthrow(new Error('No POST data provided'));\n\t\t\t}\n\t\t\tif (!('request' in postData)) {\n\t\t\t\tthrow(new Error('POST data missing request'));\n\t\t\t}\n\n\t\t\tconst conversion = assertConversionInputCanonicalJSON(postData.request);\n\t\t\tconst rateAndFee = await config.fx.getConversionRateAndFee(conversion);\n\n\t\t\tconst unsignedQuote: Omit<KeetaFXAnchorQuoteJSON, 'signed'> = KeetaNet.lib.Utils.Conversion.toJSONSerializable({\n\t\t\t\trequest: conversion,\n\t\t\t\t...rateAndFee\n\t\t\t});\n\n\t\t\tconst signedQuote = await generateSignedQuote(config.quoteSigner, unsignedQuote);\n\t\t\tconst quoteResponse: KeetaFXAnchorQuoteResponse = {\n\t\t\t\tok: true,\n\t\t\t\tquote: signedQuote\n\t\t\t};\n\n\t\t\treturn({\n\t\t\t\toutput: JSON.stringify(quoteResponse)\n\t\t\t});\n\t\t}\n\n\t\troutes['POST /api/createExchange'] = async function(_ignore_params, postData) {\n\t\t\tif (!postData || typeof postData !== 'object') {\n\t\t\t\tthrow(new Error('No POST data provided'));\n\t\t\t}\n\n\t\t\tif (!('request' in postData)) {\n\t\t\t\tthrow(new Error('POST data missing request'));\n\t\t\t}\n\t\t\tconst request = postData.request;\n\t\t\tif (!request || typeof request !== 'object') {\n\t\t\t\tthrow(new Error('Request is not an object'));\n\t\t\t}\n\n\t\t\tif (!('quote' in request)) {\n\t\t\t\tthrow(new Error('Quote is missing from request'));\n\t\t\t}\n\t\t\tif (!('block' in request) || typeof request.block !== 'string') {\n\t\t\t\tthrow(new Error('Block was not provided in exchange request'));\n\t\t\t}\n\n\t\t\tconst quote = assertConversionQuoteJSON(request.quote);\n\t\t\tconst isValidQuote = await verifySignedData(config.quoteSigner, quote);\n\t\t\tif (!isValidQuote) {\n\t\t\t\tthrow(new Error('Invalid quote signature'));\n\t\t\t}\n\n\t\t\t/* Validate the quote using the optional callback */\n\t\t\tif (config.fx.validateQuote !== undefined) {\n\t\t\t\tconst isAcceptable = await config.fx.validateQuote(quote);\n\t\t\t\tif (!isAcceptable) {\n\t\t\t\t\tthrow(new Errors.QuoteValidationFailed());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst block = new KeetaNet.lib.Block(request.block);\n\t\t\tlet userClient: KeetaNet.UserClient;\n\t\t\tif (KeetaNet.UserClient.isInstance(config.client)) {\n\t\t\t\tuserClient = config.client;\n\t\t\t} else {\n\t\t\t\tconst { account, signer } = await requestToAccounts(config, quote.request);\n\n\t\t\t\tuserClient = new KeetaNet.UserClient({\n\t\t\t\t\tclient: config.client.client,\n\t\t\t\t\tnetwork: config.client.network,\n\t\t\t\t\tnetworkAlias: config.client.networkAlias,\n\t\t\t\t\taccount: account,\n\t\t\t\t\tsigner: signer\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t/* Get Expected Amount and Token to Verify Swap */\n\t\t\tconst expectedToken = KeetaNet.lib.Account.fromPublicKeyString(quote.request.from);\n\t\t\tlet expectedAmount = quote.request.affinity === 'from' ? BigInt(quote.request.amount) : BigInt(quote.convertedAmount);\n\t\t\t/* If cost is required verify the amounts and token. */\n\t\t\tif (BigInt(quote.cost.amount) > 0) {\n\t\t\t\t/* If swap token matches the cost token the add the amount since they should be combined in one block and will be checked in `acceptSwapRequest` */\n\t\t\t\tif (expectedToken.comparePublicKey(quote.cost.token)) {\n\t\t\t\t\texpectedAmount += BigInt(quote.cost.amount);\n\t\t\t\t/* If token is different then check block operations for matching amount and token */\n\t\t\t\t} else {\n\t\t\t\t\tlet requestIncludesCost = false;\n\t\t\t\t\tfor (const operation of block.operations) {\n\t\t\t\t\t\tif (operation.type === KeetaNet.lib.Block.OperationType.SEND) {\n\t\t\t\t\t\t\tconst recipientMatches = operation.to.comparePublicKey(quote.account);\n\t\t\t\t\t\t\tconst tokenMatches = operation.token.comparePublicKey(quote.cost.token);\n\t\t\t\t\t\t\tconst amountMatches = operation.amount === BigInt(quote.cost.amount);\n\t\t\t\t\t\t\tif (recipientMatches && tokenMatches && amountMatches) {\n\t\t\t\t\t\t\t\trequestIncludesCost = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!requestIncludesCost) {\n\t\t\t\t\t\tthrow(new Error('Exchange missing required cost'));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Verify Request and Generate the Accept Swap Block */\n\t\t\tconst swapBlocks = await userClient.acceptSwapRequest({ block, expected: { token: expectedToken, amount: BigInt(expectedAmount) }});\n\t\t\tconst publishOptions: Parameters<typeof userClient.client.transmit>[1] = {};\n\t\t\tif (userClient.config.generateFeeBlock !== undefined) {\n\t\t\t\tpublishOptions.generateFeeBlock = userClient.config.generateFeeBlock;\n\t\t\t}\n\t\t\tconst publishResult = await userClient.client.transmit(swapBlocks, publishOptions);\n\t\t\tif (!publishResult.publish) {\n\t\t\t\tthrow(new Error('Exchange Publish Failed'));\n\t\t\t}\n\t\t\tconst exchangeResponse: KeetaFXAnchorExchangeResponse = {\n\t\t\t\tok: true,\n\t\t\t\texchangeID: block.hash.toString()\n\t\t\t};\n\n\t\t\treturn({\n\t\t\t\toutput: JSON.stringify(exchangeResponse)\n\t\t\t});\n\t\t}\n\n\t\troutes['GET /api/getExchangeStatus/:id'] = async function(params) {\n\t\t\tif (params === undefined || params === null) {\n\t\t\t\tthrow(new KeetaAnchorUserError('Expected params'));\n\t\t\t}\n\t\t\tconst exchangeID = params.get('id');\n\t\t\tif (typeof exchangeID !== 'string') {\n\t\t\t\tthrow(new Error('Missing exchangeID in params'));\n\t\t\t}\n\t\t\tconst blockLookup = await config.client.client.getVoteStaple(exchangeID);\n\t\t\tif (blockLookup === null) {\n\t\t\t\tthrow(new Error('Block Not Found'));\n\t\t\t}\n\t\t\tconst exchangeResponse: KeetaFXAnchorExchangeResponse = {\n\t\t\t\tok: true,\n\t\t\t\texchangeID: exchangeID\n\t\t\t};\n\n\t\t\treturn({\n\t\t\t\toutput: JSON.stringify(exchangeResponse)\n\t\t\t});\n\t\t}\n\n\t\treturn(routes);\n\t}\n\n\t/**\n\t * Return the servers endpoints and possible currency conversions metadata\n\t */\n\tasync serviceMetadata(): Promise<NonNullable<ServiceMetadata['services']['fx']>[string]> {\n\t\tconst operations: NonNullable<ServiceMetadata['services']['fx']>[string]['operations'] = {\n\t\t\tgetEstimate: (new URL('/api/getEstimate', this.url)).toString(),\n\t\t\tgetQuote: (new URL('/api/getQuote', this.url)).toString(),\n\t\t\tcreateExchange: (new URL('/api/createExchange', this.url)).toString(),\n\t\t\tgetExchangeStatus: (new URL('/api/getExchangeStatus', this.url)).toString() + '/{id}'\n\t\t};\n\n\t\treturn({\n\t\t\tfrom: this.fx.from ?? [],\n\t\t\toperations: operations\n\t\t});\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/services/fx/server.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,qBAAqB,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACN,oBAAoB,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,kCAAkC,EAClC,yBAAyB,EACzB,MAAM,EACN,MAAM,aAAa,CAAC;AAWrB,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,mCAAmC,EAAE,MAAM,0BAA0B,CAAC;AAEvG,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;;;;;;GASG;AACH,MAAM,QAAQ,GAAG,IAAI,CAAC;AAyFrB,CAAC;AAEF,KAAK,UAAU,mBAAmB,CAAC,aAAqD;IACvF,MAAM,MAAM,GAAqB;QAChC,aAAa,CAAC,OAAO,CAAC,IAAI;QAC1B,aAAa,CAAC,OAAO,CAAC,EAAE;QACxB,aAAa,CAAC,OAAO,CAAC,MAAM;QAC5B,aAAa,CAAC,OAAO,CAAC,QAAQ;QAC9B,aAAa,CAAC,OAAO;QACrB,aAAa,CAAC,eAAe;QAC7B,aAAa,CAAC,IAAI,CAAC,KAAK;QACxB,aAAa,CAAC,IAAI,CAAC,MAAM;KACzB,CAAC;IAEF,OAAM,CAAC,MAAM,CAAC,CAAC;AAgBhB,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,MAA+B,EAAE,aAAqD;IACxH,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAE7D,OAAM,CAAC;QACN,GAAG,aAAa;QAChB,MAAM,EAAE,MAAM;KACd,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAkC,EAAE,KAA6B;IAChG,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAEvD,OAAM,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,MAAiC,EAAE,OAAqC;IACxG,IAAI,OAAwD,CAAC;IAC7D,4DAA4D;IAC5D,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACjE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAC3B,CAAC;SAAM,CAAC;QACP,OAAO,GAAG,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,MAAM,GAAmC,IAAI,CAAC;IAClD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC1H,CAAC;IAED,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACtB,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;YAClD,MAAK,CAAC,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAC;QACxE,CAAC;IACF,CAAC;SAAM,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAK,CAAC,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAM,CAAC;QACN,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,MAAM;KACd,CAAC,CAAC;AACJ,CAAC;AAmCD,MAAM,gCAAiC,SAAQ,sBAAyF;IACpH,YAAY,CAA4B;IACjD,UAAU,GAAG,IAAI,CAAC;IAE5B;;OAEG;IACO,cAAc,GAAW,EAAE,GAAG,IAAI,CAAC;IAE7C,YAAY,MAAiL;QAC5L,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,cAAc,CAAC,KAA8I;QAC5K,OAAM,CAAC;YACN,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,KAAK,CAAC,MAAM;SACpB,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACO,KAAK,CAAC,SAAS,CAAC,KAA4H;QACrJ,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;QACnD,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC;QACrC,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC;QAEjC,IAAI,UAA+B,CAAC;QAEpC,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,CAAC;aAAM,CAAC;YACP,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAEnF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC9C,MAAK,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC;gBAC1D,CAAC;gBAED,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC5D,OAAM,CAAC;wBACN,MAAM,EAAE,oBAAoB;wBAC5B,MAAM,EAAE,IAAI;wBACZ,KAAK,EAAE,sFAAsF;qBAC7F,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;iBAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClE,OAAM,CAAC;oBACN,MAAM,EAAE,oBAAoB;oBAC5B,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,uFAAuF;iBAC9F,CAAC,CAAC;YACJ,CAAC;YAED,UAAU,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC;gBACpC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;gBAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;gBAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY;gBACxC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO;gBAC9B,MAAM,EAAE,MAAM;aACd,CAAC,CAAC;QACJ,CAAC;QAED,+FAA+F;QAC/F,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC;YACpC,MAAM,MAAM,GAAG,cAAc,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YAE3F,OAAM,CAAC;gBACN,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE;oBACP,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE;oBAChC,MAAM,EAAE,MAAM;iBACd;aACD,CAAC,CAAC;QACJ,CAAC;QAED,4DAA4D;QAC5D,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YAC1B,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACP,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;QACjC,CAAC;QAED,gHAAgH;QAChH,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,IAAI,sBAAsB,GAAG,KAAK,CAAC;YACnC,IAAI,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;gBACvB,oFAAoF;gBACpF,sBAAsB,GAAG,IAAI,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACP,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC7D,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;oBAC5B,sBAAsB,GAAG,IAAI,CAAC;gBAC/B,CAAC;YACF,CAAC;YAED,IAAI,mBAA2B,CAAC;YAChC,IAAI,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;gBACvB,mBAAmB,GAAG,WAAW,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACP,mBAAmB,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACjD,CAAC;YAED,6HAA6H;YAC7H,IAAI,sBAAsB,EAAE,CAAC;gBAC5B,uGAAuG;gBACvG,OAAM,CAAC;oBACN,MAAM,EAAE,oBAAoB;oBAC5B,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,mBAAmB,mBAAmB,qDAAqD;iBAClG,CAAC,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACP,qJAAqJ;gBACrJ,kFAAkF;gBAClF,OAAM,CAAC;oBACN,MAAM,EAAE,oBAAoB;oBAC5B,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,mBAAmB,mBAAmB,iCAAiC;iBAC9E,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QAED,0CAA0C;QAC1C,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,EAAE,EAAC,CAAC,CAAC;QACpI,MAAM,cAAc,GAAqD,EAAE,CAAC;QAC5E,IAAI,UAAU,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACtD,cAAc,CAAC,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC;QACtE,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACnF,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAK,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,uGAAuG;QACvG,OAAM,CAAC;YACN,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE;gBACP,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAChC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,UAAS,KAAK;oBACpC,OAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzD,CAAC,CAAC;aACF;SACD,CAAC,CAAC;IACJ,CAAC;IAES,aAAa,CAAC,OAAwC;QAC/D,MAAM,MAAM,GAAwC;YACnD,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,EAAE;YAC9C,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC9D,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE;gBACT,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE;gBACnD,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;aAC1C;SACD,CAAC;QAEF,OAAM,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAES,cAAc,CAAC,QAAiD;QACzE,OAAM,CAAC,QAAQ,CAAC,CAAC;IAClB,CAAC;IAES,aAAa,CAAC,OAAyB;QAChD,gCAAgC;QAChC,mEAAmE;QACnE,MAAM,OAAO,GAAG,yCAAyC,CAAC,OAAO,CAAC,CAAC;QAEnE,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAK,CAAC,IAAI,KAAK,CAAC,uDAAuD,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC5F,CAAC;QAED,MAAM,MAAM,GAAoC;YAC/C,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC;YAClE,KAAK,EAAE,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAC5C,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE;gBACT,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC;gBACrI,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;aACvC;SACD,CAAC;QAEF,OAAM,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAES,cAAc,CAAC,QAAiC;QACzD,gCAAgC;QAChC,mEAAmE;QACnE,OAAM,CAAC,4CAA4C,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChE,CAAC;CACD;AAED,MAAM,0BAA2B,SAAQ,gCAAmG;IAC1H,YAAY,CAA4B;IACxC,QAAQ,CAAgD;IACjE,OAAO,GAAsH,EAAE,CAAC;IAExI,YAAY,OAAqP;QAChQ,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,CAAC;IAES,KAAK,CAAC,cAAc;QAC7B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;YAC7E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAExB,MAAM,MAAM,GAAG,IAAI,gCAAgC,CAAC;gBACnD,EAAE,EAAE,0BAA0B,OAAO,CAAC,sBAAsB,EAAE;gBAC9D,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,YAAY,EAAE,IAAI,CAAC,YAAY;aAC/B,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,MAAM,CAAC;QACvD,CAAC;IACF,CAAC;IAGS,QAAQ,CAAC,eAAsI;QACxJ,MAAK,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAwC;QACjD,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC;QAEvD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAK,CAAC,IAAI,KAAK,CAAC,+BAA+B,OAAO,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,OAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAA6B;QACtC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;YAC5D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1B,SAAS;YACV,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;QACF,CAAC;QAED,OAAM,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAgE;QACzE,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnB,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;YAC5D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1B,SAAS;YACV,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,IAAI,EAAE,CAAC;gBACV,MAAM,GAAG,IAAI,CAAC;YACf,CAAC;QACF,CAAC;QAED,OAAM,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,QAAQ;QACb,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;YAC5D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1B,SAAS;YACV,CAAC;YAED,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QACzB,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAE5C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QAEtB,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC;gBACJ,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,EAAE,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YAClD,CAAC;QACF,CAAC;IACF,CAAC;CAED;AAED,MAAM,OAAO,0BAA2B,SAAQ,qBAAqB,CAAC,wBAAmD;IAC/G,QAAQ,CAAqD;IAC7D,MAAM,CAAsC;IAC5C,QAAQ,CAAqD;IAC7D,OAAO,GAAyC,SAAS,CAAC;IAC1D,MAAM,CAAmD;IACzD,WAAW,CAA2C;IACtD,EAAE,CAAkC;IACpC,QAAQ,CAA6B;IACpC,uBAAuB,GAA0C,IAAI,CAAC;IAEhF,YAAY,MAAiC;QAC5C,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QAEtC;;WAEG;QACH,4DAA4D;QAC5D,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACnE;;;eAGG;YACH,4DAA4D;YAC5D,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/D,4DAA4D;YAC5D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC;YAC/C,4DAA4D;QAC5D,CAAC;aAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1E;;eAEG;YACH,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,MAAK,CAAC,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC,CAAC;YAC/E,CAAC;YAED,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,CAAC;aAAM,CAAC;YACP,MAAK,CAAC,IAAI,KAAK,CAAC,6HAA6H,CAAC,CAAC,CAAC;QACjJ,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAK,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED;;;WAGG;QACH,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC;QAC/C,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO,GAAG,IAAI,CAAC;QAChB,CAAC;QAED;;WAEG;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,0BAA0B,CAAC;YAC9C,EAAE,EAAE,gCAAgC;YACpC,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,IAAI,IAAI,mCAAmC,CAAC;gBAC3E,EAAE,EAAE,8CAA8C;gBAClD,MAAM,EAAE,IAAI,CAAC,MAAM;aACnB,CAAC;YACF,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI;SAClB,CAAC,CAAC;QAEH;;WAEG;QACH,IAAI,OAAO,EAAE,CAAC;YACb,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,uBAAuB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;gBACrD,IAAI,OAAO,EAAE,CAAC;oBACb,OAAO;gBACR,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;gBACf,IAAI,CAAC;oBACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBAChC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,EAAE,6BAA6B,EAAE,KAAK,CAAC,CAAC;gBAChH,CAAC;gBACD,IAAI,CAAC;oBACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,EAAE,yBAAyB,EAAE,KAAK,CAAC,CAAC;gBAC5G,CAAC;wBAAS,CAAC;oBACV,OAAO,GAAG,KAAK,CAAC;gBACjB,CAAC;YACF,CAAC,EAAE,IAAI,CAAC,CAAC;QACV,CAAC;IACF,CAAC;IAES,KAAK,CAAC,UAAU,CAAC,MAAiC;QAC3D,MAAM,MAAM,GAAiC,EAAE,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAE3B;;;WAGG;QACH,4DAA4D;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC;QAEtB;;WAEG;QACH,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;YAC1B,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK;gBACtB,IAAI,YAAoB,CAAC;gBACzB,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBACzC,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACP,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;wBACtB,MAAK,CAAC,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC;oBACnE,CAAC;oBAED,YAAY,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACxC,CAAC;gBAED,OAAM,CAAC;oBACN,MAAM,EAAE,YAAY;oBACpB,WAAW,EAAE,WAAW;iBACxB,CAAC,CAAC;YACJ,CAAC,CAAC;QACH,CAAC;QAED;;WAEG;QACH,MAAM,CAAC,uBAAuB,CAAC,GAAG,KAAK,WAAU,cAAc,EAAE,QAAQ;YACxE,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/C,MAAK,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAK,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;YAC/C,CAAC;YAED,MAAM,UAAU,GAAG,kCAAkC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACxE,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;YACvE,MAAM,gBAAgB,GAAkC;gBACvD,EAAE,EAAE,IAAI;gBACR,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC;oBAC1D,OAAO,EAAE,UAAU;oBACnB,eAAe,EAAE,UAAU,CAAC,eAAe;oBAC3C,YAAY,EAAE;wBACb,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM;wBAC3B,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM;wBAC3B,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK;qBAC5B;iBACD,CAAC;aACF,CAAC;YAEF,OAAM,CAAC;gBACN,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;aACxC,CAAC,CAAC;QACJ,CAAC,CAAA;QAED,MAAM,CAAC,oBAAoB,CAAC,GAAG,KAAK,WAAU,cAAc,EAAE,QAAQ;YACrE,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/C,MAAK,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAK,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;YAC/C,CAAC;YAED,MAAM,UAAU,GAAG,kCAAkC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACxE,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;YAEvE,IAAI,QAAQ,EAAE,CAAC;gBACd,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC;gBACxC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;oBAC1C,MAAK,CAAC,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC,CAAC;gBAClG,CAAC;YACF,CAAC;YAED,MAAM,aAAa,GAA2C,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC;gBAC9G,OAAO,EAAE,UAAU;gBACnB,GAAG,UAAU;aACb,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;YACjF,MAAM,aAAa,GAA+B;gBACjD,EAAE,EAAE,IAAI;gBACR,KAAK,EAAE,WAAW;aAClB,CAAC;YAEF,OAAM,CAAC;gBACN,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;aACrC,CAAC,CAAC;QACJ,CAAC,CAAA;QAED,MAAM,CAAC,0BAA0B,CAAC,GAAG,KAAK,WAAU,cAAc,EAAE,QAAQ;YAC3E,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/C,MAAK,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAC3C,CAAC;YAED,IAAI,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAK,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;YAC/C,CAAC;YACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC7C,MAAK,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAC9C,CAAC;YAED,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;gBAC3B,MAAK,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;YACnD,CAAC;YACD,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAChE,MAAK,CAAC,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC,CAAC;YAChE,CAAC;YAED,MAAM,KAAK,GAAG,yBAAyB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACvD,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,YAAY,EAAE,CAAC;gBACnB,MAAK,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAC7C,CAAC;YAED,oDAAoD;YACpD,IAAI,MAAM,CAAC,EAAE,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;gBAC3C,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC1D,IAAI,CAAC,YAAY,EAAE,CAAC;oBACnB,MAAK,CAAC,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;gBAC3C,CAAC;YACF,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAEpD,kDAAkD;YAClD,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACnF,IAAI,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YACtH,uDAAuD;YACvD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnC,mJAAmJ;gBACnJ,IAAI,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtD,cAAc,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC7C,qFAAqF;gBACrF,CAAC;qBAAM,CAAC;oBACP,IAAI,mBAAmB,GAAG,KAAK,CAAC;oBAChC,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;wBAC1C,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;4BAC9D,MAAM,gBAAgB,GAAG,SAAS,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;4BACtE,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;4BACxE,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;4BACrE,IAAI,gBAAgB,IAAI,YAAY,IAAI,aAAa,EAAE,CAAC;gCACvD,mBAAmB,GAAG,IAAI,CAAC;4BAC5B,CAAC;wBACF,CAAC;oBACF,CAAC;oBACD,IAAI,CAAC,mBAAmB,EAAE,CAAC;wBAC1B,MAAK,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;oBACpD,CAAC;gBACF,CAAC;YACF,CAAC;YAED,kCAAkC;YAClC,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAC9C,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC;gBAChE,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,QAAQ,EAAE;oBACT,KAAK,EAAE,aAAa;oBACpB,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;iBAC9B;aACD,CAAC,CAAC;YAEH,MAAM,gBAAgB,GAAkC;gBACvD,EAAE,EAAE,IAAI;gBACR,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE;gBACjC,MAAM,EAAE,SAAS;aACjB,CAAC;YAEF,OAAM,CAAC;gBACN,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;aACxC,CAAC,CAAC;QACJ,CAAC,CAAA;QAED,MAAM,CAAC,gCAAgC,CAAC,GAAG,KAAK,WAAU,MAAM;YAC/D,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC7C,MAAK,CAAC,IAAI,oBAAoB,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACpD,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;gBACpC,MAAK,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;YAClD,CAAC;YAED,yEAAyE;YACzE,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAkD,CAAC,CAAC;YACvG,MAAM,gBAAgB,GAAG,CAAC;gBACzB,MAAM,WAAW,GAAG,cAAc,EAAE,MAAM,CAAC;gBAC3C,QAAQ,WAAW,EAAE,CAAC;oBACrB,KAAK,SAAS;wBACb,MAAK,CAAC,IAAI,oBAAoB,CAAC,uBAAuB,CAAC,CAAC,CAAC;oBAC1D,KAAK,SAAS,CAAC;oBACf,KAAK,YAAY,CAAC;oBAClB,KAAK,OAAO,CAAC;oBACb,KAAK,SAAS,CAAC;oBACf,KAAK,oBAAoB;wBACxB,OAAM,CAAC;4BACN,EAAE,EAAE,IAAI;4BACR,MAAM,EAAE,SAAS;4BACjB,UAAU,EAAE,UAAU;yBACtB,CAAC,CAAC;oBACJ,KAAK,WAAW,CAAC,CAAC,CAAC;wBAClB,MAAM,SAAS,GAAG,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC;wBACpD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;4BAC7B,OAAM,CAAC;gCACN,EAAE,EAAE,IAAI;gCACR,MAAM,EAAE,SAAS;gCACjB,UAAU,EAAE,UAAU;6BACtB,CAAC,CAAC;wBACJ,CAAC;6BAAM,CAAC;4BACP,OAAM,CAAC;gCACN,EAAE,EAAE,IAAI;gCACR,MAAM,EAAE,WAAW;gCACnB,UAAU,EAAE,UAAU;gCACtB,SAAS,EAAE,SAAS;6BACpB,CAAC,CAAC;wBACJ,CAAC;oBACF,CAAC;oBACD,KAAK,oBAAoB;wBACxB,OAAM,CAAC;4BACN,EAAE,EAAE,KAAK;4BACT,UAAU,EAAE,UAAU;4BACtB,MAAM,EAAE,QAAQ;4BAChB,KAAK,EAAE,iBAAiB;yBACxB,CAAC,CAAC;oBACJ,KAAK,OAAO;wBACX,MAAK,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;oBAChD,KAAK,WAAW;wBACf,MAAK,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;oBACvD;wBACC,WAAW,CAAC,WAAW,CAAC,CAAC;gBAC3B,CAAC;YACF,CAAC,CAAC,EAAE,CAAC;YAEL,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,wBAAwB,EAAE,UAAU,EAAE,IAAI,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,CAAC,CAAC;YAEjJ,OAAM,CAAC;gBACN,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;aACxC,CAAC,CAAC;QACJ,CAAC,CAAA;QAED,OAAM,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACpB,MAAM,UAAU,GAAyE;YACxF,WAAW,EAAE,CAAC,IAAI,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;YAC/D,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;YACzD,cAAc,EAAE,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;YACrE,iBAAiB,EAAE,CAAC,IAAI,GAAG,CAAC,wBAAwB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,OAAO;SACrF,CAAC;QAEF,OAAM,CAAC;YACN,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE;YACxB,UAAU,EAAE,UAAU;SACtB,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI;QACT,IAAI,IAAI,CAAC,uBAAuB,KAAK,IAAI,EAAE,CAAC;YAC3C,aAAa,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YAC5C,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACrC,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAE9B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;CACD;AAED;;;;;GAKG;AACH,MAAM,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAA4D,CAAC;AAC5G,MAAM,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAgE,CAAC","sourcesContent":["import * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';\nimport { KeetaNet } from '../../client/index.js';\nimport {\n\tKeetaAnchorUserError\n} from '../../lib/error.js';\nimport {\n\tassertConversionInputCanonicalJSON,\n\tassertConversionQuoteJSON,\n\tErrors\n} from './common.js';\nimport type {\n\tConversionInputCanonicalJSON,\n\tKeetaFXAnchorEstimateResponse,\n\tKeetaFXAnchorExchangeResponse,\n\tKeetaFXAnchorQuote,\n\tKeetaFXAnchorQuoteJSON,\n\tKeetaFXAnchorQuoteResponse,\n\tKeetaNetAccount,\n\tKeetaNetStorageAccount\n} from './common.ts';\nimport * as Signing from '../../lib/utils/signing.js';\nimport type { AssertNever } from '../../lib/utils/never.ts';\nimport type { ServiceMetadata } from '../../lib/resolver.ts';\nimport { KeetaAnchorQueueRunner, KeetaAnchorQueueStorageDriverMemory } from '../../lib/queue/index.js';\nimport type { KeetaAnchorQueueStorageDriver, KeetaAnchorQueueRequestID } from '../../lib/queue/index.ts';\nimport { KeetaAnchorQueuePipelineAdvanced } from '../../lib/queue/pipeline.js';\nimport type { JSONSerializable } from '../../lib/utils/json.ts';\nimport { assertNever } from '../../lib/utils/never.js';\nimport * as typia from 'typia';\n\n/**\n * Enable additional runtime \"paranoid\" checks in the FX server.\n *\n * This may have a small performance impact but increases safety\n * by ensuring that the accounts used in quotes are actually\n * configured in the server.\n *\n * During the transition to multiple accounts this may help catch\n * misconfigurations so it is enabled by default for now.\n */\nconst PARANOID = true;\n\nexport interface KeetaAnchorFXServerConfig extends KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig {\n\t/**\n\t * The data to use for the index page (optional)\n\t */\n\thomepage?: string | (() => Promise<string> | string);\n\n\t/**\n\t * All accounts that may be used by the server to perform swaps\n\t *\n\t * Temporary compatibility: If this is not provided, the single\n\t * `account` property will be used to create a set of one account.\n\t */\n\taccounts?: InstanceType<typeof KeetaNet.lib.Account.Set>;\n\n\t/**\n\t * Account to use to perform transactions\n\t *\n\t * @deprecated Use `signer` and `accounts` instead\n\t */\n\taccount?: InstanceType<typeof KeetaNet.lib.Account> | undefined;\n\n\t/**\n\t * Account which can be used to sign transactions\n\t * for the accounts above\n\t *\n\t * This may be either a function or a KeetaNet Account instance.\n\t *\n\t * Temporary compatibility: If not provided, the `account` property\n\t * will be used as the signer.\n\t */\n\tsigner?: InstanceType<typeof KeetaNet.lib.Account> | ((request: ConversionInputCanonicalJSON) => Promise<InstanceType<typeof KeetaNet.lib.Account>> | InstanceType<typeof KeetaNet.lib.Account>);\n\n\t/**\n\t * Account which performs the signing and validation of quotes\n\t */\n\tquoteSigner: Signing.SignableAccount;\n\n\t/**\n\t * Configuration for FX handling\n\t */\n\tfx: {\n\t\t/**\n\t\t * Supported conversions\n\t\t */\n\t\tfrom?: NonNullable<ServiceMetadata['services']['fx']>[string]['from'];\n\t\t/**\n\t\t * Handle the conversion request of one token to another\n\t\t *\n\t\t * This is used to handle quotes and estimates\n\t\t */\n\t\tgetConversionRateAndFee: (request: ConversionInputCanonicalJSON) => Promise<Omit<KeetaFXAnchorQuote, 'request' | 'signed' >>;\n\n\t\t/**\n\t\t * Optional callback to validate a quote before completing an exchange\n\t\t *\n\t\t * This allows the FX Server operator to reject quotes that are no longer\n\t\t * acceptable (e.g., due to price changes, expiry, or other business logic)\n\t\t *\n\t\t * @param quote The quote to validate\n\t\t * @returns true to accept the quote and proceed with the exchange, false to reject it\n\t\t */\n\t\tvalidateQuote?: (quote: KeetaFXAnchorQuoteJSON) => Promise<boolean> | boolean;\n\n\t};\n\n\t/**\n\t * Storage driver to use for stateful operation and managing queues\n\t *\n\t * You are responsible for running and maintaining the queue processor unless\n\t * you enable auto-run below.\n\t */\n\tstorage?: {\n\t\t/**\n\t\t * The storage driver or queue runner to use to serialize\n\t\t * and batch requests\n\t\t */\n\t\tqueue: KeetaAnchorQueueStorageDriver<JSONSerializable, JSONSerializable>;\n\t\t/**\n\t\t * If enabled the server will automatically run the queue processor\n\t\t */\n\t\tautoRun?: boolean;\n\t};\n\n\t/**\n\t * The network client to use for submitting blocks\n\t */\n\tclient: { client: KeetaNet.Client; network: bigint; networkAlias: typeof KeetaNet.Client.Config.networksArray[number] } | KeetaNet.UserClient;\n};\n\nasync function formatQuoteSignable(unsignedQuote: Omit<KeetaFXAnchorQuoteJSON, 'signed'>): Promise<Signing.Signable> {\n\tconst retval: Signing.Signable = [\n\t\tunsignedQuote.request.from,\n\t\tunsignedQuote.request.to,\n\t\tunsignedQuote.request.amount,\n\t\tunsignedQuote.request.affinity,\n\t\tunsignedQuote.account,\n\t\tunsignedQuote.convertedAmount,\n\t\tunsignedQuote.cost.token,\n\t\tunsignedQuote.cost.amount\n\t];\n\n\treturn(retval);\n\n\t/**\n\t * This is a static assertion to ensure that this function is updated\n\t * if new fields are added to the KeetaFXAnchorQuote type to ensure\n\t * that we are always signing all the fields.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\ttype _ignore_static_assert = AssertNever<\n\t\t// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n\t\tAssertNever<keyof Omit<typeof unsignedQuote['request'], 'from' | 'to' | 'amount' | 'affinity'>> &\n\t\t// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents,@typescript-eslint/no-duplicate-type-constituents\n\t\tAssertNever<keyof Omit<typeof unsignedQuote['cost'], 'token' | 'amount'>> &\n\t\t// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents,@typescript-eslint/no-duplicate-type-constituents\n\t\tAssertNever<keyof Omit<typeof unsignedQuote, 'request' | 'convertedAmount' | 'cost' | 'account'>>\n\t>;\n}\n\nasync function generateSignedQuote(signer: Signing.SignableAccount, unsignedQuote: Omit<KeetaFXAnchorQuoteJSON, 'signed'>): Promise<KeetaFXAnchorQuoteJSON> {\n\tconst signableQuote = await formatQuoteSignable(unsignedQuote);\n\tconst signed = await Signing.SignData(signer, signableQuote);\n\n\treturn({\n\t\t...unsignedQuote,\n\t\tsigned: signed\n\t});\n}\n\nasync function verifySignedData(signedBy: Signing.VerifableAccount, quote: KeetaFXAnchorQuoteJSON): Promise<boolean> {\n\tconst signableQuote = await formatQuoteSignable(quote);\n\n\treturn(await Signing.VerifySignedData(signedBy, signableQuote, quote.signed));\n}\n\nasync function requestToAccounts(config: KeetaAnchorFXServerConfig, request: ConversionInputCanonicalJSON): Promise<{ signer: Signing.SignableAccount; account: KeetaNetAccount | KeetaNetStorageAccount | null; }> {\n\tlet account: KeetaNetAccount | KeetaNetStorageAccount | null;\n\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\tif (config.account !== undefined) {\n\t\tconst rateFee = await config.fx.getConversionRateAndFee(request);\n\t\taccount = rateFee.account;\n\t} else {\n\t\taccount = null;\n\t}\n\n\tlet signer: Signing.SignableAccount | null = null;\n\tif (config.signer !== undefined) {\n\t\tsigner = (KeetaNet.lib.Account.isInstance(config.signer) ? config.signer : await config.signer(request)).assertAccount();\n\t}\n\n\tif (account !== null) {\n\t\tif (signer === null) {\n\t\t\tsigner = account.assertAccount();\n\t\t}\n\n\t\tif (!account.isAccount() && !account.isStorage()) {\n\t\t\tthrow(new Error('FX Account should be an Account or Storage Account'));\n\t\t}\n\t} else if (signer === null) {\n\t\tthrow(new Error('Either account or signer must be provided'));\n\t}\n\n\treturn({\n\t\taccount: account,\n\t\tsigner: signer\n\t});\n}\n\n/* QUEUE PROCESSOR PIPELINE */\ntype KeetaFXAnchorQueueStage1Request = {\n\taccount: KeetaNetAccount;\n\tblock: Parameters<typeof KeetaNet.UserClient['acceptSwapRequest']>[0]['block'];\n\trequest: ConversionInputCanonicalJSON;\n\texpected: Required<NonNullable<Parameters<typeof KeetaNet.UserClient['acceptSwapRequest']>[0]['expected']>>;\n};\ntype KeetaFXAnchorQueueStage1RequestJSON = {\n\t/** Version of the request format */\n\tversion: 1;\n\t/** FX Anchor Account performing swap */\n\taccount: string;\n\t/** Base64 encoded block from the user */\n\tblock: string;\n\t/** Original request */\n\trequest: ConversionInputCanonicalJSON;\n\t/** Expected exchange details for verification */\n\texpected: {\n\t\ttoken: string;\n\t\tamount: string;\n\t};\n};\ntype KeetaFXAnchorQueueStage1Response = {\n\t/**\n\t * All the blocks for the given swap request\n\t */\n\tblocks: string[];\n\t/**\n\t * The hash of one of the blocks submitted\n\t */\n\tblockhash: string;\n};\n\nclass KeetaFXAnchorQueuePipelineStage1 extends KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response> {\n\tprotected readonly serverConfig: KeetaAnchorFXServerConfig;\n\tprotected sequential = true;\n\n\t/**\n\t * Timeout for processing a single job -- if exceeded the job is marked as aborted\n\t */\n\tprotected processTimeout: number = 60 * 1000;\n\n\tconstructor(config: ConstructorParameters<typeof KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>>[0] & { serverConfig: KeetaAnchorFXServerConfig; }) {\n\t\tsuper(config);\n\n\t\tthis.serverConfig = config.serverConfig;\n\t\tthis.processorAborted = this.processorStuck.bind(this);\n\t}\n\n\t/**\n\t * Handles both stuck (no status update after a long period) and\n\t * aborted (timeout while processing an entry) states.\n\t *\n\t * We just put the job back into pending because the processor\n\t * will check the network state again.\n\t */\n\tprotected async processorStuck(entry: Parameters<NonNullable<KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>['processorStuck']>>[0]): ReturnType<NonNullable<KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>['processorStuck']>> {\n\t\treturn({\n\t\t\tstatus: 'pending',\n\t\t\toutput: entry.output\n\t\t});\n\t}\n\n\t/**\n\t * Process the entry, attempting to submit the swap block(s)\n\t * to the network. Verifies the block can be submitted before\n\t * attempting submission. Also verifies if the block is already\n\t * on the network and marks the job as completed if so.\n\t */\n\tprotected async processor(entry: Parameters<KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>['processor']>[0]): ReturnType<KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>['processor']> {\n\t\tconst { block, expected, request } = entry.request;\n\t\tconst expectedToken = expected.token;\n\t\tconst expectedAmount = expected.amount;\n\t\tconst config = this.serverConfig;\n\n\t\tlet userClient: KeetaNet.UserClient;\n\n\t\tif (KeetaNet.UserClient.isInstance(config.client)) {\n\t\t\tuserClient = config.client;\n\t\t} else {\n\t\t\tconst { signer, account: checkAccount } = await requestToAccounts(config, request);\n\n\t\t\tif (checkAccount === null) {\n\t\t\t\tif (this.serverConfig.accounts === undefined) {\n\t\t\t\t\tthrow(new Error('No accounts configured for FX server'));\n\t\t\t\t}\n\n\t\t\t\tif (!this.serverConfig.accounts.has(entry.request.account)) {\n\t\t\t\t\treturn({\n\t\t\t\t\t\tstatus: 'failed_permanently',\n\t\t\t\t\t\toutput: null,\n\t\t\t\t\t\terror: `Mismatched account for FX request and configured account (no matching account found)`\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (!checkAccount.comparePublicKey(entry.request.account)) {\n\t\t\t\treturn({\n\t\t\t\t\tstatus: 'failed_permanently',\n\t\t\t\t\toutput: null,\n\t\t\t\t\terror: `Mismatched account for FX request and configured account (single account not matched)`\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tuserClient = new KeetaNet.UserClient({\n\t\t\t\tclient: config.client.client,\n\t\t\t\tnetwork: config.client.network,\n\t\t\t\tnetworkAlias: config.client.networkAlias,\n\t\t\t\taccount: entry.request.account,\n\t\t\t\tsigner: signer\n\t\t\t});\n\t\t}\n\n\t\t/* Check for the block already being on the network, if so we can mark this job as completed */\n\t\tconst blockExists = await userClient.block(block.hash);\n\t\tif (blockExists !== null) {\n\t\t\tconst existingOutput = entry.output;\n\t\t\tconst blocks = existingOutput?.blocks ?? [Buffer.from(block.toBytes()).toString('base64')];\n\n\t\t\treturn({\n\t\t\t\tstatus: 'completed',\n\t\t\t\toutput: {\n\t\t\t\t\tblockhash: block.hash.toString(),\n\t\t\t\t\tblocks: blocks\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t/* Get the current head block of the account in the block */\n\t\tconst accountHead = await userClient.head({ account: block.account });\n\t\tlet isHeadBlock = false;\n\t\tif (accountHead !== null) {\n\t\t\tisHeadBlock = accountHead.compare(block.previous);\n\t\t} else {\n\t\t\tisHeadBlock = block['$opening'];\n\t\t}\n\n\t\t/* If the account's head block is not the block's previous, see if the block's previous exists on the network */\n\t\tif (!isHeadBlock) {\n\t\t\tlet previousBlockOnNetwork = false;\n\t\t\tif (block['$opening']) {\n\t\t\t\t/* Opening block means that there is no previous block, so we are free to proceed */\n\t\t\t\tpreviousBlockOnNetwork = true;\n\t\t\t} else {\n\t\t\t\tconst previousBlock = await userClient.block(block.previous);\n\t\t\t\tif (previousBlock !== null) {\n\t\t\t\t\tpreviousBlockOnNetwork = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet blockPreviousString: string;\n\t\t\tif (block['$opening']) {\n\t\t\t\tblockPreviousString = '<opening>';\n\t\t\t} else {\n\t\t\t\tblockPreviousString = block.previous.toString();\n\t\t\t}\n\n\t\t\t/* If block.previous exists on the network, and it's not the account head block we can mark this job as failed_permanently */\n\t\t\tif (previousBlockOnNetwork) {\n\t\t\t\t/* Block's previous exists on the network, but is not the account head -- mark as failed_permanently */\n\t\t\t\treturn({\n\t\t\t\t\tstatus: 'failed_permanently',\n\t\t\t\t\toutput: null,\n\t\t\t\t\terror: `Block previous (${blockPreviousString}) exists on the network but is not the account head`\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t/* If block.previous does not exist on the network we can mark this job as failed_temporarily -- it can't process until the missing block is added */\n\t\t\t\t/* Block's previous does not exist on the network -- mark as failed_temporarily */\n\t\t\t\treturn({\n\t\t\t\t\tstatus: 'failed_temporarily',\n\t\t\t\t\toutput: null,\n\t\t\t\t\terror: `Block previous (${blockPreviousString}) does not exist on the network`\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/* We are clear to attempt the swap now */\n\t\tconst swapBlocks = await userClient.acceptSwapRequest({ block, expected: { token: expectedToken, amount: BigInt(expectedAmount) }});\n\t\tconst publishOptions: Parameters<typeof userClient.client.transmit>[1] = {};\n\t\tif (userClient.config.generateFeeBlock !== undefined) {\n\t\t\tpublishOptions.generateFeeBlock = userClient.config.generateFeeBlock;\n\t\t}\n\t\tconst publishResult = await userClient.client.transmit(swapBlocks, publishOptions);\n\t\tif (!publishResult.publish) {\n\t\t\tthrow(new Error('Exchange Publish Failed'));\n\t\t}\n\n\t\t/* Set the output and mark the job as pending so we can run the queue again and check for completion */\n\t\treturn({\n\t\t\tstatus: 'pending',\n\t\t\toutput: {\n\t\t\t\tblockhash: block.hash.toString(),\n\t\t\t\tblocks: swapBlocks.map(function(block) {\n\t\t\t\t\treturn(Buffer.from(block.toBytes()).toString('base64'));\n\t\t\t\t})\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected encodeRequest(request: KeetaFXAnchorQueueStage1Request): JSONSerializable {\n\t\tconst retval: KeetaFXAnchorQueueStage1RequestJSON = {\n\t\t\tversion: 1,\n\t\t\taccount: request.account.publicKeyString.get(),\n\t\t\tblock: Buffer.from(request.block.toBytes()).toString('base64'),\n\t\t\trequest: request.request,\n\t\t\texpected: {\n\t\t\t\ttoken: request.expected.token.publicKeyString.get(),\n\t\t\t\tamount: request.expected.amount.toString()\n\t\t\t}\n\t\t};\n\n\t\treturn(retval);\n\t}\n\n\tprotected encodeResponse(response: KeetaFXAnchorQueueStage1Response | null): JSONSerializable | null {\n\t\treturn(response);\n\t}\n\n\tprotected decodeRequest(request: JSONSerializable): KeetaFXAnchorQueueStage1Request {\n\t\t/* See note at bottom of file */\n\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\tconst reqJSON = assertKeetaFXAnchorQueueStage1RequestJSON(request);\n\n\t\tif (reqJSON.version !== 1) {\n\t\t\tthrow(new Error(`Unsupported KeetaFXAnchorQueueStage1Request version ${reqJSON.version}`));\n\t\t}\n\n\t\tconst retval: KeetaFXAnchorQueueStage1Request = {\n\t\t\taccount: KeetaNet.lib.Account.fromPublicKeyString(reqJSON.account),\n\t\t\tblock: new KeetaNet.lib.Block(reqJSON.block),\n\t\t\trequest: reqJSON.request,\n\t\t\texpected: {\n\t\t\t\ttoken: KeetaNet.lib.Account.fromPublicKeyString(reqJSON.expected.token).assertKeyType(KeetaNet.lib.Account.AccountKeyAlgorithm.TOKEN),\n\t\t\t\tamount: BigInt(reqJSON.expected.amount)\n\t\t\t}\n\t\t};\n\n\t\treturn(retval);\n\t}\n\n\tprotected decodeResponse(response: JSONSerializable | null): KeetaFXAnchorQueueStage1Response | null {\n\t\t/* See note at bottom of file */\n\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\treturn(assertKeetaFXAnchorQueueStage1ResponseOrNull(response));\n\t}\n}\n\nclass KeetaFXAnchorQueuePipeline extends KeetaAnchorQueuePipelineAdvanced<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response> {\n\tprivate readonly serverConfig: KeetaAnchorFXServerConfig;\n\tprivate readonly accounts: InstanceType<typeof KeetaNet.lib.Account.Set>;\n\tprivate runners: { [account: string]: KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>; } = {};\n\n\tconstructor(options: ConstructorParameters<typeof KeetaAnchorQueuePipelineAdvanced<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>>[0] & { serverConfig: KeetaAnchorFXServerConfig; accounts: InstanceType<typeof KeetaNet.lib.Account.Set>; }) {\n\t\tsuper(options);\n\n\t\tthis.serverConfig = options.serverConfig;\n\t\tthis.accounts = options.accounts;\n\t}\n\n\tprotected async createPipeline(): Promise<void> {\n\t\tfor (const account of this.accounts) {\n\t\t\tconst queue = await this.baseQueue.partition(account.publicKeyAndTypeString);\n\t\t\tthis.queues.push(queue);\n\n\t\t\tconst runner = new KeetaFXAnchorQueuePipelineStage1({\n\t\t\t\tid: `keeta-fx-anchor-runner-${account.publicKeyAndTypeString}`,\n\t\t\t\tqueue: queue,\n\t\t\t\tlogger: this.logger,\n\t\t\t\tserverConfig: this.serverConfig\n\t\t\t});\n\t\t\tthis.runners[account.publicKeyAndTypeString] = runner;\n\t\t}\n\t}\n\n\tprotected getStage(stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.first | typeof KeetaAnchorQueuePipelineAdvanced.StageID.last): KeetaFXAnchorQueuePipelineStage1;\n\tprotected getStage(_ignore_stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.first | typeof KeetaAnchorQueuePipelineAdvanced.StageID.last | string): KeetaFXAnchorQueuePipelineStage1 | null {\n\t\tthrow(new Error('method not supported'));\n\t}\n\n\tasync add(request: KeetaFXAnchorQueueStage1Request): ReturnType<KeetaFXAnchorQueuePipelineStage1['add']> {\n\t\tawait super.init();\n\n\t\tconst account = request.account.publicKeyAndTypeString;\n\n\t\tconst runner = this.runners[account];\n\t\tif (runner === undefined) {\n\t\t\tthrow(new Error(`No queue runner for account ${account}`));\n\t\t}\n\n\t\treturn(await runner.add(request));\n\t}\n\n\tasync get(id: KeetaAnchorQueueRequestID): ReturnType<KeetaFXAnchorQueuePipelineStage1['get']> {\n\t\tawait super.init();\n\n\t\tfor (const account of this.accounts) {\n\t\t\tconst runner = this.runners[account.publicKeyAndTypeString];\n\t\t\tif (runner === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst entry = await runner.get(id);\n\t\t\tif (entry !== null) {\n\t\t\t\treturn(entry);\n\t\t\t}\n\t\t}\n\n\t\treturn(null);\n\t}\n\n\tasync run(options?: Parameters<KeetaFXAnchorQueuePipelineStage1['run']>[0]): ReturnType<KeetaFXAnchorQueuePipelineStage1['run']> {\n\t\tawait super.init();\n\n\t\tlet retval = false;\n\t\tfor (const account of this.accounts) {\n\t\t\tconst runner = this.runners[account.publicKeyAndTypeString];\n\t\t\tif (runner === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst more = await runner.run(options);\n\t\t\tif (more) {\n\t\t\t\tretval = true;\n\t\t\t}\n\t\t}\n\n\t\treturn(retval);\n\t}\n\n\tasync maintain(): Promise<void> {\n\t\tawait super.init();\n\n\t\tfor (const account of this.accounts) {\n\t\t\tconst runner = this.runners[account.publicKeyAndTypeString];\n\t\t\tif (runner === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tawait runner.maintain();\n\t\t}\n\t}\n\n\tasync destroy(): Promise<void> {\n\t\tconst logger = this.methodLogger('destroy');\n\n\t\tif (this.destroyed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.destroyed = true;\n\n\t\tawait super.destroy();\n\n\t\tfor (const runner of Object.values(this.runners)) {\n\t\t\ttry {\n\t\t\t\tawait runner.destroy();\n\t\t\t} catch (error) {\n\t\t\t\tlogger?.error('Error destroying runner:', error);\n\t\t\t}\n\t\t}\n\t}\n\n}\n\nexport class KeetaNetFXAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<KeetaAnchorFXServerConfig> implements Omit<Required<KeetaAnchorFXServerConfig>, 'storage'> {\n\treadonly homepage: NonNullable<KeetaAnchorFXServerConfig['homepage']>;\n\treadonly client: KeetaAnchorFXServerConfig['client'];\n\treadonly accounts: NonNullable<KeetaAnchorFXServerConfig['accounts']>;\n\treadonly account: KeetaAnchorFXServerConfig['account'] = undefined;\n\treadonly signer: NonNullable<KeetaAnchorFXServerConfig['signer']>;\n\treadonly quoteSigner: KeetaAnchorFXServerConfig['quoteSigner'];\n\treadonly fx: KeetaAnchorFXServerConfig['fx'];\n\treadonly pipeline: KeetaFXAnchorQueuePipeline;\n\tprotected pipelineAutoRunInterval: ReturnType<typeof setInterval> | null = null;\n\n\tconstructor(config: KeetaAnchorFXServerConfig) {\n\t\tsuper(config);\n\n\t\tthis.homepage = config.homepage ?? '';\n\t\tthis.client = config.client;\n\t\tthis.fx = config.fx;\n\t\tthis.quoteSigner = config.quoteSigner;\n\n\t\t/*\n\t\t * Setup the accounts\n\t\t */\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tif (config.account !== undefined && config.accounts === undefined) {\n\t\t\t/*\n\t\t\t * Deprecated: If a single account is provided, use that\n\t\t\t * along with the signer to create the accounts set\n\t\t\t */\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tthis.accounts = new KeetaNet.lib.Account.Set([config.account]);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tthis.signer = config.signer ?? config.account;\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t} else if (config.accounts !== undefined && config.account === undefined) {\n\t\t\t/*\n\t\t\t * Only allow either \"account\" or \"accounts\"+\"signer\" to be provided\n\t\t\t */\n\t\t\tif (config.signer === undefined) {\n\t\t\t\tthrow(new Error('If \"accounts\" is provided, \"signer\" must also be provided'));\n\t\t\t}\n\n\t\t\tthis.accounts = config.accounts;\n\t\t\tthis.signer = config.signer;\n\t\t} else {\n\t\t\tthrow(new Error('Either \"account\" (and optional \"signer\") or \"accounts\" and \"signer\" must be provided, but not both \"account\" and \"accounts\"'));\n\t\t}\n\n\t\tif (this.accounts.size === 0) {\n\t\t\tthrow(new Error('No FX accounts provided'));\n\t\t}\n\n\t\t/*\n\t\t * If no storage driver is provided, we default to an in-memory\n\t\t * that we auto-run\n\t\t */\n\t\tlet autorun = config.storage?.autoRun ?? false;\n\t\tif (config.storage === undefined) {\n\t\t\tautorun = true;\n\t\t}\n\n\t\t/*\n\t\t * Create the pipeline to process transactions\n\t\t */\n\t\tthis.pipeline = new KeetaFXAnchorQueuePipeline({\n\t\t\tid: 'keeta-fx-anchor-queue-pipeline',\n\t\t\tbaseQueue: config.storage?.queue ?? new KeetaAnchorQueueStorageDriverMemory({\n\t\t\t\tid: 'keeta-fx-anchor-queue-pipeline-memory-driver',\n\t\t\t\tlogger: this.logger\n\t\t\t}),\n\t\t\taccounts: this.accounts,\n\t\t\tlogger: this.logger,\n\t\t\tserverConfig: this\n\t\t});\n\n\t\t/*\n\t\t * If auto-run is enabled, setup the interval to run the pipeline\n\t\t */\n\t\tif (autorun) {\n\t\t\tlet running = false;\n\t\t\tthis.pipelineAutoRunInterval = setInterval(async () => {\n\t\t\t\tif (running) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trunning = true;\n\t\t\t\ttry {\n\t\t\t\t\tawait this.pipeline.maintain();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.logger.error('KeetaNetFXAnchorHTTPServer::pipelineAutoRunInterval', 'Error maintaining pipeline:', error);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.pipeline.run({ timeoutMs: 5000 });\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.logger.error('KeetaNetFXAnchorHTTPServer::pipelineAutoRunInterval', 'Error running pipeline:', error);\n\t\t\t\t} finally {\n\t\t\t\t\trunning = false;\n\t\t\t\t}\n\t\t\t}, 1000);\n\t\t}\n\t}\n\n\tprotected async initRoutes(config: KeetaAnchorFXServerConfig): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = {};\n\t\tconst logger = this.logger;\n\n\t\t/*\n\t\t * To use the instance within the route handlers, we need to\n\t\t * make a local reference to it.\n\t\t */\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst instance = this;\n\n\t\t/**\n\t\t * If a homepage is provided, setup the route for it\n\t\t */\n\t\tif ('homepage' in config) {\n\t\t\troutes['GET /'] = async function() {\n\t\t\t\tlet homepageData: string;\n\t\t\t\tif (typeof config.homepage === 'string') {\n\t\t\t\t\thomepageData = config.homepage;\n\t\t\t\t} else {\n\t\t\t\t\tif (!config.homepage) {\n\t\t\t\t\t\tthrow(new Error('internal error: No homepage function provided'));\n\t\t\t\t\t}\n\n\t\t\t\t\thomepageData = await config.homepage();\n\t\t\t\t}\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: homepageData,\n\t\t\t\t\tcontentType: 'text/html'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\t/**\n\t\t * Setup the request handler for an estimate request\n\t\t */\n\t\troutes['POST /api/getEstimate'] = async function(_ignore_params, postData) {\n\t\t\tif (!postData || typeof postData !== 'object') {\n\t\t\t\tthrow(new Error('No POST data provided'));\n\t\t\t}\n\t\t\tif (!('request' in postData)) {\n\t\t\t\tthrow(new Error('POST data missing request'));\n\t\t\t}\n\n\t\t\tconst conversion = assertConversionInputCanonicalJSON(postData.request);\n\t\t\tconst rateAndFee = await config.fx.getConversionRateAndFee(conversion);\n\t\t\tconst estimateResponse: KeetaFXAnchorEstimateResponse = {\n\t\t\t\tok: true,\n\t\t\t\testimate: KeetaNet.lib.Utils.Conversion.toJSONSerializable({\n\t\t\t\t\trequest: conversion,\n\t\t\t\t\tconvertedAmount: rateAndFee.convertedAmount,\n\t\t\t\t\texpectedCost: {\n\t\t\t\t\t\tmin: rateAndFee.cost.amount,\n\t\t\t\t\t\tmax: rateAndFee.cost.amount,\n\t\t\t\t\t\ttoken: rateAndFee.cost.token\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t};\n\n\t\t\treturn({\n\t\t\t\toutput: JSON.stringify(estimateResponse)\n\t\t\t});\n\t\t}\n\n\t\troutes['POST /api/getQuote'] = async function(_ignore_params, postData) {\n\t\t\tif (!postData || typeof postData !== 'object') {\n\t\t\t\tthrow(new Error('No POST data provided'));\n\t\t\t}\n\t\t\tif (!('request' in postData)) {\n\t\t\t\tthrow(new Error('POST data missing request'));\n\t\t\t}\n\n\t\t\tconst conversion = assertConversionInputCanonicalJSON(postData.request);\n\t\t\tconst rateAndFee = await config.fx.getConversionRateAndFee(conversion);\n\n\t\t\tif (PARANOID) {\n\t\t\t\tconst quoteAccount = rateAndFee.account;\n\t\t\t\tif (!instance.accounts.has(quoteAccount)) {\n\t\t\t\t\tthrow(new Error('\"getConversionRateAndFee\" returned an account not configured for this server'));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst unsignedQuote: Omit<KeetaFXAnchorQuoteJSON, 'signed'> = KeetaNet.lib.Utils.Conversion.toJSONSerializable({\n\t\t\t\trequest: conversion,\n\t\t\t\t...rateAndFee\n\t\t\t});\n\n\t\t\tconst signedQuote = await generateSignedQuote(config.quoteSigner, unsignedQuote);\n\t\t\tconst quoteResponse: KeetaFXAnchorQuoteResponse = {\n\t\t\t\tok: true,\n\t\t\t\tquote: signedQuote\n\t\t\t};\n\n\t\t\treturn({\n\t\t\t\toutput: JSON.stringify(quoteResponse)\n\t\t\t});\n\t\t}\n\n\t\troutes['POST /api/createExchange'] = async function(_ignore_params, postData) {\n\t\t\tif (!postData || typeof postData !== 'object') {\n\t\t\t\tthrow(new Error('No POST data provided'));\n\t\t\t}\n\n\t\t\tif (!('request' in postData)) {\n\t\t\t\tthrow(new Error('POST data missing request'));\n\t\t\t}\n\t\t\tconst request = postData.request;\n\t\t\tif (!request || typeof request !== 'object') {\n\t\t\t\tthrow(new Error('Request is not an object'));\n\t\t\t}\n\n\t\t\tif (!('quote' in request)) {\n\t\t\t\tthrow(new Error('Quote is missing from request'));\n\t\t\t}\n\t\t\tif (!('block' in request) || typeof request.block !== 'string') {\n\t\t\t\tthrow(new Error('Block was not provided in exchange request'));\n\t\t\t}\n\n\t\t\tconst quote = assertConversionQuoteJSON(request.quote);\n\t\t\tconst isValidQuote = await verifySignedData(config.quoteSigner, quote);\n\t\t\tif (!isValidQuote) {\n\t\t\t\tthrow(new Error('Invalid quote signature'));\n\t\t\t}\n\n\t\t\t/* Validate the quote using the optional callback */\n\t\t\tif (config.fx.validateQuote !== undefined) {\n\t\t\t\tconst isAcceptable = await config.fx.validateQuote(quote);\n\t\t\t\tif (!isAcceptable) {\n\t\t\t\t\tthrow(new Errors.QuoteValidationFailed());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst block = new KeetaNet.lib.Block(request.block);\n\n\t\t\t/* Get Expected Amount and Token to Verify Swap */\n\t\t\tconst expectedToken = KeetaNet.lib.Account.fromPublicKeyString(quote.request.from);\n\t\t\tlet expectedAmount = quote.request.affinity === 'from' ? BigInt(quote.request.amount) : BigInt(quote.convertedAmount);\n\t\t\t/* If cost is required verify the amounts and token. */\n\t\t\tif (BigInt(quote.cost.amount) > 0) {\n\t\t\t\t/* If swap token matches the cost token the add the amount since they should be combined in one block and will be checked in `acceptSwapRequest` */\n\t\t\t\tif (expectedToken.comparePublicKey(quote.cost.token)) {\n\t\t\t\t\texpectedAmount += BigInt(quote.cost.amount);\n\t\t\t\t/* If token is different then check block operations for matching amount and token */\n\t\t\t\t} else {\n\t\t\t\t\tlet requestIncludesCost = false;\n\t\t\t\t\tfor (const operation of block.operations) {\n\t\t\t\t\t\tif (operation.type === KeetaNet.lib.Block.OperationType.SEND) {\n\t\t\t\t\t\t\tconst recipientMatches = operation.to.comparePublicKey(quote.account);\n\t\t\t\t\t\t\tconst tokenMatches = operation.token.comparePublicKey(quote.cost.token);\n\t\t\t\t\t\t\tconst amountMatches = operation.amount === BigInt(quote.cost.amount);\n\t\t\t\t\t\t\tif (recipientMatches && tokenMatches && amountMatches) {\n\t\t\t\t\t\t\t\trequestIncludesCost = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!requestIncludesCost) {\n\t\t\t\t\t\tthrow(new Error('Exchange missing required cost'));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Enqueue the exchange request */\n\t\t\tconst exchangeID = await instance.pipeline.add({\n\t\t\t\taccount: KeetaNet.lib.Account.fromPublicKeyString(quote.account),\n\t\t\t\tblock: block,\n\t\t\t\trequest: quote.request,\n\t\t\t\texpected: {\n\t\t\t\t\ttoken: expectedToken,\n\t\t\t\t\tamount: BigInt(expectedAmount)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst exchangeResponse: KeetaFXAnchorExchangeResponse = {\n\t\t\t\tok: true,\n\t\t\t\texchangeID: exchangeID.toString(),\n\t\t\t\tstatus: 'pending'\n\t\t\t};\n\n\t\t\treturn({\n\t\t\t\toutput: JSON.stringify(exchangeResponse)\n\t\t\t});\n\t\t}\n\n\t\troutes['GET /api/getExchangeStatus/:id'] = async function(params) {\n\t\t\tif (params === undefined || params === null) {\n\t\t\t\tthrow(new KeetaAnchorUserError('Expected params'));\n\t\t\t}\n\t\t\tconst exchangeID = params.get('id');\n\t\t\tif (typeof exchangeID !== 'string') {\n\t\t\t\tthrow(new Error('Missing exchangeID in params'));\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tconst queueEntryInfo = await instance.pipeline.get(exchangeID as unknown as KeetaAnchorQueueRequestID);\n\t\t\tconst exchangeResponse = (function(): KeetaFXAnchorExchangeResponse {\n\t\t\t\tconst inputStatus = queueEntryInfo?.status;\n\t\t\t\tswitch (inputStatus) {\n\t\t\t\t\tcase undefined:\n\t\t\t\t\t\tthrow(new KeetaAnchorUserError('Exchange ID not found'));\n\t\t\t\t\tcase 'pending':\n\t\t\t\t\tcase 'processing':\n\t\t\t\t\tcase 'stuck':\n\t\t\t\t\tcase 'aborted':\n\t\t\t\t\tcase 'failed_temporarily':\n\t\t\t\t\t\treturn({\n\t\t\t\t\t\t\tok: true,\n\t\t\t\t\t\t\tstatus: 'pending',\n\t\t\t\t\t\t\texchangeID: exchangeID\n\t\t\t\t\t\t});\n\t\t\t\t\tcase 'completed': {\n\t\t\t\t\t\tconst blockhash = queueEntryInfo?.output?.blockhash;\n\t\t\t\t\t\tif (blockhash === undefined) {\n\t\t\t\t\t\t\treturn({\n\t\t\t\t\t\t\t\tok: true,\n\t\t\t\t\t\t\t\tstatus: 'pending',\n\t\t\t\t\t\t\t\texchangeID: exchangeID\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn({\n\t\t\t\t\t\t\t\tok: true,\n\t\t\t\t\t\t\t\tstatus: 'completed',\n\t\t\t\t\t\t\t\texchangeID: exchangeID,\n\t\t\t\t\t\t\t\tblockhash: blockhash\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'failed_permanently':\n\t\t\t\t\t\treturn({\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\texchangeID: exchangeID,\n\t\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t\t\terror: 'Exchange failed'\n\t\t\t\t\t\t});\n\t\t\t\t\tcase 'moved':\n\t\t\t\t\t\tthrow(new Error('Exchange ID has been moved'));\n\t\t\t\t\tcase '@internal':\n\t\t\t\t\t\tthrow(new Error('Invalid exchange status @internal'));\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tassertNever(inputStatus);\n\t\t\t\t}\n\t\t\t})();\n\n\t\t\tlogger.debug('GET /api/getExchangeStatus/:id', 'Exchange Status for ID', exchangeID, 'is', exchangeResponse, 'based on jobInfo', queueEntryInfo);\n\n\t\t\treturn({\n\t\t\t\toutput: JSON.stringify(exchangeResponse)\n\t\t\t});\n\t\t}\n\n\t\treturn(routes);\n\t}\n\n\t/**\n\t * Return the servers endpoints and possible currency conversions metadata\n\t */\n\tasync serviceMetadata(): Promise<NonNullable<ServiceMetadata['services']['fx']>[string]> {\n\t\tconst operations: NonNullable<ServiceMetadata['services']['fx']>[string]['operations'] = {\n\t\t\tgetEstimate: (new URL('/api/getEstimate', this.url)).toString(),\n\t\t\tgetQuote: (new URL('/api/getQuote', this.url)).toString(),\n\t\t\tcreateExchange: (new URL('/api/createExchange', this.url)).toString(),\n\t\t\tgetExchangeStatus: (new URL('/api/getExchangeStatus', this.url)).toString() + '/{id}'\n\t\t};\n\n\t\treturn({\n\t\t\tfrom: this.fx.from ?? [],\n\t\t\toperations: operations\n\t\t});\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tif (this.pipelineAutoRunInterval !== null) {\n\t\t\tclearInterval(this.pipelineAutoRunInterval);\n\t\t\tthis.pipelineAutoRunInterval = null;\n\t\t}\n\n\t\tawait this.pipeline.destroy();\n\n\t\tawait super.stop();\n\t}\n}\n\n/*\n * These are placed at the bottom of the file because the generation\n * breaks the code coverage computation; Normally, we'd place these\n * in a \".generated.ts\" file but for simplicity of internal types\n * we keep them here.\n */\nconst assertKeetaFXAnchorQueueStage1RequestJSON = typia.createAssert<KeetaFXAnchorQueueStage1RequestJSON>();\nconst assertKeetaFXAnchorQueueStage1ResponseOrNull = typia.createAssert<KeetaFXAnchorQueueStage1Response | null>();\n"]}
|