@atomiqlabs/sdk 8.7.7 → 8.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/api/index.d.ts +1 -0
  2. package/api/index.js +3 -0
  3. package/dist/ApiList.d.ts +37 -0
  4. package/dist/ApiList.js +30 -0
  5. package/dist/api/ApiEndpoints.d.ts +393 -0
  6. package/dist/api/ApiEndpoints.js +2 -0
  7. package/dist/api/ApiParser.d.ts +10 -0
  8. package/dist/api/ApiParser.js +134 -0
  9. package/dist/api/ApiTypes.d.ts +157 -0
  10. package/dist/api/ApiTypes.js +75 -0
  11. package/dist/api/SerializedAction.d.ts +40 -0
  12. package/dist/api/SerializedAction.js +59 -0
  13. package/dist/api/SwapperApi.d.ts +50 -0
  14. package/dist/api/SwapperApi.js +431 -0
  15. package/dist/api/index.d.ts +5 -0
  16. package/dist/api/index.js +24 -0
  17. package/dist/bitcoin/coinselect2/accumulative.d.ts +1 -0
  18. package/dist/bitcoin/coinselect2/accumulative.js +1 -1
  19. package/dist/bitcoin/coinselect2/blackjack.d.ts +1 -0
  20. package/dist/bitcoin/coinselect2/blackjack.js +1 -1
  21. package/dist/bitcoin/coinselect2/index.d.ts +3 -2
  22. package/dist/bitcoin/coinselect2/index.js +2 -2
  23. package/dist/bitcoin/coinselect2/utils.d.ts +7 -2
  24. package/dist/bitcoin/coinselect2/utils.js +45 -10
  25. package/dist/bitcoin/wallet/BitcoinWallet.d.ts +8 -25
  26. package/dist/bitcoin/wallet/BitcoinWallet.js +31 -18
  27. package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +40 -2
  28. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +7 -2
  29. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +10 -4
  30. package/dist/events/UnifiedSwapEventListener.d.ts +4 -3
  31. package/dist/events/UnifiedSwapEventListener.js +8 -2
  32. package/dist/http/HttpUtils.d.ts +4 -2
  33. package/dist/http/HttpUtils.js +10 -4
  34. package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +2 -1
  35. package/dist/http/paramcoders/client/StreamingFetchPromise.js +3 -2
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +1 -0
  38. package/dist/intermediaries/IntermediaryDiscovery.d.ts +7 -2
  39. package/dist/intermediaries/IntermediaryDiscovery.js +4 -4
  40. package/dist/intermediaries/apis/IntermediaryAPI.d.ts +182 -15
  41. package/dist/intermediaries/apis/IntermediaryAPI.js +192 -31
  42. package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -0
  43. package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -0
  44. package/dist/storage/IUnifiedStorage.d.ts +45 -3
  45. package/dist/storage/UnifiedSwapStorage.d.ts +8 -2
  46. package/dist/storage/UnifiedSwapStorage.js +46 -8
  47. package/dist/swapper/Swapper.d.ts +77 -4
  48. package/dist/swapper/Swapper.js +117 -25
  49. package/dist/swapper/SwapperUtils.d.ts +18 -2
  50. package/dist/swapper/SwapperUtils.js +39 -1
  51. package/dist/swaps/ISwap.d.ts +70 -9
  52. package/dist/swaps/ISwap.js +28 -6
  53. package/dist/swaps/ISwapWrapper.d.ts +11 -1
  54. package/dist/swaps/ISwapWrapper.js +23 -3
  55. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +1 -1
  56. package/dist/swaps/escrow_swaps/IEscrowSwap.js +4 -2
  57. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +2 -1
  58. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +2 -2
  59. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +3 -1
  60. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +3 -2
  61. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +47 -31
  62. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +201 -67
  63. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +3 -1
  64. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +6 -6
  65. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +82 -15
  66. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +304 -98
  67. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +3 -1
  68. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +6 -6
  69. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +75 -42
  70. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +424 -87
  71. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +3 -1
  72. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +7 -7
  73. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +54 -11
  74. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +214 -41
  75. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +2 -1
  76. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +7 -8
  77. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +3 -1
  78. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +5 -5
  79. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +85 -22
  80. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +299 -56
  81. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +41 -7
  82. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +183 -58
  83. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +53 -12
  84. package/dist/swaps/trusted/ln/LnForGasSwap.js +163 -49
  85. package/dist/swaps/trusted/ln/LnForGasWrapper.js +1 -2
  86. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +14 -13
  87. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +30 -47
  88. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +3 -1
  89. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +4 -4
  90. package/dist/types/SwapExecutionAction.d.ts +141 -34
  91. package/dist/types/SwapExecutionAction.js +104 -0
  92. package/dist/types/SwapExecutionStep.d.ts +144 -0
  93. package/dist/types/SwapExecutionStep.js +87 -0
  94. package/dist/types/TokenAmount.d.ts +6 -0
  95. package/dist/types/TokenAmount.js +26 -1
  96. package/dist/utils/BitcoinUtils.d.ts +4 -0
  97. package/dist/utils/BitcoinUtils.js +73 -1
  98. package/dist/utils/BitcoinWalletUtils.d.ts +2 -2
  99. package/dist/utils/Utils.d.ts +3 -1
  100. package/dist/utils/Utils.js +7 -1
  101. package/package.json +7 -4
  102. package/src/api/ApiEndpoints.ts +427 -0
  103. package/src/api/ApiParser.ts +138 -0
  104. package/src/api/ApiTypes.ts +229 -0
  105. package/src/api/SerializedAction.ts +97 -0
  106. package/src/api/SwapperApi.ts +545 -0
  107. package/src/api/index.ts +5 -0
  108. package/src/bitcoin/coinselect2/accumulative.ts +2 -1
  109. package/src/bitcoin/coinselect2/blackjack.ts +2 -1
  110. package/src/bitcoin/coinselect2/index.ts +5 -4
  111. package/src/bitcoin/coinselect2/utils.ts +55 -14
  112. package/src/bitcoin/wallet/BitcoinWallet.ts +69 -57
  113. package/src/bitcoin/wallet/IBitcoinWallet.ts +44 -3
  114. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +12 -4
  115. package/src/events/UnifiedSwapEventListener.ts +11 -3
  116. package/src/http/HttpUtils.ts +10 -4
  117. package/src/http/paramcoders/client/StreamingFetchPromise.ts +4 -2
  118. package/src/index.ts +1 -0
  119. package/src/intermediaries/IntermediaryDiscovery.ts +9 -2
  120. package/src/intermediaries/apis/IntermediaryAPI.ts +335 -35
  121. package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -0
  122. package/src/storage/IUnifiedStorage.ts +45 -4
  123. package/src/storage/UnifiedSwapStorage.ts +42 -8
  124. package/src/swapper/Swapper.ts +165 -24
  125. package/src/swapper/SwapperUtils.ts +42 -2
  126. package/src/swaps/ISwap.ts +88 -16
  127. package/src/swaps/ISwapWrapper.ts +28 -3
  128. package/src/swaps/escrow_swaps/IEscrowSwap.ts +5 -3
  129. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +3 -1
  130. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +4 -1
  131. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +264 -67
  132. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +6 -4
  133. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +390 -89
  134. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +6 -4
  135. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +548 -94
  136. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +7 -5
  137. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +276 -45
  138. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +7 -6
  139. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +5 -3
  140. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +413 -64
  141. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +239 -61
  142. package/src/swaps/trusted/ln/LnForGasSwap.ts +211 -47
  143. package/src/swaps/trusted/ln/LnForGasWrapper.ts +1 -2
  144. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +32 -51
  145. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +5 -3
  146. package/src/types/SwapExecutionAction.ts +266 -43
  147. package/src/types/SwapExecutionStep.ts +224 -0
  148. package/src/types/TokenAmount.ts +36 -2
  149. package/src/utils/BitcoinUtils.ts +73 -0
  150. package/src/utils/BitcoinWalletUtils.ts +2 -2
  151. package/src/utils/Utils.ts +10 -1
  152. package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +0 -258
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Adds a `x-atomiq-auth` header with the following binary format, that is hex-encoded:
3
+ * - 4 bytes - timestamp (timestamp when the request was sent)
4
+ * - 32 bytes - random bytes (entropy, to be signed)
5
+ *
6
+ * - 32 bytes - key of the signing authority
7
+ * - 64 bytes - schnorr signature signing the request signing key by the signing authority
8
+ *
9
+ * - 32 bytes - request signing key (signed by the signing authority)
10
+ * - 64 bytes - schnorr signature of the timestamp and random bytes
11
+ *
12
+ * Uses secp256k1 curve and schnorr signatures
13
+ */
14
+ export declare function getSignedKeyBasedAuthHandler(certificate: string, privateKey: string): (type: "GET" | "POST", url: string, body?: any) => Record<string, string>;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSignedKeyBasedAuthHandler = void 0;
4
+ const secp256k1_1 = require("@noble/curves/secp256k1");
5
+ const Utils_1 = require("../../utils/Utils");
6
+ function parsePrivateKey(value, name) {
7
+ if (!/^[0-9a-fA-F]{64}$/.test(value))
8
+ throw new Error(`${name} must be a 32-byte hex private key`);
9
+ const bytes = Buffer.from(value, "hex");
10
+ if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(bytes))
11
+ throw new Error(`${name} is not a valid secp256k1 private key`);
12
+ return bytes;
13
+ }
14
+ function parsePublicKey(value, name) {
15
+ if (!/^[0-9a-fA-F]{64}$/.test(value))
16
+ throw new Error(`${name} must be an X-only 32-byte hex public key`);
17
+ if (!secp256k1_1.secp256k1.utils.isValidPublicKey(Buffer.from("02" + value, "hex"), true))
18
+ throw new Error(`${name} is not a valid X-only 32-byte secp256k1 public key`);
19
+ return Buffer.from(value, "hex");
20
+ }
21
+ function parseSignature(value, name) {
22
+ if (!/^[0-9a-fA-F]{128}$/.test(value))
23
+ throw new Error(`${name} must be a valid 64-byte hex schnorr signature`);
24
+ return Buffer.from(value, "hex");
25
+ }
26
+ const CERTIFICATE_LENGTH = 64 + 128 + 64;
27
+ /**
28
+ * Adds a `x-atomiq-auth` header with the following binary format, that is hex-encoded:
29
+ * - 4 bytes - timestamp (timestamp when the request was sent)
30
+ * - 32 bytes - random bytes (entropy, to be signed)
31
+ *
32
+ * - 32 bytes - key of the signing authority
33
+ * - 64 bytes - schnorr signature signing the request signing key by the signing authority
34
+ *
35
+ * - 32 bytes - request signing key (signed by the signing authority)
36
+ * - 64 bytes - schnorr signature of the timestamp and random bytes
37
+ *
38
+ * Uses secp256k1 curve and schnorr signatures
39
+ */
40
+ function getSignedKeyBasedAuthHandler(certificate, privateKey) {
41
+ const _privateKey = parsePrivateKey(privateKey, "Private key");
42
+ if (certificate.length !== CERTIFICATE_LENGTH)
43
+ throw new Error(`Certificate has invalid length, expected ${CERTIFICATE_LENGTH}!`);
44
+ const authorityPublicKey = parsePublicKey(certificate.substring(0, 64), "Certificate: Authority Public key");
45
+ const authoritySignature = parseSignature(certificate.substring(64, 64 + 128), "Certificate: Authority Signature");
46
+ const signingPublicKey = parsePublicKey(certificate.substring(64 + 128), "Certificate: Signing Public key");
47
+ if (!secp256k1_1.schnorr.verify(authoritySignature, signingPublicKey, authorityPublicKey))
48
+ throw new Error("Invalid certificate, authority signature is not valid!");
49
+ if (!signingPublicKey.equals(secp256k1_1.schnorr.getPublicKey(privateKey)))
50
+ throw new Error("Passed private key doesn't match the certificate!");
51
+ const _certificate = Buffer.from(certificate, "hex");
52
+ return () => {
53
+ const timestamp = Math.floor(Date.now() / 1000);
54
+ const timestampBuffer = Buffer.alloc(4);
55
+ timestampBuffer.writeUInt32BE(timestamp);
56
+ const requestUid = (0, Utils_1.randomBytes)(32);
57
+ const toSign = Buffer.concat([timestampBuffer, requestUid]);
58
+ const signature = secp256k1_1.schnorr.sign(toSign, _privateKey);
59
+ return {
60
+ "x-atomiq-auth": Buffer.concat([
61
+ toSign,
62
+ _certificate,
63
+ signature
64
+ ]).toString("hex")
65
+ };
66
+ };
67
+ }
68
+ exports.getSignedKeyBasedAuthHandler = getSignedKeyBasedAuthHandler;
@@ -14,12 +14,14 @@ export type QueryParams = {
14
14
  value: any | any[];
15
15
  };
