@avail-project/ca-common 1.0.0-beta.7 → 1.0.0-beta.8
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/dist/cjs/_polyfill.js +147 -0
- package/dist/cjs/data/chaindata.js +39 -49
- package/dist/cjs/data/chainid.js +4 -2
- package/dist/cjs/data/currency.js +1 -2
- package/dist/cjs/index.js +4 -4
- package/dist/cjs/proto/client.js +48 -0
- package/dist/cjs/proto/definition.js +167 -448
- package/dist/cjs/proto/grpc.js +4 -9
- package/dist/cjs/rff/rff.js +0 -35
- package/dist/cjs/vaultcontracts/vaultcontracts.js +64 -23
- package/dist/cjs/xcs/autochoice.js +255 -0
- package/dist/esm/_polyfill.js +143 -0
- package/dist/esm/data/chaindata.js +39 -49
- package/dist/esm/data/chainid.js +4 -2
- package/dist/esm/data/currency.js +1 -2
- package/dist/esm/index.js +13 -12
- package/dist/esm/proto/client.js +11 -0
- package/dist/esm/proto/definition.js +167 -448
- package/dist/esm/proto/grpc.js +4 -9
- package/dist/esm/rff/rff.js +0 -35
- package/dist/esm/vaultcontracts/vaultcontracts.js +64 -23
- package/dist/esm/xcs/autochoice.js +254 -0
- package/dist/types/_polyfill.d.ts +1 -0
- package/dist/types/data/currency.d.ts +1 -2
- package/dist/types/index.d.ts +13 -12
- package/dist/types/proto/client.d.ts +2 -0
- package/dist/types/rff/rff.d.ts +0 -3
- package/dist/types/xcs/autochoice.d.ts +17 -0
- package/package.json +16 -10
- package/dist/cjs/fuelcontracts/ArcanaVault.js +0 -2407
- package/dist/cjs/fuelcontracts/ArcanaVaultFactory.js +0 -18
- package/dist/cjs/fuelcontracts/common.js +0 -3
- package/dist/cjs/fuelcontracts/index.js +0 -5
- package/dist/cjs/rff/fuel.js +0 -27
- package/dist/esm/fuelcontracts/ArcanaVault.js +0 -2402
- package/dist/esm/fuelcontracts/ArcanaVaultFactory.js +0 -14
- package/dist/esm/fuelcontracts/common.js +0 -2
- package/dist/esm/fuelcontracts/index.js +0 -2
- package/dist/esm/rff/fuel.js +0 -23
- package/dist/types/fuelcontracts/ArcanaVault.d.ts +0 -448
- package/dist/types/fuelcontracts/ArcanaVaultFactory.d.ts +0 -8
- package/dist/types/fuelcontracts/common.d.ts +0 -23
- package/dist/types/fuelcontracts/index.d.ts +0 -2
- package/dist/types/rff/fuel.d.ts +0 -4
package/dist/cjs/proto/grpc.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
3
3
|
// versions:
|
|
4
|
-
// protoc-gen-ts_proto v2.
|
|
4
|
+
// protoc-gen-ts_proto v2.8.3
|
|
5
5
|
// protoc v6.32.1
|
|
6
6
|
// source: grpc.proto
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -263,19 +263,14 @@ class GrpcWebImpl {
|
|
|
263
263
|
unary(methodDesc, _request, metadata) {
|
|
264
264
|
const request = { ..._request, ...methodDesc.requestType };
|
|
265
265
|
const maybeCombinedMetadata = metadata && this.options.metadata
|
|
266
|
-
? new browser_headers_1.BrowserHeaders({
|
|
267
|
-
|
|
268
|
-
...metadata?.headersMap,
|
|
269
|
-
})
|
|
270
|
-
: (metadata ?? this.options.metadata);
|
|
266
|
+
? new browser_headers_1.BrowserHeaders({ ...this.options?.metadata.headersMap, ...metadata?.headersMap })
|
|
267
|
+
: metadata ?? this.options.metadata;
|
|
271
268
|
return new Promise((resolve, reject) => {
|
|
272
269
|
grpc_web_1.grpc.unary(methodDesc, {
|
|
273
270
|
request,
|
|
274
271
|
host: this.host,
|
|
275
272
|
metadata: maybeCombinedMetadata ?? {},
|
|
276
|
-
...(this.options.transport !== undefined
|
|
277
|
-
? { transport: this.options.transport }
|
|
278
|
-
: {}),
|
|
273
|
+
...(this.options.transport !== undefined ? { transport: this.options.transport } : {}),
|
|
279
274
|
debug: this.options.debug ?? false,
|
|
280
275
|
onEnd: function (response) {
|
|
281
276
|
if (response.status === grpc_web_1.grpc.Code.OK) {
|
package/dist/cjs/rff/rff.js
CHANGED
|
@@ -2,18 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OmniversalRFF = void 0;
|
|
4
4
|
const viem_1 = require("viem");
|
|
5
|
-
const fuels_1 = require("fuels");
|
|
6
5
|
const data_1 = require("../data");
|
|
7
|
-
const fuel_1 = require("./fuel");
|
|
8
6
|
class OmniversalRFF {
|
|
9
7
|
protobufRFF;
|
|
10
8
|
evmRFF;
|
|
11
|
-
fuelRFF;
|
|
12
9
|
constructor(protobufRFF) {
|
|
13
10
|
this.protobufRFF = protobufRFF;
|
|
14
11
|
}
|
|
15
12
|
asEVMRFF() {
|
|
16
|
-
console.log("yge2i21ugeyu12igeui1g");
|
|
17
13
|
if (this.evmRFF == null) {
|
|
18
14
|
this.evmRFF = {
|
|
19
15
|
sources: this.protobufRFF.sources.map((s) => ({
|
|
@@ -39,37 +35,6 @@ class OmniversalRFF {
|
|
|
39
35
|
}
|
|
40
36
|
return this.evmRFF;
|
|
41
37
|
}
|
|
42
|
-
asFuelRFF() {
|
|
43
|
-
if (this.fuelRFF == null) {
|
|
44
|
-
this.fuelRFF = {
|
|
45
|
-
sources: this.protobufRFF.sources.map((s) => ({
|
|
46
|
-
universe: (0, fuel_1.protobufUniverseToFuelUniverse)(s.universe),
|
|
47
|
-
chain_id: new fuels_1.BN(s.chainID),
|
|
48
|
-
asset_id: {
|
|
49
|
-
bits: (0, data_1.ezPadTo32Hex)(s.contractAddress),
|
|
50
|
-
},
|
|
51
|
-
value: new fuels_1.BN(s.value),
|
|
52
|
-
})),
|
|
53
|
-
destination_chain_id: new fuels_1.BN(this.protobufRFF.destinationChainID),
|
|
54
|
-
destination_universe: (0, fuel_1.protobufUniverseToFuelUniverse)(this.protobufRFF.destinationUniverse),
|
|
55
|
-
destinations: this.protobufRFF.destinations.map((d) => ({
|
|
56
|
-
asset_id: {
|
|
57
|
-
bits: (0, data_1.ezPadTo32Hex)(d.contractAddress),
|
|
58
|
-
},
|
|
59
|
-
value: new fuels_1.BN(d.value),
|
|
60
|
-
})),
|
|
61
|
-
expiry: new fuels_1.BN(this.protobufRFF.expiry.toBytesBE()),
|
|
62
|
-
nonce: new fuels_1.BN(this.protobufRFF.nonce),
|
|
63
|
-
parties: this.protobufRFF.signatureData.map((sd) => ({
|
|
64
|
-
universe: (0, fuel_1.protobufUniverseToFuelUniverse)(sd.universe),
|
|
65
|
-
address: {
|
|
66
|
-
bits: (0, data_1.ezPadTo32Hex)(sd.address),
|
|
67
|
-
},
|
|
68
|
-
})),
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
return this.fuelRFF;
|
|
72
|
-
}
|
|
73
38
|
asProtobufRFF() {
|
|
74
39
|
return this.protobufRFF;
|
|
75
40
|
}
|
|
@@ -40,10 +40,6 @@ const dataSets = new Map([
|
|
|
40
40
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 10143),
|
|
41
41
|
"0xEFF0C81eC6D7c2a3B924e98B65303DDaa3030a81",
|
|
42
42
|
],
|
|
43
|
-
[
|
|
44
|
-
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 567),
|
|
45
|
-
"0xEFF0C81eC6D7c2a3B924e98B65303DDaa3030a81",
|
|
46
|
-
],
|
|
47
43
|
],
|
|
48
44
|
],
|
|
49
45
|
[
|
|
@@ -51,31 +47,31 @@ const dataSets = new Map([
|
|
|
51
47
|
[
|
|
52
48
|
[
|
|
53
49
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 137),
|
|
54
|
-
"
|
|
50
|
+
"0x111111eA4f8BdfB5AE22c37ebC3eE17b82072F57",
|
|
55
51
|
],
|
|
56
52
|
[
|
|
57
53
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 10),
|
|
58
|
-
"
|
|
54
|
+
"0x111111eA4f8BdfB5AE22c37ebC3eE17b82072F57",
|
|
59
55
|
],
|
|
60
56
|
[
|
|
61
57
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 42161),
|
|
62
|
-
"
|
|
58
|
+
"0x111111eA4f8BdfB5AE22c37ebC3eE17b82072F57",
|
|
63
59
|
],
|
|
64
60
|
[
|
|
65
61
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 8453),
|
|
66
|
-
"
|
|
62
|
+
"0x111111eA4f8BdfB5AE22c37ebC3eE17b82072F57",
|
|
67
63
|
],
|
|
68
64
|
[
|
|
69
65
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 534352),
|
|
70
|
-
"
|
|
66
|
+
"0x111111eA4f8BdfB5AE22c37ebC3eE17b82072F57",
|
|
71
67
|
],
|
|
72
68
|
[
|
|
73
69
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 56),
|
|
74
|
-
"
|
|
70
|
+
"0x111111eA4f8BdfB5AE22c37ebC3eE17b82072F57",
|
|
75
71
|
],
|
|
76
72
|
[
|
|
77
73
|
new data_1.OmniversalChainID(definition_1.Universe.TRON, 728126428),
|
|
78
|
-
"
|
|
74
|
+
"0x46de8c7e6f1da4dd851b62c20b78971f230fca5b",
|
|
79
75
|
],
|
|
80
76
|
],
|
|
81
77
|
],
|
|
@@ -84,39 +80,39 @@ const dataSets = new Map([
|
|
|
84
80
|
[
|
|
85
81
|
[
|
|
86
82
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 1),
|
|
87
|
-
"
|
|
83
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
88
84
|
],
|
|
89
85
|
[
|
|
90
86
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 10),
|
|
91
|
-
"
|
|
87
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
92
88
|
],
|
|
93
89
|
[
|
|
94
90
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 137),
|
|
95
|
-
"
|
|
91
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
96
92
|
],
|
|
97
93
|
[
|
|
98
94
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 42161),
|
|
99
|
-
"
|
|
95
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
100
96
|
],
|
|
101
97
|
[
|
|
102
98
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 534352),
|
|
103
|
-
"
|
|
99
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
104
100
|
],
|
|
105
101
|
[
|
|
106
102
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 8453),
|
|
107
|
-
"
|
|
103
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
108
104
|
],
|
|
109
105
|
[
|
|
110
106
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 43114),
|
|
111
|
-
"
|
|
107
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
112
108
|
],
|
|
113
109
|
[
|
|
114
110
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 999),
|
|
115
|
-
"
|
|
111
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
116
112
|
],
|
|
117
113
|
[
|
|
118
114
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 8217),
|
|
119
|
-
"
|
|
115
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
120
116
|
],
|
|
121
117
|
[
|
|
122
118
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 50104),
|
|
@@ -124,11 +120,56 @@ const dataSets = new Map([
|
|
|
124
120
|
],
|
|
125
121
|
[
|
|
126
122
|
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 56),
|
|
127
|
-
"
|
|
123
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 143),
|
|
127
|
+
"0xC0DED5d7F424276c821AF21F68E1e663bC671C3D",
|
|
128
128
|
],
|
|
129
|
+
],
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
Environment.JADE,
|
|
133
|
+
[
|
|
129
134
|
[
|
|
130
|
-
new data_1.OmniversalChainID(definition_1.Universe.
|
|
131
|
-
"
|
|
135
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 1),
|
|
136
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 10),
|
|
140
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
141
|
+
],
|
|
142
|
+
[
|
|
143
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 137),
|
|
144
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
145
|
+
],
|
|
146
|
+
[
|
|
147
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 42161),
|
|
148
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
149
|
+
],
|
|
150
|
+
[
|
|
151
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 534352),
|
|
152
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
153
|
+
],
|
|
154
|
+
[
|
|
155
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 8453),
|
|
156
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
157
|
+
],
|
|
158
|
+
[
|
|
159
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 43114),
|
|
160
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
161
|
+
],
|
|
162
|
+
[
|
|
163
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 999),
|
|
164
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
165
|
+
],
|
|
166
|
+
[
|
|
167
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 8217),
|
|
168
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
169
|
+
],
|
|
170
|
+
[
|
|
171
|
+
new data_1.OmniversalChainID(definition_1.Universe.ETHEREUM, 56),
|
|
172
|
+
"0x00000000ac0ac9d69424fA5Adc291D75Ec4a0F11",
|
|
132
173
|
],
|
|
133
174
|
],
|
|
134
175
|
],
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AutoSelectionError = void 0;
|
|
4
4
|
exports.aggregateAggregators = aggregateAggregators;
|
|
5
|
+
exports.autoSelectSourcesV2 = autoSelectSourcesV2;
|
|
5
6
|
exports.autoSelectSources = autoSelectSources;
|
|
6
7
|
exports.determineDestinationSwaps = determineDestinationSwaps;
|
|
7
8
|
exports.liquidateInputHoldings = liquidateInputHoldings;
|
|
@@ -66,6 +67,259 @@ async function aggregateAggregators(requests, aggregators, mode) {
|
|
|
66
67
|
}
|
|
67
68
|
return final;
|
|
68
69
|
}
|
|
70
|
+
/*
|
|
71
|
+
In original autoSelectSources:
|
|
72
|
+
Assets = [1 ETH, 1 COT, 1 ETH, 1 USDT, 1 COT]
|
|
73
|
+
Output = 4
|
|
74
|
+
|
|
75
|
+
First loop that just removes cot:
|
|
76
|
+
quoteAssets = [1 ETH, 1 ETH, 1 USDT]
|
|
77
|
+
Output = 4
|
|
78
|
+
|
|
79
|
+
Outside the function we can just remove all COT's and assume those as being used
|
|
80
|
+
but that's incorrect as we want to use assets in exact order as holdings array.
|
|
81
|
+
We can't remove only COT's that are going to be used because we don't know which ones are going
|
|
82
|
+
to get used.
|
|
83
|
+
|
|
84
|
+
Proposed solution:
|
|
85
|
+
It should actually use assets in exact order, so it cant be done outside the function
|
|
86
|
+
1. The function has to keep an order of assets, separate out COT and non-COT assets.
|
|
87
|
+
2. Get quote for non-COT assets, then loop over the original order
|
|
88
|
+
3. Used either COT or quote depending on original order
|
|
89
|
+
4. Send back quotes and COT's used
|
|
90
|
+
|
|
91
|
+
Alg:
|
|
92
|
+
Assets = [1 ETH, 1 COT, 1 ETH, 1 USDT, 1 COT]
|
|
93
|
+
Output = 4
|
|
94
|
+
|
|
95
|
+
1. separate into two with indexes:
|
|
96
|
+
quotes = [(1 ETH, 0), (1 ETH, 2), (1 USDT, 3)]
|
|
97
|
+
cots = [(1 COT, 1), (1 COT, 4)]
|
|
98
|
+
|
|
99
|
+
2. Get quotes using only quotes
|
|
100
|
+
3. merge quote cots and sort by order
|
|
101
|
+
4. loop assets (original order):
|
|
102
|
+
if a quote:
|
|
103
|
+
output = output - quote_output_amount
|
|
104
|
+
if a cot:
|
|
105
|
+
output = output - cot_amount
|
|
106
|
+
if output <= 0:
|
|
107
|
+
break
|
|
108
|
+
5. return quotes and assets used.
|
|
109
|
+
*/
|
|
110
|
+
async function autoSelectSourcesV2(userAddress, holdings, outputRequired, aggregators, commonCurrencyID = data_1.CurrencyID.USDC) {
|
|
111
|
+
// Assumption: Holding is already sorted in usage priority
|
|
112
|
+
console.log("XCS | SSV2:", {
|
|
113
|
+
holdings,
|
|
114
|
+
outputRequired: outputRequired.toFixed(),
|
|
115
|
+
});
|
|
116
|
+
const fullLiquidationQuotes = [];
|
|
117
|
+
const cotList = [];
|
|
118
|
+
for (const [idx, holding] of holdings.entries()) {
|
|
119
|
+
const chain = data_1.ChaindataMap.get(holding.chainID);
|
|
120
|
+
if (chain == null) {
|
|
121
|
+
throw new AutoSelectionError("Chain not found");
|
|
122
|
+
}
|
|
123
|
+
const correspondingCurrency = chain.Currencies.find((cur) => cur.currencyID === commonCurrencyID);
|
|
124
|
+
if (correspondingCurrency == null) {
|
|
125
|
+
console.log("XCS | SS | Skipping because correspondingCurrency is null", {
|
|
126
|
+
chain,
|
|
127
|
+
correspondingCurrency,
|
|
128
|
+
});
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (Buffer.compare(holding.tokenAddress, correspondingCurrency.tokenAddress) === 0) {
|
|
132
|
+
const normalizedAmount = new decimal_js_1.default(holding.amount).div(decimal_js_1.default.pow(10, correspondingCurrency.decimals));
|
|
133
|
+
cotList.push({
|
|
134
|
+
amount: normalizedAmount,
|
|
135
|
+
idx,
|
|
136
|
+
chainID: holding.chainID,
|
|
137
|
+
currency: correspondingCurrency,
|
|
138
|
+
originalHolding: holding,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
fullLiquidationQuotes.push({
|
|
143
|
+
req: {
|
|
144
|
+
userAddress,
|
|
145
|
+
type: iface_1.QuoteType.EXACT_IN,
|
|
146
|
+
chain: chain.ChainID,
|
|
147
|
+
inputToken: holding.tokenAddress,
|
|
148
|
+
inputAmount: holding.amount,
|
|
149
|
+
outputToken: correspondingCurrency.tokenAddress,
|
|
150
|
+
seriousness: iface_1.QuoteSeriousness.PRICE_SURVEY,
|
|
151
|
+
},
|
|
152
|
+
originalHolding: holding,
|
|
153
|
+
cur: correspondingCurrency,
|
|
154
|
+
idx,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Check if continuous COTs from the start can cover the entire requirement
|
|
159
|
+
// We can skip quoting unused holdings
|
|
160
|
+
if (cotList.length > 0 && cotList[0].idx === 0) {
|
|
161
|
+
let continuousCOTAmount = new decimal_js_1.default(0);
|
|
162
|
+
let continuousCount = 0;
|
|
163
|
+
for (const cot of cotList) {
|
|
164
|
+
// only consecutive cots allowed, otherwise we need to go to quoting
|
|
165
|
+
if (cot.idx !== continuousCount)
|
|
166
|
+
break;
|
|
167
|
+
continuousCOTAmount = continuousCOTAmount.add(cot.amount);
|
|
168
|
+
continuousCount++;
|
|
169
|
+
if (continuousCOTAmount.gte(outputRequired)) {
|
|
170
|
+
console.log("XCS | SS | Continuous COTs can satisfy requirement, skipping quotes");
|
|
171
|
+
const usedCOTs = [];
|
|
172
|
+
let remainder = outputRequired;
|
|
173
|
+
for (let i = 0; i < continuousCount; i++) {
|
|
174
|
+
const cot = cotList[i];
|
|
175
|
+
const amountToUse = decimal_js_1.default.min(remainder, cot.amount);
|
|
176
|
+
usedCOTs.push({
|
|
177
|
+
originalHolding: cot.originalHolding,
|
|
178
|
+
amountUsed: amountToUse,
|
|
179
|
+
idx: cot.idx,
|
|
180
|
+
cur: cot.currency,
|
|
181
|
+
});
|
|
182
|
+
remainder = remainder.minus(amountToUse);
|
|
183
|
+
if (remainder.lte(0))
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
console.log("XCS | SS | Early return with continuous COTs:", {
|
|
187
|
+
cots: usedCOTs,
|
|
188
|
+
});
|
|
189
|
+
return { quotes: [], usedCOTs };
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const processingQueue = [];
|
|
194
|
+
// Add COT holdings
|
|
195
|
+
for (const cot of cotList) {
|
|
196
|
+
processingQueue.push({
|
|
197
|
+
idx: cot.idx,
|
|
198
|
+
isCOT: true,
|
|
199
|
+
cotData: cot,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// Add non-COT holdings
|
|
203
|
+
for (let i = 0; i < fullLiquidationQuotes.length; i++) {
|
|
204
|
+
processingQueue.push({
|
|
205
|
+
idx: fullLiquidationQuotes[i].idx,
|
|
206
|
+
isCOT: false,
|
|
207
|
+
quoteData: fullLiquidationQuotes[i],
|
|
208
|
+
responseIdx: i,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
// Sort by original index to maintain priority
|
|
212
|
+
processingQueue.sort((a, b) => a.idx - b.idx);
|
|
213
|
+
const responses = await aggregateAggregators(fullLiquidationQuotes.map((fq) => fq.req), aggregators, 0 /* AggregateAggregatorsMode.MaximizeOutput */);
|
|
214
|
+
console.log("XCS | SS | Responses:", responses);
|
|
215
|
+
const final = [];
|
|
216
|
+
const usedCOTs = [];
|
|
217
|
+
let remainder = outputRequired;
|
|
218
|
+
for (const item of processingQueue) {
|
|
219
|
+
if (remainder.lte(0)) {
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
if (item.isCOT) {
|
|
223
|
+
// Process COT holding - direct usage, no quote
|
|
224
|
+
const { cotData } = item;
|
|
225
|
+
const amountToUse = decimal_js_1.default.min(remainder, cotData.amount);
|
|
226
|
+
usedCOTs.push({
|
|
227
|
+
originalHolding: cotData.originalHolding,
|
|
228
|
+
amountUsed: amountToUse,
|
|
229
|
+
idx: cotData.idx,
|
|
230
|
+
cur: cotData.currency,
|
|
231
|
+
});
|
|
232
|
+
remainder = remainder.minus(amountToUse);
|
|
233
|
+
console.log("XCS | SS | Used COT", {
|
|
234
|
+
idx: cotData.idx,
|
|
235
|
+
amountToUse: amountToUse.toFixed(),
|
|
236
|
+
remainder: remainder.toFixed(),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
// Process non-COT holding - use existing quote logic
|
|
241
|
+
const { quoteData, responseIdx } = item;
|
|
242
|
+
const { quote: resp, aggregator: agg } = responses[responseIdx];
|
|
243
|
+
if (resp == null) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
console.log("XCS | SS | 1", {
|
|
247
|
+
i: responseIdx,
|
|
248
|
+
idx: quoteData.idx,
|
|
249
|
+
remainder,
|
|
250
|
+
q: quoteData,
|
|
251
|
+
resp,
|
|
252
|
+
agg,
|
|
253
|
+
});
|
|
254
|
+
const divisor = decimal_js_1.default.pow(10, quoteData.cur.decimals);
|
|
255
|
+
const oamD = decimal_js_1.default.div(resp.outputAmountMinimum, divisor);
|
|
256
|
+
if (oamD.gt(remainder)) {
|
|
257
|
+
const indicativePrice = decimal_js_1.default.div(resp.inputAmount, resp.outputAmountMinimum);
|
|
258
|
+
const userBal = new decimal_js_1.default(quoteData.originalHolding.amount);
|
|
259
|
+
// remainder is the output we want, so the input amount is remainder × indicativePrice
|
|
260
|
+
let expectedInput = decimal_js_1.default.min(remainder.mul(divisor).mul(indicativePrice).mul(safetyMultiplier), userBal);
|
|
261
|
+
while (true) {
|
|
262
|
+
console.log("XCS | SS | 2⒜", {
|
|
263
|
+
indicativePrice,
|
|
264
|
+
expectedInput,
|
|
265
|
+
userBal,
|
|
266
|
+
});
|
|
267
|
+
const adequateQuoteResult = await aggregateAggregators([
|
|
268
|
+
{
|
|
269
|
+
...quoteData.req,
|
|
270
|
+
seriousness: iface_1.QuoteSeriousness.SERIOUS,
|
|
271
|
+
inputAmount: (0, data_1.convertDecimalToBigInt)(expectedInput),
|
|
272
|
+
},
|
|
273
|
+
], aggregators, 0 /* AggregateAggregatorsMode.MaximizeOutput */);
|
|
274
|
+
if (adequateQuoteResult.length !== 1) {
|
|
275
|
+
throw new AutoSelectionError("???");
|
|
276
|
+
}
|
|
277
|
+
const adequateQuote = adequateQuoteResult[0];
|
|
278
|
+
if (adequateQuote.quote == null) {
|
|
279
|
+
throw new AutoSelectionError("Couldn't get buy quote");
|
|
280
|
+
}
|
|
281
|
+
console.log("XCS | SS | 2⒜⑴", {
|
|
282
|
+
adequateQuote,
|
|
283
|
+
});
|
|
284
|
+
const oam2D = decimal_js_1.default.div(adequateQuote.quote.outputAmountMinimum, divisor);
|
|
285
|
+
if (oam2D.gte(remainder)) {
|
|
286
|
+
final.push({
|
|
287
|
+
...quoteData,
|
|
288
|
+
quote: adequateQuote.quote,
|
|
289
|
+
agg: adequateQuote.aggregator,
|
|
290
|
+
});
|
|
291
|
+
remainder = remainder.minus(oam2D);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
else if (expectedInput.eq(userBal)) {
|
|
295
|
+
throw new AutoSelectionError("Holding was supposedly enough to meet the full requirement but ceased to be so subsequently");
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
expectedInput = decimal_js_1.default.min(expectedInput.mul(safetyMultiplier), userBal); // try again with higher amount
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
console.log("XCS | SS | 2⒝", resp);
|
|
304
|
+
final.push({
|
|
305
|
+
...quoteData,
|
|
306
|
+
quote: resp,
|
|
307
|
+
agg,
|
|
308
|
+
});
|
|
309
|
+
remainder = remainder.minus((0, data_1.convertBigIntToDecimal)(resp.outputAmountMinimum).div(divisor));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
console.log("XCS | SS | 3⒜", {
|
|
314
|
+
remainder,
|
|
315
|
+
final,
|
|
316
|
+
});
|
|
317
|
+
if (remainder.gt(0)) {
|
|
318
|
+
throw new AutoSelectionError("Failed to accumulate enough swaps to meet requirement");
|
|
319
|
+
}
|
|
320
|
+
console.log("XCS | SS | Final:", { quotes: final, cots: usedCOTs });
|
|
321
|
+
return { quotes: final, usedCOTs };
|
|
322
|
+
}
|
|
69
323
|
async function autoSelectSources(userAddress, holdings, outputRequired, aggregators, collectionFees, commonCurrencyID = data_1.CurrencyID.USDC) {
|
|
70
324
|
console.log("XCS | SS | Holdings:", holdings);
|
|
71
325
|
const groupedByChainID = (0, es_toolkit_1.groupBy)(holdings, (h) => (0, viem_1.bytesToHex)(h.chainID.toBytes()));
|
|
@@ -215,6 +469,7 @@ async function determineDestinationSwaps(userAddress, chainID, requirement, aggr
|
|
|
215
469
|
if (COT == null) {
|
|
216
470
|
throw new AutoSelectionError("COT not present on the destination chain");
|
|
217
471
|
}
|
|
472
|
+
// FIXME: Replace with oracle usage - should reduce time.
|
|
218
473
|
// what happens if we happen to sell the requirement for the COT, what would the amount be?
|
|
219
474
|
const fullLiquidationQR = {
|
|
220
475
|
type: iface_1.QuoteType.EXACT_IN,
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import * as bufferModule from "buffer";
|
|
2
|
+
import { Buffer as DefaultBuffer } from "buffer";
|
|
3
|
+
const globalScope = globalThis;
|
|
4
|
+
let patched = false;
|
|
5
|
+
function collectBufferCtors() {
|
|
6
|
+
const candidates = new Set();
|
|
7
|
+
if (typeof DefaultBuffer === "function") {
|
|
8
|
+
candidates.add(DefaultBuffer);
|
|
9
|
+
}
|
|
10
|
+
const mod = bufferModule;
|
|
11
|
+
if (typeof mod?.Buffer === "function") {
|
|
12
|
+
candidates.add(mod.Buffer);
|
|
13
|
+
}
|
|
14
|
+
const defaultExport = mod?.default;
|
|
15
|
+
if (typeof defaultExport === "function") {
|
|
16
|
+
candidates.add(defaultExport);
|
|
17
|
+
}
|
|
18
|
+
else if (defaultExport &&
|
|
19
|
+
typeof defaultExport === "object" &&
|
|
20
|
+
typeof defaultExport.Buffer === "function") {
|
|
21
|
+
candidates.add(defaultExport.Buffer);
|
|
22
|
+
}
|
|
23
|
+
if (typeof globalScope.Buffer === "function") {
|
|
24
|
+
candidates.add(globalScope.Buffer);
|
|
25
|
+
}
|
|
26
|
+
return Array.from(candidates);
|
|
27
|
+
}
|
|
28
|
+
function assertOffset(buffer, offset) {
|
|
29
|
+
const numericOffset = Number(offset);
|
|
30
|
+
if (!Number.isFinite(numericOffset)) {
|
|
31
|
+
throw new TypeError("Offset must be a finite number");
|
|
32
|
+
}
|
|
33
|
+
const normalized = numericOffset >>> 0;
|
|
34
|
+
if (normalized !== numericOffset) {
|
|
35
|
+
throw new RangeError("Offset must be a non-negative integer");
|
|
36
|
+
}
|
|
37
|
+
if (normalized + 4 > buffer.length) {
|
|
38
|
+
throw new RangeError("Offset out of bounds");
|
|
39
|
+
}
|
|
40
|
+
return normalized;
|
|
41
|
+
}
|
|
42
|
+
function fallbackWriteUint32BE(value, offset = 0) {
|
|
43
|
+
const o = assertOffset(this, offset);
|
|
44
|
+
const normalized = Number(value) >>> 0;
|
|
45
|
+
this[o] = (normalized >>> 24) & 0xff;
|
|
46
|
+
this[o + 1] =
|
|
47
|
+
(normalized >>> 16) & 0xff;
|
|
48
|
+
this[o + 2] =
|
|
49
|
+
(normalized >>> 8) & 0xff;
|
|
50
|
+
this[o + 3] = normalized & 0xff;
|
|
51
|
+
return o + 4;
|
|
52
|
+
}
|
|
53
|
+
function fallbackWriteUint32LE(value, offset = 0) {
|
|
54
|
+
const o = assertOffset(this, offset);
|
|
55
|
+
const normalized = Number(value) >>> 0;
|
|
56
|
+
this[o] = normalized & 0xff;
|
|
57
|
+
this[o + 1] =
|
|
58
|
+
(normalized >>> 8) & 0xff;
|
|
59
|
+
this[o + 2] =
|
|
60
|
+
(normalized >>> 16) & 0xff;
|
|
61
|
+
this[o + 3] =
|
|
62
|
+
(normalized >>> 24) & 0xff;
|
|
63
|
+
return o + 4;
|
|
64
|
+
}
|
|
65
|
+
function fallbackReadUint32BE(offset = 0) {
|
|
66
|
+
const o = assertOffset(this, offset);
|
|
67
|
+
const store = this;
|
|
68
|
+
return ((store[o] * 0x1000000 +
|
|
69
|
+
((store[o + 1] << 16) | (store[o + 2] << 8) | store[o + 3])) >>>
|
|
70
|
+
0);
|
|
71
|
+
}
|
|
72
|
+
function fallbackReadUint32LE(offset = 0) {
|
|
73
|
+
const o = assertOffset(this, offset);
|
|
74
|
+
const store = this;
|
|
75
|
+
return ((store[o] |
|
|
76
|
+
(store[o + 1] << 8) |
|
|
77
|
+
(store[o + 2] << 16) |
|
|
78
|
+
(store[o + 3] * 0x1000000)) >>>
|
|
79
|
+
0);
|
|
80
|
+
}
|
|
81
|
+
function aliasOrDefine(proto, alias, canonical, fallback) {
|
|
82
|
+
const aliasKey = alias;
|
|
83
|
+
const canonicalKey = canonical;
|
|
84
|
+
const existingAlias = proto[aliasKey];
|
|
85
|
+
if (typeof existingAlias === "function") {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const canonicalFn = proto[canonicalKey];
|
|
89
|
+
if (typeof canonicalFn === "function") {
|
|
90
|
+
Object.defineProperty(proto, aliasKey, {
|
|
91
|
+
value: canonicalFn,
|
|
92
|
+
writable: true,
|
|
93
|
+
configurable: true,
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
Object.defineProperty(proto, aliasKey, {
|
|
98
|
+
value: fallback,
|
|
99
|
+
writable: true,
|
|
100
|
+
configurable: true,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function patchPrototype(bufferCtor) {
|
|
104
|
+
const proto = bufferCtor.prototype;
|
|
105
|
+
if (!proto) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
aliasOrDefine(proto, "writeUint32BE", "writeUInt32BE", fallbackWriteUint32BE);
|
|
109
|
+
aliasOrDefine(proto, "writeUint32LE", "writeUInt32LE", fallbackWriteUint32LE);
|
|
110
|
+
aliasOrDefine(proto, "readUint32BE", "readUInt32BE", fallbackReadUint32BE);
|
|
111
|
+
aliasOrDefine(proto, "readUint32LE", "readUInt32LE", fallbackReadUint32LE);
|
|
112
|
+
}
|
|
113
|
+
function ensureProcessEnv() {
|
|
114
|
+
if (!globalScope.process) {
|
|
115
|
+
globalScope.process = { env: { NODE_ENV: "production" } };
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const processValue = globalScope.process;
|
|
119
|
+
if (!processValue.env) {
|
|
120
|
+
processValue.env = { NODE_ENV: "production" };
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (typeof processValue.env.NODE_ENV === "undefined") {
|
|
124
|
+
processValue.env.NODE_ENV = "production";
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export function ensureBufferPolyfill() {
|
|
128
|
+
if (patched) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const candidates = collectBufferCtors();
|
|
132
|
+
candidates.forEach(patchPrototype);
|
|
133
|
+
const preferred = candidates[0];
|
|
134
|
+
if (preferred &&
|
|
135
|
+
(typeof globalScope.Buffer !== "function" ||
|
|
136
|
+
typeof globalScope.Buffer.prototype?.writeUint32BE !==
|
|
137
|
+
"function")) {
|
|
138
|
+
globalScope.Buffer = preferred;
|
|
139
|
+
}
|
|
140
|
+
ensureProcessEnv();
|
|
141
|
+
patched = true;
|
|
142
|
+
}
|
|
143
|
+
ensureBufferPolyfill();
|