@affluent-org/sdk 0.0.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/.prettierrc +11 -0
- package/Refactoring.md +548 -0
- package/dist/_compiled/Account.compiled.json +1 -0
- package/dist/_compiled/Receipt.compiled.json +1 -0
- package/dist/_compiled/WTONWallet.compiled.json +1 -0
- package/dist/_compiled/index.d.ts +4 -0
- package/dist/_compiled/index.js +12 -0
- package/dist/affluent.d.ts +14 -0
- package/dist/affluent.js +20 -0
- package/dist/constants/constants.d.ts +2 -0
- package/dist/constants/constants.js +5 -0
- package/dist/constants/contracts.d.ts +9 -0
- package/dist/constants/contracts.js +18 -0
- package/dist/context.d.ts +43 -0
- package/dist/context.js +90 -0
- package/dist/contracts/common/type.d.ts +16 -0
- package/dist/contracts/common/type.js +2 -0
- package/dist/contracts/common/utils.d.ts +3 -0
- package/dist/contracts/common/utils.js +16 -0
- package/dist/contracts/core/account/index.d.ts +38 -0
- package/dist/contracts/core/account/index.js +128 -0
- package/dist/contracts/core/account/type.d.ts +18 -0
- package/dist/contracts/core/account/type.js +2 -0
- package/dist/contracts/core/pool/index.d.ts +149 -0
- package/dist/contracts/core/pool/index.js +379 -0
- package/dist/contracts/core/pool/serializer.d.ts +15 -0
- package/dist/contracts/core/pool/serializer.js +307 -0
- package/dist/contracts/core/pool/type.d.ts +136 -0
- package/dist/contracts/core/pool/type.js +2 -0
- package/dist/contracts/dedust-farm/MockDedustFarm.d.ts +41 -0
- package/dist/contracts/dedust-farm/MockDedustFarm.js +79 -0
- package/dist/contracts/external/tonstaker.d.ts +18 -0
- package/dist/contracts/external/tonstaker.js +26 -0
- package/dist/contracts/factory/factory.d.ts +24 -0
- package/dist/contracts/factory/factory.js +58 -0
- package/dist/contracts/factory/type.d.ts +11 -0
- package/dist/contracts/factory/type.js +2 -0
- package/dist/contracts/farm/distributor.d.ts +43 -0
- package/dist/contracts/farm/distributor.js +83 -0
- package/dist/contracts/farm/receipt.d.ts +40 -0
- package/dist/contracts/farm/receipt.js +68 -0
- package/dist/contracts/irm/jump-irm/serializer.d.ts +4 -0
- package/dist/contracts/irm/jump-irm/serializer.js +26 -0
- package/dist/contracts/irm/jump-irm/type.d.ts +8 -0
- package/dist/contracts/irm/jump-irm/type.js +2 -0
- package/dist/contracts/jetton/jetton-minter.d.ts +23 -0
- package/dist/contracts/jetton/jetton-minter.js +46 -0
- package/dist/contracts/jetton/jetton-wallet.d.ts +67 -0
- package/dist/contracts/jetton/jetton-wallet.js +119 -0
- package/dist/contracts/jetton/type.d.ts +7 -0
- package/dist/contracts/jetton/type.js +2 -0
- package/dist/contracts/liquid_token/dedust/minter.d.ts +56 -0
- package/dist/contracts/liquid_token/dedust/minter.js +112 -0
- package/dist/contracts/liquid_token/dedust/wallet.d.ts +127 -0
- package/dist/contracts/liquid_token/dedust/wallet.js +213 -0
- package/dist/contracts/liquid_token/stonfi/LFStonfiJettonMinter.d.ts +53 -0
- package/dist/contracts/liquid_token/stonfi/LFStonfiJettonMinter.js +110 -0
- package/dist/contracts/liquid_token/stonfi/LFStonfiJettonWallet.d.ts +169 -0
- package/dist/contracts/liquid_token/stonfi/LFStonfiJettonWallet.js +288 -0
- package/dist/contracts/oracle/composite-onchain-oracle/index.d.ts +108 -0
- package/dist/contracts/oracle/composite-onchain-oracle/index.js +185 -0
- package/dist/contracts/oracle/parser.d.ts +7 -0
- package/dist/contracts/oracle/parser.js +77 -0
- package/dist/contracts/oracle/redstone-onchain-oracle/index.d.ts +56 -0
- package/dist/contracts/oracle/redstone-onchain-oracle/index.js +159 -0
- package/dist/contracts/oracle/redstone-onchain-oracle/serializer.d.ts +4 -0
- package/dist/contracts/oracle/redstone-onchain-oracle/serializer.js +137 -0
- package/dist/contracts/oracle/redstone-onchain-oracle/type.d.ts +57 -0
- package/dist/contracts/oracle/redstone-onchain-oracle/type.js +18 -0
- package/dist/contracts/oracle/redstone-oracle/serializer.d.ts +3 -0
- package/dist/contracts/oracle/redstone-oracle/serializer.js +30 -0
- package/dist/contracts/oracle/redstone-oracle/type.d.ts +9 -0
- package/dist/contracts/oracle/redstone-oracle/type.js +2 -0
- package/dist/contracts/oracle/redstone-parser.d.ts +9 -0
- package/dist/contracts/oracle/redstone-parser.js +58 -0
- package/dist/contracts/rfq/rfq_auction/index.d.ts +216 -0
- package/dist/contracts/rfq/rfq_auction/index.js +334 -0
- package/dist/contracts/rfq/rfq_batch/index.d.ts +346 -0
- package/dist/contracts/rfq/rfq_batch/index.js +448 -0
- package/dist/contracts/rfq/rfq_event_emitter/index.d.ts +132 -0
- package/dist/contracts/rfq/rfq_event_emitter/index.js +143 -0
- package/dist/contracts/stonfi-farm/MockStonfiFarmItem.d.ts +41 -0
- package/dist/contracts/stonfi-farm/MockStonfiFarmItem.js +83 -0
- package/dist/contracts/stonfi-farm/MockStonfiFarmMinter.d.ts +45 -0
- package/dist/contracts/stonfi-farm/MockStonfiFarmMinter.js +92 -0
- package/dist/contracts/unknown-contract/index.d.ts +14 -0
- package/dist/contracts/unknown-contract/index.js +18 -0
- package/dist/contracts/vault/share-vault/index.d.ts +206 -0
- package/dist/contracts/vault/share-vault/index.js +373 -0
- package/dist/contracts/vault/strategy-vault/codec.d.ts +710 -0
- package/dist/contracts/vault/strategy-vault/codec.js +1256 -0
- package/dist/contracts/vault/strategy-vault/computation.d.ts +11 -0
- package/dist/contracts/vault/strategy-vault/computation.js +56 -0
- package/dist/contracts/vault/strategy-vault/constants.d.ts +163 -0
- package/dist/contracts/vault/strategy-vault/constants.js +170 -0
- package/dist/contracts/vault/strategy-vault/index.d.ts +587 -0
- package/dist/contracts/vault/strategy-vault/index.js +406 -0
- package/dist/contracts/vault/strategy-vault/type.d.ts +115 -0
- package/dist/contracts/vault/strategy-vault/type.js +2 -0
- package/dist/contracts/wton/jetton-minter.d.ts +35 -0
- package/dist/contracts/wton/jetton-minter.js +71 -0
- package/dist/contracts/wton/jetton-wallet.d.ts +90 -0
- package/dist/contracts/wton/jetton-wallet.js +153 -0
- package/dist/contracts/wton/type.d.ts +7 -0
- package/dist/contracts/wton/type.js +2 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +65 -0
- package/dist/lib/assert.d.ts +1 -0
- package/dist/lib/assert.js +9 -0
- package/dist/lib/query-cache.d.ts +5 -0
- package/dist/lib/query-cache.js +57 -0
- package/dist/lib/send-msg.d.ts +11 -0
- package/dist/lib/send-msg.js +9 -0
- package/dist/services/composite-oracle/computation.d.ts +55 -0
- package/dist/services/composite-oracle/computation.js +295 -0
- package/dist/services/composite-oracle/index.d.ts +45 -0
- package/dist/services/composite-oracle/index.js +110 -0
- package/dist/services/composite-oracle/query.d.ts +36 -0
- package/dist/services/composite-oracle/query.js +251 -0
- package/dist/services/composite-oracle/types.d.ts +82 -0
- package/dist/services/composite-oracle/types.js +11 -0
- package/dist/services/pool/computation.d.ts +75 -0
- package/dist/services/pool/computation.js +219 -0
- package/dist/services/pool/index.d.ts +94 -0
- package/dist/services/pool/index.js +139 -0
- package/dist/services/pool/oracle.d.ts +20 -0
- package/dist/services/pool/oracle.js +61 -0
- package/dist/services/pool/owner/index.d.ts +37 -0
- package/dist/services/pool/owner/index.js +76 -0
- package/dist/services/pool/owner/types.d.ts +18 -0
- package/dist/services/pool/owner/types.js +2 -0
- package/dist/services/pool/query.d.ts +64 -0
- package/dist/services/pool/query.js +282 -0
- package/dist/services/pool/user/index.d.ts +86 -0
- package/dist/services/pool/user/index.js +285 -0
- package/dist/services/pool/user/types.d.ts +44 -0
- package/dist/services/pool/user/types.js +2 -0
- package/dist/services/rfq-auction/index.d.ts +81 -0
- package/dist/services/rfq-auction/index.js +93 -0
- package/dist/services/rfq-auction/oracle.d.ts +19 -0
- package/dist/services/rfq-auction/oracle.js +60 -0
- package/dist/services/rfq-auction/query.d.ts +50 -0
- package/dist/services/rfq-auction/query.js +19 -0
- package/dist/services/rfq-auction/user/index.d.ts +63 -0
- package/dist/services/rfq-auction/user/index.js +218 -0
- package/dist/services/rfq-auction/user/types.d.ts +29 -0
- package/dist/services/rfq-auction/user/types.js +2 -0
- package/dist/services/rfq-batch/index.d.ts +78 -0
- package/dist/services/rfq-batch/index.js +132 -0
- package/dist/services/rfq-batch/oracle.d.ts +22 -0
- package/dist/services/rfq-batch/oracle.js +54 -0
- package/dist/services/rfq-batch/query.d.ts +46 -0
- package/dist/services/rfq-batch/query.js +34 -0
- package/dist/services/rfq-batch/user/index.d.ts +79 -0
- package/dist/services/rfq-batch/user/index.js +171 -0
- package/dist/services/rfq-batch/user/types.d.ts +37 -0
- package/dist/services/rfq-batch/user/types.js +2 -0
- package/dist/services/share-vault/computation.d.ts +24 -0
- package/dist/services/share-vault/computation.js +42 -0
- package/dist/services/share-vault/index.d.ts +90 -0
- package/dist/services/share-vault/index.js +128 -0
- package/dist/services/share-vault/manager/index.d.ts +40 -0
- package/dist/services/share-vault/manager/index.js +111 -0
- package/dist/services/share-vault/manager/types.d.ts +23 -0
- package/dist/services/share-vault/manager/types.js +2 -0
- package/dist/services/share-vault/owner/index.d.ts +64 -0
- package/dist/services/share-vault/owner/index.js +122 -0
- package/dist/services/share-vault/owner/types.d.ts +33 -0
- package/dist/services/share-vault/owner/types.js +2 -0
- package/dist/services/share-vault/query.d.ts +34 -0
- package/dist/services/share-vault/query.js +138 -0
- package/dist/services/share-vault/user/index.d.ts +33 -0
- package/dist/services/share-vault/user/index.js +106 -0
- package/dist/services/share-vault/user/types.d.ts +13 -0
- package/dist/services/share-vault/user/types.js +2 -0
- package/dist/services/strategy-vault/index.d.ts +2124 -0
- package/dist/services/strategy-vault/index.js +268 -0
- package/dist/services/strategy-vault/manager/index.d.ts +1968 -0
- package/dist/services/strategy-vault/manager/index.js +475 -0
- package/dist/services/strategy-vault/manager/types.d.ts +144 -0
- package/dist/services/strategy-vault/manager/types.js +2 -0
- package/dist/services/strategy-vault/oracle.d.ts +66 -0
- package/dist/services/strategy-vault/oracle.js +162 -0
- package/dist/services/strategy-vault/owner/index.d.ts +277 -0
- package/dist/services/strategy-vault/owner/index.js +333 -0
- package/dist/services/strategy-vault/owner/types.d.ts +146 -0
- package/dist/services/strategy-vault/owner/types.js +2 -0
- package/dist/services/strategy-vault/query.d.ts +138 -0
- package/dist/services/strategy-vault/query.js +59 -0
- package/dist/services/strategy-vault/user/index.d.ts +89 -0
- package/dist/services/strategy-vault/user/index.js +219 -0
- package/dist/services/strategy-vault/user/types.d.ts +46 -0
- package/dist/services/strategy-vault/user/types.js +2 -0
- package/dist/types/sender.d.ts +7 -0
- package/dist/types/sender.js +2 -0
- package/dist/utils/action-parser.d.ts +7 -0
- package/dist/utils/action-parser.js +20 -0
- package/dist/utils/external-message-hash.d.ts +45 -0
- package/dist/utils/external-message-hash.js +65 -0
- package/dist/utils/oracle/redstone/readonlyCachedRedstone.d.ts +3 -0
- package/dist/utils/oracle/redstone/readonlyCachedRedstone.js +25 -0
- package/dist/utils/oracle/redstone/redstoneHelper.d.ts +21 -0
- package/dist/utils/oracle/redstone/redstoneHelper.js +228 -0
- package/dist/utils/parser.d.ts +40 -0
- package/dist/utils/parser.js +580 -0
- package/dist/utils/pending-tracker/index.d.ts +14 -0
- package/dist/utils/pending-tracker/index.js +34 -0
- package/dist/utils/pending-tracker/trackable-sender.d.ts +16 -0
- package/dist/utils/pending-tracker/trackable-sender.js +87 -0
- package/dist/utils/pending-tracker/type.d.ts +78 -0
- package/dist/utils/pending-tracker/type.js +2 -0
- package/dist/utils/pending-tracker/v3-client.d.ts +31 -0
- package/dist/utils/pending-tracker/v3-client.js +104 -0
- package/dist/utils/risk_calculator/risk_calculator.d.ts +45 -0
- package/dist/utils/risk_calculator/risk_calculator.js +332 -0
- package/dist/utils/utils.d.ts +5 -0
- package/dist/utils/utils.js +12 -0
- package/package.json +46 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createTrackableSender = createTrackableSender;
|
|
37
|
+
exports.createTrackableSenderFromMnemonic = createTrackableSenderFromMnemonic;
|
|
38
|
+
const core_1 = require("@ton/core");
|
|
39
|
+
const ton_1 = require("@ton/ton");
|
|
40
|
+
const external_message_hash_1 = require("../external-message-hash");
|
|
41
|
+
/**
|
|
42
|
+
* Create a TrackableSender from wallet contract and key pair
|
|
43
|
+
*/
|
|
44
|
+
function createTrackableSender(config) {
|
|
45
|
+
const { client, wallet, keyPair } = config;
|
|
46
|
+
const openedWallet = client.open(wallet);
|
|
47
|
+
return {
|
|
48
|
+
address: wallet.address,
|
|
49
|
+
async getSeqno() {
|
|
50
|
+
try {
|
|
51
|
+
return await openedWallet.getSeqno();
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
async send(args) {
|
|
58
|
+
const seqno = await this.getSeqno();
|
|
59
|
+
const internalMessage = (0, core_1.internal)({
|
|
60
|
+
to: args.to,
|
|
61
|
+
value: args.value,
|
|
62
|
+
body: args.body,
|
|
63
|
+
bounce: args.bounce ?? true,
|
|
64
|
+
init: args.init,
|
|
65
|
+
});
|
|
66
|
+
const sendMode = args.sendMode ?? core_1.SendMode.PAY_GAS_SEPARATELY;
|
|
67
|
+
const signedBody = openedWallet.createTransfer({
|
|
68
|
+
seqno,
|
|
69
|
+
secretKey: keyPair.secretKey,
|
|
70
|
+
sendMode,
|
|
71
|
+
messages: [internalMessage],
|
|
72
|
+
});
|
|
73
|
+
const { hashHex } = (0, external_message_hash_1.computeExternalMessageHash)(wallet.address, signedBody);
|
|
74
|
+
await openedWallet.send(signedBody);
|
|
75
|
+
return { extMsgHash: hashHex, seqno };
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create a TrackableSender from mnemonic
|
|
81
|
+
*/
|
|
82
|
+
async function createTrackableSenderFromMnemonic(client, mnemonic, workchain = 0) {
|
|
83
|
+
const { mnemonicToWalletKey } = await Promise.resolve().then(() => __importStar(require("@ton/crypto")));
|
|
84
|
+
const keyPair = await mnemonicToWalletKey(mnemonic);
|
|
85
|
+
const wallet = ton_1.WalletContractV5R1.create({ publicKey: keyPair.publicKey, workchain });
|
|
86
|
+
return createTrackableSender({ client, wallet, keyPair });
|
|
87
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Address, SenderArguments } from "@ton/core";
|
|
2
|
+
/**
|
|
3
|
+
* Result from toncenter v3 pendingTraces API
|
|
4
|
+
*/
|
|
5
|
+
export interface PendingTraceResponse {
|
|
6
|
+
traces: PendingTrace[];
|
|
7
|
+
}
|
|
8
|
+
export interface PendingTrace {
|
|
9
|
+
id: string;
|
|
10
|
+
utime: number;
|
|
11
|
+
start_lt: string;
|
|
12
|
+
end_lt: string | null;
|
|
13
|
+
state: "pending" | "complete" | "failed";
|
|
14
|
+
transaction_count: number;
|
|
15
|
+
mc_seqno_start: number;
|
|
16
|
+
mc_seqno_end: number | null;
|
|
17
|
+
edges: TraceEdge[];
|
|
18
|
+
pending_edges: TraceEdge[];
|
|
19
|
+
nodes: TraceNode[];
|
|
20
|
+
}
|
|
21
|
+
export interface TraceEdge {
|
|
22
|
+
from_node: string;
|
|
23
|
+
to_node: string;
|
|
24
|
+
in_msg_hash: string;
|
|
25
|
+
out_msg_hash: string;
|
|
26
|
+
}
|
|
27
|
+
export interface TraceNode {
|
|
28
|
+
tx_hash: string;
|
|
29
|
+
account: string;
|
|
30
|
+
lt: string;
|
|
31
|
+
trace_id: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Simplified trace result for SDK consumers
|
|
35
|
+
*/
|
|
36
|
+
export interface TraceResult {
|
|
37
|
+
traceId: string;
|
|
38
|
+
state: "pending" | "complete" | "failed";
|
|
39
|
+
startLt: string;
|
|
40
|
+
endLt: string | null;
|
|
41
|
+
transactionCount: number;
|
|
42
|
+
transactions: TraceTransaction[];
|
|
43
|
+
}
|
|
44
|
+
export interface TraceTransaction {
|
|
45
|
+
txHash: string;
|
|
46
|
+
account: Address;
|
|
47
|
+
lt: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Options for waiting on pending traces
|
|
51
|
+
*/
|
|
52
|
+
export interface WaitOptions {
|
|
53
|
+
/** Maximum time to wait in milliseconds (default: 120000 = 2 minutes) */
|
|
54
|
+
timeout?: number;
|
|
55
|
+
/** Polling interval in milliseconds (default: 2000 = 2 seconds) */
|
|
56
|
+
pollInterval?: number;
|
|
57
|
+
/** Callback for each poll attempt */
|
|
58
|
+
onPoll?: (attempt: number, elapsed: number) => void;
|
|
59
|
+
/** Callback when trace state changes */
|
|
60
|
+
onStateChange?: (state: "pending" | "complete" | "failed") => void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Send result with tracking info
|
|
64
|
+
*/
|
|
65
|
+
export interface SendResult {
|
|
66
|
+
/** External message hash for tracking */
|
|
67
|
+
extMsgHash: string;
|
|
68
|
+
/** Seqno used for the transaction */
|
|
69
|
+
seqno: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Trackable sender that exposes external message hash
|
|
73
|
+
*/
|
|
74
|
+
export interface TrackableSender {
|
|
75
|
+
readonly address: Address;
|
|
76
|
+
send(args: SenderArguments): Promise<SendResult>;
|
|
77
|
+
getSeqno(): Promise<number>;
|
|
78
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PendingTraceResponse, TraceResult, WaitOptions } from "./type";
|
|
2
|
+
/**
|
|
3
|
+
* Toncenter v3 API endpoints
|
|
4
|
+
*/
|
|
5
|
+
declare const ENDPOINTS: {
|
|
6
|
+
readonly mainnet: "https://toncenter.com/api/v3";
|
|
7
|
+
readonly testnet: "https://testnet.toncenter.com/api/v3";
|
|
8
|
+
};
|
|
9
|
+
export type Network = keyof typeof ENDPOINTS;
|
|
10
|
+
/**
|
|
11
|
+
* Toncenter v3 API client for pending traces
|
|
12
|
+
*/
|
|
13
|
+
export declare class ToncenterV3Client {
|
|
14
|
+
private baseUrl;
|
|
15
|
+
private apiKey?;
|
|
16
|
+
constructor(network: Network | string, apiKey?: string);
|
|
17
|
+
private fetch;
|
|
18
|
+
/**
|
|
19
|
+
* Get pending traces by external message hash
|
|
20
|
+
*/
|
|
21
|
+
getPendingTraces(extMsgHash: string): Promise<PendingTraceResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Convert raw trace to simplified TraceResult
|
|
24
|
+
*/
|
|
25
|
+
private toTraceResult;
|
|
26
|
+
/**
|
|
27
|
+
* Wait for a pending trace to complete
|
|
28
|
+
*/
|
|
29
|
+
waitForTrace(extMsgHash: string, options?: WaitOptions): Promise<TraceResult>;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ToncenterV3Client = void 0;
|
|
4
|
+
const core_1 = require("@ton/core");
|
|
5
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
6
|
+
/**
|
|
7
|
+
* Toncenter v3 API endpoints
|
|
8
|
+
*/
|
|
9
|
+
const ENDPOINTS = {
|
|
10
|
+
mainnet: "https://toncenter.com/api/v3",
|
|
11
|
+
testnet: "https://testnet.toncenter.com/api/v3",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Toncenter v3 API client for pending traces
|
|
15
|
+
*/
|
|
16
|
+
class ToncenterV3Client {
|
|
17
|
+
baseUrl;
|
|
18
|
+
apiKey;
|
|
19
|
+
constructor(network, apiKey) {
|
|
20
|
+
this.baseUrl = network in ENDPOINTS ? ENDPOINTS[network] : network;
|
|
21
|
+
this.apiKey = apiKey;
|
|
22
|
+
}
|
|
23
|
+
async fetch(path) {
|
|
24
|
+
const url = `${this.baseUrl}${path}`;
|
|
25
|
+
const headers = {
|
|
26
|
+
Accept: "application/json",
|
|
27
|
+
};
|
|
28
|
+
if (this.apiKey) {
|
|
29
|
+
headers["X-API-Key"] = this.apiKey;
|
|
30
|
+
}
|
|
31
|
+
const response = await fetch(url, { headers });
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
throw new Error(`Toncenter v3 API error: ${response.status} ${response.statusText}`);
|
|
34
|
+
}
|
|
35
|
+
return response.json();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get pending traces by external message hash
|
|
39
|
+
*/
|
|
40
|
+
async getPendingTraces(extMsgHash) {
|
|
41
|
+
return this.fetch(`/pendingTraces?ext_msg_hash=${extMsgHash}`);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Convert raw trace to simplified TraceResult
|
|
45
|
+
*/
|
|
46
|
+
toTraceResult(trace) {
|
|
47
|
+
return {
|
|
48
|
+
traceId: trace.id,
|
|
49
|
+
state: trace.state,
|
|
50
|
+
startLt: trace.start_lt,
|
|
51
|
+
endLt: trace.end_lt,
|
|
52
|
+
transactionCount: trace.transaction_count,
|
|
53
|
+
transactions: trace.nodes.map((node) => ({
|
|
54
|
+
txHash: node.tx_hash,
|
|
55
|
+
account: core_1.Address.parse(node.account),
|
|
56
|
+
lt: node.lt,
|
|
57
|
+
})),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Wait for a pending trace to complete
|
|
62
|
+
*/
|
|
63
|
+
async waitForTrace(extMsgHash, options = {}) {
|
|
64
|
+
const { timeout = 120000, pollInterval = 2000, onPoll, onStateChange } = options;
|
|
65
|
+
const startTime = Date.now();
|
|
66
|
+
let attempt = 0;
|
|
67
|
+
let lastState = null;
|
|
68
|
+
while (true) {
|
|
69
|
+
const elapsed = Date.now() - startTime;
|
|
70
|
+
if (elapsed > timeout) {
|
|
71
|
+
throw new Error(`Timeout waiting for trace: ${extMsgHash}`);
|
|
72
|
+
}
|
|
73
|
+
attempt++;
|
|
74
|
+
onPoll?.(attempt, elapsed);
|
|
75
|
+
try {
|
|
76
|
+
const response = await this.getPendingTraces(extMsgHash);
|
|
77
|
+
if (response.traces.length > 0) {
|
|
78
|
+
const trace = response.traces[0];
|
|
79
|
+
if (trace.state !== lastState) {
|
|
80
|
+
lastState = trace.state;
|
|
81
|
+
onStateChange?.(trace.state);
|
|
82
|
+
}
|
|
83
|
+
if (trace.state === "complete") {
|
|
84
|
+
return this.toTraceResult(trace);
|
|
85
|
+
}
|
|
86
|
+
if (trace.state === "failed") {
|
|
87
|
+
throw new Error(`Transaction failed: ${extMsgHash}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
// Ignore fetch errors and retry
|
|
93
|
+
if (error instanceof Error && error.message.startsWith("Timeout")) {
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
if (error instanceof Error && error.message.startsWith("Transaction failed")) {
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
await sleep(pollInterval);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.ToncenterV3Client = ToncenterV3Client;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AccountAssetState, AccountAssetStateWithDelta } from "../../contracts/core/account/type";
|
|
2
|
+
import { AssetPrice, AssetPriceInfo, OnchainDataInfo } from "../../contracts/oracle/redstone-onchain-oracle/type";
|
|
3
|
+
import { PoolState } from "../../contracts/core/pool/type";
|
|
4
|
+
export declare class RiskCalculator {
|
|
5
|
+
accountStatus: Record<string, AccountAssetState>;
|
|
6
|
+
prices: AssetPriceInfo;
|
|
7
|
+
onchainData: OnchainDataInfo;
|
|
8
|
+
poolData: PoolState;
|
|
9
|
+
PRICE_DECIMALS: number;
|
|
10
|
+
DELTA_DECIMALS: number;
|
|
11
|
+
RATIO_DECIMALS: number;
|
|
12
|
+
LEVERAGE_DECIMALS: number;
|
|
13
|
+
constructor(accountStatus: Record<string, AccountAssetState>, prices: AssetPriceInfo, onchainData: OnchainDataInfo, poolData: PoolState);
|
|
14
|
+
calculateDeltaForTargetRiskRatio(_targetRiskRatio: bigint, // ex : 6000n
|
|
15
|
+
targetAsset: string, dualAsset?: string): SolutionForTargetRatio[];
|
|
16
|
+
calculateDeltaForTargetLeverage(_targetLeverage: bigint, // ex : 6000n
|
|
17
|
+
targetAsset: string, action: "supply" | "borrow", dualAsset?: string): SolutionForTargetLeverage;
|
|
18
|
+
getAssetStatesWithDelta(decomposedStatus: Record<string, Omit<AccountAssetStateWithDelta, "address">>): AssetStateWithDelta[];
|
|
19
|
+
decomposeAccountStatusWithDelta(accountStatus: Record<string, AccountAssetState>, targetAsset: string, dualAsset?: string): Record<string, Omit<AccountAssetStateWithDelta, "address">>;
|
|
20
|
+
findDeltaSolutionsForTargetRatio(assetStates: AssetStateWithDelta[], targetRiskRatio: bigint): SolutionForTargetRatio[];
|
|
21
|
+
findDeltaSolutionForTargetLeverage(assetStates: AssetStateWithDelta[], targetLeverage: bigint, action: "supply" | "borrow"): SolutionForTargetLeverage;
|
|
22
|
+
}
|
|
23
|
+
export interface AssetStateWithDelta {
|
|
24
|
+
asset: string;
|
|
25
|
+
supply: bigint;
|
|
26
|
+
borrow: bigint;
|
|
27
|
+
deltaCoefficient: bigint;
|
|
28
|
+
threshold: bigint | null;
|
|
29
|
+
riskFactor: bigint;
|
|
30
|
+
price: AssetPrice;
|
|
31
|
+
isCollateral: boolean;
|
|
32
|
+
}
|
|
33
|
+
interface SolutionForTargetRatio {
|
|
34
|
+
delta: bigint;
|
|
35
|
+
interval: {
|
|
36
|
+
start: bigint;
|
|
37
|
+
end: bigint;
|
|
38
|
+
};
|
|
39
|
+
targetRiskRatio: bigint;
|
|
40
|
+
}
|
|
41
|
+
interface SolutionForTargetLeverage {
|
|
42
|
+
delta: bigint;
|
|
43
|
+
targetLeverage: bigint;
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RiskCalculator = void 0;
|
|
4
|
+
const type_1 = require("../../contracts/oracle/redstone-onchain-oracle/type");
|
|
5
|
+
const core_1 = require("@ton/core");
|
|
6
|
+
class RiskCalculator {
|
|
7
|
+
accountStatus;
|
|
8
|
+
prices;
|
|
9
|
+
onchainData;
|
|
10
|
+
poolData;
|
|
11
|
+
PRICE_DECIMALS = 8;
|
|
12
|
+
DELTA_DECIMALS = 18;
|
|
13
|
+
RATIO_DECIMALS = 4;
|
|
14
|
+
LEVERAGE_DECIMALS = 4;
|
|
15
|
+
constructor(accountStatus, prices, onchainData, poolData) {
|
|
16
|
+
this.accountStatus = accountStatus;
|
|
17
|
+
this.prices = prices;
|
|
18
|
+
this.onchainData = onchainData;
|
|
19
|
+
this.poolData = poolData;
|
|
20
|
+
const assetAddresses = Object.keys(poolData.assets);
|
|
21
|
+
for (const assetAddress of assetAddresses) {
|
|
22
|
+
if (!this.accountStatus[assetAddress]) {
|
|
23
|
+
this.accountStatus[assetAddress] = {
|
|
24
|
+
address: core_1.Address.parse(assetAddress),
|
|
25
|
+
supply: 0n,
|
|
26
|
+
borrow: 0n,
|
|
27
|
+
};
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
calculateDeltaForTargetRiskRatio(_targetRiskRatio, // ex : 6000n
|
|
33
|
+
targetAsset, dualAsset) {
|
|
34
|
+
const decomposedStatusWithDelta = this.decomposeAccountStatusWithDelta(this.accountStatus, targetAsset, dualAsset);
|
|
35
|
+
const assetStatesWithDelta = this.getAssetStatesWithDelta(decomposedStatusWithDelta);
|
|
36
|
+
const solutions = this.findDeltaSolutionsForTargetRatio(assetStatesWithDelta, _targetRiskRatio);
|
|
37
|
+
return solutions;
|
|
38
|
+
}
|
|
39
|
+
calculateDeltaForTargetLeverage(_targetLeverage, // ex : 6000n
|
|
40
|
+
targetAsset, action, dualAsset) {
|
|
41
|
+
const decomposedStatusWithDelta = this.decomposeAccountStatusWithDelta(this.accountStatus, targetAsset, dualAsset);
|
|
42
|
+
const assetStatesWithDelta = this.getAssetStatesWithDelta(decomposedStatusWithDelta);
|
|
43
|
+
const solution = this.findDeltaSolutionForTargetLeverage(assetStatesWithDelta, _targetLeverage, action);
|
|
44
|
+
return solution;
|
|
45
|
+
}
|
|
46
|
+
getAssetStatesWithDelta(decomposedStatus) {
|
|
47
|
+
const assetStatesWithDelta = Object.entries(decomposedStatus).map(([assetAddress, state]) => {
|
|
48
|
+
const assetPrice = this.prices[assetAddress];
|
|
49
|
+
let threshold = null;
|
|
50
|
+
if (state.deltaCoefficient !== 0n) {
|
|
51
|
+
threshold = ((state.borrow - state.supply) * 10n ** BigInt(this.DELTA_DECIMALS)) / state.deltaCoefficient;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
threshold = null;
|
|
55
|
+
}
|
|
56
|
+
const riskFactor = this.poolData.assets[assetAddress].riskFactor;
|
|
57
|
+
return {
|
|
58
|
+
asset: assetAddress,
|
|
59
|
+
supply: state.supply,
|
|
60
|
+
borrow: state.borrow,
|
|
61
|
+
deltaCoefficient: state.deltaCoefficient,
|
|
62
|
+
threshold: threshold,
|
|
63
|
+
riskFactor: riskFactor,
|
|
64
|
+
price: assetPrice,
|
|
65
|
+
isCollateral: this.poolData.assets[assetAddress].isCollateral,
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
return assetStatesWithDelta;
|
|
69
|
+
}
|
|
70
|
+
// 내부 헬퍼 메서드들
|
|
71
|
+
decomposeAccountStatusWithDelta(accountStatus, targetAsset, dualAsset) {
|
|
72
|
+
const accumStatus = {};
|
|
73
|
+
const assetAddresses = Object.keys(accountStatus);
|
|
74
|
+
let userAssets;
|
|
75
|
+
if (!assetAddresses.includes(targetAsset)) {
|
|
76
|
+
throw new Error("Target asset not found in account status");
|
|
77
|
+
}
|
|
78
|
+
if (dualAsset) {
|
|
79
|
+
const targetAssetPrice = this.prices[targetAsset].price;
|
|
80
|
+
const dualAssetPrice = this.prices[dualAsset].price;
|
|
81
|
+
if (!targetAssetPrice || !dualAssetPrice) {
|
|
82
|
+
throw new Error("Dual asset price not found");
|
|
83
|
+
}
|
|
84
|
+
// const dualDeltaCoefficient = targetAssetPrice / dualAssetPrice;
|
|
85
|
+
const dualDeltaCoefficient = (10n ** BigInt(this.DELTA_DECIMALS) * targetAssetPrice) / dualAssetPrice;
|
|
86
|
+
userAssets = Object.values(accountStatus).map((asset) => {
|
|
87
|
+
let initialDeltaCoefficient = 0n;
|
|
88
|
+
if (asset.address.toString() === dualAsset) {
|
|
89
|
+
initialDeltaCoefficient = dualDeltaCoefficient;
|
|
90
|
+
}
|
|
91
|
+
if (asset.address.toString() === targetAsset) {
|
|
92
|
+
initialDeltaCoefficient = 10n ** BigInt(this.DELTA_DECIMALS);
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
...asset,
|
|
96
|
+
deltaCoefficient: initialDeltaCoefficient,
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
userAssets = Object.values(accountStatus).map((asset) => ({
|
|
102
|
+
...asset,
|
|
103
|
+
deltaCoefficient: asset.address.toString() === targetAsset ? 10n ** BigInt(this.DELTA_DECIMALS) : 0n,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
while (userAssets.length !== 0) {
|
|
107
|
+
const restUserAssets = [];
|
|
108
|
+
for (let i = 0; i < userAssets.length; i++) {
|
|
109
|
+
const state = userAssets[i];
|
|
110
|
+
if (state.supply > 0n || state.borrow > 0n || state.deltaCoefficient > 0n) {
|
|
111
|
+
if (!accumStatus[userAssets[i].address.toString()])
|
|
112
|
+
accumStatus[userAssets[i].address.toString()] = {
|
|
113
|
+
supply: 0n,
|
|
114
|
+
borrow: 0n,
|
|
115
|
+
deltaCoefficient: 0n,
|
|
116
|
+
};
|
|
117
|
+
if (state.supply > 0n) {
|
|
118
|
+
accumStatus[userAssets[i].address.toString()].supply += state.supply;
|
|
119
|
+
}
|
|
120
|
+
if (state.borrow > 0n) {
|
|
121
|
+
accumStatus[userAssets[i].address.toString()].borrow += state.borrow;
|
|
122
|
+
}
|
|
123
|
+
if (state.deltaCoefficient !== 0n) {
|
|
124
|
+
accumStatus[userAssets[i].address.toString()].deltaCoefficient += state.deltaCoefficient;
|
|
125
|
+
}
|
|
126
|
+
const onchainDataInfo = this.onchainData[state.address.toString()];
|
|
127
|
+
if (!onchainDataInfo && !this.prices[state.address.toString()])
|
|
128
|
+
throw "not found onchain data info2";
|
|
129
|
+
if (onchainDataInfo) {
|
|
130
|
+
if (onchainDataInfo.assetType === type_1.AssetType.SingleAsset &&
|
|
131
|
+
onchainDataInfo.underlyingReserve &&
|
|
132
|
+
onchainDataInfo.totalSupply) {
|
|
133
|
+
const underlyingSupply = (state.supply * onchainDataInfo.underlyingReserve) / onchainDataInfo.totalSupply;
|
|
134
|
+
const underlyingBorrow = (state.borrow * onchainDataInfo.underlyingReserve) / onchainDataInfo.totalSupply;
|
|
135
|
+
const underlyingDelta = (state.deltaCoefficient * onchainDataInfo.underlyingReserve) / onchainDataInfo.totalSupply;
|
|
136
|
+
restUserAssets.push({
|
|
137
|
+
address: onchainDataInfo.underlyingAddress,
|
|
138
|
+
supply: underlyingSupply,
|
|
139
|
+
borrow: underlyingBorrow,
|
|
140
|
+
deltaCoefficient: underlyingDelta,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else if (onchainDataInfo.assetType === type_1.AssetType.MultiAsset &&
|
|
144
|
+
onchainDataInfo.underlying0Reserve &&
|
|
145
|
+
onchainDataInfo.underlying1Reserve &&
|
|
146
|
+
onchainDataInfo.totalSupply) {
|
|
147
|
+
const underlying0Supply = (state.supply * onchainDataInfo.underlying0Reserve) / onchainDataInfo.totalSupply;
|
|
148
|
+
const underlying0Borrow = (state.borrow * onchainDataInfo.underlying0Reserve) / onchainDataInfo.totalSupply;
|
|
149
|
+
const underlying0Delta = (state.deltaCoefficient * onchainDataInfo.underlying0Reserve) / onchainDataInfo.totalSupply;
|
|
150
|
+
const underlying1Supply = (state.supply * onchainDataInfo.underlying1Reserve) / onchainDataInfo.totalSupply;
|
|
151
|
+
const underlying1Borrow = (state.borrow * onchainDataInfo.underlying1Reserve) / onchainDataInfo.totalSupply;
|
|
152
|
+
const underlying1Delta = (state.deltaCoefficient * onchainDataInfo.underlying1Reserve) / onchainDataInfo.totalSupply;
|
|
153
|
+
restUserAssets.push({
|
|
154
|
+
address: onchainDataInfo.underlying0Address,
|
|
155
|
+
supply: underlying0Supply,
|
|
156
|
+
borrow: underlying0Borrow,
|
|
157
|
+
deltaCoefficient: underlying0Delta,
|
|
158
|
+
});
|
|
159
|
+
restUserAssets.push({
|
|
160
|
+
address: onchainDataInfo.underlying1Address,
|
|
161
|
+
supply: underlying1Supply,
|
|
162
|
+
borrow: underlying1Borrow,
|
|
163
|
+
deltaCoefficient: underlying1Delta,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else if (this.prices[state.address.toString()]?.type === type_1.AssetType.VaultAsset) {
|
|
168
|
+
const priceData = this.prices[state.address.toString()];
|
|
169
|
+
const decomposed = priceData.additionalData.decomposed;
|
|
170
|
+
const totalSupply = priceData.additionalData.totalSupply;
|
|
171
|
+
for (const asset of Object.keys(decomposed)) {
|
|
172
|
+
const underlyingSupply = (state.supply * decomposed[asset].supply) / totalSupply +
|
|
173
|
+
(state.borrow * decomposed[asset].borrow) / totalSupply;
|
|
174
|
+
const underlyingBorrow = (state.supply * decomposed[asset].borrow) / totalSupply +
|
|
175
|
+
(state.borrow * decomposed[asset].supply) / totalSupply;
|
|
176
|
+
const underlyingSupplyDelta = (state.deltaCoefficient * decomposed[asset].supply) / totalSupply;
|
|
177
|
+
const underlyingBorrowDelta = (state.deltaCoefficient * decomposed[asset].borrow) / totalSupply;
|
|
178
|
+
const underlyingDelta = underlyingSupplyDelta - underlyingBorrowDelta;
|
|
179
|
+
restUserAssets.push({
|
|
180
|
+
address: core_1.Address.parse(asset),
|
|
181
|
+
supply: underlyingSupply,
|
|
182
|
+
borrow: underlyingBorrow,
|
|
183
|
+
deltaCoefficient: underlyingDelta,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
userAssets = restUserAssets;
|
|
190
|
+
}
|
|
191
|
+
return accumStatus;
|
|
192
|
+
}
|
|
193
|
+
findDeltaSolutionsForTargetRatio(assetStates, targetRiskRatio) {
|
|
194
|
+
const sortedThresholds = [
|
|
195
|
+
...new Set([...assetStates].map((state) => state.threshold).filter((t) => t !== null)),
|
|
196
|
+
].sort((a, b) => Number(a - b));
|
|
197
|
+
const solutions = [];
|
|
198
|
+
for (let i = 0; i <= sortedThresholds.length; i++) {
|
|
199
|
+
const maxBigint = 1n << 255n;
|
|
200
|
+
const intervalStart = i === 0 ? -maxBigint : sortedThresholds[i - 1];
|
|
201
|
+
const intervalEnd = i === sortedThresholds.length ? maxBigint : sortedThresholds[i];
|
|
202
|
+
const nominatorConstant = assetStates.reduce((sum, state) => {
|
|
203
|
+
const netPosition = state.supply - state.borrow;
|
|
204
|
+
if (state.threshold === null) {
|
|
205
|
+
const absoluteNetPosition = netPosition > 0n ? netPosition : -netPosition;
|
|
206
|
+
return (sum +
|
|
207
|
+
(absoluteNetPosition * state.price.price * state.riskFactor) /
|
|
208
|
+
BigInt(10 ** (this.PRICE_DECIMALS + this.RATIO_DECIMALS)));
|
|
209
|
+
}
|
|
210
|
+
const sign = state.threshold === null || state.threshold <= intervalStart ? 1n : -1n;
|
|
211
|
+
return (sum +
|
|
212
|
+
(sign * (netPosition * state.price.price * state.riskFactor)) /
|
|
213
|
+
BigInt(10 ** (this.PRICE_DECIMALS + this.RATIO_DECIMALS)));
|
|
214
|
+
}, 0n);
|
|
215
|
+
const nominatorCoefficient = assetStates.reduce((sum, state) => {
|
|
216
|
+
const sign = state.threshold === null || state.threshold <= intervalStart ? 1n : -1n;
|
|
217
|
+
return (sum +
|
|
218
|
+
(sign * (state.deltaCoefficient * state.riskFactor * state.price.price)) /
|
|
219
|
+
BigInt(10 ** (this.PRICE_DECIMALS + this.RATIO_DECIMALS)));
|
|
220
|
+
}, 0n);
|
|
221
|
+
const denominatorConstant = assetStates.reduce((sum, state) => {
|
|
222
|
+
if (!state.isCollateral || state.price.type !== type_1.AssetType.Native)
|
|
223
|
+
return sum;
|
|
224
|
+
const netPosition = state.supply - state.borrow;
|
|
225
|
+
return sum + (netPosition * state.price.price) / BigInt(10 ** this.PRICE_DECIMALS);
|
|
226
|
+
}, 0n);
|
|
227
|
+
const denominatorCoefficient = assetStates.reduce((sum, state) => {
|
|
228
|
+
if (!state.isCollateral || state.price.type !== type_1.AssetType.Native)
|
|
229
|
+
return sum;
|
|
230
|
+
return sum + (state.deltaCoefficient * state.price.price) / BigInt(10 ** this.PRICE_DECIMALS);
|
|
231
|
+
}, 0n);
|
|
232
|
+
// 분자 0 Case
|
|
233
|
+
if (nominatorCoefficient === 0n && nominatorConstant === 0n) {
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
236
|
+
// 분모 0 Case
|
|
237
|
+
if (denominatorCoefficient === 0n && denominatorConstant === 0n) {
|
|
238
|
+
return [];
|
|
239
|
+
}
|
|
240
|
+
const nominator = BigInt(10 ** this.RATIO_DECIMALS) * nominatorConstant - targetRiskRatio * denominatorConstant;
|
|
241
|
+
const denominator = targetRiskRatio * denominatorCoefficient - nominatorCoefficient * BigInt(10 ** this.RATIO_DECIMALS);
|
|
242
|
+
if (denominator === 0n) {
|
|
243
|
+
throw new Error("Denominator cannot be zero");
|
|
244
|
+
}
|
|
245
|
+
const deltaSolution = (nominator * BigInt(10 ** this.DELTA_DECIMALS)) / denominator;
|
|
246
|
+
let currentRisk = 0n;
|
|
247
|
+
if (intervalStart === sortedThresholds[sortedThresholds.length - 1] &&
|
|
248
|
+
intervalEnd === maxBigint &&
|
|
249
|
+
denominatorConstant !== 0n) {
|
|
250
|
+
currentRisk = (nominatorConstant * BigInt(10 ** this.RATIO_DECIMALS)) / denominatorConstant;
|
|
251
|
+
}
|
|
252
|
+
if (currentRisk === targetRiskRatio) {
|
|
253
|
+
return [
|
|
254
|
+
{
|
|
255
|
+
delta: 0n,
|
|
256
|
+
interval: {
|
|
257
|
+
start: intervalStart,
|
|
258
|
+
end: intervalEnd,
|
|
259
|
+
},
|
|
260
|
+
targetRiskRatio: targetRiskRatio,
|
|
261
|
+
},
|
|
262
|
+
];
|
|
263
|
+
}
|
|
264
|
+
// 구간 내에 있는 delta만 solutions에 추가
|
|
265
|
+
if (deltaSolution >= intervalStart && deltaSolution < intervalEnd) {
|
|
266
|
+
solutions.push({
|
|
267
|
+
delta: deltaSolution,
|
|
268
|
+
interval: {
|
|
269
|
+
start: intervalStart,
|
|
270
|
+
end: intervalEnd,
|
|
271
|
+
},
|
|
272
|
+
targetRiskRatio: targetRiskRatio,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return solutions;
|
|
277
|
+
}
|
|
278
|
+
findDeltaSolutionForTargetLeverage(assetStates, targetLeverage, action) {
|
|
279
|
+
const nominatorConstant = assetStates.reduce((sum, state) => {
|
|
280
|
+
if (!state.isCollateral || state.price.type !== type_1.AssetType.Native)
|
|
281
|
+
return sum;
|
|
282
|
+
return sum + (state.supply * state.price.price) / BigInt(10 ** this.PRICE_DECIMALS);
|
|
283
|
+
}, 0n);
|
|
284
|
+
const nominatorCoefficient = assetStates.reduce((sum, state) => {
|
|
285
|
+
if (!state.isCollateral || state.price.type !== type_1.AssetType.Native)
|
|
286
|
+
return sum;
|
|
287
|
+
if (action === "borrow")
|
|
288
|
+
return sum;
|
|
289
|
+
return sum + (state.deltaCoefficient * state.price.price) / BigInt(10 ** this.PRICE_DECIMALS);
|
|
290
|
+
}, 0n);
|
|
291
|
+
const denominatorConstant = assetStates.reduce((sum, state) => {
|
|
292
|
+
if (!state.isCollateral || state.price.type !== type_1.AssetType.Native)
|
|
293
|
+
return sum;
|
|
294
|
+
const netPosition = state.supply - state.borrow;
|
|
295
|
+
return sum + (netPosition * state.price.price) / BigInt(10 ** this.PRICE_DECIMALS);
|
|
296
|
+
}, 0n);
|
|
297
|
+
const denominatorCoefficient = assetStates.reduce((sum, state) => {
|
|
298
|
+
if (!state.isCollateral || state.price.type !== type_1.AssetType.Native)
|
|
299
|
+
return sum;
|
|
300
|
+
const sign = action === "supply" ? 1n : -1n;
|
|
301
|
+
return sum + (sign * state.deltaCoefficient * state.price.price) / BigInt(10 ** this.PRICE_DECIMALS);
|
|
302
|
+
}, 0n);
|
|
303
|
+
// 분자 0 Case
|
|
304
|
+
if (nominatorCoefficient === 0n && nominatorConstant === 0n) {
|
|
305
|
+
return {
|
|
306
|
+
delta: 0n,
|
|
307
|
+
targetLeverage: targetLeverage,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
// 분모 0 Case
|
|
311
|
+
if (denominatorCoefficient === 0n && denominatorConstant === 0n) {
|
|
312
|
+
return {
|
|
313
|
+
delta: 0n,
|
|
314
|
+
targetLeverage: targetLeverage,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
const nominator = BigInt(10 ** this.LEVERAGE_DECIMALS) * nominatorConstant - targetLeverage * denominatorConstant;
|
|
318
|
+
const denominator = targetLeverage * denominatorCoefficient - nominatorCoefficient * BigInt(10 ** this.LEVERAGE_DECIMALS);
|
|
319
|
+
if (denominator === 0n) {
|
|
320
|
+
throw new Error("Denominator cannot be zero");
|
|
321
|
+
}
|
|
322
|
+
// const currentLeverage =
|
|
323
|
+
// (nominatorConstant * BigInt(10 ** this.LEVERAGE_DECIMALS)) /
|
|
324
|
+
// denominatorConstant;
|
|
325
|
+
const deltaSolution = (nominator * BigInt(10 ** this.DELTA_DECIMALS)) / denominator;
|
|
326
|
+
return {
|
|
327
|
+
delta: deltaSolution,
|
|
328
|
+
targetLeverage: targetLeverage,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
exports.RiskCalculator = RiskCalculator;
|