@atomiqlabs/sdk 8.8.3 → 8.9.1
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/api/index.d.ts +1 -0
- package/api/index.js +3 -0
- package/dist/ApiList.d.ts +37 -0
- package/dist/ApiList.js +30 -0
- package/dist/api/ApiEndpoints.d.ts +393 -0
- package/dist/api/ApiEndpoints.js +2 -0
- package/dist/api/ApiParser.d.ts +10 -0
- package/dist/api/ApiParser.js +134 -0
- package/dist/api/ApiTypes.d.ts +157 -0
- package/dist/api/ApiTypes.js +75 -0
- package/dist/api/SerializedAction.d.ts +40 -0
- package/dist/api/SerializedAction.js +59 -0
- package/dist/api/SwapperApi.d.ts +50 -0
- package/dist/api/SwapperApi.js +431 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.js +24 -0
- package/dist/events/UnifiedSwapEventListener.d.ts +4 -3
- package/dist/events/UnifiedSwapEventListener.js +8 -2
- package/dist/http/HttpUtils.d.ts +4 -2
- package/dist/http/HttpUtils.js +10 -4
- package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +2 -1
- package/dist/http/paramcoders/client/StreamingFetchPromise.js +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +7 -2
- package/dist/intermediaries/IntermediaryDiscovery.js +4 -4
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +171 -14
- package/dist/intermediaries/apis/IntermediaryAPI.js +174 -28
- package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -0
- package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -0
- package/dist/storage/IUnifiedStorage.d.ts +45 -3
- package/dist/storage/UnifiedSwapStorage.d.ts +8 -2
- package/dist/storage/UnifiedSwapStorage.js +46 -8
- package/dist/swapper/Swapper.d.ts +41 -3
- package/dist/swapper/Swapper.js +93 -48
- package/dist/swapper/SwapperUtils.d.ts +18 -2
- package/dist/swapper/SwapperUtils.js +39 -1
- package/dist/swaps/ISwap.d.ts +70 -9
- package/dist/swaps/ISwap.js +28 -6
- package/dist/swaps/ISwapWrapper.d.ts +11 -1
- package/dist/swaps/ISwapWrapper.js +23 -3
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +1 -1
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +4 -2
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +2 -1
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +2 -2
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +3 -2
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +47 -31
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +201 -67
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +6 -6
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +82 -15
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +304 -98
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +6 -6
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +75 -42
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +424 -87
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +7 -7
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +54 -11
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +214 -41
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +2 -1
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +7 -8
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +5 -5
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +76 -19
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +290 -51
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +3 -1
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +5 -5
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +53 -12
- package/dist/swaps/trusted/ln/LnForGasSwap.js +163 -49
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +1 -2
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +14 -13
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +30 -47
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +3 -1
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +4 -4
- package/dist/types/SwapExecutionAction.d.ts +141 -34
- package/dist/types/SwapExecutionAction.js +104 -0
- package/dist/types/SwapExecutionStep.d.ts +144 -0
- package/dist/types/SwapExecutionStep.js +87 -0
- package/dist/types/TokenAmount.d.ts +6 -0
- package/dist/types/TokenAmount.js +26 -1
- package/dist/utils/BitcoinUtils.d.ts +2 -0
- package/dist/utils/BitcoinUtils.js +34 -1
- package/dist/utils/Utils.d.ts +3 -1
- package/dist/utils/Utils.js +7 -1
- package/package.json +7 -4
- package/src/api/ApiEndpoints.ts +427 -0
- package/src/api/ApiParser.ts +138 -0
- package/src/api/ApiTypes.ts +229 -0
- package/src/api/SerializedAction.ts +97 -0
- package/src/api/SwapperApi.ts +545 -0
- package/src/api/index.ts +5 -0
- package/src/events/UnifiedSwapEventListener.ts +11 -3
- package/src/http/HttpUtils.ts +10 -4
- package/src/http/paramcoders/client/StreamingFetchPromise.ts +4 -2
- package/src/index.ts +1 -0
- package/src/intermediaries/IntermediaryDiscovery.ts +9 -2
- package/src/intermediaries/apis/IntermediaryAPI.ts +314 -30
- package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -0
- package/src/storage/IUnifiedStorage.ts +45 -4
- package/src/storage/UnifiedSwapStorage.ts +42 -8
- package/src/swapper/Swapper.ts +134 -52
- package/src/swapper/SwapperUtils.ts +42 -2
- package/src/swaps/ISwap.ts +88 -16
- package/src/swaps/ISwapWrapper.ts +28 -3
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +5 -3
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +3 -1
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +4 -1
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +264 -67
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +6 -4
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +390 -89
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +6 -4
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +548 -94
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +7 -5
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +276 -45
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +7 -6
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +5 -3
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +393 -57
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +5 -3
- package/src/swaps/trusted/ln/LnForGasSwap.ts +211 -47
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +1 -2
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +32 -51
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +5 -3
- package/src/types/SwapExecutionAction.ts +266 -43
- package/src/types/SwapExecutionStep.ts +224 -0
- package/src/types/TokenAmount.ts +36 -2
- package/src/utils/BitcoinUtils.ts +32 -0
- package/src/utils/Utils.ts +10 -1
- package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +0 -258
|
@@ -16,11 +16,12 @@ export type QueryParams = {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Base type for stored objects, every storage object MUST have an `id` field
|
|
19
|
+
* Base type for stored objects, every storage object MUST have an `id` field. The object might also specify a `_meta`
|
|
20
|
+
* field which gets carried to the delete/save operations (and can be used to implement optimistic concurrency)
|
|
20
21
|
*
|
|
21
22
|
* @category Storage
|
|
22
23
|
*/
|
|
23
|
-
export type UnifiedStoredObject = {id: string} & any;
|
|
24
|
+
export type UnifiedStoredObject = {id: string, _meta?: any} & any;
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* Defines simple indexes (for queries that use a single key)
|
|
@@ -64,32 +65,72 @@ export interface IUnifiedStorage<I extends UnifiedStorageIndexes, C extends Unif
|
|
|
64
65
|
* - [[condition1, condition2]] - returns all rows where condition1 AND condition2 is met
|
|
65
66
|
* - [[condition1], [condition2]] - returns all rows where condition1 OR condition2 is met
|
|
66
67
|
* - [[condition1, condition2], [condition3]] - returns all rows where (condition1 AND condition2) OR condition3 is met
|
|
68
|
+
*
|
|
69
|
+
* You can also add an optional `_meta` field in the returned unified storage object which gets attached to that
|
|
70
|
+
* returned object and will be present for subsequent saves and removal of this object, if you specify the `_meta`
|
|
71
|
+
* field here, you need to explicitly handle it in the all the saving and remove functions and not simply serialize
|
|
72
|
+
* it into the storage
|
|
73
|
+
*
|
|
67
74
|
* @param params
|
|
68
75
|
*/
|
|
69
76
|
query(params: Array<Array<QueryParams>>): Promise<Array<UnifiedStoredObject>>;
|
|
70
77
|
|
|
71
78
|
/**
|
|
72
79
|
* Saves an object to storage, updating indexes as needed
|
|
80
|
+
*
|
|
81
|
+
* If the object contains a `_meta` field, this will be also present in the to-be-saved value, to mutate the `_meta`
|
|
82
|
+
* field of the object that is saved, you can mutate the `_meta` field directly on the passed value, which then
|
|
83
|
+
* gets reflected automatically in the existing object. The mutated `_meta` field is copied even if the function
|
|
84
|
+
* throws, hence the implementations must be careful with setting the `_meta` field on the still in-flight requests
|
|
85
|
+
* that might fail.
|
|
86
|
+
*
|
|
73
87
|
* @param value Object to save (must have an id property)
|
|
74
88
|
*/
|
|
75
89
|
save(value: UnifiedStoredObject): Promise<void>;
|
|
76
90
|
|
|
77
91
|
/**
|
|
78
92
|
* Saves multiple objects to storage in a batch operation
|
|
93
|
+
*
|
|
94
|
+
* If the objects contain a `_meta` field, this will be also present in the to-be-saved values, to mutate the `_meta`
|
|
95
|
+
* field of the objects that are saved, you can mutate the `_meta` field directly on the passed values, which then
|
|
96
|
+
* gets reflected automatically in the existing objects. The mutated `_meta` field is copied even if the function
|
|
97
|
+
* throws, hence the implementations must be careful with setting the `_meta` field on the still in-flight requests
|
|
98
|
+
* that might fail.
|
|
99
|
+
*
|
|
79
100
|
* @param value Array of objects to save
|
|
101
|
+
* @param lenient In lenient mode the persistency 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)
|
|
80
104
|
*/
|
|
81
|
-
saveAll(value: UnifiedStoredObject[]): Promise<void>;
|
|
105
|
+
saveAll(value: UnifiedStoredObject[], lenient?: boolean): Promise<void>;
|
|
82
106
|
|
|
83
107
|
/**
|
|
84
108
|
* Removes an object from storage
|
|
109
|
+
*
|
|
110
|
+
* If the object contains a `_meta` field, this will be also present in the to-be-removed value, to mutate the `_meta`
|
|
111
|
+
* field of the object that is saved, you can mutate the `_meta` field directly on the passed value, which then
|
|
112
|
+
* gets reflected automatically in the existing object. The mutated `_meta` field is copied even if the function
|
|
113
|
+
* throws, hence the implementations must be careful with setting the `_meta` field on the still in-flight requests
|
|
114
|
+
* that might fail.
|
|
115
|
+
*
|
|
85
116
|
* @param value Object to remove (must have an id property)
|
|
86
117
|
*/
|
|
87
118
|
remove(value: UnifiedStoredObject): Promise<void>;
|
|
88
119
|
|
|
89
120
|
/**
|
|
90
121
|
* Removes multiple objects from storage in a batch operation
|
|
122
|
+
*
|
|
123
|
+
* If the objects contain a `_meta` field, this will be also present in the to-be-removed values, to mutate the `_meta`
|
|
124
|
+
* field of the objects that are saved, you can mutate the `_meta` field directly on the passed values, which then
|
|
125
|
+
* gets reflected automatically in the existing objects. The mutated `_meta` field is copied even if the function
|
|
126
|
+
* throws, hence the implementations must be careful with setting the `_meta` field on the still in-flight requests
|
|
127
|
+
* that might fail.
|
|
128
|
+
*
|
|
91
129
|
* @param value Array of objects to remove
|
|
130
|
+
* @param lenient In lenient mode the persistency layer doesn't throw on individual swap failures due to
|
|
131
|
+
* optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
|
|
132
|
+
* isn't mission-critical for executing next steps (e.g. in tick or sync loops)
|
|
92
133
|
*/
|
|
93
|
-
removeAll(value: UnifiedStoredObject[]): Promise<void>;
|
|
134
|
+
removeAll(value: UnifiedStoredObject[], lenient?: boolean): Promise<void>;
|
|
94
135
|
|
|
95
136
|
}
|
|
@@ -104,18 +104,35 @@ export class UnifiedSwapStorage<T extends ChainType> {
|
|
|
104
104
|
*/
|
|
105
105
|
async save<S extends ISwap<T>>(value: S): Promise<void> {
|
|
106
106
|
if(!this.noWeakRefMap) this.weakRefCache.set(value.getId(), new WeakRef<ISwap<T>>(value));
|
|
107
|
-
|
|
107
|
+
const serialized = value.serialize();
|
|
108
|
+
try {
|
|
109
|
+
await this.storage.save(serialized);
|
|
110
|
+
} finally {
|
|
111
|
+
value._meta = serialized._meta;
|
|
112
|
+
}
|
|
108
113
|
value._persisted = true;
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
/**
|
|
112
117
|
* Saves multiple swaps to storage in a batch operation
|
|
113
118
|
* @param values Array of swaps to save
|
|
119
|
+
* @param lenient In lenient mode the underlying persistent layer doesn't throw on individual swap failures due to
|
|
120
|
+
* optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
|
|
121
|
+
* isn't mission-critical for executing next steps (e.g. in tick or sync loops)
|
|
114
122
|
*/
|
|
115
|
-
async saveAll<S extends ISwap<T>>(values: S[]): Promise<void> {
|
|
123
|
+
async saveAll<S extends ISwap<T>>(values: S[], lenient?: boolean): Promise<void> {
|
|
116
124
|
if(!this.noWeakRefMap) values.forEach(value => this.weakRefCache.set(value.getId(), new WeakRef<ISwap<T>>(value)));
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
const serialized = values.map(obj => obj.serialize());
|
|
126
|
+
try {
|
|
127
|
+
await this.storage.saveAll(serialized, lenient);
|
|
128
|
+
} finally {
|
|
129
|
+
values.forEach((value, index) => {
|
|
130
|
+
value._meta = serialized[index]._meta;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
values.forEach((value) => {
|
|
134
|
+
value._persisted = true;
|
|
135
|
+
});
|
|
119
136
|
}
|
|
120
137
|
|
|
121
138
|
/**
|
|
@@ -124,18 +141,35 @@ export class UnifiedSwapStorage<T extends ChainType> {
|
|
|
124
141
|
*/
|
|
125
142
|
async remove<S extends ISwap<T>>(value: S): Promise<void> {
|
|
126
143
|
if(!this.noWeakRefMap) this.weakRefCache.delete(value.getId());
|
|
127
|
-
|
|
144
|
+
const serialized = value.serialize();
|
|
145
|
+
try {
|
|
146
|
+
await this.storage.remove(serialized);
|
|
147
|
+
} finally {
|
|
148
|
+
value._meta = serialized._meta;
|
|
149
|
+
}
|
|
128
150
|
value._persisted = false;
|
|
129
151
|
}
|
|
130
152
|
|
|
131
153
|
/**
|
|
132
154
|
* Removes multiple swaps from storage in a batch operation
|
|
133
155
|
* @param values Array of swaps to remove
|
|
156
|
+
* @param lenient In lenient mode the underlying persistent layer doesn't throw on individual swap failures due to
|
|
157
|
+
* optimistic concurrency, or other (implementation specific), this flag is to be used when the saving of the swap
|
|
158
|
+
* isn't mission-critical for executing next steps (e.g. in tick or sync loops)
|
|
134
159
|
*/
|
|
135
|
-
async removeAll<S extends ISwap<T>>(values: S[]): Promise<void> {
|
|
160
|
+
async removeAll<S extends ISwap<T>>(values: S[], lenient?: boolean): Promise<void> {
|
|
136
161
|
if(!this.noWeakRefMap) values.forEach(value => this.weakRefCache.delete(value.getId()));
|
|
137
|
-
|
|
138
|
-
|
|
162
|
+
const serialized = values.map(obj => obj.serialize());
|
|
163
|
+
try {
|
|
164
|
+
await this.storage.removeAll(serialized, lenient);
|
|
165
|
+
} finally {
|
|
166
|
+
values.forEach((value, index) => {
|
|
167
|
+
value._meta = serialized[index]._meta;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
values.forEach((value) => {
|
|
171
|
+
value._persisted = false;
|
|
172
|
+
});
|
|
139
173
|
}
|
|
140
174
|
|
|
141
175
|
}
|
package/src/swapper/Swapper.ts
CHANGED
|
@@ -65,9 +65,11 @@ import {NotNever} from "../utils/TypeUtils";
|
|
|
65
65
|
import {IEscrowSwap} from "../swaps/escrow_swaps/IEscrowSwap";
|
|
66
66
|
import {LightningInvoiceCreateService, isLightningInvoiceCreateService} from "../types/wallets/LightningInvoiceCreateService";
|
|
67
67
|
import {SwapSide} from "../enums/SwapSide";
|
|
68
|
+
import {IntermediaryAPI} from "../intermediaries/apis/IntermediaryAPI";
|
|
68
69
|
import {BitcoinWalletUtxo, BitcoinWalletUtxoBase, IBitcoinWallet} from "../bitcoin/wallet/IBitcoinWallet";
|
|
69
70
|
import {MinimalBitcoinWalletInterface} from "../types/wallets/MinimalBitcoinWalletInterface";
|
|
70
71
|
import {toBitcoinWallet} from "../utils/BitcoinWalletUtils";
|
|
72
|
+
import {getSignedKeyBasedAuthHandler} from "../intermediaries/auth/SignedKeyBasedAuth";
|
|
71
73
|
|
|
72
74
|
/**
|
|
73
75
|
* Configuration options for the Swapper
|
|
@@ -129,8 +131,9 @@ export type SwapperOptions = {
|
|
|
129
131
|
noTimers?: boolean,
|
|
130
132
|
/**
|
|
131
133
|
* By setting this flag, the swapper doesn't subscribe to on-chain events. To make sure the swap states are
|
|
132
|
-
* properly updated you should call the {@link Swapper._syncSwaps} function periodically
|
|
133
|
-
*
|
|
134
|
+
* properly updated you should either call the {@link Swapper._syncSwaps} function periodically, or use the
|
|
135
|
+
* {@link Swapper._pollChainEvents} function to manually poll for on-chain events. This flag should be set
|
|
136
|
+
* when you run an environment that doesn't support long-running timers and websocket connections - e.g.
|
|
134
137
|
* serverless environments like Azure Function Apps or AWS Lambda
|
|
135
138
|
*/
|
|
136
139
|
noEvents?: boolean,
|
|
@@ -160,7 +163,7 @@ export type SwapperOptions = {
|
|
|
160
163
|
* want to only create a swap, and then later on retrieve it with the `swapper.getSwapById()` function.
|
|
161
164
|
*
|
|
162
165
|
* Setting this to `false` means the SDK only saves and persists swaps that are considered initiated, i.e. when
|
|
163
|
-
* `commit()`, `execute()` or `waitTillPayment` is called (or their respective txs... prefixed variations). This
|
|
166
|
+
* `commit()`, `execute()` or `waitTillPayment()` is called (or their respective txs... prefixed variations). This
|
|
164
167
|
* might save calls to the persistent storage for swaps that are never initiated. This is useful in e.g.
|
|
165
168
|
* frontend implementations where the frontend holds the swap object reference until it is initiated anyway, not
|
|
166
169
|
* necessitating the saving of the swap data to the persistent storage until it is actually initiated.
|
|
@@ -170,7 +173,20 @@ export type SwapperOptions = {
|
|
|
170
173
|
* Automatically checks system time on initialize, if the system time drifts too far from the actual time
|
|
171
174
|
* (as checked from multiple server sources) it adjusts the `Date.now()` function to return proper actual time.
|
|
172
175
|
*/
|
|
173
|
-
automaticClockDriftCorrection?: boolean
|
|
176
|
+
automaticClockDriftCorrection?: boolean,
|
|
177
|
+
/**
|
|
178
|
+
* Used in centralized API deployments to allow higher rate limits from LPs
|
|
179
|
+
*/
|
|
180
|
+
signedKeyBasedAuth?: {
|
|
181
|
+
certificate: string,
|
|
182
|
+
privateKey: string
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* If you set the option to `true` the chains for which the RPC is unresponsive are skipped and not initialized
|
|
187
|
+
* letting the swapper continue with only the available chains with responsive RPCs
|
|
188
|
+
*/
|
|
189
|
+
gracefullyHandleChainErrors?: boolean,
|
|
174
190
|
};
|
|
175
191
|
|
|
176
192
|
/**
|
|
@@ -307,6 +323,10 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
307
323
|
* Pricing API used by the SDK
|
|
308
324
|
*/
|
|
309
325
|
readonly prices: ISwapPrice<T>;
|
|
326
|
+
/**
|
|
327
|
+
* API for contacting LPs
|
|
328
|
+
*/
|
|
329
|
+
readonly lpApi: IntermediaryAPI;
|
|
310
330
|
/**
|
|
311
331
|
* Intermediary discovery instance
|
|
312
332
|
*/
|
|
@@ -362,6 +382,13 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
362
382
|
this._tokens[chainId][tokenData.address] = this._tokensByTicker[chainId][tokenData.ticker] = tokenData;
|
|
363
383
|
}
|
|
364
384
|
|
|
385
|
+
const lpApi = new IntermediaryAPI(
|
|
386
|
+
this.options.signedKeyBasedAuth!=null
|
|
387
|
+
? getSignedKeyBasedAuthHandler(this.options.signedKeyBasedAuth.certificate, this.options.signedKeyBasedAuth.privateKey)
|
|
388
|
+
: undefined
|
|
389
|
+
);
|
|
390
|
+
this.lpApi = lpApi;
|
|
391
|
+
|
|
365
392
|
this.swapStateListener = (swap: ISwap) => {
|
|
366
393
|
this.emit("swapState", swap);
|
|
367
394
|
};
|
|
@@ -413,6 +440,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
413
440
|
pricing,
|
|
414
441
|
this._tokens[chainId],
|
|
415
442
|
versions,
|
|
443
|
+
lpApi,
|
|
416
444
|
{
|
|
417
445
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
418
446
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
@@ -428,6 +456,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
428
456
|
this._tokens[chainId],
|
|
429
457
|
versions,
|
|
430
458
|
this._bitcoinRpc,
|
|
459
|
+
lpApi,
|
|
431
460
|
{
|
|
432
461
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
433
462
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
@@ -444,6 +473,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
444
473
|
this._tokens[chainId],
|
|
445
474
|
versions,
|
|
446
475
|
lightningApi,
|
|
476
|
+
lpApi,
|
|
447
477
|
{
|
|
448
478
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
449
479
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
@@ -461,6 +491,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
461
491
|
versions,
|
|
462
492
|
versionedContracts,
|
|
463
493
|
this._bitcoinRpc,
|
|
494
|
+
lpApi,
|
|
464
495
|
{
|
|
465
496
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
466
497
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
@@ -475,6 +506,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
475
506
|
chainInterface,
|
|
476
507
|
pricing,
|
|
477
508
|
this._tokens[chainId],
|
|
509
|
+
lpApi,
|
|
478
510
|
{
|
|
479
511
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
480
512
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
@@ -489,6 +521,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
489
521
|
pricing,
|
|
490
522
|
this._tokens[chainId],
|
|
491
523
|
bitcoinRpc,
|
|
524
|
+
lpApi,
|
|
492
525
|
{
|
|
493
526
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
494
527
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
@@ -509,6 +542,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
509
542
|
versions,
|
|
510
543
|
versionedContracts,
|
|
511
544
|
bitcoinRpc,
|
|
545
|
+
lpApi,
|
|
512
546
|
{
|
|
513
547
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
514
548
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
@@ -530,6 +564,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
530
564
|
versions,
|
|
531
565
|
lightningApi,
|
|
532
566
|
this.messenger,
|
|
567
|
+
lpApi,
|
|
533
568
|
{
|
|
534
569
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
535
570
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
@@ -566,9 +601,9 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
566
601
|
|
|
567
602
|
const contracts = objectMap(chainsData, (data) => data.versions ?? {[data.defaultVersion ?? "v1"]: {swapContract: data.swapContract, spvVaultContract: data.spvVaultContract}});
|
|
568
603
|
if(options.intermediaryUrl!=null) {
|
|
569
|
-
this.intermediaryDiscovery = new IntermediaryDiscovery(contracts, options.registryUrl, Array.isArray(options.intermediaryUrl) ? options.intermediaryUrl : [options.intermediaryUrl], options.getRequestTimeout);
|
|
604
|
+
this.intermediaryDiscovery = new IntermediaryDiscovery(contracts, lpApi, options.registryUrl, Array.isArray(options.intermediaryUrl) ? options.intermediaryUrl : [options.intermediaryUrl], options.getRequestTimeout);
|
|
570
605
|
} else {
|
|
571
|
-
this.intermediaryDiscovery = new IntermediaryDiscovery(contracts, options.registryUrl, undefined, options.getRequestTimeout);
|
|
606
|
+
this.intermediaryDiscovery = new IntermediaryDiscovery(contracts, lpApi, options.registryUrl, undefined, options.getRequestTimeout);
|
|
572
607
|
}
|
|
573
608
|
|
|
574
609
|
this.intermediaryDiscovery.on("removed", (intermediaries: Intermediary[]) => {
|
|
@@ -581,7 +616,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
581
616
|
}
|
|
582
617
|
|
|
583
618
|
private async _init(): Promise<void> {
|
|
584
|
-
this.logger.debug("init(): Initializing swapper
|
|
619
|
+
this.logger.debug("init(): Initializing swapper");
|
|
585
620
|
|
|
586
621
|
const abortController = new AbortController();
|
|
587
622
|
|
|
@@ -630,45 +665,52 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
630
665
|
reviver
|
|
631
666
|
} = this._chains[chainIdentifier];
|
|
632
667
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
668
|
+
try {
|
|
669
|
+
const _chainInterface: any = chainInterface;
|
|
670
|
+
if(_chainInterface.verifyNetwork!=null) {
|
|
671
|
+
await _chainInterface.verifyNetwork(this.bitcoinNetwork);
|
|
672
|
+
}
|
|
637
673
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
674
|
+
for(let contractVersion in versionedContracts) {
|
|
675
|
+
await versionedContracts[contractVersion].swapContract.start();
|
|
676
|
+
this.logger.debug("init(): Intialized swap contract: "+chainIdentifier+` version: ${contractVersion}`);
|
|
677
|
+
}
|
|
642
678
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
679
|
+
await unifiedSwapStorage.init();
|
|
680
|
+
if(unifiedSwapStorage.storage instanceof IndexedDBUnifiedStorage) {
|
|
681
|
+
//Try to migrate the data here
|
|
682
|
+
const storagePrefix = chainIdentifier==="SOLANA" ?
|
|
683
|
+
"SOLv4-"+this.bitcoinNetwork+"-Swaps-" :
|
|
684
|
+
"atomiqsdk-"+this.bitcoinNetwork+chainIdentifier+"-Swaps-";
|
|
685
|
+
await unifiedSwapStorage.storage.tryMigrate(
|
|
686
|
+
[
|
|
687
|
+
[storagePrefix+"FromBTC", SwapType.FROM_BTC],
|
|
688
|
+
[storagePrefix+"FromBTCLN", SwapType.FROM_BTCLN],
|
|
689
|
+
[storagePrefix+"ToBTC", SwapType.TO_BTC],
|
|
690
|
+
[storagePrefix+"ToBTCLN", SwapType.TO_BTCLN]
|
|
691
|
+
],
|
|
692
|
+
(obj: any) => {
|
|
693
|
+
const swap = reviver(obj);
|
|
694
|
+
if(swap._randomNonce==null) {
|
|
695
|
+
const oldIdentifierHash = swap.getId();
|
|
696
|
+
swap._randomNonce = randomBytes(16).toString("hex");
|
|
697
|
+
const newIdentifierHash = swap.getId();
|
|
698
|
+
this.logger.info("init(): Found older swap version without randomNonce, replacing, old hash: "+oldIdentifierHash+
|
|
699
|
+
" new hash: "+newIdentifierHash);
|
|
700
|
+
}
|
|
701
|
+
return swap;
|
|
664
702
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
)
|
|
668
|
-
}
|
|
703
|
+
)
|
|
704
|
+
}
|
|
669
705
|
|
|
670
|
-
|
|
671
|
-
|
|
706
|
+
await unifiedChainEvents.start(this.options.noEvents);
|
|
707
|
+
this.logger.debug("init(): Initialized events: "+chainIdentifier);
|
|
708
|
+
} catch (e) {
|
|
709
|
+
if(!this.options.gracefullyHandleChainErrors) throw e;
|
|
710
|
+
this.logger.error(`init(): Failed to initialize ${chainIdentifier} (skipped): `, e);
|
|
711
|
+
delete this._chains[chainIdentifier];
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
672
714
|
|
|
673
715
|
for(let key in wrappers) {
|
|
674
716
|
// this.logger.debug("init(): Initializing "+SwapType[key]+": "+chainIdentifier);
|
|
@@ -709,6 +751,13 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
709
751
|
}
|
|
710
752
|
}
|
|
711
753
|
|
|
754
|
+
/**
|
|
755
|
+
* Whether the SDK is initialized (after {@link init} is called)
|
|
756
|
+
*/
|
|
757
|
+
isInitialized(): boolean {
|
|
758
|
+
return this.initialized;
|
|
759
|
+
}
|
|
760
|
+
|
|
712
761
|
/**
|
|
713
762
|
* Stops listening for onchain events and closes this Swapper instance
|
|
714
763
|
*/
|
|
@@ -1521,6 +1570,9 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1521
1570
|
dst: string | LNURLPay | LightningInvoiceCreateService,
|
|
1522
1571
|
options?: FromBTCLNOptions | SpvFromBTCOptions | FromBTCOptions | ToBTCOptions | (ToBTCLNOptions & {comment?: string}) | FromBTCLNAutoOptions
|
|
1523
1572
|
): Promise<ISwap<T[C]>> {
|
|
1573
|
+
if(typeof(src)==="string") src = this.Utils.stripAddress(src);
|
|
1574
|
+
if(typeof(dst)==="string") dst = this.Utils.stripAddress(dst);
|
|
1575
|
+
|
|
1524
1576
|
const srcToken = typeof(_srcToken)==="string" ? this.getToken(_srcToken) as Token<C> : _srcToken;
|
|
1525
1577
|
const dstToken = typeof(_dstToken)==="string" ? this.getToken(_dstToken) as Token<C> : _dstToken;
|
|
1526
1578
|
const amount = _amount==null ? null : (typeof(_amount)==="bigint" ? _amount : fromDecimal(_amount, exactIn ? srcToken.decimals : dstToken.decimals));
|
|
@@ -1634,7 +1686,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1634
1686
|
const bitcoinFeeRatePromise = options?.bitcoinFeeRate ?? wallet.getFeeRate();
|
|
1635
1687
|
|
|
1636
1688
|
const swap = await this.createFromBTCSwapNew(
|
|
1637
|
-
dstToken.chainId, dstAddress, dstToken.address, null, false, undefined, {
|
|
1689
|
+
dstToken.chainId as C, dstAddress, dstToken.address, null, false, undefined, {
|
|
1638
1690
|
...options,
|
|
1639
1691
|
sourceWalletUtxos: walletUtxosPromise,
|
|
1640
1692
|
bitcoinFeeRate: bitcoinFeeRatePromise
|
|
@@ -1673,14 +1725,14 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1673
1725
|
}
|
|
1674
1726
|
|
|
1675
1727
|
/**
|
|
1676
|
-
* Returns all swaps
|
|
1728
|
+
* Returns all swaps which are pending (i.e. not in their final state yet)
|
|
1677
1729
|
*/
|
|
1678
|
-
|
|
1730
|
+
getPendingSwaps(): Promise<ISwap[]>;
|
|
1679
1731
|
/**
|
|
1680
|
-
* Returns swaps
|
|
1732
|
+
* 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
|
|
1681
1733
|
*/
|
|
1682
|
-
|
|
1683
|
-
async
|
|
1734
|
+
getPendingSwaps<C extends ChainIds<T>>(chainId: C, signer?: string): Promise<ISwap<T[C]>[]>;
|
|
1735
|
+
async getPendingSwaps<C extends ChainIds<T>>(chainId?: C, signer?: string): Promise<ISwap[]> {
|
|
1684
1736
|
if(chainId==null) {
|
|
1685
1737
|
const res: ISwap[][] = await Promise.all(Object.keys(this._chains).map((chainId) => {
|
|
1686
1738
|
const {unifiedSwapStorage, reviver, wrappers} = this._chains[chainId];
|
|
@@ -1694,7 +1746,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1694
1746
|
}
|
|
1695
1747
|
return unifiedSwapStorage.query(queryParams, reviver);
|
|
1696
1748
|
}));
|
|
1697
|
-
return res.flat()
|
|
1749
|
+
return res.flat();
|
|
1698
1750
|
} else {
|
|
1699
1751
|
const {unifiedSwapStorage, reviver, wrappers} = this._chains[chainId];
|
|
1700
1752
|
const queryParams: Array<QueryParams[]> = [];
|
|
@@ -1705,7 +1757,23 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1705
1757
|
swapTypeQueryParams.push({key: "state", value: wrapper._pendingSwapStates});
|
|
1706
1758
|
queryParams.push(swapTypeQueryParams);
|
|
1707
1759
|
}
|
|
1708
|
-
return
|
|
1760
|
+
return await unifiedSwapStorage.query(queryParams, reviver);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
/**
|
|
1765
|
+
* Returns all swaps where an action is required (either claim or refund)
|
|
1766
|
+
*/
|
|
1767
|
+
getActionableSwaps(): Promise<ISwap[]>;
|
|
1768
|
+
/**
|
|
1769
|
+
* Returns swaps where an action is required (either claim or refund) for the specific chain, and optionally also for a specific signer's address
|
|
1770
|
+
*/
|
|
1771
|
+
getActionableSwaps<C extends ChainIds<T>>(chainId: C, signer?: string): Promise<ISwap<T[C]>[]>;
|
|
1772
|
+
async getActionableSwaps<C extends ChainIds<T>>(chainId?: C, signer?: string): Promise<ISwap[]> {
|
|
1773
|
+
if(chainId==null) {
|
|
1774
|
+
return (await this.getPendingSwaps()).filter(swap => swap.requiresAction());
|
|
1775
|
+
} else {
|
|
1776
|
+
return (await this.getPendingSwaps(chainId, signer)).filter(swap => swap.requiresAction());
|
|
1709
1777
|
}
|
|
1710
1778
|
}
|
|
1711
1779
|
|
|
@@ -1903,8 +1971,8 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1903
1971
|
}
|
|
1904
1972
|
|
|
1905
1973
|
this.logger.debug("_syncSwaps(): Done syncing "+swaps.length+" swaps, saving "+changedSwaps.length+" changed swaps, removing "+removeSwaps.length+" swaps!");
|
|
1906
|
-
await unifiedSwapStorage.saveAll(changedSwaps);
|
|
1907
|
-
await unifiedSwapStorage.removeAll(removeSwaps);
|
|
1974
|
+
await unifiedSwapStorage.saveAll(changedSwaps, true);
|
|
1975
|
+
await unifiedSwapStorage.removeAll(removeSwaps, true);
|
|
1908
1976
|
|
|
1909
1977
|
changedSwaps.forEach(swap => swap._emitEvent());
|
|
1910
1978
|
removeSwaps.forEach(swap => swap._emitEvent());
|
|
@@ -1961,6 +2029,20 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1961
2029
|
}
|
|
1962
2030
|
}
|
|
1963
2031
|
|
|
2032
|
+
/**
|
|
2033
|
+
* When the swapper is initiated with the `noEvents` config this function allows you to manually poll for on-chain
|
|
2034
|
+
* events. It returns an events cursor which you should save and pass to the next call to the `poll()` function.
|
|
2035
|
+
*
|
|
2036
|
+
* @param chainId Chain for which to poll the chain events listener for
|
|
2037
|
+
* @param lastEventCursorState Event cursor state returned from the last call to the `poll()` function
|
|
2038
|
+
*/
|
|
2039
|
+
async _pollChainEvents<C extends ChainIds<T>>(chainId: C, lastEventCursorState?: any): Promise<any> {
|
|
2040
|
+
const chain = this._chains[chainId];
|
|
2041
|
+
if(chain==null) throw new Error(`Invalid chain id ${chainId}!`);
|
|
2042
|
+
|
|
2043
|
+
return chain.unifiedChainEvents.poll(lastEventCursorState);
|
|
2044
|
+
}
|
|
2045
|
+
|
|
1964
2046
|
/**
|
|
1965
2047
|
* Recovers swaps from on-chain historical data.
|
|
1966
2048
|
*
|
|
@@ -337,6 +337,22 @@ export class SwapperUtils<T extends MultiChain> {
|
|
|
337
337
|
return this.parseSmartchainAddress(addressString);
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Strips the URL encoding around `bitcoin:` and `lightning:` addresses, leaving just the raw address
|
|
342
|
+
*
|
|
343
|
+
* @param addressString Address to strip
|
|
344
|
+
*
|
|
345
|
+
* @returns Raw clean address
|
|
346
|
+
*/
|
|
347
|
+
stripAddress(addressString: string): string {
|
|
348
|
+
if(addressString.startsWith("lightning:") || addressString.startsWith("bitcoin:")) {
|
|
349
|
+
addressString = addressString.substring(addressString.indexOf(":")+1);
|
|
350
|
+
const delimeterIndex = addressString.indexOf("?");
|
|
351
|
+
if(delimeterIndex!==-1) addressString = addressString.substring(0, delimeterIndex);
|
|
352
|
+
}
|
|
353
|
+
return addressString;
|
|
354
|
+
}
|
|
355
|
+
|
|
340
356
|
/**
|
|
341
357
|
* Returns a random PSBT that can be used for fee estimation for SPV vault (UTXO-controlled vault) based swaps
|
|
342
358
|
* {@link SwapType.SPV_VAULT_FROM_BTC}, the last output (the LP output) is omitted to allow for coinselection
|
|
@@ -477,11 +493,18 @@ export class SwapperUtils<T extends MultiChain> {
|
|
|
477
493
|
}
|
|
478
494
|
|
|
479
495
|
/**
|
|
480
|
-
* Returns a random address for a given smart chain
|
|
496
|
+
* Returns a random address for a given smart chain or bitcoin
|
|
481
497
|
*
|
|
482
498
|
* @param chainIdentifier
|
|
483
499
|
*/
|
|
484
|
-
randomAddress<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier): string {
|
|
500
|
+
randomAddress<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier | "BITCOIN"): string {
|
|
501
|
+
if(chainIdentifier==="BITCOIN") {
|
|
502
|
+
// Return random p2wkh address
|
|
503
|
+
return Address(this.bitcoinNetwork).encode({
|
|
504
|
+
type: "wpkh",
|
|
505
|
+
hash: randomBytes(20)
|
|
506
|
+
});
|
|
507
|
+
}
|
|
485
508
|
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
486
509
|
return this.root._chains[chainIdentifier].chainInterface.randomAddress();
|
|
487
510
|
}
|
|
@@ -524,6 +547,23 @@ export class SwapperUtils<T extends MultiChain> {
|
|
|
524
547
|
return this.root._chains[chainIdentifier].chainInterface.sendSignedAndConfirm(txs, true, abortSignal, false, onBeforePublish);
|
|
525
548
|
}
|
|
526
549
|
|
|
550
|
+
/**
|
|
551
|
+
* Prepares a set of unsigned transactions for signing, by adding required nonces or recent blockhashes, might
|
|
552
|
+
* also add hints of account deployment on e.g. Starknet
|
|
553
|
+
*
|
|
554
|
+
* @param chainIdentifier A chain for which to prepare the txs
|
|
555
|
+
* @param txs Transactions to prepare
|
|
556
|
+
*/
|
|
557
|
+
prepareUnsignedTransactions<ChainIdentifier extends ChainIds<T>>(
|
|
558
|
+
chainIdentifier: ChainIdentifier,
|
|
559
|
+
txs: T[ChainIdentifier]["TX"][]
|
|
560
|
+
): Promise<T[ChainIdentifier]["TX"][]> {
|
|
561
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
562
|
+
const chainInterface = this.root._chains[chainIdentifier].chainInterface;
|
|
563
|
+
if(chainInterface.prepareTxs==null) throw new Error("Chain doesn't support tx preparation, chainId: "+chainIdentifier);
|
|
564
|
+
return chainInterface.prepareTxs(txs);
|
|
565
|
+
}
|
|
566
|
+
|
|
527
567
|
/**
|
|
528
568
|
* Serializes an unsigned smart chain transaction
|
|
529
569
|
*
|