16
16
  /**
17
- * Base type for stored objects, every storage object MUST have an `id` field
17
+ * Base type for stored objects, every storage object MUST have an `id` field. The object might also specify a `_meta`
18
+ * field which gets carried to the delete/save operations (and can be used to implement optimistic concurrency)
18
19
  *
19
20
  * @category Storage
20
21
  */
21
22
  export type UnifiedStoredObject = {
22
23
  id: string;
24
+ _meta?: any;
23
25
  } & any;
24
26
  /**
25
27
  * Defines simple indexes (for queries that use a single key)
@@ -59,27 +61,67 @@ export interface IUnifiedStorage<I extends UnifiedStorageIndexes, C extends Unif
59
61
  * - [[condition1, condition2]] - returns all rows where condition1 AND condition2 is met
60
62
  * - [[condition1], [condition2]] - returns all rows where condition1 OR condition2 is met
61
63
  * - [[condition1, condition2], [condition3]] - returns all rows where (condition1 AND condition2) OR condition3 is met
64
+ *
65
+ * You can also add an optional `_meta` field in the returned unified storage object which gets attached to that
66
+ * returned object and will be present for subsequent saves and removal of this object, if you specify the `_meta`
67
+ * field here, you need to explicitly handle it in the all the saving and remove functions and not simply serialize
68
+ * it into the storage
69
+ *
62
70
  * @param params
63
71
  */
