@keetanetwork/anchor 0.0.3 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/client/index.d.ts +6 -0
  2. package/client/index.d.ts.map +1 -1
  3. package/client/index.js +7 -0
  4. package/client/index.js.map +1 -1
  5. package/lib/error.d.ts +14 -0
  6. package/lib/error.d.ts.map +1 -0
  7. package/lib/error.js +38 -0
  8. package/lib/error.js.map +1 -0
  9. package/lib/http-server.d.ts +59 -0
  10. package/lib/http-server.d.ts.map +1 -0
  11. package/lib/http-server.js +383 -0
  12. package/lib/http-server.js.map +1 -0
  13. package/lib/resolver.d.ts +159 -60
  14. package/lib/resolver.d.ts.map +1 -1
  15. package/lib/resolver.js +3519 -384
  16. package/lib/resolver.js.map +1 -1
  17. package/lib/utils/brand.d.ts +12 -0
  18. package/lib/utils/brand.d.ts.map +1 -0
  19. package/lib/utils/brand.js +2 -0
  20. package/lib/utils/brand.js.map +1 -0
  21. package/lib/utils/never.d.ts +4 -0
  22. package/lib/utils/never.d.ts.map +1 -1
  23. package/lib/utils/never.js.map +1 -1
  24. package/lib/utils/signing.d.ts +17 -0
  25. package/lib/utils/signing.d.ts.map +1 -0
  26. package/lib/utils/signing.js +73 -0
  27. package/lib/utils/signing.js.map +1 -0
  28. package/lib/utils/url.d.ts +2 -0
  29. package/lib/utils/url.d.ts.map +1 -0
  30. package/lib/utils/url.js +8 -0
  31. package/lib/utils/url.js.map +1 -0
  32. package/npm-shrinkwrap.json +529 -16210
  33. package/package.json +31 -40
  34. package/services/fx/client.d.ts +137 -0
  35. package/services/fx/client.d.ts.map +1 -0
  36. package/services/fx/client.js +519 -0
  37. package/services/fx/client.js.map +1 -0
  38. package/services/fx/common.d.ts +133 -0
  39. package/services/fx/common.d.ts.map +1 -0
  40. package/services/fx/common.js +45 -0
  41. package/services/fx/common.js.map +1 -0
  42. package/services/fx/server.d.ts +58 -0
  43. package/services/fx/server.d.ts.map +1 -0
  44. package/services/fx/server.js +349 -0
  45. package/services/fx/server.js.map +1 -0
  46. package/services/kyc/client.d.ts +1 -1
  47. package/services/kyc/client.d.ts.map +1 -1
  48. package/services/kyc/client.js +7 -53
  49. package/services/kyc/client.js.map +1 -1
