@affluent-org/sdk 0.0.2 → 0.0.3
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/build/Account.compiled.json +1 -0
- package/dist/build/Receipt.compiled.json +1 -0
- package/dist/build/WTONWallet.compiled.json +1 -0
- package/dist/common/cache.d.ts +16 -0
- package/dist/common/cache.js +96 -0
- package/dist/common/service.d.ts +20 -0
- package/dist/common/service.js +69 -0
- package/dist/common/type.d.ts +14 -0
- package/dist/common/type.js +2 -0
- package/dist/common/unknown-contract.d.ts +14 -0
- package/dist/common/unknown-contract.js +18 -0
- package/dist/common/versions.d.ts +14 -0
- package/dist/common/versions.js +22 -0
- package/dist/constants/pool.d.ts +1 -0
- package/dist/constants/pool.js +2 -0
- package/dist/contracts/_mock/simple-oracle.d.ts +34 -0
- package/dist/contracts/_mock/simple-oracle.js +73 -0
- package/dist/contracts/vault/share-vault/type.d.ts +30 -0
- package/dist/contracts/vault/share-vault/type.js +2 -0
- package/dist/contracts/vault/strategy-vault/utils.d.ts +6 -0
- package/dist/contracts/vault/strategy-vault/utils.js +32 -0
- package/dist/factorial.d.ts +14 -0
- package/dist/factorial.js +20 -0
- package/dist/farm.d.ts +92 -0
- package/dist/farm.js +209 -0
- package/dist/monitor.d.ts +57 -0
- package/dist/monitor.js +527 -0
- package/dist/monitorCacheV1.d.ts +52 -0
- package/dist/monitorCacheV1.js +504 -0
- package/dist/oracle/oracle-v2.d.ts +39 -0
- package/dist/oracle/oracle-v2.js +151 -0
- package/dist/oracle/oracle.d.ts +107 -0
- package/dist/oracle/oracle.js +392 -0
- package/dist/periphery.d.ts +259 -0
- package/dist/periphery.js +1087 -0
- package/dist/pool.d.ts +216 -0
- package/dist/pool.js +2298 -0
- package/dist/poolCacheV1.d.ts +139 -0
- package/dist/poolCacheV1.js +1841 -0
- package/dist/rfq-auction.d.ts +75 -0
- package/dist/rfq-auction.js +220 -0
- package/dist/rfq-batch.d.ts +112 -0
- package/dist/rfq-batch.js +284 -0
- package/dist/services/share-vault/computation.d.ts +14 -17
- package/dist/services/share-vault/computation.js +39 -0
- package/dist/services/share-vault/index.js +6 -3
- package/dist/services/share-vault/query.d.ts +38 -8
- package/dist/services/share-vault/query.js +20 -27
- package/dist/services/share-vault/type.d.ts +19 -0
- package/dist/services/share-vault/type.js +2 -0
- package/dist/services/share-vault/user/index.js +3 -1
- package/dist/services/strategy-vault/computation.d.ts +1 -0
- package/dist/services/strategy-vault/computation.js +15 -0
- package/dist/services/strategy-vault/query.d.ts +147 -0
- package/dist/services/strategy-vault/query.js +67 -0
- package/dist/services/strategy-vault/type.d.ts +2 -0
- package/dist/services/strategy-vault/type.js +2 -0
- package/dist/share-vault.d.ts +91 -0
- package/dist/share-vault.js +747 -0
- package/dist/stonfi.d.ts +18 -0
- package/dist/stonfi.js +76 -0
- package/dist/strategy_vault/base.d.ts +399 -0
- package/dist/strategy_vault/base.js +1199 -0
- package/dist/strategy_vault/index.d.ts +3 -0
- package/dist/strategy_vault/index.js +7 -0
- package/dist/strategy_vault/steps.d.ts +49 -0
- package/dist/strategy_vault/steps.js +170 -0
- package/dist/types/action.d.ts +55 -0
- package/dist/types/action.js +2 -0
- package/dist/types/messages.d.ts +7 -0
- package/dist/types/messages.js +2 -0
- package/dist/types/params.d.ts +19 -0
- package/dist/types/params.js +2 -0
- package/dist/types/pool.d.ts +83 -0
- package/dist/types/pool.js +2 -0
- package/dist/types/transaction.d.ts +40 -0
- package/dist/types/transaction.js +2 -0
- package/dist/utils/_parse_temp/JumpIRM.d.ts +37 -0
- package/dist/utils/_parse_temp/JumpIRM.js +71 -0
- package/dist/utils/_parse_temp/Pool.d.ts +559 -0
- package/dist/utils/_parse_temp/Pool.js +1023 -0
- package/dist/utils/_parse_temp/ShareVault.d.ts +264 -0
- package/dist/utils/_parse_temp/ShareVault.js +479 -0
- package/dist/utils/_parse_temp/StrategyVault.d.ts +729 -0
- package/dist/utils/_parse_temp/StrategyVault.js +1865 -0
- package/dist/utils/_parse_temp/parseMsgBody.d.ts +13 -0
- package/dist/utils/_parse_temp/parseMsgBody.js +313 -0
- package/dist/utils/assert.d.ts +1 -0
- package/dist/utils/assert.js +9 -0
- package/dist/utils/client-for-parameter.d.ts +12 -0
- package/dist/utils/client-for-parameter.js +97 -0
- package/dist/utils/oracle/index.d.ts +4 -0
- package/dist/utils/oracle/index.js +19 -0
- package/dist/utils/oracle/redstone/helper.d.ts +22 -0
- package/dist/utils/oracle/redstone/helper.js +186 -0
- package/dist/utils/tracer.d.ts +13 -0
- package/dist/utils/tracer.js +137 -0
- package/dist/utils/tracker/index.d.ts +5 -0
- package/dist/utils/tracker/index.js +118 -0
- package/dist/utils/tracker/query-id-generactor.d.ts +2 -0
- package/dist/utils/tracker/query-id-generactor.js +12 -0
- package/dist/utils/tracker/type.d.ts +34 -0
- package/dist/utils/tracker/type.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedstoneHelper = void 0;
|
|
4
|
+
exports.storeMetadata = storeMetadata;
|
|
5
|
+
exports.splitPayloadHex = splitPayloadHex;
|
|
6
|
+
exports.stringToBytes = stringToBytes;
|
|
7
|
+
exports.storeSignatureAndData = storeSignatureAndData;
|
|
8
|
+
exports.parseDataPackageHex = parseDataPackageHex;
|
|
9
|
+
const protocol_1 = require("@redstone-finance/protocol");
|
|
10
|
+
const sdk_1 = require("@redstone-finance/sdk");
|
|
11
|
+
const core_1 = require("@ton/core");
|
|
12
|
+
const serializeDict_1 = require("@ton/core/dist/dict/serializeDict");
|
|
13
|
+
const assert_1 = require("../../assert");
|
|
14
|
+
function storeMetadata(metadataHex, builder) {
|
|
15
|
+
const maxUnsignedDataLength = Math.floor(builder.availableBits / 8 -
|
|
16
|
+
(protocol_1.consts.REDSTONE_MARKER_BS +
|
|
17
|
+
protocol_1.consts.DATA_PACKAGES_COUNT_BS +
|
|
18
|
+
protocol_1.consts.UNSIGNED_METADATA_BYTE_SIZE_BS));
|
|
19
|
+
(0, assert_1.assert)(builder.availableBits >= metadataHex.length * 8, `Not enough bits available for metadata in builder. Unsigned metadata for this payload must not be larger than ${maxUnsignedDataLength}.`);
|
|
20
|
+
builder.storeBuilder(createBuilderFromString(metadataHex));
|
|
21
|
+
}
|
|
22
|
+
function createBuilderFromString(value) {
|
|
23
|
+
return (0, core_1.beginCell)().storeBuffer(Buffer.from(stringToBytes(value.startsWith("0x") ? value : "0x" + value)));
|
|
24
|
+
}
|
|
25
|
+
class RedstoneHelper {
|
|
26
|
+
dataServiceId;
|
|
27
|
+
uniqueSignersCount;
|
|
28
|
+
constructor(type) {
|
|
29
|
+
this.dataServiceId =
|
|
30
|
+
type === "demo" ? "redstone-main-demo" : "redstone-primary-prod";
|
|
31
|
+
this.uniqueSignersCount = type === "demo" ? 1 : 5;
|
|
32
|
+
}
|
|
33
|
+
/////////////////////////////////////////////
|
|
34
|
+
/////////////// CREATE PAYLOAD //////////////
|
|
35
|
+
async createPayload(assets) {
|
|
36
|
+
const paramsProvider = new sdk_1.ContractParamsProvider({
|
|
37
|
+
dataServiceId: this.dataServiceId,
|
|
38
|
+
uniqueSignersCount: this.uniqueSignersCount,
|
|
39
|
+
dataPackagesIds: assets,
|
|
40
|
+
});
|
|
41
|
+
const payloadHex = await paramsProvider.getPayloadHex(false);
|
|
42
|
+
const { dataPackageChunks, metadata } = splitPayloadHex(payloadHex);
|
|
43
|
+
const payloadCell = (0, core_1.beginCell)();
|
|
44
|
+
const cells = new Map();
|
|
45
|
+
for (let i = 0; i < dataPackageChunks.length; i++) {
|
|
46
|
+
cells.set(BigInt(i), dataPackageChunks[i]);
|
|
47
|
+
}
|
|
48
|
+
const dataPackagesDict = (0, core_1.beginCell)();
|
|
49
|
+
const BASE_KEY_LEN = 16;
|
|
50
|
+
(0, serializeDict_1.serializeDict)(cells, BASE_KEY_LEN, storeSignatureAndData, dataPackagesDict);
|
|
51
|
+
payloadCell.storeRef(dataPackagesDict);
|
|
52
|
+
storeMetadata(metadata, payloadCell);
|
|
53
|
+
return payloadCell.endCell();
|
|
54
|
+
}
|
|
55
|
+
async getPrices(assets) {
|
|
56
|
+
const paramsProvider = new sdk_1.ContractParamsProvider({
|
|
57
|
+
dataServiceId: this.dataServiceId,
|
|
58
|
+
uniqueSignersCount: this.uniqueSignersCount,
|
|
59
|
+
dataPackagesIds: assets,
|
|
60
|
+
});
|
|
61
|
+
const payloadHex = await paramsProvider.getPayloadHex(false);
|
|
62
|
+
const { dataPackageChunks, metadata } = splitPayloadHex(payloadHex);
|
|
63
|
+
const result = [];
|
|
64
|
+
for (let i = 0; i < dataPackageChunks.length; i++) {
|
|
65
|
+
result.push({
|
|
66
|
+
name: assets[i],
|
|
67
|
+
...parseDataPackageHex(dataPackageChunks[i]),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
/////////////////////////////////////////////
|
|
73
|
+
////////////// CREATE FEED_IDS //////////////
|
|
74
|
+
getHexlifiedFeedIds(assets) {
|
|
75
|
+
const paramsProvider = new sdk_1.ContractParamsProvider({
|
|
76
|
+
dataServiceId: this.dataServiceId,
|
|
77
|
+
uniqueSignersCount: this.uniqueSignersCount,
|
|
78
|
+
dataPackagesIds: assets,
|
|
79
|
+
});
|
|
80
|
+
return paramsProvider.getHexlifiedFeedIds();
|
|
81
|
+
}
|
|
82
|
+
getDataFeedIdTuples(assets) {
|
|
83
|
+
const dataFeedIdsTupleBuilder = new core_1.TupleBuilder();
|
|
84
|
+
this.getHexlifiedFeedIds(assets).forEach((item) => dataFeedIdsTupleBuilder.writeNumber(BigInt(item)));
|
|
85
|
+
return (0, core_1.serializeTuple)(dataFeedIdsTupleBuilder.build());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.RedstoneHelper = RedstoneHelper;
|
|
89
|
+
function splitPayloadHex(payloadHex) {
|
|
90
|
+
//TODO: assert value size == 32;
|
|
91
|
+
const DATA_PACKAGE_BS = protocol_1.consts.DATA_FEED_ID_BS +
|
|
92
|
+
protocol_1.consts.DEFAULT_NUM_VALUE_BS +
|
|
93
|
+
protocol_1.consts.TIMESTAMP_BS +
|
|
94
|
+
protocol_1.consts.DATA_POINTS_COUNT_BS +
|
|
95
|
+
protocol_1.consts.DATA_POINT_VALUE_BYTE_SIZE_BS +
|
|
96
|
+
protocol_1.consts.SIGNATURE_BS;
|
|
97
|
+
const unsignedMetadataBS = new BigNumber("0x" +
|
|
98
|
+
payloadHex.substring(payloadHex.length -
|
|
99
|
+
2 *
|
|
100
|
+
(protocol_1.consts.REDSTONE_MARKER_BS + protocol_1.consts.UNSIGNED_METADATA_BYTE_SIZE_BS), payloadHex.length - 2 * protocol_1.consts.REDSTONE_MARKER_BS)).toNumber();
|
|
101
|
+
const metadataBS = protocol_1.consts.REDSTONE_MARKER_BS +
|
|
102
|
+
protocol_1.consts.UNSIGNED_METADATA_BYTE_SIZE_BS +
|
|
103
|
+
unsignedMetadataBS +
|
|
104
|
+
protocol_1.consts.DATA_PACKAGES_COUNT_BS;
|
|
105
|
+
const metadata = payloadHex.substring(payloadHex.length - 2 * metadataBS, payloadHex.length);
|
|
106
|
+
const dataPackageCount = new BigNumber("0x" + metadata.substring(0, protocol_1.consts.DATA_PACKAGES_COUNT_BS * 2)).toNumber();
|
|
107
|
+
if (payloadHex.length - 2 * metadataBS !=
|
|
108
|
+
2 * DATA_PACKAGE_BS * dataPackageCount) {
|
|
109
|
+
throw "Must be implemented for multi-datapoint packages";
|
|
110
|
+
}
|
|
111
|
+
const dataPackageChunks = [];
|
|
112
|
+
for (let i = 0; i < dataPackageCount; i++) {
|
|
113
|
+
dataPackageChunks.push(payloadHex.substring(i * 2 * DATA_PACKAGE_BS, (i + 1) * 2 * DATA_PACKAGE_BS));
|
|
114
|
+
}
|
|
115
|
+
return { dataPackageChunks, metadata };
|
|
116
|
+
}
|
|
117
|
+
function stringToBytes(value) {
|
|
118
|
+
const hexArray = value
|
|
119
|
+
.slice(2)
|
|
120
|
+
.match(/.{1,2}/g)
|
|
121
|
+
?.map((byte) => parseInt(byte, 16));
|
|
122
|
+
const buffer = Buffer.from(hexArray);
|
|
123
|
+
return buffer;
|
|
124
|
+
}
|
|
125
|
+
function storeSignatureAndData(dataPackageHex, builder) {
|
|
126
|
+
const data = dataPackageHex.substring(0, dataPackageHex.length - 2 * protocol_1.consts.SIGNATURE_BS);
|
|
127
|
+
const signature = dataPackageHex.substring(dataPackageHex.length - 2 * protocol_1.consts.SIGNATURE_BS, dataPackageHex.length);
|
|
128
|
+
const v = BigInt("0x" + signature.substring(128, 130));
|
|
129
|
+
(0, assert_1.assert)([27, 28].map(BigInt).includes(v), `Wrong signature 'v' value (${v})`);
|
|
130
|
+
const signatureCell = (0, core_1.beginCell)()
|
|
131
|
+
.storeUint(BigInt("0x" + signature.substring(0, 64)), 256)
|
|
132
|
+
.storeUint(BigInt("0x" + signature.substring(64, 128)), 256)
|
|
133
|
+
.storeUint(v, 8)
|
|
134
|
+
.endCell();
|
|
135
|
+
console.assert(data.length / 2 <= 127, "Must be implemented for larger data");
|
|
136
|
+
const dataCell = (0, core_1.beginCell)()
|
|
137
|
+
.storeBuffer(Buffer.from(stringToBytes("0x" + data)))
|
|
138
|
+
.endCell();
|
|
139
|
+
builder.storeSlice(signatureCell.beginParse()).storeRef(dataCell);
|
|
140
|
+
}
|
|
141
|
+
function parseDataPackageHex(dataPackageHex) {
|
|
142
|
+
const data = dataPackageHex.substring(0, dataPackageHex.length - 2 * protocol_1.consts.SIGNATURE_BS);
|
|
143
|
+
const signature = dataPackageHex.substring(dataPackageHex.length - 2 * protocol_1.consts.SIGNATURE_BS, dataPackageHex.length);
|
|
144
|
+
const v = BigInt("0x" + signature.substring(128, 130));
|
|
145
|
+
(0, assert_1.assert)([27, 28].map(BigInt).includes(v), `Wrong signature 'v' value (${v})`);
|
|
146
|
+
const signatureCell = (0, core_1.beginCell)()
|
|
147
|
+
.storeUint(BigInt("0x" + signature.substring(0, 64)), 256)
|
|
148
|
+
.storeUint(BigInt("0x" + signature.substring(64, 128)), 256)
|
|
149
|
+
.storeUint(v, 8)
|
|
150
|
+
.endCell();
|
|
151
|
+
console.assert(data.length / 2 <= 127, "Must be implemented for larger data");
|
|
152
|
+
const dataCell = (0, core_1.beginCell)()
|
|
153
|
+
.storeBuffer(Buffer.from(stringToBytes("0x" + data)))
|
|
154
|
+
.endCell();
|
|
155
|
+
let skipLastBit = protocol_1.consts.DATA_POINTS_COUNT_BS * 8;
|
|
156
|
+
const dataPointsCount = dataCell
|
|
157
|
+
.asSlice()
|
|
158
|
+
.skip(dataCell.bits.length - skipLastBit)
|
|
159
|
+
.loadUintBig(protocol_1.consts.DATA_POINTS_COUNT_BS * 8);
|
|
160
|
+
skipLastBit += protocol_1.consts.DATA_POINT_VALUE_BYTE_SIZE_BS * 8;
|
|
161
|
+
const dataPointValueByteSize = dataCell
|
|
162
|
+
.asSlice()
|
|
163
|
+
.skip(dataCell.bits.length - skipLastBit)
|
|
164
|
+
.loadUintBig(protocol_1.consts.DATA_POINT_VALUE_BYTE_SIZE_BS * 8);
|
|
165
|
+
skipLastBit += protocol_1.consts.TIMESTAMP_BS * 8;
|
|
166
|
+
const timestamp = dataCell
|
|
167
|
+
.asSlice()
|
|
168
|
+
.skip(dataCell.bits.length - skipLastBit)
|
|
169
|
+
.loadUintBig(protocol_1.consts.TIMESTAMP_BS * 8);
|
|
170
|
+
skipLastBit += Number(dataPointValueByteSize) * 8;
|
|
171
|
+
const value = dataCell
|
|
172
|
+
.asSlice()
|
|
173
|
+
.skip(dataCell.bits.length - skipLastBit)
|
|
174
|
+
.loadUintBig(Number(dataPointValueByteSize) * 8);
|
|
175
|
+
let feedId = dataCell.asSlice().loadUintBig(protocol_1.consts.DATA_FEED_ID_BS * 8);
|
|
176
|
+
if (feedId != 0n) {
|
|
177
|
+
while (feedId == (feedId / 256n) * 256n) {
|
|
178
|
+
feedId = feedId / 256n;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
timestamp,
|
|
183
|
+
price: value,
|
|
184
|
+
feedId,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Address, Transaction } from "@ton/core";
|
|
2
|
+
import { TonClient } from "@ton/ton";
|
|
3
|
+
export declare class Tracer {
|
|
4
|
+
client: TonClient;
|
|
5
|
+
constructor(client: TonClient);
|
|
6
|
+
traceActionNotificaitonTx(tx: Transaction): Promise<(import("..").SuccessActionNotificationMsgBody | import("..").SuccessLiquidateActionNotificationMsgBody | import("..").FailTransferInActionNotificationMsgBody | import("..").FailLiquidateActionNotificationMsgBody | import("..").FailTransferOutActionNotificationMsgBody)[]>;
|
|
7
|
+
traverseOutgoingTransactions(transaction: Transaction): Promise<Transaction[]>;
|
|
8
|
+
findOutgoingTransactions(transaction: Transaction): Promise<Transaction[]>;
|
|
9
|
+
findInternalTx(src: Address, dst: Address, createdLt: string): Promise<Transaction>;
|
|
10
|
+
getExternalTx(target: Address, lt: bigint): Promise<Transaction | undefined>;
|
|
11
|
+
getLastExternalTx(target: Address, limit: number, minTime: bigint): Promise<Transaction>;
|
|
12
|
+
waitLastExternalTx(target: Address, limit: number, minTime: bigint, timeout: number): Promise<Transaction>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Tracer = void 0;
|
|
4
|
+
const pool_1 = require("../contracts/core/pool");
|
|
5
|
+
const serializer_1 = require("../contracts/core/pool/serializer");
|
|
6
|
+
const jetton_wallet_1 = require("../contracts/jetton/jetton-wallet");
|
|
7
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
8
|
+
class Tracer {
|
|
9
|
+
client;
|
|
10
|
+
constructor(client) {
|
|
11
|
+
this.client = client;
|
|
12
|
+
}
|
|
13
|
+
async traceActionNotificaitonTx(tx) {
|
|
14
|
+
const txs = await this.traverseOutgoingTransactions(tx);
|
|
15
|
+
return txs
|
|
16
|
+
.map((item) => item.inMessage && parseActionNotification(item.inMessage.body))
|
|
17
|
+
.filter((item) => !!item);
|
|
18
|
+
}
|
|
19
|
+
async traverseOutgoingTransactions(transaction) {
|
|
20
|
+
const txs = [];
|
|
21
|
+
const outTxs = await this.findOutgoingTransactions(transaction);
|
|
22
|
+
txs.push(...outTxs);
|
|
23
|
+
for (const out of outTxs) {
|
|
24
|
+
const _outTxs = await this.traverseOutgoingTransactions(out);
|
|
25
|
+
txs.push(..._outTxs);
|
|
26
|
+
}
|
|
27
|
+
return txs;
|
|
28
|
+
}
|
|
29
|
+
async findOutgoingTransactions(transaction) {
|
|
30
|
+
const outMessagesInfos = transaction.outMessages
|
|
31
|
+
.values()
|
|
32
|
+
.map((message) => message.info)
|
|
33
|
+
.filter((info) => info.type === "internal");
|
|
34
|
+
return Promise.all(outMessagesInfos.map((info) => {
|
|
35
|
+
return this.findInternalTx(info.src, info.dest, info.createdLt.toString());
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
async findInternalTx(src, dst, createdLt) {
|
|
39
|
+
const startTime = Date.now();
|
|
40
|
+
while (true) {
|
|
41
|
+
if (Date.now() - startTime > 60 * 1000)
|
|
42
|
+
throw "timeout";
|
|
43
|
+
const txs = await this.client.getTransactions(dst, {
|
|
44
|
+
limit: 100,
|
|
45
|
+
lt: createdLt,
|
|
46
|
+
archival: true,
|
|
47
|
+
});
|
|
48
|
+
const tx = txs.find((item) => {
|
|
49
|
+
if (item.inMessage?.info.type === "internal" &&
|
|
50
|
+
item.inMessage.info.src.equals(src) &&
|
|
51
|
+
BigInt(createdLt) === item.inMessage.info.createdLt) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
if (tx)
|
|
56
|
+
return tx;
|
|
57
|
+
await sleep(5000);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async getExternalTx(target, lt) {
|
|
61
|
+
const txs = await this.client.getTransactions(target, { limit: 20 });
|
|
62
|
+
const externalTx = txs.filter((item) => item.inMessage?.info.type === "external-in" && item.lt === lt)[0];
|
|
63
|
+
if (externalTx)
|
|
64
|
+
return externalTx;
|
|
65
|
+
}
|
|
66
|
+
async getLastExternalTx(target, limit, minTime) {
|
|
67
|
+
const txs = await this.client.getTransactions(target, { limit: limit });
|
|
68
|
+
const externalTx = txs.filter((item) => item.inMessage?.info.type === "external-in" && item.now >= minTime)[0];
|
|
69
|
+
return externalTx;
|
|
70
|
+
}
|
|
71
|
+
async waitLastExternalTx(target, limit, minTime, timeout) {
|
|
72
|
+
const startTime = Date.now();
|
|
73
|
+
while (true) {
|
|
74
|
+
try {
|
|
75
|
+
if (Date.now() - startTime > timeout * 1000)
|
|
76
|
+
throw null;
|
|
77
|
+
const externalTx = await this.getLastExternalTx(target, limit, minTime);
|
|
78
|
+
if (externalTx)
|
|
79
|
+
return externalTx;
|
|
80
|
+
}
|
|
81
|
+
catch (e) { }
|
|
82
|
+
await sleep(5000);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.Tracer = Tracer;
|
|
87
|
+
function parseActionNotification(cell) {
|
|
88
|
+
const ds = cell.beginParse();
|
|
89
|
+
const opCode = ds.loadUint(32);
|
|
90
|
+
if (opCode !== pool_1.Pool.Op.actionNotification)
|
|
91
|
+
return null;
|
|
92
|
+
const queryId = ds.loadUint(64);
|
|
93
|
+
const actionOpCode = ds.loadUint(32);
|
|
94
|
+
const errorCode = ds.loadUint(16);
|
|
95
|
+
if (errorCode === 0) {
|
|
96
|
+
if (actionOpCode === pool_1.Pool.Op.supply) {
|
|
97
|
+
return (0, serializer_1.parseSuccessActionNotificationMsgBody)(cell);
|
|
98
|
+
}
|
|
99
|
+
else if (actionOpCode === pool_1.Pool.Op.withdraw) {
|
|
100
|
+
return (0, serializer_1.parseSuccessActionNotificationMsgBody)(cell);
|
|
101
|
+
}
|
|
102
|
+
else if (actionOpCode === pool_1.Pool.Op.borrow) {
|
|
103
|
+
return (0, serializer_1.parseSuccessActionNotificationMsgBody)(cell);
|
|
104
|
+
}
|
|
105
|
+
else if (actionOpCode === pool_1.Pool.Op.repay) {
|
|
106
|
+
return (0, serializer_1.parseSuccessRepayActionNotificationMsgBody)(cell);
|
|
107
|
+
}
|
|
108
|
+
else if (actionOpCode === pool_1.Pool.Op.liquidate) {
|
|
109
|
+
return (0, serializer_1.parseSuccessLiquidationActionNotificationMsgBody)(cell);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
if (actionOpCode === jetton_wallet_1.JettonWallet.Op.TransferNotification) {
|
|
114
|
+
ds.loadCoins();
|
|
115
|
+
ds.loadAddress();
|
|
116
|
+
const forwardDS = ds.loadRef().beginParse();
|
|
117
|
+
forwardDS.loadAddress();
|
|
118
|
+
const subOp = forwardDS.loadUint(32);
|
|
119
|
+
if (subOp === pool_1.Pool.Op.supply) {
|
|
120
|
+
return (0, serializer_1.parseFailTransferInActionNotificationMsgBody)(cell);
|
|
121
|
+
}
|
|
122
|
+
else if (subOp === pool_1.Pool.Op.repay) {
|
|
123
|
+
return (0, serializer_1.parseFailTransferInActionNotificationMsgBody)(cell);
|
|
124
|
+
}
|
|
125
|
+
else if (subOp === pool_1.Pool.Op.liquidate) {
|
|
126
|
+
return (0, serializer_1.parseFailLiquidateActionNotificationMsgBody)(cell);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else if (actionOpCode === pool_1.Pool.Op.withdraw) {
|
|
130
|
+
return (0, serializer_1.parseFailTransferOutActionNotificationMsgBody)(cell);
|
|
131
|
+
}
|
|
132
|
+
else if (actionOpCode === pool_1.Pool.Op.borrow) {
|
|
133
|
+
return (0, serializer_1.parseFailTransferOutActionNotificationMsgBody)(cell);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Address } from "@ton/core";
|
|
2
|
+
import { TonClient } from "@ton/ton";
|
|
3
|
+
import { MatchedTxResult, TxStep } from "./type";
|
|
4
|
+
export declare function findTx(client: TonClient, dst: Address, createdLt: string | undefined, match: TxStep): Promise<MatchedTxResult>;
|
|
5
|
+
export declare function track(client: TonClient, dst: Address, createdLt: string | undefined, match: TxStep): Promise<MatchedTxResult>;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findTx = findTx;
|
|
4
|
+
exports.track = track;
|
|
5
|
+
const parser_1 = require("../parser");
|
|
6
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
7
|
+
async function findTx(client, dst, createdLt = "0", match) {
|
|
8
|
+
const startTime = Date.now();
|
|
9
|
+
let findingTime = 0;
|
|
10
|
+
while (true) {
|
|
11
|
+
try {
|
|
12
|
+
if (Date.now() - startTime > 120000)
|
|
13
|
+
throw "timeout";
|
|
14
|
+
const txs = await client.getTransactions(dst, {
|
|
15
|
+
limit: 100,
|
|
16
|
+
lt: createdLt,
|
|
17
|
+
archival: true,
|
|
18
|
+
});
|
|
19
|
+
const tx = txs.find((item) => {
|
|
20
|
+
const messages = [...item.outMessages.values(), item.inMessage];
|
|
21
|
+
for (let message of messages) {
|
|
22
|
+
try {
|
|
23
|
+
if (!message || message.info.type !== "internal")
|
|
24
|
+
continue;
|
|
25
|
+
if (match.from && !match.from.equals(message.info.src))
|
|
26
|
+
continue;
|
|
27
|
+
if (match.to && !match.to.equals(message.info.dest))
|
|
28
|
+
continue;
|
|
29
|
+
if (match.value && match.value !== message.info.value.coins)
|
|
30
|
+
continue;
|
|
31
|
+
const ds = message.body.beginParse();
|
|
32
|
+
const opcode = ds.loadUint(32);
|
|
33
|
+
const queryId = ds.loadUintBig(64);
|
|
34
|
+
if (match.opcode && match.opcode !== opcode)
|
|
35
|
+
continue;
|
|
36
|
+
if (match.queryId && match.queryId !== queryId)
|
|
37
|
+
continue;
|
|
38
|
+
if (match.body &&
|
|
39
|
+
match.body.toBoc().toString() !== message.body.toBoc().toString())
|
|
40
|
+
continue;
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
catch (e) { }
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
if (tx) {
|
|
47
|
+
return {
|
|
48
|
+
address: dst,
|
|
49
|
+
lt: tx.lt,
|
|
50
|
+
now: tx.now,
|
|
51
|
+
hash: tx.hash().toString("base64"),
|
|
52
|
+
prevTxHash: tx.prevTransactionHash,
|
|
53
|
+
inMessage: (0, parser_1.parseTxInternalMessage)(tx.inMessage),
|
|
54
|
+
outMessages: tx.outMessages.values().map(parser_1.parseTxInternalMessage),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (e) { }
|
|
59
|
+
await sleep(5000);
|
|
60
|
+
findingTime += 5000;
|
|
61
|
+
if (findingTime > 30_000 * 3) {
|
|
62
|
+
throw "findTx timeout";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function track(client, dst, createdLt = "0", match) {
|
|
67
|
+
const startTime = Date.now();
|
|
68
|
+
let findingTime = 0;
|
|
69
|
+
while (true) {
|
|
70
|
+
if (Date.now() - startTime > 120000)
|
|
71
|
+
throw "timeout";
|
|
72
|
+
const txs = await client.getTransactions(dst, {
|
|
73
|
+
limit: 20,
|
|
74
|
+
lt: createdLt,
|
|
75
|
+
archival: true,
|
|
76
|
+
});
|
|
77
|
+
const tx = txs.find((item) => {
|
|
78
|
+
const messages = [...item.outMessages.values(), item.inMessage];
|
|
79
|
+
for (let message of messages) {
|
|
80
|
+
if (!message || message.info.type !== "internal")
|
|
81
|
+
continue;
|
|
82
|
+
if (match.from && !match.from.equals(message.info.src))
|
|
83
|
+
continue;
|
|
84
|
+
if (match.to && !match.to.equals(message.info.dest))
|
|
85
|
+
continue;
|
|
86
|
+
if (match.value && match.value !== message.info.value.coins)
|
|
87
|
+
continue;
|
|
88
|
+
const ds = message.body.beginParse();
|
|
89
|
+
const opcode = ds.loadUint(32);
|
|
90
|
+
const queryId = ds.loadUintBig(64);
|
|
91
|
+
if (match.opcode && match.opcode !== opcode)
|
|
92
|
+
continue;
|
|
93
|
+
if (match.queryId && match.queryId !== queryId)
|
|
94
|
+
continue;
|
|
95
|
+
if (match.body &&
|
|
96
|
+
match.body.toBoc().toString() !== message.body.toBoc().toString())
|
|
97
|
+
continue;
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
if (tx) {
|
|
102
|
+
return {
|
|
103
|
+
address: dst,
|
|
104
|
+
lt: tx.lt,
|
|
105
|
+
now: tx.now,
|
|
106
|
+
hash: tx.hash().toString("base64"),
|
|
107
|
+
prevTxHash: tx.prevTransactionHash,
|
|
108
|
+
inMessage: (0, parser_1.parseTxInternalMessage)(tx.inMessage),
|
|
109
|
+
outMessages: tx.outMessages.values().map(parser_1.parseTxInternalMessage),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
await sleep(5000);
|
|
113
|
+
findingTime += 5000;
|
|
114
|
+
if (findingTime > 30000) {
|
|
115
|
+
console.log("findingTime", findingTime);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateQueryId = generateQueryId;
|
|
4
|
+
const core_1 = require("@ton/core");
|
|
5
|
+
function generateQueryId(sender, body) {
|
|
6
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
7
|
+
const _hash = (0, core_1.beginCell)()
|
|
8
|
+
.storeUint(currentTime, 40)
|
|
9
|
+
.storeAddress((sender))
|
|
10
|
+
.storeRef(body).endCell().hash();
|
|
11
|
+
return (0, core_1.beginCell)().storeBuffer(_hash, 32).asSlice().loadUintBig(64);
|
|
12
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Address, Cell } from "@ton/core";
|
|
2
|
+
import { ActionNotificationMsgBody, FailLiquidateActionNotificationMsgBody, FailTransferInActionNotificationMsgBody, FailTransferOutActionNotificationMsgBody, SuccessActionNotificationMsgBody, SuccessLiquidateActionNotificationMsgBody } from "../../contracts/core/pool/type";
|
|
3
|
+
import { TxMsgBody } from "../parser";
|
|
4
|
+
export type TxStep = {
|
|
5
|
+
description: string;
|
|
6
|
+
from?: Address;
|
|
7
|
+
to?: Address;
|
|
8
|
+
opcode?: number;
|
|
9
|
+
queryId?: bigint;
|
|
10
|
+
value?: bigint;
|
|
11
|
+
body?: Cell;
|
|
12
|
+
matchedTx?: MatchedTxResult | MatchedTxResult[];
|
|
13
|
+
actionNotificationResult?: ActionNotificationMsgBody | ActionNotificationMsgBody[];
|
|
14
|
+
};
|
|
15
|
+
export type MatchedTxResult = {
|
|
16
|
+
address: Address;
|
|
17
|
+
lt: bigint;
|
|
18
|
+
now: number;
|
|
19
|
+
hash: string;
|
|
20
|
+
prevTxHash: bigint;
|
|
21
|
+
inMessage?: TxMessage | null;
|
|
22
|
+
outMessages: (TxMessage | null | undefined)[];
|
|
23
|
+
};
|
|
24
|
+
export type TxCallBackFn = (step: TxStep) => void;
|
|
25
|
+
export type ActionMsgBody = SuccessActionNotificationMsgBody | SuccessLiquidateActionNotificationMsgBody | FailTransferInActionNotificationMsgBody | FailLiquidateActionNotificationMsgBody | FailTransferOutActionNotificationMsgBody | null;
|
|
26
|
+
export type TxMessage = {
|
|
27
|
+
src: Address;
|
|
28
|
+
dst: Address;
|
|
29
|
+
value: bigint;
|
|
30
|
+
createdAt: number;
|
|
31
|
+
createdLt: bigint;
|
|
32
|
+
body: Cell;
|
|
33
|
+
parsedBody?: TxMsgBody;
|
|
34
|
+
};
|