64
72
  query(params: Array<Array<QueryParams>>): Promise<Array<UnifiedStoredObject>>;
65
73
  /**
66
74
  * Saves an object to storage, updating indexes as needed
75
+ *
76
+ * If the object contains a `_meta` field, this will be also present in the to-be-saved value, to mutate the `_meta`
77
+ * field of the object that is saved, you can mutate the `_meta` field directly on the passed value, which then
78
+ * gets reflected automatically in the existing object. The mutated `_meta` field is copied even if the function
79
+ * throws, hence the implementations must be careful with setting the `_meta` field on the still in-flight requests
80
+ * that might fail.
81
+ *
67
82
  * @param value Object to save (must have an id property)
68
83
  */
69
84
  save(value: UnifiedStoredObject): Promise<void>;
70
85
  /**
71
86
  * Saves multiple objects to storage in a batch operation
87
+ *
88
+ * If the objects contain a `_meta` field, this will be also present in the to-be-saved values, to mutate the `_meta`
89
+ * field of the objects that are saved, you can mutate the `_meta` field directly on the passed values, which then
90
+ * gets reflected automatically in the existing objects. The mutated `_meta` field is copied even if the function
91
+ * throws, hence the implementations must be careful with setting the `_meta` field on the still in-flight requests
92
+ * that might fail.
93
+ *
72
94
  * @param value Array of objects to save
95
+ * @param lenient In lenient mode the persistency layer doesn't throw on individual swap failures due to
96
+ * optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
97
+ * isn't mission-critical for executing next steps (e.g. in tick or sync loops)
73
98
  */
