@keetanetwork/anchor 0.0.49 → 0.0.51
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/resolver.d.ts +1 -0
- package/lib/resolver.d.ts.map +1 -1
- package/lib/resolver.js +52 -37
- package/lib/resolver.js.map +1 -1
- package/npm-shrinkwrap.json +8 -8
- package/package.json +2 -2
- package/services/asset-movement/client.d.ts.map +1 -1
- package/services/asset-movement/client.js +8 -6
- package/services/asset-movement/client.js.map +1 -1
- package/services/asset-movement/common.d.ts +9 -5
- package/services/asset-movement/common.d.ts.map +1 -1
- package/services/asset-movement/common.js +18113 -9853
- package/services/asset-movement/common.js.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/bcr-pay.d.ts +4 -0
- package/services/asset-movement/lib/data/addresses/bank-account/bcr-pay.d.ts.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/bcr-pay.js +36 -0
- package/services/asset-movement/lib/data/addresses/bank-account/bcr-pay.js.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/duit-now.d.ts +4 -0
- package/services/asset-movement/lib/data/addresses/bank-account/duit-now.d.ts.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/duit-now.js +35 -0
- package/services/asset-movement/lib/data/addresses/bank-account/duit-now.js.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/hk-fps.d.ts +4 -0
- package/services/asset-movement/lib/data/addresses/bank-account/hk-fps.d.ts.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/hk-fps.js +36 -0
- package/services/asset-movement/lib/data/addresses/bank-account/hk-fps.js.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/index.generated.d.ts +10 -0
- package/services/asset-movement/lib/data/addresses/bank-account/index.generated.d.ts.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/index.generated.js +10 -0
- package/services/asset-movement/lib/data/addresses/bank-account/index.generated.js.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/pay-now.d.ts +4 -0
- package/services/asset-movement/lib/data/addresses/bank-account/pay-now.d.ts.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/pay-now.js +36 -0
- package/services/asset-movement/lib/data/addresses/bank-account/pay-now.js.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/pix.d.ts.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/pix.js +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/pix.js.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/upi.d.ts +4 -0
- package/services/asset-movement/lib/data/addresses/bank-account/upi.d.ts.map +1 -0
- package/services/asset-movement/lib/data/addresses/bank-account/upi.js +37 -0
- package/services/asset-movement/lib/data/addresses/bank-account/upi.js.map +1 -0
- package/services/asset-movement/lib/data/addresses/types.generated.d.ts +458 -2
- package/services/asset-movement/lib/data/addresses/types.generated.d.ts.map +1 -1
- package/services/asset-movement/lib/data/addresses/types.generated.js +508 -0
- package/services/asset-movement/lib/data/addresses/types.generated.js.map +1 -1
- package/services/asset-movement/lib/location.generated.js +3 -3
- package/services/fx/common.d.ts +1 -1
- package/services/fx/common.d.ts.map +1 -1
- package/services/fx/common.js +16 -16
- package/services/fx/common.js.map +1 -1
- package/services/fx/server.d.ts.map +1 -1
- package/services/fx/server.js +13 -17
- package/services/fx/server.js.map +1 -1
- package/services/notification/common.generated.js +34 -34
- package/services/storage/client.d.ts +38 -0
- package/services/storage/client.d.ts.map +1 -1
- package/services/storage/client.js +87 -13
- package/services/storage/client.js.map +1 -1
- package/services/storage/clients/contacts.d.ts +2 -2
- package/services/storage/clients/contacts.d.ts.map +1 -1
- package/services/storage/clients/contacts.generated.js +1216 -406
- package/services/storage/clients/contacts.generated.js.map +1 -1
- package/services/storage/clients/contacts.js +27 -9
- package/services/storage/clients/contacts.js.map +1 -1
- package/services/storage/clients/icon.d.ts +2 -2
- package/services/storage/clients/icon.d.ts.map +1 -1
- package/services/storage/clients/icon.js +11 -2
- package/services/storage/clients/icon.js.map +1 -1
- package/services/storage/common.d.ts +38 -1
- package/services/storage/common.d.ts.map +1 -1
- package/services/storage/common.generated.d.ts +2 -1
- package/services/storage/common.generated.d.ts.map +1 -1
- package/services/storage/common.generated.js +67 -0
- package/services/storage/common.generated.js.map +1 -1
- package/services/storage/common.js +8 -0
- package/services/storage/common.js.map +1 -1
- package/services/storage/server.d.ts.map +1 -1
- package/services/storage/server.js +70 -27
- package/services/storage/server.js.map +1 -1
- package/services/storage/test-utils.d.ts +1 -0
- package/services/storage/test-utils.d.ts.map +1 -1
- package/services/storage/test-utils.js +15 -0
- package/services/storage/test-utils.js.map +1 -1
- package/services/username/common.generated.js +23 -23
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/services/fx/server.ts"],"names":[],"mappings":"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","sourcesContent":["import * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';\nimport { KeetaNet } from '../../client/index.js';\nimport {\n\tKeetaAnchorError,\n\tKeetaAnchorUserError\n} from '../../lib/error.js';\nimport {\n\tassertConversionInputCanonicalJSON,\n\tassertKeetaFXAnchorClientCreateExchangeRequestJSON,\n\tErrors\n} from './common.js';\nimport type {\n\tConversionInputCanonicalJSON,\n\tKeetaFXAnchorEstimate,\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, KeetaAnchorQueueRunnerConfigurationObject } from '../../lib/queue/index.ts';\nimport { KeetaAnchorQueuePipelineAdvanced } from '../../lib/queue/pipeline.js';\nimport type { JSONSerializable, ToJSONSerializable } from '../../lib/utils/json.ts';\nimport { assertNever } from '../../lib/utils/never.js';\nimport type { DeepRequired } from '../../lib/utils/types.ts';\nimport * as typia from 'typia';\nimport { assertExchangeBlockParametersAndComputeRefund, convertQuoteToExpectedSwapWithoutCost } from './util.js';\nimport { AsyncDisposableStack } from '../../lib/utils/defer.js';\nimport { asleep } from '../../lib/utils/asleep.js';\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 type GetConversionRateAndFeeContext = {\n\t/**\n\t * The purpose for why getConversionRateAndFee is being called\n\t * estimate means it is being called to get an estimate for a swap\n\t * quote means it is being called to get a firm quote for a swap that will be executed\n\t */\n\tpurpose: 'quote' | 'estimate';\n} | {\n\t/**\n\t * The purpose for why getConversionRateAndFee is being called\n\t * exchange means it is being called right before executing a swap, when the user is requesting a floating rate swap\n\t */\n\tpurpose: 'exchange';\n\n\t/**\n\t * The request information related to this exchange\n\t */\n\trequest: KeetaFXAnchorQueueStage1Request;\n}\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 * This can be null but only if `quoteConfiguration.issueQuotes` is false.\n\t */\n\tquoteSigner: Signing.SignableAccount | null;\n\n\t/**\n\t * Indicates whether the liquidity provider requires a quote before performing an exchange\n\t * defaults to requiresQuote: true\n\t */\n\tquoteConfiguration?: {\n\t\trequiresQuote: true;\n\t} | {\n\t\trequiresQuote: false;\n\n\t\t/**\n\t\t * Indicates whether to call validateQuote before performing the exchange, defaults to true if validateQuote is provided\n\t\t */\n\t\tvalidateQuoteBeforeExchange: boolean;\n\n\t\t/**\n\t\t * Indicates if the server should issue quotes when requested, if not it will throw a\n\t\t */\n\t\tissueQuotes: boolean;\n\t};\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\n\t\t/**\n\t\t * Asset identifiers in which this FX provider accepts fee\n\t\t * denomination. Advertised in service metadata so clients\n\t\t * can select a preferred cost asset.\n\t\t */\n\t\tacceptedCostAssets?: NonNullable<ServiceMetadata['services']['fx']>[string]['acceptedCostAssets'];\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: ValidateQuoteArguments) => Promise<boolean> | boolean;\n\t} & ({\n\t\tperformExchanges?: true;\n\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, context: GetConversionRateAndFeeContext) => Promise<KeetaFXInternalPriceQuote>;\n\t} | {\n\t\tperformExchanges: false;\n\n\t\t/**\n\t\t * Get the estimate price of an exchange, this should be provided when getConversionRateAndFee is not provided\n\t\t * The server will not handle exchanges if getConversionRateAndFee is not provided, but it will still provide quotes and estimates based on this function\n\t\t */\n\t\testimateRateAndFee: (request: ConversionInputCanonicalJSON) => Promise<KeetaFXInternalPriceEstimate>;\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 * Methods to extend the shared queue pipeline runners used by all accounts.\n\t *\n\t * These extensions add shared success and failure handlers that receive\n\t * results from all account-specific runners (in the `runners` object),\n\t * which internally pipe into these shared handlers.\n\t *\n\t * Useful for adding jobs before or after the main FX processing.\n\t */\n\tqueueRunnerExtensions?: KeetaFXAnchorQueuePipelineExtensions;\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\tif (unsignedQuote.request.preferredCostAsset !== undefined) {\n\t\tretval.push(unsignedQuote.request.preferredCostAsset);\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' | 'preferredCostAsset'>> &\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.VerifiableAccount, 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\tif (!('getConversionRateAndFee' in config.fx)) {\n\t\t\tthrow(new Error('getConversionRateAndFee must be provided in fx configuration when using account property'));\n\t\t}\n\n\t\tconst rateFee = await config.fx.getConversionRateAndFee(request, { purpose: 'estimate' });\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\nexport type KeetaFXInternalPriceQuote = Omit<KeetaFXAnchorQuote, 'signed' | 'request'> & Pick<KeetaFXAnchorEstimate, 'convertedAmountBound'>;\nexport type KeetaFXInternalPriceEstimate = Omit<KeetaFXInternalPriceQuote, 'account'>;\nexport type ValidateQuoteArguments = KeetaFXInternalPriceQuote & Partial<Omit<KeetaFXAnchorQuote, keyof KeetaFXInternalPriceQuote>>;\n\nexport function toValidateQuoteInput(input: KeetaFXAnchorQuoteJSON | KeetaFXInternalPriceQuote | KeetaFXAnchorQuote): ValidateQuoteArguments {\n\tconst ret: ValidateQuoteArguments = {\n\t\taccount: KeetaNet.lib.Account.toAccount(input.account),\n\t\tconvertedAmount: BigInt(input.convertedAmount),\n\t\tcost: {\n\t\t\tamount: BigInt(input.cost.amount),\n\t\t\ttoken: KeetaNet.lib.Account.toAccount(input.cost.token)\n\t\t}\n\t};\n\n\tif ('convertedAmountBound' in input && input.convertedAmountBound !== undefined) {\n\t\tret.convertedAmountBound = BigInt(input.convertedAmountBound);\n\t}\n\n\tif ('signed' in input && input.signed !== undefined) {\n\t\tret.signed = input.signed;\n\t}\n\n\tif ('request' in input && input.request !== undefined) {\n\t\tret.request = {\n\t\t\tfrom: KeetaNet.lib.Account.toAccount(input.request.from),\n\t\t\tto: KeetaNet.lib.Account.toAccount(input.request.to),\n\t\t\tamount: BigInt(input.request.amount),\n\t\t\taffinity: input.request.affinity\n\t\t};\n\t}\n\n\treturn(ret);\n}\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: Extract<DeepRequired<NonNullable<Parameters<typeof KeetaNet.UserClient['acceptSwapRequest']>[0]['expected']>>, { receive: unknown; }> | null;\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: ToJSONSerializable<KeetaFXAnchorQueueStage1Request['expected']> | null;\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\nfunction encodeKeetaFXAnchorQueueStage1Request(request: KeetaFXAnchorQueueStage1Request): JSONSerializable {\n\tlet expected: KeetaFXAnchorQueueStage1RequestJSON['expected'];\n\tif (request.expected === null) {\n\t\texpected = null;\n\t} else {\n\t\texpected = {\n\t\t\treceive: {\n\t\t\t\ttoken: request.expected.receive.token.publicKeyString.get(),\n\t\t\t\tamount: request.expected.receive.amount.toString()\n\t\t\t},\n\t\t\tsend: {\n\t\t\t\ttoken: request.expected.send.token.publicKeyString.get(),\n\t\t\t\tamount: request.expected.send.amount.toString()\n\t\t\t}\n\t\t};\n\t};\n\n\tconst { preferredCostAsset, ...requestBase } = request.request;\n\tconst requestForQueue: { [key: string]: JSONSerializable } = { ...requestBase };\n\tif (preferredCostAsset !== undefined) {\n\t\trequestForQueue.preferredCostAsset = preferredCostAsset;\n\t}\n\n\tconst account = request.account.publicKeyString.get();\n\tconst block = Buffer.from(request.block.toBytes()).toString('base64');\n\n\treturn({\n\t\tversion: 1 as const,\n\t\trequest: requestForQueue,\n\t\taccount,\n\t\tblock,\n\t\texpected\n\t});\n}\n\nfunction decodeKeetaFXAnchorQueueStage1Request(request: JSONSerializable): KeetaFXAnchorQueueStage1Request {\n\t/* See note at bottom of file */\n\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\tconst reqJSON = assertKeetaFXAnchorQueueStage1RequestJSON(request);\n\n\tif (reqJSON.version !== 1) {\n\t\tthrow(new Error(`Unsupported KeetaFXAnchorQueueStage1Request version ${reqJSON.version}`));\n\t}\n\n\tlet expected: KeetaFXAnchorQueueStage1Request['expected'];\n\tif (reqJSON.expected === null) {\n\t\texpected = null;\n\t} else {\n\t\texpected = {\n\t\t\treceive: {\n\t\t\t\ttoken: KeetaNet.lib.Account.fromPublicKeyString(reqJSON.expected.receive.token).assertKeyType(KeetaNet.lib.Account.AccountKeyAlgorithm.TOKEN),\n\t\t\t\tamount: BigInt(reqJSON.expected.receive.amount)\n\t\t\t},\n\t\t\tsend: {\n\t\t\t\ttoken: KeetaNet.lib.Account.fromPublicKeyString(reqJSON.expected.send.token).assertKeyType(KeetaNet.lib.Account.AccountKeyAlgorithm.TOKEN),\n\t\t\t\tamount: BigInt(reqJSON.expected.send.amount)\n\t\t\t}\n\t\t};\n\t}\n\n\tconst retval: KeetaFXAnchorQueueStage1Request = {\n\t\taccount: KeetaNet.lib.Account.fromPublicKeyString(reqJSON.account),\n\t\tblock: new KeetaNet.lib.Block(reqJSON.block),\n\t\trequest: reqJSON.request,\n\t\texpected: expected\n\t};\n\n\treturn(retval);\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, request } = entry.request;\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\n\t\t\tif (!(userClient.account.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 with configured UserClient account`\n\t\t\t\t});\n\t\t\t}\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 builder = userClient.initBuilder();\n\t\tlet expected = entry.request.expected;\n\n\t\t/**\n\t\t * We only want to refund excess for cost/paying token if it is not a fixed rate\n\t\t * as if it is a fixed rate transfer, you can assume the client did not send unintentionally\n\t\t *\n\t\t * Additionally, other FX anchors are not forced to refund any, so there is no guarantee to client that refunds will occur\n\t\t */\n\t\tif (expected === null) {\n\t\t\tif (!('getConversionRateAndFee' in this.serverConfig.fx)) {\n\t\t\t\tthis.serverConfig.logger?.error('KeetaFXAnchorQueuePipelineStage1::processor', 'getConversionRateAndFee must be provided in fx configuration to process exchanges without expected details');\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: 'Server misconfiguration: getConversionRateAndFee must be provided in fx configuration to process exchanges without expected details'\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (request.preferredCostAsset !== undefined) {\n\t\t\t\tif (this.serverConfig.fx.acceptedCostAssets === undefined) {\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: 'This server does not support preferred cost asset selection'\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (!this.serverConfig.fx.acceptedCostAssets.includes(request.preferredCostAsset)) {\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: `Preferred cost asset \"${request.preferredCostAsset}\" is not accepted by this server`\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst quote = await this.serverConfig.fx.getConversionRateAndFee(request, { purpose: 'exchange', request: entry.request });\n\n\t\t\tconst { refunds } = assertExchangeBlockParametersAndComputeRefund({\n\t\t\t\tblock: block,\n\t\t\t\tliquidityAccount: entry.request.account,\n\t\t\t\tallowedLiquidityAccounts: null,\n\t\t\t\tchecks: { quote, request },\n\t\t\t\tisQuoteBasedExchange: false\n\t\t\t});\n\n\t\t\tfor (const refund of refunds) {\n\t\t\t\tbuilder.send(block.account, refund.amount, refund.token);\n\t\t\t}\n\n\t\t\texpected = convertQuoteToExpectedSwapWithoutCost({ quote, request });\n\t\t}\n\n\t\tbuilder.send(block.account, expected.send.amount, expected.send.token);\n\n\t\tconst sendBlock = await builder.computeBlocks();\n\n\t\tconst swapBlocks = [ ...sendBlock.blocks, block ];\n\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\n\t\ttry {\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} catch (error) {\n\t\t\tif (\n\t\t\t\tKeetaNet.lib.Error.isInstance(error) &&\n\t\t\t\t'shouldRetry' in error &&\n\t\t\t\t// Disable this warning as there is nothing stopping this from not being a boolean\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare\n\t\t\t\terror.shouldRetry === false\n\t\t\t) {\n\t\t\t\tthis.serverConfig.logger?.warn('KeetaFXAnchorQueuePipelineStage1::processor', 'Non-retryable error publishing swap blocks:', error);\n\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: `${error.code} ${error.message}`\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow(error);\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\treturn(encodeKeetaFXAnchorQueueStage1Request(request));\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\treturn(decodeKeetaFXAnchorQueueStage1Request(request));\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\ntype RunnerOrRunnerWithOptions<Req, Res> = ({\n\tprocessor: KeetaAnchorQueueRunner<Req, Res>['processor'];\n} & KeetaAnchorQueueRunnerConfigurationObject) | KeetaAnchorQueueRunner<Req, Res>['processor'];\n\ntype KeetaFXAnchorQueuePipelineExtensions = {\n\tsuccess?: RunnerOrRunnerWithOptions<KeetaFXAnchorQueueStage1Response, KeetaFXAnchorQueueStage1Response>;\n\tfailure?: RunnerOrRunnerWithOptions<KeetaFXAnchorQueueStage1Request, JSONSerializable>;\n}\n\ntype KeetaFXAnchorQueuePipelineAdditionalConfig = {\n\tserverConfig: KeetaAnchorFXServerConfig;\n\taccounts: InstanceType<typeof KeetaNet.lib.Account.Set>;\n\textensions?: KeetaFXAnchorQueuePipelineExtensions | undefined;\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\tprivate extensions?: KeetaFXAnchorQueuePipelineExtensions | undefined;\n\n\tprivate successStageRunner: KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Response, KeetaFXAnchorQueueStage1Response> | null = null;\n\tprivate failureStageRunner: KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, JSONSerializable> | null = null;\n\n\tconstructor(\n\t\toptions:\n\t\t\tConstructorParameters<typeof KeetaAnchorQueuePipelineAdvanced<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>>[0] &\n\t\t\tKeetaFXAnchorQueuePipelineAdditionalConfig\n\t) {\n\t\tsuper(options);\n\n\t\tthis.serverConfig = options.serverConfig;\n\t\tthis.accounts = options.accounts;\n\t\tthis.extensions = options.extensions;\n\t}\n\n\tprotected async createPipeline(): Promise<void> {\n\t\tconst failureExtension = this.extensions?.failure;\n\t\tconst successExtension = this.extensions?.success;\n\n\t\tif (failureExtension || successExtension) {\n\t\t\tabstract class BaseExtensionClass<Req, Res> extends KeetaAnchorQueueRunner<Req, Res> {\n\t\t\t\t#configSet = false;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n\t\t\t\t#processorMethod: Extract<RunnerOrRunnerWithOptions<Req, Res>, Function> = (() => {\n\t\t\t\t\tthrow(new Error('config not set'));\n\t\t\t\t});\n\n\t\t\t\t_setConfigurationAndProcessor(config: RunnerOrRunnerWithOptions<Req, Res>) {\n\t\t\t\t\tif (this.#configSet) {\n\t\t\t\t\t\tthrow(new Error('Configuration can only be set once'));\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.#configSet = true;\n\n\t\t\t\t\tif (typeof config === 'function') {\n\t\t\t\t\t\tthis.#processorMethod = config;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst { processor, ...parameters } = config;\n\t\t\t\t\t\tthis.#processorMethod = processor;\n\n\t\t\t\t\t\tthis.setConfiguration(parameters);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tprotected async processor(entry: Parameters<KeetaAnchorQueueRunner<Req, Res>['processor']>[0]) {\n\t\t\t\t\treturn(await this.#processorMethod(entry));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (failureExtension) {\n\t\t\t\tconst failureQueue = await this.baseQueue.partition('failed');\n\t\t\t\tthis.queues.push(failureQueue);\n\n\t\t\t\tconst runner = (new class extends BaseExtensionClass<KeetaFXAnchorQueueStage1Request, JSONSerializable> {\n\t\t\t\t\tprotected encodeRequest(request: KeetaFXAnchorQueueStage1Request) { return(encodeKeetaFXAnchorQueueStage1Request(request)); }\n\t\t\t\t\tprotected decodeRequest(request: JSONSerializable): KeetaFXAnchorQueueStage1Request { return(decodeKeetaFXAnchorQueueStage1Request(request)); }\n\t\t\t\t\tprotected encodeResponse(response: JSONSerializable | null) { return(response); }\n\t\t\t\t\tprotected decodeResponse(response: JSONSerializable | null) { return(response); }\n\t\t\t\t}({\n\t\t\t\t\tid: 'keeta-fx-anchor-failure-runner',\n\t\t\t\t\tqueue: failureQueue,\n\t\t\t\t\tlogger: this.logger\n\t\t\t\t}));\n\n\t\t\t\trunner._setConfigurationAndProcessor(failureExtension);\n\n\t\t\t\tthis.failureStageRunner = runner;\n\t\t\t}\n\n\t\t\tif (successExtension) {\n\t\t\t\tconst successQueue = await this.baseQueue.partition('success');\n\t\t\t\tthis.queues.push(successQueue);\n\n\t\t\t\tconst runner = (new class extends BaseExtensionClass<KeetaFXAnchorQueueStage1Response, KeetaFXAnchorQueueStage1Response> {\n\t\t\t\t\tprotected encodeRequest(request: KeetaFXAnchorQueueStage1Response) { return(request); }\n\t\t\t\t\tprotected decodeRequest(request: JSONSerializable): KeetaFXAnchorQueueStage1Response {\n\t\t\t\t\t\t/* See note at bottom of file */\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\t\t\t\t\tconst parsed = assertKeetaFXAnchorQueueStage1ResponseOrNull(request);\n\t\t\t\t\t\tif (parsed === null) {\n\t\t\t\t\t\t\tthrow(new Error('Invalid request for success extension'));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn(parsed);\n\t\t\t\t\t}\n\n\t\t\t\t\tprotected encodeResponse(response: KeetaFXAnchorQueueStage1Response | null) { return(response); }\n\t\t\t\t\tprotected decodeResponse(response: JSONSerializable | null): KeetaFXAnchorQueueStage1Response | null {\n\t\t\t\t\t\t/* See note at bottom of file */\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\t\t\t\t\treturn(assertKeetaFXAnchorQueueStage1ResponseOrNull(response));\n\t\t\t\t\t}\n\t\t\t\t}({\n\t\t\t\t\tid: 'keeta-fx-anchor-success-runner',\n\t\t\t\t\tqueue: successQueue,\n\t\t\t\t\tlogger: this.logger\n\t\t\t\t}));\n\n\t\t\t\trunner._setConfigurationAndProcessor(successExtension);\n\n\t\t\t\tthis.successStageRunner = runner;\n\t\t\t}\n\t\t}\n\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\n\t\t\tif (this.successStageRunner) {\n\t\t\t\trunner.pipe(this.successStageRunner, { exclusiveTarget: false });\n\t\t\t}\n\n\t\t\tif (this.failureStageRunner) {\n\t\t\t\trunner.pipeFailed(this.failureStageRunner, { exclusiveTarget: false });\n\t\t\t}\n\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\t/**\n\t * Get the status of a request by ID.\n\t * If the request is found in any of the runners, it is returned with its current status.\n\t * Because typically the user will only care about the status of the first stage-\n\t * The request will be marked as failed or completed if it is found in the success or failure stages, instead of the status from those stages.\n\t * @param id The ID of the request to get the status of\n\t * @returns The inferred status of the request, or null if the request is not found\n\t */\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\tif (entry.status === 'moved') {\n\t\t\t\t\tlet failedFound = null;\n\t\t\t\t\tlet successFound = null;\n\n\t\t\t\t\tif (this.failureStageRunner || this.successStageRunner) {\n\t\t\t\t\t\tawait Promise.all([\n\t\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\t\tif (!this.failureStageRunner) {\n\t\t\t\t\t\t\t\t\treturn(null);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfailedFound = await this.failureStageRunner.get(id);\n\t\t\t\t\t\t\t})(),\n\t\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\t\tif (!this.successStageRunner) {\n\t\t\t\t\t\t\t\t\treturn(null);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsuccessFound = await this.successStageRunner.get(id);\n\t\t\t\t\t\t\t})()\n\t\t\t\t\t\t]);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (failedFound && successFound) {\n\t\t\t\t\t\tthis.logger?.warn(`Request with ID ${String(id)} was found in both the success and failure stages -- this should not happen`, { requestID: id });\n\t\t\t\t\t} else if (failedFound) {\n\t\t\t\t\t\tentry.status = 'failed_permanently';\n\t\t\t\t\t} else if (successFound) {\n\t\t\t\t\t\tentry.status = 'completed';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.logger?.warn(`Request with ID ${String(id)} has moved from the main processing stage but was not found in either the success or failure stages -- leaving status as \"moved\"`, { requestID: id });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn(entry);\n\t\t\t}\n\t\t}\n\n\t\treturn(null);\n\t}\n\n\t#getAllRunners() {\n\t\tconst runners = [];\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\t\t\trunners.push(runner);\n\t\t}\n\n\t\tif (this.successStageRunner) {\n\t\t\trunners.push(this.successStageRunner);\n\t\t}\n\n\t\tif (this.failureStageRunner) {\n\t\t\trunners.push(this.failureStageRunner);\n\t\t}\n\n\t\treturn(runners);\n\t}\n\n\tasync run(options?: Parameters<KeetaFXAnchorQueuePipelineStage1['run']>[0]): ReturnType<KeetaFXAnchorQueuePipelineStage1['run']> {\n\t\tawait super.init();\n\n\t\tconst runners = this.#getAllRunners();\n\n\t\tlet retval = false;\n\t\tfor (const runner of runners) {\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\tconst runners = this.#getAllRunners();\n\n\t\tfor (const runner of runners) {\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\tconst runners = this.#getAllRunners();\n\t\tfor (const runner of 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\ntype SharedHTTPServerConfigType = Pick<KeetaAnchorFXServerConfig, 'fx' | 'homepage' | keyof KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig>;\nabstract class BaseKeetaNetFXAnchorHTTPServer<ConfigType extends SharedHTTPServerConfigType> extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<ConfigType> implements Omit<Required<KeetaAnchorFXServerConfig>, 'storage' | 'queueRunnerExtensions' | 'accounts' | 'account' | 'signer' | 'client' | 'quoteSigner' | 'quoteConfiguration'> {\n\treadonly homepage: NonNullable<KeetaAnchorFXServerConfig['homepage']>;\n\treadonly fx: KeetaAnchorFXServerConfig['fx'];\n\treadonly canPerformExchanges: boolean;\n\n\tprotected abstract quoteConfiguration: Exclude<KeetaAnchorFXServerConfig['quoteConfiguration'], undefined> | null;\n\n\tprotected accounts: InstanceType<typeof KeetaNet.lib.Account.Set> | null = null;\n\n\tconstructor(config: ConfigType) {\n\t\tsuper(config);\n\n\t\tthis.homepage = config.homepage ?? '';\n\t\tthis.fx = config.fx;\n\n\t\t// This is incorrect as undefined and true are the same (because default is true), but using a negation will not result in the correct type for canPerformExchanges, so we have to disable the lint warning and accept the incorrectness\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare\n\t\tthis.canPerformExchanges = config.fx.performExchanges === undefined || config.fx.performExchanges === true;\n\t}\n\n\tprotected async getUnsignedQuoteData(conversion: ConversionInputCanonicalJSON, purpose: 'estimate'): Promise<KeetaFXInternalPriceEstimate | KeetaFXInternalPriceQuote>;\n\tprotected async getUnsignedQuoteData(conversion: ConversionInputCanonicalJSON, purpose: 'quote'): Promise<KeetaFXInternalPriceQuote>;\n\tprotected async getUnsignedQuoteData(conversion: ConversionInputCanonicalJSON, purpose: Exclude<GetConversionRateAndFeeContext['purpose'], 'exchange'>): Promise<KeetaFXInternalPriceQuote | KeetaFXInternalPriceEstimate> {\n\t\tif (purpose !== 'estimate' && !this.canPerformExchanges) {\n\t\t\tthrow(new Error(`FX configuration does not support performing exchanges, so purpose \"${purpose}\" is invalid`));\n\t\t}\n\n\t\tif (conversion.preferredCostAsset !== undefined) {\n\t\t\tif (this.fx.acceptedCostAssets === undefined) {\n\t\t\t\tthrow(new KeetaAnchorUserError('This server does not support preferred cost asset selection'));\n\t\t\t}\n\n\t\t\tif (!this.fx.acceptedCostAssets.includes(conversion.preferredCostAsset)) {\n\t\t\t\tthrow(new KeetaAnchorUserError(`Preferred cost asset \"${conversion.preferredCostAsset}\" is not accepted by this server`));\n\t\t\t}\n\t\t}\n\n\t\tif ('getConversionRateAndFee' in this.fx) {\n\t\t\tif (!this.accounts) {\n\t\t\t\tthrow(new Error('Accounts must be configured to use \"getConversionRateAndFee\" in fx configuration'));\n\t\t\t}\n\n\t\t\tconst rateAndFee = await this.fx.getConversionRateAndFee(conversion, { purpose });\n\n\t\t\tif (PARANOID) {\n\t\t\t\tconst quoteAccount = rateAndFee.account;\n\t\t\t\tif (!this.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\treturn(rateAndFee);\n\t\t} else if ('estimateRateAndFee' in this.fx) {\n\t\t\tif (purpose !== 'estimate') {\n\t\t\t\tthrow(new Error('FX configuration only supports \"estimateRateAndFee\", so purpose must be \"estimate\"'));\n\t\t\t}\n\n\t\t\treturn(await this.fx.estimateRateAndFee(conversion));\n\t\t} else {\n\t\t\tassertNever(this.fx);\n\t\t}\n\t}\n\n\tprotected async initRoutes(config: ConfigType): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = {};\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\n\t\t/**\n\t\t * Setup the request handler for an estimate request\n\t\t */\n\t\troutes['POST /api/getEstimate'] = async (_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 this.getUnsignedQuoteData(conversion, 'estimate');\n\n\t\t\tlet requiresQuoteBody: { canPerformExchange: false; } | { requiresQuote: true } | { requiresQuote: false; account: KeetaNetAccount | KeetaNetStorageAccount; };\n\n\t\t\tif (!instance.quoteConfiguration || !instance.canPerformExchanges) {\n\t\t\t\trequiresQuoteBody = { canPerformExchange: false };\n\t\t\t} else if (instance.quoteConfiguration.requiresQuote) {\n\t\t\t\trequiresQuoteBody = { requiresQuote: true };\n\t\t\t} else {\n\t\t\t\tif (rateAndFee.convertedAmountBound === undefined) {\n\t\t\t\t\tinstance.logger.warn('POST /api/getEstimate', 'FX configuration indicates quotes are not required, but \"convertedAmountBound\" was not provided in the rate and fee response');\n\t\t\t\t} else {\n\t\t\t\t\tif (conversion.affinity === 'to' && (BigInt(rateAndFee.convertedAmount) > rateAndFee.convertedAmountBound)) {\n\t\t\t\t\t\tthrow(new KeetaAnchorError('Affinity is to, but bound is less than estimated sent amount'));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (conversion.affinity === 'from' && (BigInt(rateAndFee.convertedAmount) < rateAndFee.convertedAmountBound)) {\n\t\t\t\t\t\tthrow(new KeetaAnchorError('Affinity is from, but bound is greater than estimated received amount'));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!('account' in rateAndFee) || !rateAndFee.account) {\n\t\t\t\t\tthrow(new Error('FX configuration indicates quotes are not required, but no account was provided in the rate and fee response'));\n\t\t\t\t}\n\n\t\t\t\trequiresQuoteBody = { requiresQuote: false, account: rateAndFee.account };\n\t\t\t}\n\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\tconvertedAmountBound: rateAndFee.convertedAmountBound,\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\t...requiresQuoteBody\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\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};\n\n\t\tconst metadata: NonNullable<ServiceMetadata['services']['fx']>[string] = {\n\t\t\tfrom: this.fx.from ?? [],\n\t\t\toperations: operations\n\t\t};\n\n\t\tif (this.fx.acceptedCostAssets) {\n\t\t\tmetadata.acceptedCostAssets = this.fx.acceptedCostAssets;\n\t\t}\n\n\t\treturn(metadata);\n\t}\n}\n\nexport class KeetaNetFXAnchorEstimateHTTPServer extends BaseKeetaNetFXAnchorHTTPServer<SharedHTTPServerConfigType> {\n\tprotected quoteConfiguration = null;\n\n\tconstructor(config: SharedHTTPServerConfigType) {\n\t\tsuper(config);\n\n\t\tif (this.canPerformExchanges) {\n\t\t\tthrow(new Error('FX configuration indicates exchanges can be performed, but KeetaNetFXAnchorEstimateHTTPServer does not support exchange capability'));\n\t\t}\n\t}\n}\n\nexport class KeetaNetFXAnchorHTTPServer extends BaseKeetaNetFXAnchorHTTPServer<KeetaAnchorFXServerConfig> implements Omit<Required<KeetaAnchorFXServerConfig>, 'storage' | 'queueRunnerExtensions'> {\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\treadonly quoteConfiguration: Exclude<KeetaAnchorFXServerConfig['quoteConfiguration'], undefined>;\n\n\tprotected autoRun: boolean;\n\tprotected autoRunRunning = false;\n\n\tconstructor(config: KeetaAnchorFXServerConfig) {\n\t\tsuper(config);\n\n\t\tthis.client = config.client;\n\t\tthis.fx = config.fx;\n\t\tthis.quoteSigner = config.quoteSigner;\n\t\tthis.quoteConfiguration = config.quoteConfiguration ?? { requiresQuote: true };\n\n\t\tif (!this.canPerformExchanges) {\n\t\t\tthrow(new Error('FX configuration indicates exchanges cannot be performed, but KeetaNetFXAnchorHTTPServer requires exchange capability'));\n\t\t}\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\tthis.autoRun = config.storage?.autoRun ?? false;\n\t\tif (config.storage === undefined) {\n\t\t\tthis.autoRun = 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\textensions: config.queueRunnerExtensions\n\t\t});\n\t}\n\n\tprotected async initRoutes(config: KeetaAnchorFXServerConfig): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = await super.initRoutes(config);\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\n\t\troutes['POST /api/getQuote'] = async (_ignore_params, postData) => {\n\t\t\tif (!instance.quoteConfiguration.requiresQuote && !instance.quoteConfiguration.issueQuotes) {\n\t\t\t\tthrow(new Errors.QuoteIssuanceDisabled());\n\t\t\t}\n\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\n\t\t\tconst conversion = assertConversionInputCanonicalJSON(postData.request);\n\t\t\tconst rateAndFee = await this.getUnsignedQuoteData(conversion, 'quote');\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\tif (config.quoteSigner === null) {\n\t\t\t\tthrow(new Error('Quote signer not configured, this is required when issuing quotes'));\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 (_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\n\t\t\tconst request = assertKeetaFXAnchorClientCreateExchangeRequestJSON(postData.request);\n\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 block = new KeetaNet.lib.Block(request.block);\n\n\t\t\tlet quoteInput;\n\t\t\tlet conversionInput;\n\t\t\tlet shouldValidateQuote;\n\t\t\tlet liquidityAccount;\n\t\t\tlet expectedConversion: KeetaFXAnchorQueueStage1Request['expected'];\n\t\t\tlet isQuoteBasedExchange;\n\t\t\tif ('quote' in request && 'estimate' in request && request.quote && request.estimate) {\n\t\t\t\tthrow(new Error('Request cannot contain both quote and estimate'));\n\t\t\t} else if ('quote' in request && request.quote) {\n\t\t\t\tisQuoteBasedExchange = true;\n\t\t\t\tshouldValidateQuote = true;\n\t\t\t\tquoteInput = request.quote;\n\t\t\t\tconversionInput = quoteInput.request;\n\n\t\t\t\tconst isValidQuote = await (async () => {\n\t\t\t\t\tif (config.quoteSigner === null) {\n\t\t\t\t\t\treturn(false);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn(await verifySignedData(config.quoteSigner, quoteInput));\n\t\t\t\t})();\n\n\t\t\t\tif (!isValidQuote) {\n\t\t\t\t\tthrow(new Errors.QuoteValidationFailed());\n\t\t\t\t}\n\n\t\t\t\tliquidityAccount = quoteInput.account;\n\t\t\t\texpectedConversion = convertQuoteToExpectedSwapWithoutCost({\n\t\t\t\t\tquote: toValidateQuoteInput(quoteInput),\n\t\t\t\t\trequest: conversionInput\n\t\t\t\t});\n\t\t\t} else if ('request' in request && request.request) {\n\t\t\t\tisQuoteBasedExchange = false;\n\t\t\t\tif (instance.quoteConfiguration.requiresQuote) {\n\t\t\t\t\tthrow(new Errors.QuoteRequired());\n\t\t\t\t}\n\n\t\t\t\tconversionInput = request.request;\n\t\t\t\tquoteInput = await this.getUnsignedQuoteData(conversionInput, 'estimate');\n\n\t\t\t\tif (instance.quoteConfiguration.validateQuoteBeforeExchange !== undefined) {\n\t\t\t\t\tshouldValidateQuote = instance.quoteConfiguration.validateQuoteBeforeExchange;\n\t\t\t\t} else {\n\t\t\t\t\tshouldValidateQuote = config.fx.validateQuote !== undefined;\n\t\t\t\t}\n\n\t\t\t\tfor (const operation of block.operations) {\n\t\t\t\t\tif (operation.type === KeetaNet.lib.Block.OperationType.SEND) {\n\t\t\t\t\t\tif (!config.accounts) {\n\t\t\t\t\t\t\tthrow(new Error('No accounts configured for FX server, cannot infer liquidity account from block'));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (config.accounts.has(operation.to)) {\n\t\t\t\t\t\t\tliquidityAccount = operation.to;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!liquidityAccount) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Could not determine liquidity account from exchange block'));\n\t\t\t\t}\n\n\t\t\t\t// No expected conversion provided when using estimate, we determine the rate when processing the exchange\n\t\t\t\texpectedConversion = null;\n\t\t\t} else {\n\t\t\t\tthrow(new Error('Either quote or request must be provided (but not both) in exchange request'));\n\t\t\t}\n\n\t\t\tif (!('account' in quoteInput) || !quoteInput.account) {\n\t\t\t\tthrow(new Error('Quote is missing account, createExchange should not be supported for quotes without an account'));\n\t\t\t}\n\n\t\t\tconst parsedQuote = toValidateQuoteInput(quoteInput);\n\n\t\t\t/* Validate the quote using the optional callback */\n\t\t\tif (config.fx.validateQuote !== undefined && shouldValidateQuote) {\n\t\t\t\tconst isAcceptable = await config.fx.validateQuote(parsedQuote);\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 liquidityAccountInstance = KeetaNet.lib.Account.toAccount(liquidityAccount);\n\n\t\t\tlet allowedLiquidityAccounts;\n\t\t\tif (config.accounts) {\n\t\t\t\tallowedLiquidityAccounts = config.accounts;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t} else if (config.account) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\tallowedLiquidityAccounts = new KeetaNet.lib.Account.Set([ config.account ]);\n\t\t\t} else {\n\t\t\t\tthrow(new Error('config.account or config.accounts must be provided'));\n\t\t\t}\n\n\t\t\tassertExchangeBlockParametersAndComputeRefund({\n\t\t\t\tblock: block,\n\t\t\t\tliquidityAccount: liquidityAccountInstance,\n\t\t\t\tallowedLiquidityAccounts: allowedLiquidityAccounts,\n\t\t\t\tchecks: { quote: parsedQuote, request: conversionInput },\n\t\t\t\tisQuoteBasedExchange: isQuoteBasedExchange\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: liquidityAccountInstance,\n\t\t\t\tblock: block,\n\t\t\t\trequest: conversionInput,\n\t\t\t\texpected: expectedConversion\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\tif (instance.autoRun && !instance.autoRunRunning) {\n\t\t\t\t/*\n\t\t\t\t * Keep track of how many times, consecutively, the queue was empty when we\n\t\t\t\t * went to run it\n\t\t\t\t */\n\t\t\t\tlet noMoreJobsCount = 0;\n\n\t\t\t\t/*\n\t\t\t\t * Create a mutex around the queue running so we don't have\n\t\t\t\t * lock contention for the worker ID if multiple requests\n\t\t\t\t * are being served by the same instance\n\t\t\t\t */\n\t\t\t\tinstance.autoRunRunning = true;\n\t\t\t\tawait using cleanup = new AsyncDisposableStack();\n\t\t\t\tcleanup.defer(async function() {\n\t\t\t\t\tinstance.autoRunRunning = false;\n\t\t\t\t});\n\n\t\t\t\t/*\n\t\t\t\t * For up to 15s process the queue, stopping only when\n\t\t\t\t * we've had 2 consecutive runs that indicate there is\n\t\t\t\t * no more in the queue to process\n\t\t\t\t */\n\t\t\t\tfor (const startTime = Date.now(); Date.now() - startTime < 15000;) {\n\t\t\t\t\tconst more = await instance.pipeline.run({ timeoutMs: 1500 });\n\t\t\t\t\tif (!more) {\n\t\t\t\t\t\tnoMoreJobsCount++;\n\t\t\t\t\t\tif (noMoreJobsCount >= 2) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnoMoreJobsCount = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait instance.pipeline.maintain();\n\t\t\t\t\tawait asleep(100);\n\t\t\t\t}\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\toverride async serviceMetadata(): Promise<NonNullable<ServiceMetadata['services']['fx']>[string]> {\n\t\tconst baseMetadata = await super.serviceMetadata();\n\n\t\tif (this.quoteConfiguration.requiresQuote || this.quoteConfiguration.issueQuotes) {\n\t\t\tbaseMetadata.operations.getQuote = (new URL('/api/getQuote', this.url)).toString();\n\t\t}\n\n\t\tbaseMetadata.operations.getExchangeStatus = (new URL('/api/getExchangeStatus', this.url)).toString() + '/{id}';\n\t\tbaseMetadata.operations.createExchange = (new URL('/api/createExchange', this.url)).toString();\n\n\t\treturn(baseMetadata);\n\t}\n\n\tasync stop(): Promise<void> {\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"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/services/fx/server.ts"],"names":[],"mappings":"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","sourcesContent":["import * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';\nimport { KeetaNet } from '../../client/index.js';\nimport {\n\tKeetaAnchorError,\n\tKeetaAnchorUserError\n} from '../../lib/error.js';\nimport {\n\tassertConversionInputCanonicalJSON,\n\tassertKeetaFXAnchorClientCreateExchangeRequestJSON,\n\tErrors\n} from './common.js';\nimport type {\n\tConversionInputCanonicalJSON,\n\tKeetaFXAnchorEstimate,\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, KeetaAnchorQueueRunnerConfigurationObject } from '../../lib/queue/index.ts';\nimport { KeetaAnchorQueuePipelineAdvanced } from '../../lib/queue/pipeline.js';\nimport type { JSONSerializable, ToJSONSerializable } from '../../lib/utils/json.ts';\nimport { assertNever } from '../../lib/utils/never.js';\nimport type { DeepRequired } from '../../lib/utils/types.ts';\nimport * as typia from 'typia';\nimport { assertExchangeBlockParametersAndComputeRefund, convertQuoteToExpectedSwapWithoutCost } from './util.js';\nimport { AsyncDisposableStack } from '../../lib/utils/defer.js';\nimport { asleep } from '../../lib/utils/asleep.js';\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 type GetConversionRateAndFeeContext = {\n\t/**\n\t * The purpose for why getConversionRateAndFee is being called\n\t * estimate means it is being called to get an estimate for a swap\n\t * quote means it is being called to get a firm quote for a swap that will be executed\n\t */\n\tpurpose: 'quote' | 'estimate';\n} | {\n\t/**\n\t * The purpose for why getConversionRateAndFee is being called\n\t * exchange means it is being called right before executing a swap, when the user is requesting a floating rate swap\n\t */\n\tpurpose: 'exchange';\n\n\t/**\n\t * The request information related to this exchange\n\t */\n\trequest: KeetaFXAnchorQueueStage1Request;\n}\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 * This can be null but only if `quoteConfiguration.issueQuotes` is false.\n\t */\n\tquoteSigner: Signing.SignableAccount | null;\n\n\t/**\n\t * Indicates whether the liquidity provider requires a quote before performing an exchange\n\t * defaults to requiresQuote: true\n\t */\n\tquoteConfiguration?: {\n\t\trequiresQuote: true;\n\t} | {\n\t\trequiresQuote: false;\n\n\t\t/**\n\t\t * Indicates whether to call validateQuote before performing the exchange, defaults to true if validateQuote is provided\n\t\t */\n\t\tvalidateQuoteBeforeExchange: boolean;\n\n\t\t/**\n\t\t * Indicates if the server should issue quotes when requested, if not it will throw a\n\t\t */\n\t\tissueQuotes: boolean;\n\t};\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\n\t\t/**\n\t\t * Asset identifiers in which this FX provider accepts fee\n\t\t * denomination. Advertised in service metadata so clients\n\t\t * can select a preferred cost asset.\n\t\t */\n\t\tacceptedCostAssets?: NonNullable<ServiceMetadata['services']['fx']>[string]['acceptedCostAssets'];\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: ValidateQuoteArguments) => Promise<boolean> | boolean;\n\t} & ({\n\t\tperformExchanges?: true;\n\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, context: GetConversionRateAndFeeContext) => Promise<KeetaFXInternalPriceQuote>;\n\t} | {\n\t\tperformExchanges: false;\n\n\t\t/**\n\t\t * Get the estimate price of an exchange, this should be provided when getConversionRateAndFee is not provided\n\t\t * The server will not handle exchanges if getConversionRateAndFee is not provided, but it will still provide quotes and estimates based on this function\n\t\t */\n\t\testimateRateAndFee: (request: ConversionInputCanonicalJSON) => Promise<KeetaFXInternalPriceEstimate>;\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 * Methods to extend the shared queue pipeline runners used by all accounts.\n\t *\n\t * These extensions add shared success and failure handlers that receive\n\t * results from all account-specific runners (in the `runners` object),\n\t * which internally pipe into these shared handlers.\n\t *\n\t * Useful for adding jobs before or after the main FX processing.\n\t */\n\tqueueRunnerExtensions?: KeetaFXAnchorQueuePipelineExtensions;\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\tif (unsignedQuote.request.preferredCostAsset !== undefined) {\n\t\tretval.push(unsignedQuote.request.preferredCostAsset);\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' | 'preferredCostAsset'>> &\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.VerifiableAccount, 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\tif (!('getConversionRateAndFee' in config.fx)) {\n\t\t\tthrow(new Error('getConversionRateAndFee must be provided in fx configuration when using account property'));\n\t\t}\n\n\t\tconst rateFee = await config.fx.getConversionRateAndFee(request, { purpose: 'estimate' });\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\nexport type KeetaFXInternalPriceQuote = Omit<KeetaFXAnchorQuote, 'signed' | 'request'> & Pick<KeetaFXAnchorEstimate, 'convertedAmountBound'>;\nexport type KeetaFXInternalPriceEstimate = Omit<KeetaFXInternalPriceQuote, 'account'>;\nexport type ValidateQuoteArguments = KeetaFXInternalPriceQuote & Partial<Omit<KeetaFXAnchorQuote, keyof KeetaFXInternalPriceQuote>>;\n\nexport function toValidateQuoteInput(input: KeetaFXAnchorQuoteJSON | KeetaFXInternalPriceQuote | KeetaFXAnchorQuote): ValidateQuoteArguments {\n\tconst ret: ValidateQuoteArguments = {\n\t\taccount: KeetaNet.lib.Account.toAccount(input.account),\n\t\tconvertedAmount: BigInt(input.convertedAmount),\n\t\tcost: {\n\t\t\tamount: BigInt(input.cost.amount),\n\t\t\ttoken: KeetaNet.lib.Account.toAccount(input.cost.token)\n\t\t}\n\t};\n\n\tif ('convertedAmountBound' in input && input.convertedAmountBound !== undefined) {\n\t\tret.convertedAmountBound = BigInt(input.convertedAmountBound);\n\t}\n\n\tif ('signed' in input && input.signed !== undefined) {\n\t\tret.signed = input.signed;\n\t}\n\n\tif ('request' in input && input.request !== undefined) {\n\t\tret.request = {\n\t\t\tfrom: KeetaNet.lib.Account.toAccount(input.request.from),\n\t\t\tto: KeetaNet.lib.Account.toAccount(input.request.to),\n\t\t\tamount: BigInt(input.request.amount),\n\t\t\taffinity: input.request.affinity\n\t\t};\n\t}\n\n\treturn(ret);\n}\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: Extract<DeepRequired<NonNullable<Parameters<typeof KeetaNet.UserClient['acceptSwapRequest']>[0]['expected']>>, { receive: unknown; }> | null;\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: ToJSONSerializable<KeetaFXAnchorQueueStage1Request['expected']> | null;\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\nfunction encodeKeetaFXAnchorQueueStage1Request(request: KeetaFXAnchorQueueStage1Request): JSONSerializable {\n\tlet expected: KeetaFXAnchorQueueStage1RequestJSON['expected'];\n\tif (request.expected === null) {\n\t\texpected = null;\n\t} else {\n\t\texpected = {\n\t\t\treceive: {\n\t\t\t\ttoken: request.expected.receive.token.publicKeyString.get(),\n\t\t\t\tamount: request.expected.receive.amount.toString()\n\t\t\t},\n\t\t\tsend: {\n\t\t\t\ttoken: request.expected.send.token.publicKeyString.get(),\n\t\t\t\tamount: request.expected.send.amount.toString()\n\t\t\t}\n\t\t};\n\t};\n\n\tconst account = request.account.publicKeyString.get();\n\tconst block = Buffer.from(request.block.toBytes()).toString('base64');\n\tconst retval: KeetaFXAnchorQueueStage1RequestJSON = {\n\t\tversion: 1,\n\t\taccount,\n\t\tblock,\n\t\trequest: request.request,\n\t\texpected: expected\n\t};\n\n\treturn(retval);\n}\n\nfunction decodeKeetaFXAnchorQueueStage1Request(request: JSONSerializable): KeetaFXAnchorQueueStage1Request {\n\t/* See note at bottom of file */\n\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\tconst reqJSON = assertKeetaFXAnchorQueueStage1RequestJSON(request);\n\n\tif (reqJSON.version !== 1) {\n\t\tthrow(new Error(`Unsupported KeetaFXAnchorQueueStage1Request version ${reqJSON.version}`));\n\t}\n\n\tlet expected: KeetaFXAnchorQueueStage1Request['expected'];\n\tif (reqJSON.expected === null) {\n\t\texpected = null;\n\t} else {\n\t\texpected = {\n\t\t\treceive: {\n\t\t\t\ttoken: KeetaNet.lib.Account.fromPublicKeyString(reqJSON.expected.receive.token).assertKeyType(KeetaNet.lib.Account.AccountKeyAlgorithm.TOKEN),\n\t\t\t\tamount: BigInt(reqJSON.expected.receive.amount)\n\t\t\t},\n\t\t\tsend: {\n\t\t\t\ttoken: KeetaNet.lib.Account.fromPublicKeyString(reqJSON.expected.send.token).assertKeyType(KeetaNet.lib.Account.AccountKeyAlgorithm.TOKEN),\n\t\t\t\tamount: BigInt(reqJSON.expected.send.amount)\n\t\t\t}\n\t\t};\n\t}\n\n\tconst retval: KeetaFXAnchorQueueStage1Request = {\n\t\taccount: KeetaNet.lib.Account.fromPublicKeyString(reqJSON.account),\n\t\tblock: new KeetaNet.lib.Block(reqJSON.block),\n\t\trequest: reqJSON.request,\n\t\texpected: expected\n\t};\n\n\treturn(retval);\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, request } = entry.request;\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\n\t\t\tif (!(userClient.account.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 with configured UserClient account`\n\t\t\t\t});\n\t\t\t}\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 builder = userClient.initBuilder();\n\t\tlet expected = entry.request.expected;\n\n\t\t/**\n\t\t * We only want to refund excess for cost/paying token if it is not a fixed rate\n\t\t * as if it is a fixed rate transfer, you can assume the client did not send unintentionally\n\t\t *\n\t\t * Additionally, other FX anchors are not forced to refund any, so there is no guarantee to client that refunds will occur\n\t\t */\n\t\tif (expected === null) {\n\t\t\tif (!('getConversionRateAndFee' in this.serverConfig.fx)) {\n\t\t\t\tthis.serverConfig.logger?.error('KeetaFXAnchorQueuePipelineStage1::processor', 'getConversionRateAndFee must be provided in fx configuration to process exchanges without expected details');\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: 'Server misconfiguration: getConversionRateAndFee must be provided in fx configuration to process exchanges without expected details'\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (request.preferredCostAsset !== undefined) {\n\t\t\t\tif (this.serverConfig.fx.acceptedCostAssets === undefined) {\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: 'This server does not support preferred cost asset selection'\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (!this.serverConfig.fx.acceptedCostAssets.includes(request.preferredCostAsset)) {\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: `Preferred cost asset \"${request.preferredCostAsset}\" is not accepted by this server`\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst quote = await this.serverConfig.fx.getConversionRateAndFee(request, { purpose: 'exchange', request: entry.request });\n\n\t\t\tconst { refunds } = assertExchangeBlockParametersAndComputeRefund({\n\t\t\t\tblock: block,\n\t\t\t\tliquidityAccount: entry.request.account,\n\t\t\t\tallowedLiquidityAccounts: null,\n\t\t\t\tchecks: { quote, request },\n\t\t\t\tisQuoteBasedExchange: false\n\t\t\t});\n\n\t\t\tfor (const refund of refunds) {\n\t\t\t\tbuilder.send(block.account, refund.amount, refund.token);\n\t\t\t}\n\n\t\t\texpected = convertQuoteToExpectedSwapWithoutCost({ quote, request });\n\t\t}\n\n\t\tbuilder.send(block.account, expected.send.amount, expected.send.token);\n\n\t\tconst sendBlock = await builder.computeBlocks();\n\n\t\tconst swapBlocks = [ ...sendBlock.blocks, block ];\n\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\n\t\ttry {\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} catch (error) {\n\t\t\tif (\n\t\t\t\tKeetaNet.lib.Error.isInstance(error) &&\n\t\t\t\t'shouldRetry' in error &&\n\t\t\t\t// Disable this warning as there is nothing stopping this from not being a boolean\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare\n\t\t\t\terror.shouldRetry === false\n\t\t\t) {\n\t\t\t\tthis.serverConfig.logger?.warn('KeetaFXAnchorQueuePipelineStage1::processor', 'Non-retryable error publishing swap blocks:', error);\n\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: `${error.code} ${error.message}`\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow(error);\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\treturn(encodeKeetaFXAnchorQueueStage1Request(request));\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\treturn(decodeKeetaFXAnchorQueueStage1Request(request));\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\ntype RunnerOrRunnerWithOptions<Req, Res> = ({\n\tprocessor: KeetaAnchorQueueRunner<Req, Res>['processor'];\n} & KeetaAnchorQueueRunnerConfigurationObject) | KeetaAnchorQueueRunner<Req, Res>['processor'];\n\ntype KeetaFXAnchorQueuePipelineExtensions = {\n\tsuccess?: RunnerOrRunnerWithOptions<KeetaFXAnchorQueueStage1Response, KeetaFXAnchorQueueStage1Response>;\n\tfailure?: RunnerOrRunnerWithOptions<KeetaFXAnchorQueueStage1Request, JSONSerializable>;\n}\n\ntype KeetaFXAnchorQueuePipelineAdditionalConfig = {\n\tserverConfig: KeetaAnchorFXServerConfig;\n\taccounts: InstanceType<typeof KeetaNet.lib.Account.Set>;\n\textensions?: KeetaFXAnchorQueuePipelineExtensions | undefined;\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\tprivate extensions?: KeetaFXAnchorQueuePipelineExtensions | undefined;\n\n\tprivate successStageRunner: KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Response, KeetaFXAnchorQueueStage1Response> | null = null;\n\tprivate failureStageRunner: KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, JSONSerializable> | null = null;\n\n\tconstructor(\n\t\toptions:\n\t\t\tConstructorParameters<typeof KeetaAnchorQueuePipelineAdvanced<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>>[0] &\n\t\t\tKeetaFXAnchorQueuePipelineAdditionalConfig\n\t) {\n\t\tsuper(options);\n\n\t\tthis.serverConfig = options.serverConfig;\n\t\tthis.accounts = options.accounts;\n\t\tthis.extensions = options.extensions;\n\t}\n\n\tprotected async createPipeline(): Promise<void> {\n\t\tconst failureExtension = this.extensions?.failure;\n\t\tconst successExtension = this.extensions?.success;\n\n\t\tif (failureExtension || successExtension) {\n\t\t\tabstract class BaseExtensionClass<Req, Res> extends KeetaAnchorQueueRunner<Req, Res> {\n\t\t\t\t#configSet = false;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n\t\t\t\t#processorMethod: Extract<RunnerOrRunnerWithOptions<Req, Res>, Function> = (() => {\n\t\t\t\t\tthrow(new Error('config not set'));\n\t\t\t\t});\n\n\t\t\t\t_setConfigurationAndProcessor(config: RunnerOrRunnerWithOptions<Req, Res>) {\n\t\t\t\t\tif (this.#configSet) {\n\t\t\t\t\t\tthrow(new Error('Configuration can only be set once'));\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.#configSet = true;\n\n\t\t\t\t\tif (typeof config === 'function') {\n\t\t\t\t\t\tthis.#processorMethod = config;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst { processor, ...parameters } = config;\n\t\t\t\t\t\tthis.#processorMethod = processor;\n\n\t\t\t\t\t\tthis.setConfiguration(parameters);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tprotected async processor(entry: Parameters<KeetaAnchorQueueRunner<Req, Res>['processor']>[0]) {\n\t\t\t\t\treturn(await this.#processorMethod(entry));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (failureExtension) {\n\t\t\t\tconst failureQueue = await this.baseQueue.partition('failed');\n\t\t\t\tthis.queues.push(failureQueue);\n\n\t\t\t\tconst runner = (new class extends BaseExtensionClass<KeetaFXAnchorQueueStage1Request, JSONSerializable> {\n\t\t\t\t\tprotected encodeRequest(request: KeetaFXAnchorQueueStage1Request) { return(encodeKeetaFXAnchorQueueStage1Request(request)); }\n\t\t\t\t\tprotected decodeRequest(request: JSONSerializable): KeetaFXAnchorQueueStage1Request { return(decodeKeetaFXAnchorQueueStage1Request(request)); }\n\t\t\t\t\tprotected encodeResponse(response: JSONSerializable | null) { return(response); }\n\t\t\t\t\tprotected decodeResponse(response: JSONSerializable | null) { return(response); }\n\t\t\t\t}({\n\t\t\t\t\tid: 'keeta-fx-anchor-failure-runner',\n\t\t\t\t\tqueue: failureQueue,\n\t\t\t\t\tlogger: this.logger\n\t\t\t\t}));\n\n\t\t\t\trunner._setConfigurationAndProcessor(failureExtension);\n\n\t\t\t\tthis.failureStageRunner = runner;\n\t\t\t}\n\n\t\t\tif (successExtension) {\n\t\t\t\tconst successQueue = await this.baseQueue.partition('success');\n\t\t\t\tthis.queues.push(successQueue);\n\n\t\t\t\tconst runner = (new class extends BaseExtensionClass<KeetaFXAnchorQueueStage1Response, KeetaFXAnchorQueueStage1Response> {\n\t\t\t\t\tprotected encodeRequest(request: KeetaFXAnchorQueueStage1Response) { return(request); }\n\t\t\t\t\tprotected decodeRequest(request: JSONSerializable): KeetaFXAnchorQueueStage1Response {\n\t\t\t\t\t\t/* See note at bottom of file */\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\t\t\t\t\tconst parsed = assertKeetaFXAnchorQueueStage1ResponseOrNull(request);\n\t\t\t\t\t\tif (parsed === null) {\n\t\t\t\t\t\t\tthrow(new Error('Invalid request for success extension'));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn(parsed);\n\t\t\t\t\t}\n\n\t\t\t\t\tprotected encodeResponse(response: KeetaFXAnchorQueueStage1Response | null) { return(response); }\n\t\t\t\t\tprotected decodeResponse(response: JSONSerializable | null): KeetaFXAnchorQueueStage1Response | null {\n\t\t\t\t\t\t/* See note at bottom of file */\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\t\t\t\t\treturn(assertKeetaFXAnchorQueueStage1ResponseOrNull(response));\n\t\t\t\t\t}\n\t\t\t\t}({\n\t\t\t\t\tid: 'keeta-fx-anchor-success-runner',\n\t\t\t\t\tqueue: successQueue,\n\t\t\t\t\tlogger: this.logger\n\t\t\t\t}));\n\n\t\t\t\trunner._setConfigurationAndProcessor(successExtension);\n\n\t\t\t\tthis.successStageRunner = runner;\n\t\t\t}\n\t\t}\n\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\n\t\t\tif (this.successStageRunner) {\n\t\t\t\trunner.pipe(this.successStageRunner, { exclusiveTarget: false });\n\t\t\t}\n\n\t\t\tif (this.failureStageRunner) {\n\t\t\t\trunner.pipeFailed(this.failureStageRunner, { exclusiveTarget: false });\n\t\t\t}\n\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\t/**\n\t * Get the status of a request by ID.\n\t * If the request is found in any of the runners, it is returned with its current status.\n\t * Because typically the user will only care about the status of the first stage-\n\t * The request will be marked as failed or completed if it is found in the success or failure stages, instead of the status from those stages.\n\t * @param id The ID of the request to get the status of\n\t * @returns The inferred status of the request, or null if the request is not found\n\t */\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\tif (entry.status === 'moved') {\n\t\t\t\t\tlet failedFound = null;\n\t\t\t\t\tlet successFound = null;\n\n\t\t\t\t\tif (this.failureStageRunner || this.successStageRunner) {\n\t\t\t\t\t\tawait Promise.all([\n\t\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\t\tif (!this.failureStageRunner) {\n\t\t\t\t\t\t\t\t\treturn(null);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfailedFound = await this.failureStageRunner.get(id);\n\t\t\t\t\t\t\t})(),\n\t\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\t\tif (!this.successStageRunner) {\n\t\t\t\t\t\t\t\t\treturn(null);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsuccessFound = await this.successStageRunner.get(id);\n\t\t\t\t\t\t\t})()\n\t\t\t\t\t\t]);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (failedFound && successFound) {\n\t\t\t\t\t\tthis.logger?.warn(`Request with ID ${String(id)} was found in both the success and failure stages -- this should not happen`, { requestID: id });\n\t\t\t\t\t} else if (failedFound) {\n\t\t\t\t\t\tentry.status = 'failed_permanently';\n\t\t\t\t\t} else if (successFound) {\n\t\t\t\t\t\tentry.status = 'completed';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.logger?.warn(`Request with ID ${String(id)} has moved from the main processing stage but was not found in either the success or failure stages -- leaving status as \"moved\"`, { requestID: id });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn(entry);\n\t\t\t}\n\t\t}\n\n\t\treturn(null);\n\t}\n\n\t#getAllRunners() {\n\t\tconst runners = [];\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\t\t\trunners.push(runner);\n\t\t}\n\n\t\tif (this.successStageRunner) {\n\t\t\trunners.push(this.successStageRunner);\n\t\t}\n\n\t\tif (this.failureStageRunner) {\n\t\t\trunners.push(this.failureStageRunner);\n\t\t}\n\n\t\treturn(runners);\n\t}\n\n\tasync run(options?: Parameters<KeetaFXAnchorQueuePipelineStage1['run']>[0]): ReturnType<KeetaFXAnchorQueuePipelineStage1['run']> {\n\t\tawait super.init();\n\n\t\tconst runners = this.#getAllRunners();\n\n\t\tlet retval = false;\n\t\tfor (const runner of runners) {\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\tconst runners = this.#getAllRunners();\n\n\t\tfor (const runner of runners) {\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\tconst runners = this.#getAllRunners();\n\t\tfor (const runner of 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\ntype SharedHTTPServerConfigType = Pick<KeetaAnchorFXServerConfig, 'fx' | 'homepage' | keyof KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig>;\nabstract class BaseKeetaNetFXAnchorHTTPServer<ConfigType extends SharedHTTPServerConfigType> extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<ConfigType> implements Omit<Required<KeetaAnchorFXServerConfig>, 'storage' | 'queueRunnerExtensions' | 'accounts' | 'account' | 'signer' | 'client' | 'quoteSigner' | 'quoteConfiguration'> {\n\treadonly homepage: NonNullable<KeetaAnchorFXServerConfig['homepage']>;\n\treadonly fx: KeetaAnchorFXServerConfig['fx'];\n\treadonly canPerformExchanges: boolean;\n\n\tprotected abstract quoteConfiguration: Exclude<KeetaAnchorFXServerConfig['quoteConfiguration'], undefined> | null;\n\n\tprotected accounts: InstanceType<typeof KeetaNet.lib.Account.Set> | null = null;\n\n\tconstructor(config: ConfigType) {\n\t\tsuper(config);\n\n\t\tthis.homepage = config.homepage ?? '';\n\t\tthis.fx = config.fx;\n\n\t\t// This is incorrect as undefined and true are the same (because default is true), but using a negation will not result in the correct type for canPerformExchanges, so we have to disable the lint warning and accept the incorrectness\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare\n\t\tthis.canPerformExchanges = config.fx.performExchanges === undefined || config.fx.performExchanges === true;\n\t}\n\n\tprotected async getUnsignedQuoteData(conversion: ConversionInputCanonicalJSON, purpose: 'estimate'): Promise<KeetaFXInternalPriceEstimate | KeetaFXInternalPriceQuote>;\n\tprotected async getUnsignedQuoteData(conversion: ConversionInputCanonicalJSON, purpose: 'quote'): Promise<KeetaFXInternalPriceQuote>;\n\tprotected async getUnsignedQuoteData(conversion: ConversionInputCanonicalJSON, purpose: Exclude<GetConversionRateAndFeeContext['purpose'], 'exchange'>): Promise<KeetaFXInternalPriceQuote | KeetaFXInternalPriceEstimate> {\n\t\tif (purpose !== 'estimate' && !this.canPerformExchanges) {\n\t\t\tthrow(new Error(`FX configuration does not support performing exchanges, so purpose \"${purpose}\" is invalid`));\n\t\t}\n\n\t\tif (conversion.preferredCostAsset !== undefined) {\n\t\t\tif (this.fx.acceptedCostAssets === undefined) {\n\t\t\t\tthrow(new KeetaAnchorUserError('This server does not support preferred cost asset selection'));\n\t\t\t}\n\n\t\t\tif (!this.fx.acceptedCostAssets.includes(conversion.preferredCostAsset)) {\n\t\t\t\tthrow(new KeetaAnchorUserError(`Preferred cost asset \"${conversion.preferredCostAsset}\" is not accepted by this server`));\n\t\t\t}\n\t\t}\n\n\t\tif ('getConversionRateAndFee' in this.fx) {\n\t\t\tif (!this.accounts) {\n\t\t\t\tthrow(new Error('Accounts must be configured to use \"getConversionRateAndFee\" in fx configuration'));\n\t\t\t}\n\n\t\t\tconst rateAndFee = await this.fx.getConversionRateAndFee(conversion, { purpose });\n\n\t\t\tif (PARANOID) {\n\t\t\t\tconst quoteAccount = rateAndFee.account;\n\t\t\t\tif (!this.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\treturn(rateAndFee);\n\t\t} else if ('estimateRateAndFee' in this.fx) {\n\t\t\tif (purpose !== 'estimate') {\n\t\t\t\tthrow(new Error('FX configuration only supports \"estimateRateAndFee\", so purpose must be \"estimate\"'));\n\t\t\t}\n\n\t\t\treturn(await this.fx.estimateRateAndFee(conversion));\n\t\t} else {\n\t\t\tassertNever(this.fx);\n\t\t}\n\t}\n\n\tprotected async initRoutes(config: ConfigType): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = {};\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\n\t\t/**\n\t\t * Setup the request handler for an estimate request\n\t\t */\n\t\troutes['POST /api/getEstimate'] = async (_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 this.getUnsignedQuoteData(conversion, 'estimate');\n\n\t\t\tlet requiresQuoteBody: { canPerformExchange: false; } | { requiresQuote: true } | { requiresQuote: false; account: KeetaNetAccount | KeetaNetStorageAccount; };\n\n\t\t\tif (!instance.quoteConfiguration || !instance.canPerformExchanges) {\n\t\t\t\trequiresQuoteBody = { canPerformExchange: false };\n\t\t\t} else if (instance.quoteConfiguration.requiresQuote) {\n\t\t\t\trequiresQuoteBody = { requiresQuote: true };\n\t\t\t} else {\n\t\t\t\tif (rateAndFee.convertedAmountBound === undefined) {\n\t\t\t\t\tinstance.logger.warn('POST /api/getEstimate', 'FX configuration indicates quotes are not required, but \"convertedAmountBound\" was not provided in the rate and fee response');\n\t\t\t\t} else {\n\t\t\t\t\tif (conversion.affinity === 'to' && (BigInt(rateAndFee.convertedAmount) > rateAndFee.convertedAmountBound)) {\n\t\t\t\t\t\tthrow(new KeetaAnchorError('Affinity is to, but bound is less than estimated sent amount'));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (conversion.affinity === 'from' && (BigInt(rateAndFee.convertedAmount) < rateAndFee.convertedAmountBound)) {\n\t\t\t\t\t\tthrow(new KeetaAnchorError('Affinity is from, but bound is greater than estimated received amount'));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!('account' in rateAndFee) || !rateAndFee.account) {\n\t\t\t\t\tthrow(new Error('FX configuration indicates quotes are not required, but no account was provided in the rate and fee response'));\n\t\t\t\t}\n\n\t\t\t\trequiresQuoteBody = { requiresQuote: false, account: rateAndFee.account };\n\t\t\t}\n\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\tconvertedAmountBound: rateAndFee.convertedAmountBound,\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\t...requiresQuoteBody\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\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};\n\n\t\tconst metadata: NonNullable<ServiceMetadata['services']['fx']>[string] = {\n\t\t\tfrom: this.fx.from ?? [],\n\t\t\toperations: operations\n\t\t};\n\n\t\tif (this.fx.acceptedCostAssets) {\n\t\t\tmetadata.acceptedCostAssets = this.fx.acceptedCostAssets;\n\t\t}\n\n\t\treturn(metadata);\n\t}\n}\n\nexport class KeetaNetFXAnchorEstimateHTTPServer extends BaseKeetaNetFXAnchorHTTPServer<SharedHTTPServerConfigType> {\n\tprotected quoteConfiguration = null;\n\n\tconstructor(config: SharedHTTPServerConfigType) {\n\t\tsuper(config);\n\n\t\tif (this.canPerformExchanges) {\n\t\t\tthrow(new Error('FX configuration indicates exchanges can be performed, but KeetaNetFXAnchorEstimateHTTPServer does not support exchange capability'));\n\t\t}\n\t}\n}\n\nexport class KeetaNetFXAnchorHTTPServer extends BaseKeetaNetFXAnchorHTTPServer<KeetaAnchorFXServerConfig> implements Omit<Required<KeetaAnchorFXServerConfig>, 'storage' | 'queueRunnerExtensions'> {\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\treadonly quoteConfiguration: Exclude<KeetaAnchorFXServerConfig['quoteConfiguration'], undefined>;\n\n\tprotected autoRun: boolean;\n\tprotected autoRunRunning = false;\n\n\tconstructor(config: KeetaAnchorFXServerConfig) {\n\t\tsuper(config);\n\n\t\tthis.client = config.client;\n\t\tthis.fx = config.fx;\n\t\tthis.quoteSigner = config.quoteSigner;\n\t\tthis.quoteConfiguration = config.quoteConfiguration ?? { requiresQuote: true };\n\n\t\tif (!this.canPerformExchanges) {\n\t\t\tthrow(new Error('FX configuration indicates exchanges cannot be performed, but KeetaNetFXAnchorHTTPServer requires exchange capability'));\n\t\t}\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\tthis.autoRun = config.storage?.autoRun ?? false;\n\t\tif (config.storage === undefined) {\n\t\t\tthis.autoRun = 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\textensions: config.queueRunnerExtensions\n\t\t});\n\t}\n\n\tprotected async initRoutes(config: KeetaAnchorFXServerConfig): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = await super.initRoutes(config);\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\n\t\troutes['POST /api/getQuote'] = async (_ignore_params, postData) => {\n\t\t\tif (!instance.quoteConfiguration.requiresQuote && !instance.quoteConfiguration.issueQuotes) {\n\t\t\t\tthrow(new Errors.QuoteIssuanceDisabled());\n\t\t\t}\n\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\n\t\t\tconst conversion = assertConversionInputCanonicalJSON(postData.request);\n\t\t\tconst rateAndFee = await this.getUnsignedQuoteData(conversion, 'quote');\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\tif (config.quoteSigner === null) {\n\t\t\t\tthrow(new Error('Quote signer not configured, this is required when issuing quotes'));\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 (_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\n\t\t\tconst request = assertKeetaFXAnchorClientCreateExchangeRequestJSON(postData.request);\n\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 block = new KeetaNet.lib.Block(request.block);\n\n\t\t\tlet quoteInput;\n\t\t\tlet conversionInput;\n\t\t\tlet shouldValidateQuote;\n\t\t\tlet liquidityAccount;\n\t\t\tlet expectedConversion: KeetaFXAnchorQueueStage1Request['expected'];\n\t\t\tlet isQuoteBasedExchange;\n\t\t\tif ('quote' in request && 'estimate' in request && request.quote && request.estimate) {\n\t\t\t\tthrow(new Error('Request cannot contain both quote and estimate'));\n\t\t\t} else if ('quote' in request && request.quote) {\n\t\t\t\tisQuoteBasedExchange = true;\n\t\t\t\tshouldValidateQuote = true;\n\t\t\t\tquoteInput = request.quote;\n\t\t\t\tconversionInput = quoteInput.request;\n\n\t\t\t\tconst isValidQuote = await (async () => {\n\t\t\t\t\tif (config.quoteSigner === null) {\n\t\t\t\t\t\treturn(false);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn(await verifySignedData(config.quoteSigner, quoteInput));\n\t\t\t\t})();\n\n\t\t\t\tif (!isValidQuote) {\n\t\t\t\t\tthrow(new Errors.QuoteValidationFailed());\n\t\t\t\t}\n\n\t\t\t\tliquidityAccount = quoteInput.account;\n\t\t\t\texpectedConversion = convertQuoteToExpectedSwapWithoutCost({\n\t\t\t\t\tquote: toValidateQuoteInput(quoteInput),\n\t\t\t\t\trequest: conversionInput\n\t\t\t\t});\n\t\t\t} else if ('request' in request && request.request) {\n\t\t\t\tisQuoteBasedExchange = false;\n\t\t\t\tif (instance.quoteConfiguration.requiresQuote) {\n\t\t\t\t\tthrow(new Errors.QuoteRequired());\n\t\t\t\t}\n\n\t\t\t\tconversionInput = request.request;\n\t\t\t\tquoteInput = await this.getUnsignedQuoteData(conversionInput, 'estimate');\n\n\t\t\t\tif (instance.quoteConfiguration.validateQuoteBeforeExchange !== undefined) {\n\t\t\t\t\tshouldValidateQuote = instance.quoteConfiguration.validateQuoteBeforeExchange;\n\t\t\t\t} else {\n\t\t\t\t\tshouldValidateQuote = config.fx.validateQuote !== undefined;\n\t\t\t\t}\n\n\t\t\t\tfor (const operation of block.operations) {\n\t\t\t\t\tif (operation.type === KeetaNet.lib.Block.OperationType.SEND) {\n\t\t\t\t\t\tif (!config.accounts) {\n\t\t\t\t\t\t\tthrow(new Error('No accounts configured for FX server, cannot infer liquidity account from block'));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (config.accounts.has(operation.to)) {\n\t\t\t\t\t\t\tliquidityAccount = operation.to;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!liquidityAccount) {\n\t\t\t\t\tthrow(new KeetaAnchorUserError('Could not determine liquidity account from exchange block'));\n\t\t\t\t}\n\n\t\t\t\t// No expected conversion provided when using estimate, we determine the rate when processing the exchange\n\t\t\t\texpectedConversion = null;\n\t\t\t} else {\n\t\t\t\tthrow(new Error('Either quote or request must be provided (but not both) in exchange request'));\n\t\t\t}\n\n\t\t\tif (!('account' in quoteInput) || !quoteInput.account) {\n\t\t\t\tthrow(new Error('Quote is missing account, createExchange should not be supported for quotes without an account'));\n\t\t\t}\n\n\t\t\tconst parsedQuote = toValidateQuoteInput(quoteInput);\n\n\t\t\t/* Validate the quote using the optional callback */\n\t\t\tif (config.fx.validateQuote !== undefined && shouldValidateQuote) {\n\t\t\t\tconst isAcceptable = await config.fx.validateQuote(parsedQuote);\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 liquidityAccountInstance = KeetaNet.lib.Account.toAccount(liquidityAccount);\n\n\t\t\tlet allowedLiquidityAccounts;\n\t\t\tif (config.accounts) {\n\t\t\t\tallowedLiquidityAccounts = config.accounts;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t} else if (config.account) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\tallowedLiquidityAccounts = new KeetaNet.lib.Account.Set([ config.account ]);\n\t\t\t} else {\n\t\t\t\tthrow(new Error('config.account or config.accounts must be provided'));\n\t\t\t}\n\n\t\t\tassertExchangeBlockParametersAndComputeRefund({\n\t\t\t\tblock: block,\n\t\t\t\tliquidityAccount: liquidityAccountInstance,\n\t\t\t\tallowedLiquidityAccounts: allowedLiquidityAccounts,\n\t\t\t\tchecks: { quote: parsedQuote, request: conversionInput },\n\t\t\t\tisQuoteBasedExchange: isQuoteBasedExchange\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: liquidityAccountInstance,\n\t\t\t\tblock: block,\n\t\t\t\trequest: conversionInput,\n\t\t\t\texpected: expectedConversion\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\tif (instance.autoRun && !instance.autoRunRunning) {\n\t\t\t\t/*\n\t\t\t\t * Keep track of how many times, consecutively, the queue was empty when we\n\t\t\t\t * went to run it\n\t\t\t\t */\n\t\t\t\tlet noMoreJobsCount = 0;\n\n\t\t\t\t/*\n\t\t\t\t * Create a mutex around the queue running so we don't have\n\t\t\t\t * lock contention for the worker ID if multiple requests\n\t\t\t\t * are being served by the same instance\n\t\t\t\t */\n\t\t\t\tinstance.autoRunRunning = true;\n\t\t\t\tawait using cleanup = new AsyncDisposableStack();\n\t\t\t\tcleanup.defer(async function() {\n\t\t\t\t\tinstance.autoRunRunning = false;\n\t\t\t\t});\n\n\t\t\t\t/*\n\t\t\t\t * For up to 15s process the queue, stopping only when\n\t\t\t\t * we've had 2 consecutive runs that indicate there is\n\t\t\t\t * no more in the queue to process\n\t\t\t\t */\n\t\t\t\tfor (const startTime = Date.now(); Date.now() - startTime < 15000;) {\n\t\t\t\t\tconst more = await instance.pipeline.run({ timeoutMs: 1500 });\n\t\t\t\t\tif (!more) {\n\t\t\t\t\t\tnoMoreJobsCount++;\n\t\t\t\t\t\tif (noMoreJobsCount >= 2) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnoMoreJobsCount = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait instance.pipeline.maintain();\n\t\t\t\t\tawait asleep(100);\n\t\t\t\t}\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\toverride async serviceMetadata(): Promise<NonNullable<ServiceMetadata['services']['fx']>[string]> {\n\t\tconst baseMetadata = await super.serviceMetadata();\n\n\t\tif (this.quoteConfiguration.requiresQuote || this.quoteConfiguration.issueQuotes) {\n\t\t\tbaseMetadata.operations.getQuote = (new URL('/api/getQuote', this.url)).toString();\n\t\t}\n\n\t\tbaseMetadata.operations.getExchangeStatus = (new URL('/api/getExchangeStatus', this.url)).toString() + '/{id}';\n\t\tbaseMetadata.operations.createExchange = (new URL('/api/createExchange', this.url)).toString();\n\n\t\treturn(baseMetadata);\n\t}\n\n\tasync stop(): Promise<void> {\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"]}
|