@gearbox-protocol/sdk 7.7.0 → 7.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.
- package/dist/cjs/dev/CachedStateSubscriber.js +78 -0
- package/dist/cjs/dev/index.js +2 -0
- package/dist/cjs/sdk/GearboxSDK.js +23 -2
- package/dist/cjs/sdk/market/MarketSuite.js +0 -3
- package/dist/cjs/sdk/market/oracle/createPriceOracle.js +12 -8
- package/dist/esm/dev/CachedStateSubscriber.js +54 -0
- package/dist/esm/dev/index.js +1 -0
- package/dist/esm/sdk/GearboxSDK.js +23 -2
- package/dist/esm/sdk/market/MarketSuite.js +0 -3
- package/dist/esm/sdk/market/oracle/createPriceOracle.js +12 -8
- package/dist/types/dev/CachedStateSubscriber.d.ts +21 -0
- package/dist/types/dev/index.d.ts +1 -0
- package/dist/types/sdk/GearboxSDK.d.ts +4 -0
- package/package.json +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var CachedStateSubscriber_exports = {};
|
|
20
|
+
__export(CachedStateSubscriber_exports, {
|
|
21
|
+
CachedStateSubscriber: () => CachedStateSubscriber
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(CachedStateSubscriber_exports);
|
|
24
|
+
var import_sdk = require("../sdk/index.js");
|
|
25
|
+
class CachedStateSubscriber {
|
|
26
|
+
#stateURL;
|
|
27
|
+
#etag;
|
|
28
|
+
#currentBlock;
|
|
29
|
+
#sdk;
|
|
30
|
+
constructor(sdk, stateURL) {
|
|
31
|
+
this.#stateURL = stateURL;
|
|
32
|
+
this.#sdk = sdk;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Subscribe to sdk state changes
|
|
36
|
+
* @param opts - Options
|
|
37
|
+
* @returns Unsubscribe function
|
|
38
|
+
*/
|
|
39
|
+
subscribe(opts) {
|
|
40
|
+
const intervalMs = opts?.pollInterval ?? 10 * 60 * 1e3;
|
|
41
|
+
const interval = setInterval(async () => {
|
|
42
|
+
const newBlock = await this.#poll();
|
|
43
|
+
if (newBlock && opts?.onChange) {
|
|
44
|
+
opts.onChange(newBlock);
|
|
45
|
+
}
|
|
46
|
+
}, intervalMs);
|
|
47
|
+
return () => clearInterval(interval);
|
|
48
|
+
}
|
|
49
|
+
async #poll() {
|
|
50
|
+
try {
|
|
51
|
+
const head = await fetch(this.#stateURL, { method: "HEAD" });
|
|
52
|
+
const etag = head.headers.get("ETag");
|
|
53
|
+
if (!etag || etag === this.#etag) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const response = await fetch(this.#stateURL);
|
|
57
|
+
const txt = await response.text();
|
|
58
|
+
const state = (0, import_sdk.json_parse)(txt);
|
|
59
|
+
if (state.currentBlock === this.#currentBlock) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.#etag = etag;
|
|
63
|
+
this.#currentBlock = state.currentBlock;
|
|
64
|
+
this.#logger?.debug(`rehydrating state at block ${state.currentBlock}`);
|
|
65
|
+
this.#sdk.rehydrate(state);
|
|
66
|
+
return state.currentBlock;
|
|
67
|
+
} catch (e) {
|
|
68
|
+
this.#logger?.error(e, "error while polling cached state");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
get #logger() {
|
|
72
|
+
return this.#sdk.logger;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
76
|
+
0 && (module.exports = {
|
|
77
|
+
CachedStateSubscriber
|
|
78
|
+
});
|
package/dist/cjs/dev/index.js
CHANGED
|
@@ -17,6 +17,7 @@ var dev_exports = {};
|
|
|
17
17
|
module.exports = __toCommonJS(dev_exports);
|
|
18
18
|
__reExport(dev_exports, require("./AccountOpener.js"), module.exports);
|
|
19
19
|
__reExport(dev_exports, require("./AccountsCounterPlugin.js"), module.exports);
|
|
20
|
+
__reExport(dev_exports, require("./CachedStateSubscriber.js"), module.exports);
|
|
20
21
|
__reExport(dev_exports, require("./calcLiquidatableLTs.js"), module.exports);
|
|
21
22
|
__reExport(dev_exports, require("./create2.js"), module.exports);
|
|
22
23
|
__reExport(dev_exports, require("./createAnvilClient.js"), module.exports);
|
|
@@ -28,6 +29,7 @@ __reExport(dev_exports, require("./migrateFaucet.js"), module.exports);
|
|
|
28
29
|
0 && (module.exports = {
|
|
29
30
|
...require("./AccountOpener.js"),
|
|
30
31
|
...require("./AccountsCounterPlugin.js"),
|
|
32
|
+
...require("./CachedStateSubscriber.js"),
|
|
31
33
|
...require("./calcLiquidatableLTs.js"),
|
|
32
34
|
...require("./create2.js"),
|
|
33
35
|
...require("./createAnvilClient.js"),
|
|
@@ -210,15 +210,22 @@ class GearboxSDK {
|
|
|
210
210
|
return this;
|
|
211
211
|
}
|
|
212
212
|
#hydrate(options, state) {
|
|
213
|
-
const { logger: _logger,
|
|
213
|
+
const { logger: _logger, ...opts } = options;
|
|
214
214
|
if (state.version !== STATE_VERSION) {
|
|
215
215
|
throw new Error(
|
|
216
216
|
`hydrated state version is ${state.version}, but expected ${STATE_VERSION}`
|
|
217
217
|
);
|
|
218
218
|
}
|
|
219
|
+
const re = this.#attachConfig ? "re" : "";
|
|
220
|
+
this.logger?.info(
|
|
221
|
+
{
|
|
222
|
+
networkType: this.provider.networkType
|
|
223
|
+
},
|
|
224
|
+
`${re}hydrating sdk state`
|
|
225
|
+
);
|
|
219
226
|
this.#currentBlock = state.currentBlock;
|
|
220
227
|
this.#timestamp = state.timestamp;
|
|
221
|
-
this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, { redstone });
|
|
228
|
+
this.#priceFeeds = new import_pricefeeds.PriceFeedRegister(this, { redstone: opts.redstone });
|
|
222
229
|
this.#addressProvider = (0, import_core.hydrateAddressProvider)(this, state.addressProvider);
|
|
223
230
|
this.logger?.debug(
|
|
224
231
|
`address provider version: ${this.#addressProvider.version}`
|
|
@@ -242,6 +249,7 @@ class GearboxSDK {
|
|
|
242
249
|
plugin.hydrate(pluginState);
|
|
243
250
|
}
|
|
244
251
|
}
|
|
252
|
+
this.logger?.info(`${re}hydrated sdk state`);
|
|
245
253
|
return this;
|
|
246
254
|
}
|
|
247
255
|
/**
|
|
@@ -254,6 +262,19 @@ class GearboxSDK {
|
|
|
254
262
|
}
|
|
255
263
|
await this.#attach(this.#attachConfig);
|
|
256
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* Rehydrate existing SDK from new state without re-creating instance
|
|
267
|
+
*/
|
|
268
|
+
rehydrate(state) {
|
|
269
|
+
if (!this.#attachConfig) {
|
|
270
|
+
throw new Error("cannot rehydrate, attach config is not set");
|
|
271
|
+
}
|
|
272
|
+
const opts = {
|
|
273
|
+
ignoreUpdateablePrices: this.#attachConfig.ignoreUpdateablePrices,
|
|
274
|
+
redstone: this.#attachConfig.redstone
|
|
275
|
+
};
|
|
276
|
+
this.#hydrate(opts, state);
|
|
277
|
+
}
|
|
257
278
|
/**
|
|
258
279
|
* Converts contract call into some human-friendly string
|
|
259
280
|
* This method is safe and should not throw
|
|
@@ -59,9 +59,6 @@ class MarketSuite extends import_base.SDKConstruct {
|
|
|
59
59
|
this.creditManagers.push(new import_credit.CreditSuite(sdk, marketData, i));
|
|
60
60
|
}
|
|
61
61
|
this.priceOracle = (0, import_oracle.getOrCreatePriceOracle)(sdk, marketData.priceOracle);
|
|
62
|
-
sdk.logger?.debug(
|
|
63
|
-
`oracle ${this.labelAddress(this.priceOracle.address)} has ${this.priceOracle.mainPriceFeeds.size} main and ${this.priceOracle.reservePriceFeeds.size} reserve price feeds`
|
|
64
|
-
);
|
|
65
62
|
}
|
|
66
63
|
get dirty() {
|
|
67
64
|
return this.configurator.dirty || this.pool.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
|
|
@@ -28,16 +28,20 @@ var import_PriceOracleV310Contract = require("./PriceOracleV310Contract.js");
|
|
|
28
28
|
function getOrCreatePriceOracle(sdk, data) {
|
|
29
29
|
const { version, addr } = data.baseParams;
|
|
30
30
|
const existing = sdk.contracts.get(addr);
|
|
31
|
+
let result;
|
|
31
32
|
if (existing) {
|
|
32
|
-
|
|
33
|
+
result = tryExtendExistingOracle(existing, data);
|
|
34
|
+
} else if ((0, import_constants.isV300)(version)) {
|
|
35
|
+
result = new import_PriceOracleV300Contract.PriceOracleV300Contract(sdk, data);
|
|
36
|
+
} else if ((0, import_constants.isV310)(version)) {
|
|
37
|
+
result = new import_PriceOracleV310Contract.PriceOracleV310Contract(sdk, data);
|
|
38
|
+
} else {
|
|
39
|
+
throw new Error(`Unsupported oracle version ${version}`);
|
|
33
40
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return new import_PriceOracleV310Contract.PriceOracleV310Contract(sdk, data);
|
|
39
|
-
}
|
|
40
|
-
throw new Error(`Unsupported oracle version ${version}`);
|
|
41
|
+
sdk.logger?.debug(
|
|
42
|
+
`oracle ${addr} v${version} was ${existing ? "extended" : "created"} with ${result.mainPriceFeeds.size} main and ${result.reservePriceFeeds.size} reserve price feeds`
|
|
43
|
+
);
|
|
44
|
+
return result;
|
|
41
45
|
}
|
|
42
46
|
function tryExtendExistingOracle(existing, data) {
|
|
43
47
|
const { version, addr } = data.baseParams;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { json_parse } from "../sdk/index.js";
|
|
2
|
+
class CachedStateSubscriber {
|
|
3
|
+
#stateURL;
|
|
4
|
+
#etag;
|
|
5
|
+
#currentBlock;
|
|
6
|
+
#sdk;
|
|
7
|
+
constructor(sdk, stateURL) {
|
|
8
|
+
this.#stateURL = stateURL;
|
|
9
|
+
this.#sdk = sdk;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Subscribe to sdk state changes
|
|
13
|
+
* @param opts - Options
|
|
14
|
+
* @returns Unsubscribe function
|
|
15
|
+
*/
|
|
16
|
+
subscribe(opts) {
|
|
17
|
+
const intervalMs = opts?.pollInterval ?? 10 * 60 * 1e3;
|
|
18
|
+
const interval = setInterval(async () => {
|
|
19
|
+
const newBlock = await this.#poll();
|
|
20
|
+
if (newBlock && opts?.onChange) {
|
|
21
|
+
opts.onChange(newBlock);
|
|
22
|
+
}
|
|
23
|
+
}, intervalMs);
|
|
24
|
+
return () => clearInterval(interval);
|
|
25
|
+
}
|
|
26
|
+
async #poll() {
|
|
27
|
+
try {
|
|
28
|
+
const head = await fetch(this.#stateURL, { method: "HEAD" });
|
|
29
|
+
const etag = head.headers.get("ETag");
|
|
30
|
+
if (!etag || etag === this.#etag) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const response = await fetch(this.#stateURL);
|
|
34
|
+
const txt = await response.text();
|
|
35
|
+
const state = json_parse(txt);
|
|
36
|
+
if (state.currentBlock === this.#currentBlock) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.#etag = etag;
|
|
40
|
+
this.#currentBlock = state.currentBlock;
|
|
41
|
+
this.#logger?.debug(`rehydrating state at block ${state.currentBlock}`);
|
|
42
|
+
this.#sdk.rehydrate(state);
|
|
43
|
+
return state.currentBlock;
|
|
44
|
+
} catch (e) {
|
|
45
|
+
this.#logger?.error(e, "error while polling cached state");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
get #logger() {
|
|
49
|
+
return this.#sdk.logger;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
CachedStateSubscriber
|
|
54
|
+
};
|
package/dist/esm/dev/index.js
CHANGED
|
@@ -208,15 +208,22 @@ class GearboxSDK {
|
|
|
208
208
|
return this;
|
|
209
209
|
}
|
|
210
210
|
#hydrate(options, state) {
|
|
211
|
-
const { logger: _logger,
|
|
211
|
+
const { logger: _logger, ...opts } = options;
|
|
212
212
|
if (state.version !== STATE_VERSION) {
|
|
213
213
|
throw new Error(
|
|
214
214
|
`hydrated state version is ${state.version}, but expected ${STATE_VERSION}`
|
|
215
215
|
);
|
|
216
216
|
}
|
|
217
|
+
const re = this.#attachConfig ? "re" : "";
|
|
218
|
+
this.logger?.info(
|
|
219
|
+
{
|
|
220
|
+
networkType: this.provider.networkType
|
|
221
|
+
},
|
|
222
|
+
`${re}hydrating sdk state`
|
|
223
|
+
);
|
|
217
224
|
this.#currentBlock = state.currentBlock;
|
|
218
225
|
this.#timestamp = state.timestamp;
|
|
219
|
-
this.#priceFeeds = new PriceFeedRegister(this, { redstone });
|
|
226
|
+
this.#priceFeeds = new PriceFeedRegister(this, { redstone: opts.redstone });
|
|
220
227
|
this.#addressProvider = hydrateAddressProvider(this, state.addressProvider);
|
|
221
228
|
this.logger?.debug(
|
|
222
229
|
`address provider version: ${this.#addressProvider.version}`
|
|
@@ -240,6 +247,7 @@ class GearboxSDK {
|
|
|
240
247
|
plugin.hydrate(pluginState);
|
|
241
248
|
}
|
|
242
249
|
}
|
|
250
|
+
this.logger?.info(`${re}hydrated sdk state`);
|
|
243
251
|
return this;
|
|
244
252
|
}
|
|
245
253
|
/**
|
|
@@ -252,6 +260,19 @@ class GearboxSDK {
|
|
|
252
260
|
}
|
|
253
261
|
await this.#attach(this.#attachConfig);
|
|
254
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Rehydrate existing SDK from new state without re-creating instance
|
|
265
|
+
*/
|
|
266
|
+
rehydrate(state) {
|
|
267
|
+
if (!this.#attachConfig) {
|
|
268
|
+
throw new Error("cannot rehydrate, attach config is not set");
|
|
269
|
+
}
|
|
270
|
+
const opts = {
|
|
271
|
+
ignoreUpdateablePrices: this.#attachConfig.ignoreUpdateablePrices,
|
|
272
|
+
redstone: this.#attachConfig.redstone
|
|
273
|
+
};
|
|
274
|
+
this.#hydrate(opts, state);
|
|
275
|
+
}
|
|
255
276
|
/**
|
|
256
277
|
* Converts contract call into some human-friendly string
|
|
257
278
|
* This method is safe and should not throw
|
|
@@ -36,9 +36,6 @@ class MarketSuite extends SDKConstruct {
|
|
|
36
36
|
this.creditManagers.push(new CreditSuite(sdk, marketData, i));
|
|
37
37
|
}
|
|
38
38
|
this.priceOracle = getOrCreatePriceOracle(sdk, marketData.priceOracle);
|
|
39
|
-
sdk.logger?.debug(
|
|
40
|
-
`oracle ${this.labelAddress(this.priceOracle.address)} has ${this.priceOracle.mainPriceFeeds.size} main and ${this.priceOracle.reservePriceFeeds.size} reserve price feeds`
|
|
41
|
-
);
|
|
42
39
|
}
|
|
43
40
|
get dirty() {
|
|
44
41
|
return this.configurator.dirty || this.pool.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
|
|
@@ -5,16 +5,20 @@ import { PriceOracleV310Contract } from "./PriceOracleV310Contract.js";
|
|
|
5
5
|
function getOrCreatePriceOracle(sdk, data) {
|
|
6
6
|
const { version, addr } = data.baseParams;
|
|
7
7
|
const existing = sdk.contracts.get(addr);
|
|
8
|
+
let result;
|
|
8
9
|
if (existing) {
|
|
9
|
-
|
|
10
|
+
result = tryExtendExistingOracle(existing, data);
|
|
11
|
+
} else if (isV300(version)) {
|
|
12
|
+
result = new PriceOracleV300Contract(sdk, data);
|
|
13
|
+
} else if (isV310(version)) {
|
|
14
|
+
result = new PriceOracleV310Contract(sdk, data);
|
|
15
|
+
} else {
|
|
16
|
+
throw new Error(`Unsupported oracle version ${version}`);
|
|
10
17
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return new PriceOracleV310Contract(sdk, data);
|
|
16
|
-
}
|
|
17
|
-
throw new Error(`Unsupported oracle version ${version}`);
|
|
18
|
+
sdk.logger?.debug(
|
|
19
|
+
`oracle ${addr} v${version} was ${existing ? "extended" : "created"} with ${result.mainPriceFeeds.size} main and ${result.reservePriceFeeds.size} reserve price feeds`
|
|
20
|
+
);
|
|
21
|
+
return result;
|
|
18
22
|
}
|
|
19
23
|
function tryExtendExistingOracle(existing, data) {
|
|
20
24
|
const { version, addr } = data.baseParams;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { GearboxSDK, PluginsMap } from "../sdk/index.js";
|
|
2
|
+
export interface CachedStateSubscriberOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Polling interval in milliseconds
|
|
5
|
+
*/
|
|
6
|
+
pollInterval?: number;
|
|
7
|
+
/**
|
|
8
|
+
* Callback to be called when state changes
|
|
9
|
+
*/
|
|
10
|
+
onChange?: (blockNumber: bigint) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare class CachedStateSubscriber<const Plugins extends PluginsMap = {}> {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(sdk: GearboxSDK<Plugins>, stateURL: string);
|
|
15
|
+
/**
|
|
16
|
+
* Subscribe to sdk state changes
|
|
17
|
+
* @param opts - Options
|
|
18
|
+
* @returns Unsubscribe function
|
|
19
|
+
*/
|
|
20
|
+
subscribe(opts?: CachedStateSubscriberOptions): () => void;
|
|
21
|
+
}
|
|
@@ -92,6 +92,10 @@ export declare class GearboxSDK<const Plugins extends PluginsMap = {}> {
|
|
|
92
92
|
* Be mindful of block number, for example
|
|
93
93
|
*/
|
|
94
94
|
reattach(): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Rehydrate existing SDK from new state without re-creating instance
|
|
97
|
+
*/
|
|
98
|
+
rehydrate(state: GearboxState<Plugins>): void;
|
|
95
99
|
/**
|
|
96
100
|
* Converts contract call into some human-friendly string
|
|
97
101
|
* This method is safe and should not throw
|