74
- saveAll(value: UnifiedStoredObject[]): Promise<void>;
99
+ saveAll(value: UnifiedStoredObject[], lenient?: boolean): Promise<void>;
75
100
  /**
76
101
  * Removes an object from storage
102
+ *
103
+ * If the object contains a `_meta` field, this will be also present in the to-be-removed value, to mutate the `_meta`
104
+ * field of the object that is saved, you can mutate the `_meta` field directly on the passed value, which then
105
+ * gets reflected automatically in the existing object. The mutated `_meta` field is copied even if the function
106
+ * throws, hence the implementations must be careful with setting the `_meta` field on the still in-flight requests
107
+ * that might fail.
108
+ *
77
109
  * @param value Object to remove (must have an id property)
78
110
  */
79
111
  remove(value: UnifiedStoredObject): Promise<void>;
80
112
  /**
81
113
  * Removes multiple objects from storage in a batch operation
114
+ *
115
+ * If the objects contain a `_meta` field, this will be also present in the to-be-removed values, to mutate the `_meta`
116
+ * field of the objects that are saved, you can mutate the `_meta` field directly on the passed values, which then
117
+ * gets reflected automatically in the existing objects. The mutated `_meta` field is copied even if the function
118
+ * throws, hence the implementations must be careful with setting the `_meta` field on the still in-flight requests
119
+ * that might fail.
120
+ *
82
121
  * @param value Array of objects to remove
122
+ * @param lenient In lenient mode the persistency layer doesn't throw on individual swap failures due to
123
+ * optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
124
+ * isn't mission-critical for executing next steps (e.g. in tick or sync loops)
83
125
  */