@@ -0,0 +1,133 @@
1
+ import { lib as KeetaNetLib, type UserClient as KeetaNetUserClient } from '@keetanetwork/keetanet-client';
2
+ import type { Decimal } from 'decimal.js';
3
+ import type { ServiceSearchCriteria } from '../../lib/resolver.js';
4
+ export type KeetaNetAccount = InstanceType<typeof KeetaNetLib.Account>;
5
+ export type KeetaNetToken = InstanceType<typeof KeetaNetLib.Account<typeof KeetaNetLib.Account.AccountKeyAlgorithm.TOKEN>>;
6
+ export type KeetaNetTokenPublicKeyString = ReturnType<InstanceType<typeof KeetaNetLib.Account<typeof KeetaNetLib.Account.AccountKeyAlgorithm.TOKEN>>['publicKeyString']['get']>;
7
+ export type ConversionInput = {
8
+ /**
9
+ * The currency code to convert from (i.e., what the user has).
10
+ */
11
+ from: ServiceSearchCriteria<'fx'>['inputCurrencyCode'] | KeetaNetToken;
12
+ /**
13
+ * The currency code to convert to (i.e., what the user wants).
14
+ */
15
+ to: ServiceSearchCriteria<'fx'>['outputCurrencyCode'] | KeetaNetToken;
16
+ /**
17
+ * The amount to convert. This is a string or Decimal representing the
18
+ * amount in the currency specified by either `from` or `to`, as
19
+ * specified by the `affinity` property.
20
+ */
21
+ amount: string | number | Decimal;
22
+ /**
23
+ * Indicates whether the amount specified is in terms of the `from`
24
+ * currency (i.e., the user has this much) or the `to` currency
25
+ * (i.e., the user wants this much).
26
+ */
27
+ affinity: 'from' | 'to';
28
+ };
29
+ export type ConversionInputCanonical = {
30
+ [k in keyof ConversionInput]: k extends 'amount' ? string : k extends 'from' ? KeetaNetTokenPublicKeyString : k extends 'to' ? KeetaNetTokenPublicKeyString : ConversionInput[k];
31
+ };
32
+ export type KeetaFXAnchorClientCreateExchangeRequest = {
33
+ quote: KeetaFXAnchorQuote;
34
+ block: InstanceType<typeof KeetaNetLib.Block>;
35
+ };
36
+ export type KeetaFXAnchorClientGetExchangeStatusRequest = {
37
+ exchangeID: string;
38
+ };
39
+ export type KeetaFXAnchorEstimate = {
40
+ /**
41
+ * Conversion request that was provided
42
+ */
43
+ request: ConversionInputCanonical;
44
+ /**
45
+ * Amount after the conversion as specified by either `from` or `to`, as specified by the `affinity` property in the request.
46
+ */
47
+ convertedAmount: string;
48
+ /**
49
+ * The expected cost of the fx request, in the form of a
50
+ * token and a range of minimum and maximum expected costs
51
+ */
52
+ expectedCost: {
53
+ min: string;
54
+ max: string;
55
+ token: KeetaNetTokenPublicKeyString;
56
+ };
57
+ };
58
+ export type KeetaFXAnchorEstimateResponse = ({
59
+ ok: true;
60
+ estimate: KeetaFXAnchorEstimate;
61
+ } | {
62
+ ok: false;
63
+ error: string;
64
+ });
65
+ export type KeetaFXAnchorQuote = {
66
+ /**
67
+ * Conversion request that was provided
68
+ */
69
+ request: ConversionInputCanonical;
70
+ /**
71
+ * The public key of the liquidity provider account
72
+ */
73
+ account: string;
74
+ /**
75
+ * Amount after the conversion as specified by either `from` or `to`, as specified by the `affinity` property in the request.
76
+ */
77
+ convertedAmount: string;
78
+ /**
79
+ * The cost of the fx request, in the form of a
80
+ * token and amount that should be included with the swap
81
+ */
82
+ cost: {
83
+ amount: string;
84
+ token: KeetaNetTokenPublicKeyString;
85
+ };
86
+ /**
87
+ * Signature information to verify the quote
88
+ */
89
+ signed: {
90
+ nonce: string;
91
+ timestamp: string;
92
+ signature: string;
93
+ };
94
+ };
95
+ export type KeetaFXAnchorQuoteResponse = ({
96
+ ok: true;
97
+ quote: KeetaFXAnchorQuote;
98
+ } | {
99
+ ok: false;
100
+ error: string;
101
+ });
102
+ export type KeetaFXAnchorExchange = {
103
+ /**
104
+ * ID used to identify the conversion request
105
+ */
106
+ exchangeID: string;
107
+ };
108
+ export type KeetaFXAnchorExchangeResponse = KeetaFXAnchorExchange & ({
109
+ ok: true;
110
+ } | {
111
+ ok: false;
112
+ error: string;
113
+ });
114
+ /**
115
+ * @deprecated Use the Node UserClient methods in the future instead of this function
116
+ */
117
+ export declare function createSwapRequest(userClient: KeetaNetUserClient, from: {
118
+ account: KeetaNetAccount;
119
+ token: KeetaNetToken;
120
+ amount: bigint;
121
+ }, to: {
122
+ account: KeetaNetAccount;
123
+ token: KeetaNetToken;
124
+ amount: bigint;
125
+ }): Promise<InstanceType<typeof KeetaNetLib.Block>>;
126
+ /**
127
+ * @deprecated Use the Node UserClient methods in the future instead of this function
128
+ */
129
+ export declare function acceptSwapRequest(userClient: KeetaNetUserClient, request: InstanceType<typeof KeetaNetLib.Block>, expected: {
130
+ token?: KeetaNetToken;
131
+ amount?: bigint;
132
+ }): Promise<InstanceType<typeof KeetaNetLib.Block>[]>;
133
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/services/fx/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';
2
+ /**
3
+ * @deprecated Use the Node UserClient methods in the future instead of this function
4
+ */
5
+ export async function createSwapRequest(userClient, from, to) {
6
+ const builder = userClient.initBuilder();
7
+ builder.send(to.account, from.amount, from.token);
8
+ builder.receive(to.account, to.amount, to.token, true);
9
+ const blocks = await builder.computeBlocks();
10
+ if (blocks.blocks.length !== 1) {
11
+ throw (new Error('Compute Swap Request Generated more than 1 block'));
12
+ }
13
+ const block = blocks.blocks[0];
14
+ if (block === undefined) {
15
+ throw (new Error('Swap Block is undefined'));
16
+ }
17
+ return (block);
18
+ }
19
+ /**
20
+ * @deprecated Use the Node UserClient methods in the future instead of this function
21
+ */
22
+ export async function acceptSwapRequest(userClient, request, expected) {
23
+ const builder = userClient.initBuilder();
24
+ const sendOperation = request.operations.find(({ type }) => KeetaNetLib.Block.OperationType.SEND === type);
25
+ if (!sendOperation || sendOperation.type !== KeetaNetLib.Block.OperationType.SEND) {
26
+ throw (new Error('Swap Request is missing send'));
27
+ }
28
+ if (!sendOperation.to.comparePublicKey(userClient.account)) {
29
+ throw (new Error(`Swap Request send account does not match`));
30
+ }
31
+ if (expected.token !== undefined && !sendOperation.token.comparePublicKey(expected.token)) {
32
+ throw (new Error('Swap Request send token does not match expected'));
33
+ }
34
+ if (expected.amount !== undefined && sendOperation.amount !== expected.amount) {
35
+ throw (new Error(`Swap Request send amount ${sendOperation.amount} does not match expected amount ${expected.amount}`));
36
+ }
37
+ const receiveOperation = request.operations.find(({ type }) => KeetaNetLib.Block.OperationType.RECEIVE === type);
38
+ if (!receiveOperation || receiveOperation.type !== KeetaNetLib.Block.OperationType.RECEIVE) {
39
+ throw (new Error("Swap Request is missing receive operation"));
40
+ }
41
+ builder.send(request.account, receiveOperation.amount, receiveOperation.token);
42
+ const blocks = await builder.computeBlocks();
43
+ return ([...blocks.blocks, request]);
44
+ }
45
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/services/fx/common.ts"],"names":[],"mappings":"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","sourcesContent":["import { lib as KeetaNetLib, type UserClient as KeetaNetUserClient } from '@keetanetwork/keetanet-client';\nimport type { Decimal } from 'decimal.js';\n\nimport type { ServiceSearchCriteria } from '../../lib/resolver.js';\n\nexport type KeetaNetAccount = InstanceType<typeof KeetaNetLib.Account>;\nexport type KeetaNetToken = InstanceType<typeof KeetaNetLib.Account<typeof KeetaNetLib.Account.AccountKeyAlgorithm.TOKEN>>;\nexport type KeetaNetTokenPublicKeyString = ReturnType<InstanceType<typeof KeetaNetLib.Account<typeof KeetaNetLib.Account.AccountKeyAlgorithm.TOKEN>>['publicKeyString']['get']>;\n\nexport type ConversionInput = {\n\t/**\n\t * The currency code to convert from (i.e., what the user has).\n\t */\n\tfrom: ServiceSearchCriteria<'fx'>['inputCurrencyCode'] | KeetaNetToken;\n\t/**\n\t * The currency code to convert to (i.e., what the user wants).\n\t */\n\tto: ServiceSearchCriteria<'fx'>['outputCurrencyCode'] | KeetaNetToken;\n\t/**\n\t * The amount to convert. This is a string or Decimal representing the\n\t * amount in the currency specified by either `from` or `to`, as\n\t * specified by the `affinity` property.\n\t */\n\tamount: string | number | Decimal;\n\t/**\n\t * Indicates whether the amount specified is in terms of the `from`\n\t * currency (i.e., the user has this much) or the `to` currency\n\t * (i.e., the user wants this much).\n\t */\n\taffinity: 'from' | 'to';\n};\n\nexport type ConversionInputCanonical = {\n\t[k in keyof ConversionInput]: k extends 'amount' ? string : k extends 'from' ? KeetaNetTokenPublicKeyString : k extends 'to' ? KeetaNetTokenPublicKeyString : ConversionInput[k];\n};\n\nexport type KeetaFXAnchorClientCreateExchangeRequest = {\n\tquote: KeetaFXAnchorQuote;\n\tblock: InstanceType<typeof KeetaNetLib.Block>;\n};\n\nexport type KeetaFXAnchorClientGetExchangeStatusRequest = {\n\texchangeID: string\n};\n\nexport type KeetaFXAnchorEstimate = {\n\t/**\n\t * Conversion request that was provided\n\t */\n\trequest: ConversionInputCanonical;\n\n\t/**\n\t * Amount after the conversion as specified by either `from` or `to`, as specified by the `affinity` property in the request.\n\t */\n\tconvertedAmount: string;\n\n\t/**\n\t * The expected cost of the fx request, in the form of a\n\t * token and a range of minimum and maximum expected costs\n\t */\n\texpectedCost: {\n\t\tmin: string;\n\t\tmax: string;\n\t\ttoken: KeetaNetTokenPublicKeyString;\n\t};\n};\n\nexport type KeetaFXAnchorEstimateResponse = ({\n\tok: true;\n\testimate: KeetaFXAnchorEstimate;\n} | {\n\tok: false;\n\terror: string;\n});\n\nexport type KeetaFXAnchorQuote = {\n\t/**\n\t * Conversion request that was provided\n\t */\n\trequest: ConversionInputCanonical;\n\n\t/**\n\t * The public key of the liquidity provider account\n\t */\n\taccount: string;\n\n\t/**\n\t * Amount after the conversion as specified by either `from` or `to`, as specified by the `affinity` property in the request.\n\t */\n\n\tconvertedAmount: string;\n\n\t/**\n\t * The cost of the fx request, in the form of a\n\t * token and amount that should be included with the swap\n\t */\n\tcost: {\n\t\tamount: string;\n\t\ttoken: KeetaNetTokenPublicKeyString;\n\t};\n\n\t/**\n\t * Signature information to verify the quote\n\t */\n\tsigned: {\n\t\tnonce: string;\n\t\t/* Date and time of the request in ISO 8601 format */\n\t\ttimestamp: string;\n\t\t/* Signature of the account public key and the nonce as an ASN.1 Sequence, Base64 DER */\n\t\tsignature: string;\n\t}\n};\n\nexport type KeetaFXAnchorQuoteResponse = ({\n\tok: true;\n\tquote: KeetaFXAnchorQuote\n} | {\n\tok: false;\n\terror: string;\n});\n\nexport type KeetaFXAnchorExchange = {\n\t/**\n\t * ID used to identify the conversion request\n\t */\n\texchangeID: string\n}\n\nexport type KeetaFXAnchorExchangeResponse = KeetaFXAnchorExchange &\n({\n\tok: true;\n} | {\n\tok: false;\n\terror: string;\n});\n\n/**\n * @deprecated Use the Node UserClient methods in the future instead of this function\n */\nexport async function createSwapRequest(userClient: KeetaNetUserClient, from: { account: KeetaNetAccount, token: KeetaNetToken, amount: bigint }, to: { account: KeetaNetAccount, token: KeetaNetToken, amount: bigint }): Promise<InstanceType<typeof KeetaNetLib.Block>> {\n\tconst builder = userClient.initBuilder();\n\tbuilder.send(to.account, from.amount, from.token);\n\tbuilder.receive(to.account, to.amount, to.token, true)\n\tconst blocks = await builder.computeBlocks();\n\n\tif (blocks.blocks.length !== 1) {\n\t\tthrow(new Error('Compute Swap Request Generated more than 1 block'));\n\t}\n\n\tconst block = blocks.blocks[0];\n\tif (block === undefined) {\n\t\tthrow(new Error('Swap Block is undefined'));\n\t}\n\n\treturn(block);\n}\n\n/**\n * @deprecated Use the Node UserClient methods in the future instead of this function\n */\nexport async function acceptSwapRequest(userClient: KeetaNetUserClient, request: InstanceType<typeof KeetaNetLib.Block>, expected: { token?: KeetaNetToken, amount?: bigint }): Promise<InstanceType<typeof KeetaNetLib.Block>[]> {\n\tconst builder = userClient.initBuilder();\n\n\tconst sendOperation = request.operations.find(({ type }) => KeetaNetLib.Block.OperationType.SEND === type);\n\tif (!sendOperation || sendOperation.type !== KeetaNetLib.Block.OperationType.SEND) {\n\t\tthrow(new Error('Swap Request is missing send'));\n\t}\n\tif (!sendOperation.to.comparePublicKey(userClient.account)) {\n\t\tthrow(new Error(`Swap Request send account does not match`));\n\t}\n\tif (expected.token !== undefined && !sendOperation.token.comparePublicKey(expected.token)) {\n\t\tthrow(new Error('Swap Request send token does not match expected'))\n\t}\n\tif (expected.amount !== undefined && sendOperation.amount !== expected.amount) {\n\t\tthrow(new Error(`Swap Request send amount ${sendOperation.amount} does not match expected amount ${expected.amount}`))\n\t}\n\n\tconst receiveOperation = request.operations.find(({ type }) => KeetaNetLib.Block.OperationType.RECEIVE === type);\n\tif (!receiveOperation || receiveOperation.type !== KeetaNetLib.Block.OperationType.RECEIVE) {\n\t\tthrow(new Error(\"Swap Request is missing receive operation\"));\n\t}\n\tbuilder.send(request.account, receiveOperation.amount, receiveOperation.token);\n\n\tconst blocks = await builder.computeBlocks();\n\treturn([...blocks.blocks, request]);\n}\n"]}
@@ -0,0 +1,58 @@
1
+ import * as KeetaAnchorHTTPServer from '../../lib/http-server.js';
2
+ import KeetaNet from '@keetanetwork/keetanet-client';
3
+ import type { ConversionInputCanonical, KeetaFXAnchorQuote } from './common.ts';
4
+ import * as Signing from '../../lib/utils/signing.js';
5
+ export interface KeetaAnchorFXServerConfig extends KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig {
6
+ /**
7
+ * The data to use for the index page (optional)
8
+ */
9
+ homepage?: string | (() => Promise<string> | string);
10
+ /**
11
+ * The account to use for performing swaps for a given pair
12
+ *
13
+ * This may be either a function or a KeetaNet Account instance.
14
+ */
15
+ account: InstanceType<typeof KeetaNet.lib.Account> | ((request: ConversionInputCanonical) => Promise<InstanceType<typeof KeetaNet.lib.Account>> | InstanceType<typeof KeetaNet.lib.Account>);
16
+ /**
17
+ * Account which can be used to sign transactions
18
+ * for the account above (if not supplied the
19
+ * account will be used).
20
+ *
21
+ * This may be either a function or a KeetaNet Account instance.
22
+ */
23
+ signer?: InstanceType<typeof KeetaNet.lib.Account> | ((request: ConversionInputCanonical) => Promise<InstanceType<typeof KeetaNet.lib.Account>> | InstanceType<typeof KeetaNet.lib.Account>);
24
+ /**
25
+ * Account which performs the signing and validation of quotes
26
+ */
27
+ quoteSigner: Signing.SignableAccount;
28
+ /**
29
+ * Configuration for FX handling
30
+ */
31
+ fx: {
32
+ /**
33
+ * Handle the conversion request of one token to another
34
+ *
35
+ * This is used to handle quotes and estimates
36
+ */
37
+ getConversionRateAndFee: (request: ConversionInputCanonical) => Promise<Omit<KeetaFXAnchorQuote, 'request' | 'signed'>>;
38
+ };
39
+ /**
40
+ * The network client to use for submitting blocks
41
+ */
42
+ client: {
43
+ client: KeetaNet.Client;
44
+ network: bigint;
45
+ networkAlias: typeof KeetaNet.Client.Config.networksArray[number];
46
+ } | KeetaNet.UserClient;
47
+ }
48
+ export declare class KeetaNetFXAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<KeetaAnchorFXServerConfig> implements Required<KeetaAnchorFXServerConfig> {
49
+ readonly homepage: NonNullable<KeetaAnchorFXServerConfig['homepage']>;
50
+ readonly client: KeetaAnchorFXServerConfig['client'];
51
+ readonly account: KeetaAnchorFXServerConfig['account'];
52
+ readonly signer: NonNullable<KeetaAnchorFXServerConfig['signer']>;
53
+ readonly quoteSigner: KeetaAnchorFXServerConfig['quoteSigner'];
54
+ readonly fx: KeetaAnchorFXServerConfig['fx'];
55
+ constructor(config: KeetaAnchorFXServerConfig);
56
+ protected initRoutes(config: KeetaAnchorFXServerConfig): Promise<KeetaAnchorHTTPServer.Routes>;
57
+ }
58
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/services/fx/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,qBAAqB,MAAM,0BAA0B,CAAC;AAClE,OAAO,QAAQ,MAAM,+BAA+B,CAAC;AAKrD,OAAO,KAAK,EACX,wBAAwB,EAGxB,kBAAkB,EAElB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AAMtD,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB,CAAC,2BAA2B;IACnG;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IAErD;;;;OAIG;IACH,OAAO,EAAE,YAAY,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,wBAAwB,KAAK,OAAO,CAAC,YAAY,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7L;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,wBAAwB,KAAK,OAAO,CAAC,YAAY,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAE7L;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC,eAAe,CAAC;IAErC;;OAEG;IACH,EAAE,EAAE;QACH;;;;WAIG;QACH,uBAAuB,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,QAAQ,CAAE,CAAC,CAAC;KACzH,CAAC;IAEF;;OAEG;IACH,MAAM,EAAE;QAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,QAAQ,CAAC,UAAU,CAAC;CAC9I;AA6DD,qBAAa,0BAA2B,SAAQ,qBAAqB,CAAC,wBAAwB,CAAC,yBAAyB,CAAE,YAAW,QAAQ,CAAC,yBAAyB,CAAC;IACvK,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAC,CAAC;IACtE,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IACrD,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,yBAAyB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClE,QAAQ,CAAC,WAAW,EAAE,yBAAyB,CAAC,aAAa,CAAC,CAAC;IAC/D,QAAQ,CAAC,EAAE,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC;gBAEjC,MAAM,EAAE,yBAAyB;cAW7B,UAAU,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC;CAwKpG"}
@@ -0,0 +1,349 @@
1
+ import * as __typia_transform__assertGuard from "typia/lib/internal/_assertGuard.js";
2
+ import * as KeetaAnchorHTTPServer from '../../lib/http-server.js';
3
+ import KeetaNet from '@keetanetwork/keetanet-client';
4
+ import { createAssert } from 'typia';
5
+ import { KeetaAnchorUserError } from '../../lib/error.js';
6
+ import { acceptSwapRequest } from './common.js';
7
+ import * as Signing from '../../lib/utils/signing.js';
8
+ const assertConversionInputCanonical = (() => { const _io0 = input => "string" === typeof input.from && (RegExp(/^keeta_am(.*)/).test(input.from) || RegExp(/^keeta_an(.*)/).test(input.from) || RegExp(/^keeta_ao(.*)/).test(input.from) || RegExp(/^keeta_ap(.*)/).test(input.from) || RegExp(/^tyblocks_am(.*)/).test(input.from) || RegExp(/^tyblocks_an(.*)/).test(input.from) || RegExp(/^tyblocks_ao(.*)/).test(input.from) || RegExp(/^tyblocks_ap(.*)/).test(input.from)) && ("string" === typeof input.to && (RegExp(/^keeta_am(.*)/).test(input.to) || RegExp(/^keeta_an(.*)/).test(input.to) || RegExp(/^keeta_ao(.*)/).test(input.to) || RegExp(/^keeta_ap(.*)/).test(input.to) || RegExp(/^tyblocks_am(.*)/).test(input.to) || RegExp(/^tyblocks_an(.*)/).test(input.to) || RegExp(/^tyblocks_ao(.*)/).test(input.to) || RegExp(/^tyblocks_ap(.*)/).test(input.to))) && "string" === typeof input.amount && ("from" === input.affinity || "to" === input.affinity); const _ao0 = (input, _path, _exceptionable = true) => ("string" === typeof input.from && (RegExp(/^keeta_am(.*)/).test(input.from) || RegExp(/^keeta_an(.*)/).test(input.from) || RegExp(/^keeta_ao(.*)/).test(input.from) || RegExp(/^keeta_ap(.*)/).test(input.from) || RegExp(/^tyblocks_am(.*)/).test(input.from) || RegExp(/^tyblocks_an(.*)/).test(input.from) || RegExp(/^tyblocks_ao(.*)/).test(input.from) || RegExp(/^tyblocks_ap(.*)/).test(input.from)) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
9
+ method: "createAssert",
10
+ path: _path + ".from",
11
+ expected: "(`keeta_am${string}` | `keeta_an${string}` | `keeta_ao${string}` | `keeta_ap${string}` | `tyblocks_am${string}` | `tyblocks_an${string}` | `tyblocks_ao${string}` | `tyblocks_ap${string}`)",
12
+ value: input.from
13
+ }, _errorFactory)) && ("string" === typeof input.to && (RegExp(/^keeta_am(.*)/).test(input.to) || RegExp(/^keeta_an(.*)/).test(input.to) || RegExp(/^keeta_ao(.*)/).test(input.to) || RegExp(/^keeta_ap(.*)/).test(input.to) || RegExp(/^tyblocks_am(.*)/).test(input.to) || RegExp(/^tyblocks_an(.*)/).test(input.to) || RegExp(/^tyblocks_ao(.*)/).test(input.to) || RegExp(/^tyblocks_ap(.*)/).test(input.to)) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
14
+ method: "createAssert",
15
+ path: _path + ".to",
16
+ expected: "(`keeta_am${string}` | `keeta_an${string}` | `keeta_ao${string}` | `keeta_ap${string}` | `tyblocks_am${string}` | `tyblocks_an${string}` | `tyblocks_ao${string}` | `tyblocks_ap${string}`)",
17
+ value: input.to
18
+ }, _errorFactory)) && ("string" === typeof input.amount || __typia_transform__assertGuard._assertGuard(_exceptionable, {
19
+ method: "createAssert",
20
+ path: _path + ".amount",
21
+ expected: "string",
22
+ value: input.amount
23
+ }, _errorFactory)) && ("from" === input.affinity || "to" === input.affinity || __typia_transform__assertGuard._assertGuard(_exceptionable, {
24
+ method: "createAssert",
25
+ path: _path + ".affinity",
26
+ expected: "(\"from\" | \"to\")",
27
+ value: input.affinity
28
+ }, _errorFactory)); const __is = input => "object" === typeof input && null !== input && _io0(input); let _errorFactory; return (input, errorFactory) => {
29
+ if (false === __is(input)) {
30
+ _errorFactory = errorFactory;
31
+ ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || __typia_transform__assertGuard._assertGuard(true, {
32
+ method: "createAssert",
33
+ path: _path + "",
34
+ expected: "ConversionInputCanonical",
35
+ value: input
36
+ }, _errorFactory)) && _ao0(input, _path + "", true) || __typia_transform__assertGuard._assertGuard(true, {
37
+ method: "createAssert",
38
+ path: _path + "",
39
+ expected: "ConversionInputCanonical",
40
+ value: input
41
+ }, _errorFactory))(input, "$input", true);
42
+ }
43
+ return input;
44
+ }; })();
45
+ const assertConversionQuote = (() => { const _io0 = input => "object" === typeof input.request && null !== input.request && _io1(input.request) && "string" === typeof input.account && "string" === typeof input.convertedAmount && ("object" === typeof input.cost && null !== input.cost && _io2(input.cost)) && ("object" === typeof input.signed && null !== input.signed && _io3(input.signed)); const _io1 = input => "string" === typeof input.from && (RegExp(/^keeta_am(.*)/).test(input.from) || RegExp(/^keeta_an(.*)/).test(input.from) || RegExp(/^keeta_ao(.*)/).test(input.from) || RegExp(/^keeta_ap(.*)/).test(input.from) || RegExp(/^tyblocks_am(.*)/).test(input.from) || RegExp(/^tyblocks_an(.*)/).test(input.from) || RegExp(/^tyblocks_ao(.*)/).test(input.from) || RegExp(/^tyblocks_ap(.*)/).test(input.from)) && ("string" === typeof input.to && (RegExp(/^keeta_am(.*)/).test(input.to) || RegExp(/^keeta_an(.*)/).test(input.to) || RegExp(/^keeta_ao(.*)/).test(input.to) || RegExp(/^keeta_ap(.*)/).test(input.to) || RegExp(/^tyblocks_am(.*)/).test(input.to) || RegExp(/^tyblocks_an(.*)/).test(input.to) || RegExp(/^tyblocks_ao(.*)/).test(input.to) || RegExp(/^tyblocks_ap(.*)/).test(input.to))) && "string" === typeof input.amount && ("from" === input.affinity || "to" === input.affinity); const _io2 = input => "string" === typeof input.amount && ("string" === typeof input.token && (RegExp(/^keeta_am(.*)/).test(input.token) || RegExp(/^keeta_an(.*)/).test(input.token) || RegExp(/^keeta_ao(.*)/).test(input.token) || RegExp(/^keeta_ap(.*)/).test(input.token) || RegExp(/^tyblocks_am(.*)/).test(input.token) || RegExp(/^tyblocks_an(.*)/).test(input.token) || RegExp(/^tyblocks_ao(.*)/).test(input.token) || RegExp(/^tyblocks_ap(.*)/).test(input.token))); const _io3 = input => "string" === typeof input.nonce && "string" === typeof input.timestamp && "string" === typeof input.signature; const _ao0 = (input, _path, _exceptionable = true) => (("object" === typeof input.request && null !== input.request || __typia_transform__assertGuard._assertGuard(_exceptionable, {
46
+ method: "createAssert",
47
+ path: _path + ".request",
48
+ expected: "ConversionInputCanonical",
49
+ value: input.request
50
+ }, _errorFactory)) && _ao1(input.request, _path + ".request", true && _exceptionable) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
51
+ method: "createAssert",
52
+ path: _path + ".request",
53
+ expected: "ConversionInputCanonical",
54
+ value: input.request
55
+ }, _errorFactory)) && ("string" === typeof input.account || __typia_transform__assertGuard._assertGuard(_exceptionable, {
56
+ method: "createAssert",
57
+ path: _path + ".account",
58
+ expected: "string",
59
+ value: input.account
60
+ }, _errorFactory)) && ("string" === typeof input.convertedAmount || __typia_transform__assertGuard._assertGuard(_exceptionable, {
61
+ method: "createAssert",
62
+ path: _path + ".convertedAmount",
63
+ expected: "string",
64
+ value: input.convertedAmount
65
+ }, _errorFactory)) && (("object" === typeof input.cost && null !== input.cost || __typia_transform__assertGuard._assertGuard(_exceptionable, {
66
+ method: "createAssert",
67
+ path: _path + ".cost",
68
+ expected: "__type",
69
+ value: input.cost
70
+ }, _errorFactory)) && _ao2(input.cost, _path + ".cost", true && _exceptionable) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
71
+ method: "createAssert",
72
+ path: _path + ".cost",
73
+ expected: "__type",
74
+ value: input.cost
75
+ }, _errorFactory)) && (("object" === typeof input.signed && null !== input.signed || __typia_transform__assertGuard._assertGuard(_exceptionable, {
76
+ method: "createAssert",
77
+ path: _path + ".signed",
78
+ expected: "__type.o1",
79
+ value: input.signed
80
+ }, _errorFactory)) && _ao3(input.signed, _path + ".signed", true && _exceptionable) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
81
+ method: "createAssert",
82
+ path: _path + ".signed",
83
+ expected: "__type.o1",
84
+ value: input.signed
85
+ }, _errorFactory)); const _ao1 = (input, _path, _exceptionable = true) => ("string" === typeof input.from && (RegExp(/^keeta_am(.*)/).test(input.from) || RegExp(/^keeta_an(.*)/).test(input.from) || RegExp(/^keeta_ao(.*)/).test(input.from) || RegExp(/^keeta_ap(.*)/).test(input.from) || RegExp(/^tyblocks_am(.*)/).test(input.from) || RegExp(/^tyblocks_an(.*)/).test(input.from) || RegExp(/^tyblocks_ao(.*)/).test(input.from) || RegExp(/^tyblocks_ap(.*)/).test(input.from)) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
86
+ method: "createAssert",
87
+ path: _path + ".from",
88
+ expected: "(`keeta_am${string}` | `keeta_an${string}` | `keeta_ao${string}` | `keeta_ap${string}` | `tyblocks_am${string}` | `tyblocks_an${string}` | `tyblocks_ao${string}` | `tyblocks_ap${string}`)",
89
+ value: input.from
90
+ }, _errorFactory)) && ("string" === typeof input.to && (RegExp(/^keeta_am(.*)/).test(input.to) || RegExp(/^keeta_an(.*)/).test(input.to) || RegExp(/^keeta_ao(.*)/).test(input.to) || RegExp(/^keeta_ap(.*)/).test(input.to) || RegExp(/^tyblocks_am(.*)/).test(input.to) || RegExp(/^tyblocks_an(.*)/).test(input.to) || RegExp(/^tyblocks_ao(.*)/).test(input.to) || RegExp(/^tyblocks_ap(.*)/).test(input.to)) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
91
+ method: "createAssert",
92
+ path: _path + ".to",
93
+ expected: "(`keeta_am${string}` | `keeta_an${string}` | `keeta_ao${string}` | `keeta_ap${string}` | `tyblocks_am${string}` | `tyblocks_an${string}` | `tyblocks_ao${string}` | `tyblocks_ap${string}`)",
94
+ value: input.to
95
+ }, _errorFactory)) && ("string" === typeof input.amount || __typia_transform__assertGuard._assertGuard(_exceptionable, {
96
+ method: "createAssert",
97
+ path: _path + ".amount",
98
+ expected: "string",
99
+ value: input.amount
100
+ }, _errorFactory)) && ("from" === input.affinity || "to" === input.affinity || __typia_transform__assertGuard._assertGuard(_exceptionable, {
101
+ method: "createAssert",
102
+ path: _path + ".affinity",
103
+ expected: "(\"from\" | \"to\")",
104
+ value: input.affinity
105
+ }, _errorFactory)); const _ao2 = (input, _path, _exceptionable = true) => ("string" === typeof input.amount || __typia_transform__assertGuard._assertGuard(_exceptionable, {
106
+ method: "createAssert",
107
+ path: _path + ".amount",
108
+ expected: "string",
109
+ value: input.amount
110
+ }, _errorFactory)) && ("string" === typeof input.token && (RegExp(/^keeta_am(.*)/).test(input.token) || RegExp(/^keeta_an(.*)/).test(input.token) || RegExp(/^keeta_ao(.*)/).test(input.token) || RegExp(/^keeta_ap(.*)/).test(input.token) || RegExp(/^tyblocks_am(.*)/).test(input.token) || RegExp(/^tyblocks_an(.*)/).test(input.token) || RegExp(/^tyblocks_ao(.*)/).test(input.token) || RegExp(/^tyblocks_ap(.*)/).test(input.token)) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
111
+ method: "createAssert",
112
+ path: _path + ".token",
113
+ expected: "(`keeta_am${string}` | `keeta_an${string}` | `keeta_ao${string}` | `keeta_ap${string}` | `tyblocks_am${string}` | `tyblocks_an${string}` | `tyblocks_ao${string}` | `tyblocks_ap${string}`)",
114
+ value: input.token
115
+ }, _errorFactory)); const _ao3 = (input, _path, _exceptionable = true) => ("string" === typeof input.nonce || __typia_transform__assertGuard._assertGuard(_exceptionable, {
116
+ method: "createAssert",
117
+ path: _path + ".nonce",
118
+ expected: "string",
119
+ value: input.nonce
120
+ }, _errorFactory)) && ("string" === typeof input.timestamp || __typia_transform__assertGuard._assertGuard(_exceptionable, {
121
+ method: "createAssert",
122
+ path: _path + ".timestamp",
123
+ expected: "string",
124
+ value: input.timestamp
125
+ }, _errorFactory)) && ("string" === typeof input.signature || __typia_transform__assertGuard._assertGuard(_exceptionable, {
126
+ method: "createAssert",
127
+ path: _path + ".signature",
128
+ expected: "string",
129
+ value: input.signature
130
+ }, _errorFactory)); const __is = input => "object" === typeof input && null !== input && _io0(input); let _errorFactory; return (input, errorFactory) => {
131
+ if (false === __is(input)) {
132
+ _errorFactory = errorFactory;
133
+ ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || __typia_transform__assertGuard._assertGuard(true, {
134
+ method: "createAssert",
135
+ path: _path + "",
136
+ expected: "KeetaFXAnchorQuote",
137
+ value: input
138
+ }, _errorFactory)) && _ao0(input, _path + "", true) || __typia_transform__assertGuard._assertGuard(true, {
139
+ method: "createAssert",
140
+ path: _path + "",
141
+ expected: "KeetaFXAnchorQuote",
142
+ value: input
143
+ }, _errorFactory))(input, "$input", true);
144
+ }
145
+ return input;
146
+ }; })();
147
+ ;
148
+ async function formatQuoteSignable(unsignedQuote) {
149
+ const retval = [
150
+ unsignedQuote.request.from,
151
+ unsignedQuote.request.to,
152
+ unsignedQuote.request.amount,
153
+ unsignedQuote.request.affinity,
154
+ unsignedQuote.account,
155
+ unsignedQuote.convertedAmount,
156
+ unsignedQuote.cost.token,
157
+ unsignedQuote.cost.amount
158
+ ];
159
+ return (retval);
160
+ }
161
+ async function generateSignedQuote(signer, unsignedQuote) {
162
+ const signableQuote = await formatQuoteSignable(unsignedQuote);
163
+ const signed = await Signing.SignData(signer, signableQuote);
164
+ return ({
165
+ ...unsignedQuote,
166
+ signed: signed
167
+ });
168
+ }
169
+ async function verifySignedData(signedBy, quote) {
170
+ const signableQuote = await formatQuoteSignable(quote);
171
+ return (await Signing.VerifySignedData(signedBy, signableQuote, quote.signed));
172
+ }
173
+ async function requestToAccounts(config, request) {
174
+ const account = KeetaNet.lib.Account.isInstance(config.account) ? config.account : await config.account(request);
175
+ let signer = null;
176
+ if (config.signer !== undefined) {
177
+ signer = (KeetaNet.lib.Account.isInstance(config.signer) ? config.signer : await config.signer(request)).assertAccount();
178
+ }
179
+ return ({
180
+ signer: signer ?? account.assertAccount(),
181
+ account: account.assertAccount()
182
+ });
183
+ }
184
+ export class KeetaNetFXAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer {
185
+ homepage;
186
+ client;
187
+ account;
188
+ signer;
189
+ quoteSigner;
190
+ fx;
191
+ constructor(config) {
192
+ super(config);
193
+ this.homepage = config.homepage ?? '';
194
+ this.client = config.client;
195
+ this.fx = config.fx;
196
+ this.account = config.account;
197
+ this.signer = config.signer ?? config.account;
198
+ this.quoteSigner = config.quoteSigner;
199
+ }
200
+ async initRoutes(config) {
201
+ const routes = {};
202
+ /**
203
+ * If a homepage is provided, setup the route for it
204
+ */
205
+ if ('homepage' in config) {
206
+ routes['GET /'] = async function () {
207
+ let homepageData;
208
+ if (typeof config.homepage === 'string') {
209
+ homepageData = config.homepage;
210
+ }
211
+ else {
212
+ if (!config.homepage) {
213
+ throw (new Error('internal error: No homepage function provided'));
214
+ }
215
+ homepageData = await config.homepage();
216
+ }
217
+ return ({
218
+ output: homepageData,
219
+ contentType: 'text/html'
220
+ });
221
+ };
222
+ }
223
+ /**
224
+ * Setup the request handler for an estimate request
225
+ */
226
+ routes['POST /api/getEstimate'] = async function (_ignore_params, postData) {
227
+ if (!postData || typeof postData !== 'object') {
228
+ throw (new Error('No POST data provided'));
229
+ }
230
+ if (!('request' in postData)) {
231
+ throw (new Error('POST data missing request'));
232
+ }
233
+ const conversion = assertConversionInputCanonical(postData.request);
234
+ const rateAndFee = await config.fx.getConversionRateAndFee(conversion);
235
+ const estimateResponse = {
236
+ ok: true,
237
+ estimate: {
238
+ request: conversion,
239
+ convertedAmount: rateAndFee.convertedAmount,
240
+ expectedCost: {
241
+ min: rateAndFee.cost.amount,
242
+ max: rateAndFee.cost.amount,
243
+ token: rateAndFee.cost.token
244
+ }
245
+ }
246
+ };
247
+ return ({
248
+ output: JSON.stringify(estimateResponse)
249
+ });
250
+ };
251
+ routes['POST /api/getQuote'] = async function (_ignore_params, postData) {
252
+ if (!postData || typeof postData !== 'object') {
253
+ throw (new Error('No POST data provided'));
254
+ }
255
+ if (!('request' in postData)) {
256
+ throw (new Error('POST data missing request'));
257
+ }
258
+ const conversion = assertConversionInputCanonical(postData.request);
259
+ const rateAndFee = await config.fx.getConversionRateAndFee(conversion);
260
+ const unsignedQuote = {
261
+ request: conversion,
262
+ ...rateAndFee
263
+ };
264
+ const signedQuote = await generateSignedQuote(config.quoteSigner, unsignedQuote);
265
+ const quoteResponse = {
266
+ ok: true,
267
+ quote: signedQuote
268
+ };
269
+ return ({
270
+ output: JSON.stringify(quoteResponse)
271
+ });
272
+ };
273
+ routes['POST /api/createExchange'] = async function (_ignore_params, postData) {
274
+ if (!postData || typeof postData !== 'object') {
275
+ throw (new Error('No POST data provided'));
276
+ }
277
+ if (!('request' in postData)) {
278
+ throw (new Error('POST data missing request'));
279
+ }
280
+ const request = postData.request;
281
+ if (!request || typeof request !== 'object') {
282
+ throw (new Error('Request is not an object'));
283
+ }
284
+ if (!('quote' in request)) {
285
+ throw (new Error('Quote is missing from request'));
286
+ }
287
+ if (!('block' in request) || typeof request.block !== 'string') {
288
+ throw (new Error('Block was not provided in exchange request'));
289
+ }
290
+ const quote = assertConversionQuote(request.quote);
291
+ const isValidQuote = await verifySignedData(config.quoteSigner, quote);
292
+ if (!isValidQuote) {
293
+ throw (new Error('Invalid quote signature'));
294
+ }
295
+ const block = new KeetaNet.lib.Block(request.block);
296
+ let userClient;
297
+ if (KeetaNet.UserClient.isInstance(config.client)) {
298
+ userClient = config.client;
299
+ }
300
+ else {
301
+ const { account, signer } = await requestToAccounts(config, quote.request);
302
+ userClient = new KeetaNet.UserClient({
303
+ client: config.client.client,
304
+ network: config.client.network,
305
+ networkAlias: config.client.networkAlias,
306
+ account: account,
307
+ signer: signer
308
+ });
309
+ }
310
+ const expectedToken = KeetaNet.lib.Account.fromPublicKeyString(quote.request.from);
311
+ const expectedAmount = quote.request.affinity === 'from' ? quote.request.amount : quote.convertedAmount;
312
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
313
+ const swapBlocks = await acceptSwapRequest(userClient, block, { token: expectedToken, amount: BigInt(expectedAmount) });
314
+ const publishResult = await userClient.client.transmit(swapBlocks);
315
+ if (!publishResult.publish) {
316
+ throw (new Error('Exchange Publish Failed'));
317
+ }
318
+ const exchangeResponse = {
319
+ ok: true,
320
+ exchangeID: block.hash.toString()
321
+ };
322
+ return ({
323
+ output: JSON.stringify(exchangeResponse)
324
+ });
325
+ };
326
+ routes['GET /api/getExchangeStatus/:id'] = async function (params) {
327
+ if (params === undefined || params === null) {
328
+ throw (new KeetaAnchorUserError('Expected params'));
329
+ }
330
+ const exchangeID = params.get('id');
331
+ if (typeof exchangeID !== 'string') {
332
+ throw (new Error('Missing exchangeID in params'));
333
+ }
334
+ const blockLookup = await config.client.client.getVoteStaple(exchangeID);
335
+ if (blockLookup === null) {
336
+ throw (new Error('Block Not Found'));
337
+ }
338
+ const exchangeResponse = {
339
+ ok: true,
340
+ exchangeID: exchangeID
341
+ };
342
+ return ({
343
+ output: JSON.stringify(exchangeResponse)
344
+ });
345
+ };
346
+ return (routes);
347
+ }
348
+ }
349
+ //# sourceMappingURL=server.js.map