@suilend/sdk 13.1.0 → 13.4.0-next.g390db54
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/package.json +1 -1
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/priceGuard.d.ts +15 -0
- package/utils/priceGuard.js +48 -0
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@suilend/sdk","version":"13.
|
|
1
|
+
{"name":"@suilend/sdk","version":"13.4.0-next.g390db54","private":false,"description":"A TypeScript SDK for interacting with the Suilend program","author":"Suilend","license":"MIT","main":"./index.js","exports":{".":"./index.js","./client":"./client.js","./mmt":"./mmt.js","./strategies":"./strategies.js","./api/events":"./api/events.js","./api":"./api/index.js","./lib/constants":"./lib/constants.js","./lib":"./lib/index.js","./lib/initialize":"./lib/initialize.js","./lib/liquidityMining":"./lib/liquidityMining.js","./lib/proCompatible":"./lib/proCompatible.js","./lib/pyth":"./lib/pyth.js","./lib/strategyOwnerCap":"./lib/strategyOwnerCap.js","./lib/transactions":"./lib/transactions.js","./lib/types":"./lib/types.js","./margin":"./margin/index.js","./parsers/apiReserveAssetDataEvent":"./parsers/apiReserveAssetDataEvent.js","./parsers":"./parsers/index.js","./parsers/lendingMarket":"./parsers/lendingMarket.js","./parsers/obligation":"./parsers/obligation.js","./parsers/rateLimiter":"./parsers/rateLimiter.js","./parsers/reserve":"./parsers/reserve.js","./swap":"./swap/index.js","./swap/quote":"./swap/quote.js","./swap/transaction":"./swap/transaction.js","./utils/events":"./utils/events.js","./utils/feedId":"./utils/feedId.js","./utils":"./utils/index.js","./utils/obligation":"./utils/obligation.js","./utils/priceGuard":"./utils/priceGuard.js","./utils/simulate":"./utils/simulate.js","./_generated/_envs":"./_generated/_envs/index.js","./_generated/_envs/mainnet":"./_generated/_envs/mainnet.js","./_generated/_framework/env":"./_generated/_framework/env.js","./_generated/_framework/reified":"./_generated/_framework/reified.js","./_generated/_framework/util":"./_generated/_framework/util.js","./_generated/_framework/vector":"./_generated/_framework/vector.js","./_generated/suilend":"./_generated/suilend/index.js","./margin/margin/admin_cap":"./margin/margin/admin_cap.js","./margin/margin/market":"./margin/margin/market.js","./margin/margin/permissions":"./margin/margin/permissions.js","./margin/margin/position":"./margin/margin/position.js","./margin/margin/router":"./margin/margin/router.js","./margin/margin/version":"./margin/margin/version.js","./margin/utils":"./margin/utils/index.js","./_generated/suilend/cell/structs":"./_generated/suilend/cell/structs.js","./_generated/suilend/decimal/structs":"./_generated/suilend/decimal/structs.js","./_generated/suilend/lending-market/functions":"./_generated/suilend/lending-market/functions.js","./_generated/suilend/lending-market/structs":"./_generated/suilend/lending-market/structs.js","./_generated/suilend/lending-market-registry/functions":"./_generated/suilend/lending-market-registry/functions.js","./_generated/suilend/liquidity-mining/structs":"./_generated/suilend/liquidity-mining/structs.js","./_generated/suilend/obligation/structs":"./_generated/suilend/obligation/structs.js","./_generated/suilend/rate-limiter/functions":"./_generated/suilend/rate-limiter/functions.js","./_generated/suilend/rate-limiter/structs":"./_generated/suilend/rate-limiter/structs.js","./_generated/suilend/reserve/structs":"./_generated/suilend/reserve/structs.js","./_generated/suilend/reserve-config/functions":"./_generated/suilend/reserve-config/functions.js","./_generated/suilend/reserve-config/structs":"./_generated/suilend/reserve-config/structs.js","./_generated/_dependencies/pyth-2/price-identifier/structs":"./_generated/_dependencies/pyth-2/price-identifier/structs.js","./_generated/_dependencies/std/ascii/structs":"./_generated/_dependencies/std/ascii/structs.js","./_generated/_dependencies/std/option/structs":"./_generated/_dependencies/std/option/structs.js","./_generated/_dependencies/std/type-name/structs":"./_generated/_dependencies/std/type-name/structs.js","./_generated/_dependencies/sui/bag/structs":"./_generated/_dependencies/sui/bag/structs.js","./_generated/_dependencies/sui/balance/structs":"./_generated/_dependencies/sui/balance/structs.js","./_generated/_dependencies/sui/object/structs":"./_generated/_dependencies/sui/object/structs.js","./_generated/_dependencies/sui/object-table/structs":"./_generated/_dependencies/sui/object-table/structs.js","./margin/margin/deps/std/type_name":"./margin/margin/deps/std/type_name.js","./margin/margin/deps/sui/vec_set":"./margin/margin/deps/sui/vec_set.js","./margin/margin/deps/suilend/lending_market":"./margin/margin/deps/suilend/lending_market.js"},"types":"./index.d.ts","scripts":{"codegen":"node ./codegen.js","codegen:install":"node ./install-codegen.js","build":"rm -rf ./dist && tsc && node ./fix-esm-imports.js","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.test.json","test":"vitest run","lint:ci":"yarn run typecheck","prettier":"prettier --write src/ tests/","release":"yarn run build && node ./release.js && cd ./dist && npm publish --access public"},"repository":{"type":"git","url":"git+https://github.com/fireflyprotocol/lending-mono.git","directory":"ts/sdks/sdk"},"dependencies":{"@bluefin-exchange/bluefin7k-aggregator-sdk":"7.6.3","@cetusprotocol/aggregator-sdk":"1.7.3","@flowx-finance/sdk":"2.1.0","@pythnetwork/hermes-client":"3.1.0","@pythnetwork/pyth-sui-js":"4.0.0","@suilend/springsui-sdk":"4.1.0","bignumber.js":"11.1.5","bn.js":"5.2.5","crypto-js":"4.2.0","lodash":"4.18.1","p-limit":"7.3.3","uuid":"14.0.2"},"devDependencies":{"@mysten/bcs":"2.1.2","@mysten/sui":"2.33.1","@suilend/sui-core":"2.1.0","@tsconfig/recommended":"1.0.13","@types/bn.js":"5.2.0","@types/lodash":"4.17.25","@types/node":"26.6.4","fast-check":"4.10.2","prettier":"3.9.9","ts-node":"10.9.2","typescript":"6.0.3","vite":"8.3.2","vitest":"5.0.3"},"peerDependencies":{"@mysten/bcs":"^2.1.1","@mysten/sui":">=2.22.1 <3","@suilend/sui-core":"^2.0.1"},"type":"module"}
|
package/utils/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import BigNumber from "bignumber.js";
|
|
|
2
2
|
import { ParsedReserve } from "../parsers/reserve";
|
|
3
3
|
export * from "./events";
|
|
4
4
|
export * from "./obligation";
|
|
5
|
+
export * from "./priceGuard";
|
|
5
6
|
export * from "./simulate";
|
|
6
7
|
export declare const toHexString: (bytes: number[]) => string;
|
|
7
8
|
export declare const reserveSort: (reserves: ParsedReserve[], aCoinType: string, bCoinType: string) => number;
|
package/utils/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
2
|
export * from "./events.js";
|
|
3
3
|
export * from "./obligation.js";
|
|
4
|
+
export * from "./priceGuard.js";
|
|
4
5
|
export * from "./simulate.js";
|
|
5
6
|
export const toHexString = (bytes) => Array.from(bytes, function (byte) {
|
|
6
7
|
return ("0" + (byte & 0xff).toString(16)).slice(-2);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type PriceGuardState = {
|
|
2
|
+
maxPriceChangeBps: bigint;
|
|
3
|
+
minUpdateIntervalS: bigint;
|
|
4
|
+
priceAnchor: bigint;
|
|
5
|
+
smoothedPriceAnchor: bigint;
|
|
6
|
+
anchorTimestampS: bigint;
|
|
7
|
+
};
|
|
8
|
+
export declare const clampToBand: (anchor: bigint, price: bigint, bandBps: bigint) => bigint;
|
|
9
|
+
export declare const applyPriceGuard: (price: bigint, smoothedPrice: bigint, guard: PriceGuardState) => {
|
|
10
|
+
price: bigint;
|
|
11
|
+
smoothedPrice: bigint;
|
|
12
|
+
wasClamped: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare const decodePriceGuardField: (content: Uint8Array) => PriceGuardState;
|
|
15
|
+
export declare const priceGuardFieldId: (reserveId: string, typeOriginPackageId?: string) => string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { deriveDynamicFieldID } from "@mysten/sui/utils";
|
|
2
|
+
import { getTypeOrigin } from "../_generated/_framework/env.js";
|
|
3
|
+
import { PriceGuard } from "../_generated/suilend/reserve/structs.js";
|
|
4
|
+
const WAD = 10n ** 18n;
|
|
5
|
+
const BPS = 10000n;
|
|
6
|
+
// Every division floors, as Move's Decimal `mul` and `from_bps` do, so the edges match
|
|
7
|
+
// the chain for in-range inputs; Move's u256 overflow aborts are not modelled.
|
|
8
|
+
export const clampToBand = (anchor, price, bandBps) => {
|
|
9
|
+
if (bandBps === 0n || anchor === 0n)
|
|
10
|
+
return price;
|
|
11
|
+
const band = (bandBps * WAD) / BPS;
|
|
12
|
+
const lower = (anchor * (band >= WAD ? 0n : WAD - band)) / WAD;
|
|
13
|
+
const upper = (anchor * (WAD + band)) / WAD;
|
|
14
|
+
const atLeastLower = price > lower ? price : lower;
|
|
15
|
+
return atLeastLower < upper ? atLeastLower : upper;
|
|
16
|
+
};
|
|
17
|
+
// Models one refresh against the stored anchors. The chain advances the anchors after
|
|
18
|
+
// clamping, which this does not, so callers must re-read the guard instead of chaining results.
|
|
19
|
+
export const applyPriceGuard = (price, smoothedPrice, guard) => {
|
|
20
|
+
const clampedPrice = clampToBand(guard.priceAnchor, price, guard.maxPriceChangeBps);
|
|
21
|
+
const clampedSmoothedPrice = clampToBand(guard.smoothedPriceAnchor, smoothedPrice, guard.maxPriceChangeBps);
|
|
22
|
+
return {
|
|
23
|
+
price: clampedPrice,
|
|
24
|
+
smoothedPrice: clampedSmoothedPrice,
|
|
25
|
+
wasClamped: clampedPrice !== price || clampedSmoothedPrice !== smoothedPrice,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
const UID_BYTES = 32;
|
|
29
|
+
const EMPTY_KEY_BYTES = 1;
|
|
30
|
+
const PRICE_GUARD_BYTES = 8 + 8 + 32 + 32 + 8;
|
|
31
|
+
const FIELD_VALUE_OFFSET = UID_BYTES + EMPTY_KEY_BYTES;
|
|
32
|
+
const PRICE_GUARD_FIELD_BYTES = FIELD_VALUE_OFFSET + PRICE_GUARD_BYTES;
|
|
33
|
+
export const decodePriceGuardField = (content) => {
|
|
34
|
+
if (content.length !== PRICE_GUARD_FIELD_BYTES) {
|
|
35
|
+
throw new Error(`PriceGuard dynamic field must be ${PRICE_GUARD_FIELD_BYTES} bytes, got ${content.length}`);
|
|
36
|
+
}
|
|
37
|
+
const guard = PriceGuard.fromBcs(content.slice(FIELD_VALUE_OFFSET));
|
|
38
|
+
return {
|
|
39
|
+
maxPriceChangeBps: guard.maxPriceChangeBps,
|
|
40
|
+
minUpdateIntervalS: guard.minUpdateIntervalS,
|
|
41
|
+
priceAnchor: guard.priceAnchor.value,
|
|
42
|
+
smoothedPriceAnchor: guard.smoothedPriceAnchor.value,
|
|
43
|
+
anchorTimestampS: guard.anchorTimestampS,
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
// The dynamic field's key type is addressed by the package that first defined it, which
|
|
47
|
+
// is not the package the rest of the reserve module lives at.
|
|
48
|
+
export const priceGuardFieldId = (reserveId, typeOriginPackageId = getTypeOrigin("suilend", "reserve::PriceGuardKey")) => deriveDynamicFieldID(reserveId, `${typeOriginPackageId}::reserve::PriceGuardKey`, new Uint8Array([0]));
|