84
- removeAll(value: UnifiedStoredObject[]): Promise<void>;
126
+ removeAll(value: UnifiedStoredObject[], lenient?: boolean): Promise<void>;
85
127
  }
@@ -98,8 +98,11 @@ export declare class UnifiedSwapStorage<T extends ChainType> {
98
98
  /**
99
99
  * Saves multiple swaps to storage in a batch operation
100
100
  * @param values Array of swaps to save
101
+ * @param lenient In lenient mode the underlying persistent layer doesn't throw on individual swap failures due to
102
+ * optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
103
+ * isn't mission-critical for executing next steps (e.g. in tick or sync loops)
101
104
  */
102
- saveAll<S extends ISwap<T>>(values: S[]): Promise<void>;
105
+ saveAll<S extends ISwap<T>>(values: S[], lenient?: boolean): Promise<void>;
103
106
  /**
104
107
  * Removes a swap from storage
105
108
  * @param value Swap to remove
@@ -108,7 +111,10 @@ export declare class UnifiedSwapStorage<T extends ChainType> {
108
111
  /**
109
112
  * Removes multiple swaps from storage in a batch operation
110
113
  * @param values Array of swaps to remove
114
+ * @param lenient In lenient mode the underlying persistent layer doesn't throw on individual swap failures due to
115
+ * optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
116
+ * isn't mission-critical for executing next steps (e.g. in tick or sync loops)
111
117
  */
112
- removeAll<S extends ISwap<T>>(values: S[]): Promise<void>;
118
+ removeAll<S extends ISwap<T>>(values: S[], lenient?: boolean): Promise<void>;
113
119
  }
114
120
  export {};
@@ -79,18 +79,37 @@ class UnifiedSwapStorage {
79
79
  async save(value) {
80
80
  if (!this.noWeakRefMap)
81
81
  this.weakRefCache.set(value.getId(), new WeakRef(value));
82
- await this.storage.save(value.serialize());
82
+ const serialized = value.serialize();
83
+ try {
84
+ await this.storage.save(serialized);
85
+ }
86
+ finally {
87
+ value._meta = serialized._meta;
88
+ }
83
89
  value._persisted = true;
84
90
  }
85
91
  /**
86
92
  * Saves multiple swaps to storage in a batch operation
87
93
  * @param values Array of swaps to save
94
+ * @param lenient In lenient mode the underlying persistent layer doesn't throw on individual swap failures due to
95
+ * optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
96
+ * isn't mission-critical for executing next steps (e.g. in tick or sync loops)
88
97
  */
89
- async saveAll(values) {
98
+ async saveAll(values, lenient) {
90
99
  if (!this.noWeakRefMap)
91
100
  values.forEach(value => this.weakRefCache.set(value.getId(), new WeakRef(value)));
92
- await this.storage.saveAll(values.map(obj => obj.serialize()));
93
- values.forEach(value => value._persisted = true);
101
+ const serialized = values.map(obj => obj.serialize());
102
+ try {
103
+ await this.storage.saveAll(serialized, lenient);
104
+ }
105
+ finally {
106
+ values.forEach((value, index) => {
107
+ value._meta = serialized[index]._meta;
108
+ });
109
+ }
110
+ values.forEach((value) => {
111
+ value._persisted = true;
112
+ });
94
113
  }
95
114
  /**
96
115
  * Removes a swap from storage
@@ -99,18 +118,37 @@ class UnifiedSwapStorage {
99
118
  async remove(value) {
100
119
  if (!this.noWeakRefMap)
101
120
  this.weakRefCache.delete(value.getId());
102
- await this.storage.remove(value.serialize());
121
+ const serialized = value.serialize();
122
+ try {
123
+ await this.storage.remove(serialized);
124
+ }
125
+ finally {
126
+ value._meta = serialized._meta;
127
+ }
103
128
  value._persisted = false;
104
129
  }
105
130
  /**
106
131
  * Removes multiple swaps from storage in a batch operation
107
132
  * @param values Array of swaps to remove
133
+ * @param lenient In lenient mode the underlying persistent layer doesn't throw on individual swap failures due to
134
+ * optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
135
+ * isn't mission-critical for executing next steps (e.g. in tick or sync loops)
108
136
  */
109
- async removeAll(values) {
137
+ async removeAll(values, lenient) {
110
138
  if (!this.noWeakRefMap)
111
139
  values.forEach(value => this.weakRefCache.delete(value.getId()));
112
- await this.storage.removeAll(values.map(obj => obj.serialize()));
113
- values.forEach(value => value._persisted = false);
140
+ const serialized = values.map(obj => obj.serialize());
141
+ try {
142
+ await this.storage.removeAll(serialized, lenient);
143
+ }
144
+ finally {
145
+ values.forEach((value, index) => {
146
+ value._meta = serialized[index]._meta;
147
+ });
148
+ }
149
+ values.forEach((value) => {
150
+ value._persisted = false;
151
+ });
114
152
  }
115
153
  }
116
154
  exports.UnifiedSwapStorage = UnifiedSwapStorage;
@@ -39,6 +39,9 @@ import { LNURLPay } from "../types/lnurl/LNURLPay";
39
39
  import { NotNever } from "../utils/TypeUtils";
40
40
  import { LightningInvoiceCreateService } from "../types/wallets/LightningInvoiceCreateService";
41
41
  import { SwapSide } from "../enums/SwapSide";
42
+ import { IntermediaryAPI } from "../intermediaries/apis/IntermediaryAPI";
43
+ import { BitcoinWalletUtxo, IBitcoinWallet } from "../bitcoin/wallet/IBitcoinWallet";
44
+ import { MinimalBitcoinWalletInterface } from "../types/wallets/MinimalBitcoinWalletInterface";
42
45
  /**
43
46
  * Configuration options for the Swapper
44
47
  * @category Core
@@ -97,8 +100,9 @@ export type SwapperOptions = {
97
100
  noTimers?: boolean;
98
101
  /**
99
102
  * By setting this flag, the swapper doesn't subscribe to on-chain events. To make sure the swap states are
100
- * properly updated you should call the {@link Swapper._syncSwaps} function periodically. This flag should be
101
- * set when you run an environment that doesn't support long-running timers and websocket connections - e.g.
103
+ * properly updated you should either call the {@link Swapper._syncSwaps} function periodically, or use the
104
+ * {@link Swapper._pollChainEvents} function to manually poll for on-chain events. This flag should be set
105
+ * when you run an environment that doesn't support long-running timers and websocket connections - e.g.
102
106
  * serverless environments like Azure Function Apps or AWS Lambda
103
107
  */
104
108
  noEvents?: boolean;
@@ -128,7 +132,7 @@ export type SwapperOptions = {
128
132
  * want to only create a swap, and then later on retrieve it with the `swapper.getSwapById()` function.
129
133
  *
130
134
  * Setting this to `false` means the SDK only saves and persists swaps that are considered initiated, i.e. when
131
- * `commit()`, `execute()` or `waitTillPayment` is called (or their respective txs... prefixed variations). This
135
+ * `commit()`, `execute()` or `waitTillPayment()` is called (or their respective txs... prefixed variations). This
132
136
  * might save calls to the persistent storage for swaps that are never initiated. This is useful in e.g.
133
137
  * frontend implementations where the frontend holds the swap object reference until it is initiated anyway, not
134
138
  * necessitating the saving of the swap data to the persistent storage until it is actually initiated.
@@ -139,6 +143,13 @@ export type SwapperOptions = {
139
143
  * (as checked from multiple server sources) it adjusts the `Date.now()` function to return proper actual time.
140
144
  */
141
145
  automaticClockDriftCorrection?: boolean;
146
+ /**
147
+ * Used in centralized API deployments to allow higher rate limits from LPs
148
+ */
149
+ signedKeyBasedAuth?: {
150
+ certificate: string;
151
+ privateKey: string;
152
+ };
142
153
  };
143
154
  /**
144
155
  * Type representing multiple blockchain configurations
@@ -246,6 +257,10 @@ export declare class Swapper<T extends MultiChain> extends EventEmitter<{
246
257
  * Pricing API used by the SDK
247
258
  */
248
259
  readonly prices: ISwapPrice<T>;
260
+ /**
261
+ * API for contacting LPs
262
+ */
263
+ readonly lpApi: IntermediaryAPI;
249
264
  /**
250
265
  * Intermediary discovery instance
251
266
  */
@@ -265,6 +280,10 @@ export declare class Swapper<T extends MultiChain> extends EventEmitter<{
265
280
  * Initializes the swap storage and loads existing swaps, needs to be called before any other action
266
281
  */
267
282
  init(): Promise<void>;
283
+ /**
284
+ * Whether the SDK is initialized (after {@link init} is called)
285
+ */
286
+ isInitialized(): boolean;
268
287
  /**
269
288
  * Stops listening for onchain events and closes this Swapper instance
270
289
  */
@@ -346,7 +365,7 @@ export declare class Swapper<T extends MultiChain> extends EventEmitter<{
346
365
  * @param additionalParams Additional parameters sent to the LP when creating the swap
347
366
  * @param options Additional options for the swap
348
367
  */
349
- createFromBTCSwapNew<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, recipient: string, tokenAddress: string, amount: bigint, exactOut?: boolean, additionalParams?: Record<string, any> | undefined, options?: SpvFromBTCOptions): Promise<SpvFromBTCSwap<T[ChainIdentifier]>>;
368
+ createFromBTCSwapNew<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, recipient: string, tokenAddress: string, amount: bigint | null, exactOut?: boolean, additionalParams?: Record<string, any> | undefined, options?: SpvFromBTCOptions): Promise<SpvFromBTCSwap<T[ChainIdentifier]>>;
350
369
  /**
351
370
  * Creates LEGACY Bitcoin -> Smart chain ({@link SwapType.FROM_BTC}) swap
352
371
  *
@@ -505,6 +524,44 @@ export declare class Swapper<T extends MultiChain> extends EventEmitter<{
505
524
  swap<C extends ChainIds<T>>(srcToken: Token<C> | string, dstToken: Token<C> | string, amount: bigint | string | undefined, exactIn: boolean | SwapAmountType, src: undefined | string | LNURLWithdraw, dst: string | LNURLPay | LightningInvoiceCreateService, options?: FromBTCLNOptions | SpvFromBTCOptions | FromBTCOptions | ToBTCOptions | (ToBTCLNOptions & {
506
525
  comment?: string;
507
526
  }) | FromBTCLNAutoOptions): Promise<ISwap<T[C]>>;
527
+ /**
528
+ * A helper function to sweep all the funds from a given wallet in a single swap, after getting the quote you can
529
+ * execute the swap by passing the returned `feeRate` and `utxos` to the {@link SpvFromBTCSwap.execute},
530
+ * {@link SpvFromBTCSwap.getFundedPsbt} or {@link SpvFromBTCSwap.sendBitcoinTransaction} functions along
531
+ * with `spendFully=true`.
532
+ *
533
+ * @example
534
+ * Create the swap first using this function
535
+ * ```ts
536
+ * const {swap, utxos, btcFeeRate} = await swapper.sweepBitcoinWallet(wallet, Tokens.CITREA.CBTC, dstAddress);
537
+ * ```
538
+ * Then execute it using one of these execution paths - ensure that you supply the returned `utxos`, `btcFeeRate`
539
+ * params and also set `spendFully` to `true`!
540
+ *
541
+ * a) Execute and pass the returned utxos and btcFeeRate:
542
+ * ```ts
543
+ * await swap.execute(wallet, undefined, {feeRate: btcFeeRate, utxos: utxos, spendFully: true});
544
+ * ```
545
+ *
546
+ * b) Get funded PSBT to sign externally:
547
+ * ```ts
548
+ * const {psbt, psbtHex, psbtBase64, signInputs} = await swap.getFundedPsbt(wallet, btcFeeRate, undefined, utxos, true);
549
+ * // Sign the psbt at the specified signInputs indices
550
+ * const signedPsbt = ...;
551
+ * // Then submit back to the SDK
552
+ * await swap.submitPsbt(signedPsbt);
553
+ * ```
554
+ *
555
+ * c) Only sign and send the signed PSBT with the provided wallet:
556
+ * ```ts
557
+ * await swap.sendBitcoinTransaction(wallet, btcFeeRate, utxos, true);
558
+ * ```
559
+ */
560
+ sweepBitcoinWallet<C extends ChainIds<T>>(srcWallet: IBitcoinWallet | MinimalBitcoinWalletInterface, _dstToken: SCToken<C> | string, dstAddress: string, options?: SpvFromBTCOptions): Promise<{
561
+ swap: SpvFromBTCSwap<T[C]>;
562
+ utxos: BitcoinWalletUtxo[];
563
+ btcFeeRate: number;
564
+ }>;
508
565
  /**
509
566
  * Returns all swaps
510
567
  */
@@ -513,6 +570,14 @@ export declare class Swapper<T extends MultiChain> extends EventEmitter<{
513
570
  * Returns all swaps for the specific chain, and optionally also for a specific signer's address
514
571
  */
515
572
  getAllSwaps<C extends ChainIds<T>>(chainId: C, signer?: string): Promise<ISwap<T[C]>[]>;
573
+ /**
574
+ * Returns all swaps which are pending (i.e. not in their final state yet)
575
+ */
576
+ getPendingSwaps(): Promise<ISwap[]>;
577
+ /**
578
+ * Returns swaps which are pending (i.e. not in their final state yet) for the specific chain, and optionally also for a specific signer's address
579
+ */
580
+ getPendingSwaps<C extends ChainIds<T>>(chainId: C, signer?: string): Promise<ISwap<T[C]>[]>;
516
581
  /**
517
582
  * Returns all swaps where an action is required (either claim or refund)
518
583
  */
@@ -574,6 +639,14 @@ export declare class Swapper<T extends MultiChain> extends EventEmitter<{
574
639
  * @param signer Optional signer to only run swap sync for swaps initiated by this signer
575
640
  */
576
641
  _syncSwaps<C extends ChainIds<T>>(chainId?: C, signer?: string): Promise<void>;
642
+ /**
643
+ * When the swapper is initiated with the `noEvents` config this function allows you to manually poll for on-chain
644
+ * events. It returns an events cursor which you should save and pass to the next call to the `poll()` function.
645
+ *
646
+ * @param chainId Chain for which to poll the chain events listener for
647
+ * @param lastEventCursorState Event cursor state returned from the last call to the `poll()` function
648
+ */
649
+ _pollChainEvents<C extends ChainIds<T>>(chainId: C, lastEventCursorState?: any): Promise<any>;
577
650
  /**
578
651
  * Recovers swaps from on-chain historical data.
579
652
  *