@pythnetwork/pyth-ton-js 0.1.2 → 0.3.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/LICENSE +1 -1
- package/README.md +5 -1
- package/dist/cjs/index.cjs +303 -0
- package/{lib → dist/cjs}/index.d.ts +8 -9
- package/dist/cjs/package.json +1 -0
- package/dist/esm/index.d.ts +69 -0
- package/{lib/index.js → dist/esm/index.mjs} +82 -74
- package/dist/esm/package.json +1 -0
- package/package.json +37 -20
- package/lib/index.d.ts.map +0 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -57,9 +57,13 @@ async function main() {
|
|
|
57
57
|
);
|
|
58
58
|
console.log("Hermes BTC price:", latestPriceUpdates.parsed?.[0].price);
|
|
59
59
|
|
|
60
|
+
const numUpdates = 1; // Only BTC price
|
|
60
61
|
const updateData = Buffer.from(latestPriceUpdates.binary.data[0], "hex");
|
|
61
62
|
console.log("Update data:", updateData);
|
|
62
63
|
|
|
64
|
+
// NOTE: As of 2025/10/19 There's a bug with TON Access (https://ton.access.orbs.network) RPC service where if you provide an
|
|
65
|
+
// update data buffer with length of more than ~320 then the rpc returns error 404 and the function fails. In this case you can use the
|
|
66
|
+
// contract.getSingleUpdateFee() method to get the single update fee and multiply it by the number of updates you want to perform.
|
|
63
67
|
const updateFee = await contract.getUpdateFee(updateData);
|
|
64
68
|
console.log("Update fee:", updateFee);
|
|
65
69
|
|
|
@@ -74,7 +78,7 @@ async function main() {
|
|
|
74
78
|
await contract.sendUpdatePriceFeeds(
|
|
75
79
|
provider.sender(key.secretKey),
|
|
76
80
|
updateData,
|
|
77
|
-
calculateUpdatePriceFeedsFee(
|
|
81
|
+
calculateUpdatePriceFeedsFee(numUpdates) + BigInt(updateFee)
|
|
78
82
|
);
|
|
79
83
|
console.log("Price feeds updated successfully.");
|
|
80
84
|
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get GAS_PRICE_FACTOR () {
|
|
13
|
+
return GAS_PRICE_FACTOR;
|
|
14
|
+
},
|
|
15
|
+
get PYTH_CONTRACT_ADDRESS_MAINNET () {
|
|
16
|
+
return PYTH_CONTRACT_ADDRESS_MAINNET;
|
|
17
|
+
},
|
|
18
|
+
get PYTH_CONTRACT_ADDRESS_TESTNET () {
|
|
19
|
+
return PYTH_CONTRACT_ADDRESS_TESTNET;
|
|
20
|
+
},
|
|
21
|
+
get PythContract () {
|
|
22
|
+
return PythContract;
|
|
23
|
+
},
|
|
24
|
+
get UPDATE_PRICE_FEEDS_BASE_GAS () {
|
|
25
|
+
return UPDATE_PRICE_FEEDS_BASE_GAS;
|
|
26
|
+
},
|
|
27
|
+
get UPDATE_PRICE_FEEDS_PER_UPDATE_GAS () {
|
|
28
|
+
return UPDATE_PRICE_FEEDS_PER_UPDATE_GAS;
|
|
29
|
+
},
|
|
30
|
+
get calculateUpdatePriceFeedsFee () {
|
|
31
|
+
return calculateUpdatePriceFeedsFee;
|
|
32
|
+
},
|
|
33
|
+
get createCellChain () {
|
|
34
|
+
return createCellChain;
|
|
35
|
+
},
|
|
36
|
+
get parseDataSource () {
|
|
37
|
+
return parseDataSource;
|
|
38
|
+
},
|
|
39
|
+
get parseDataSources () {
|
|
40
|
+
return parseDataSources;
|
|
41
|
+
},
|
|
42
|
+
get parseGuardianSetKeys () {
|
|
43
|
+
return parseGuardianSetKeys;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const _core = require("@ton/core");
|
|
47
|
+
const PYTH_CONTRACT_ADDRESS_MAINNET = "EQBgtfuGIzWLiOzpZO48_psYvco4xRtkAbdbmTwy0_o95LtZ";
|
|
48
|
+
const PYTH_CONTRACT_ADDRESS_TESTNET = "EQB4ZnrI5qsP_IUJgVJNwEGKLzZWsQOFhiaqDbD7pTt_f9oU";
|
|
49
|
+
const UPDATE_PRICE_FEEDS_BASE_GAS = 300_000n;
|
|
50
|
+
const UPDATE_PRICE_FEEDS_PER_UPDATE_GAS = 90_000n;
|
|
51
|
+
const GAS_PRICE_FACTOR = 400n;
|
|
52
|
+
class PythContract {
|
|
53
|
+
address;
|
|
54
|
+
init;
|
|
55
|
+
constructor(address, init){
|
|
56
|
+
this.address = address;
|
|
57
|
+
this.init = init;
|
|
58
|
+
}
|
|
59
|
+
static createFromAddress(address) {
|
|
60
|
+
return new PythContract(address);
|
|
61
|
+
}
|
|
62
|
+
async getCurrentGuardianSetIndex(provider) {
|
|
63
|
+
const result = await provider.get("get_current_guardian_set_index", []);
|
|
64
|
+
return result.stack.readNumber();
|
|
65
|
+
}
|
|
66
|
+
async sendUpdateGuardianSet(provider, via, vm) {
|
|
67
|
+
const messageBody = (0, _core.beginCell)().storeUint(1, 32) // OP_UPDATE_GUARDIAN_SET
|
|
68
|
+
.storeRef(createCellChain(vm)).endCell();
|
|
69
|
+
await provider.internal(via, {
|
|
70
|
+
value: (0, _core.toNano)("0.1"),
|
|
71
|
+
sendMode: _core.SendMode.PAY_GAS_SEPARATELY,
|
|
72
|
+
body: messageBody
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async sendUpdatePriceFeeds(provider, via, updateData, updateFee) {
|
|
76
|
+
const messageBody = (0, _core.beginCell)().storeUint(2, 32) // OP_UPDATE_PRICE_FEEDS
|
|
77
|
+
.storeRef(createCellChain(updateData)).endCell();
|
|
78
|
+
await provider.internal(via, {
|
|
79
|
+
value: updateFee,
|
|
80
|
+
sendMode: _core.SendMode.PAY_GAS_SEPARATELY,
|
|
81
|
+
body: messageBody
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async sendExecuteGovernanceAction(provider, via, governanceAction) {
|
|
85
|
+
const messageBody = (0, _core.beginCell)().storeUint(3, 32) // OP_EXECUTE_GOVERNANCE_ACTION
|
|
86
|
+
.storeRef(createCellChain(governanceAction)).endCell();
|
|
87
|
+
await provider.internal(via, {
|
|
88
|
+
value: (0, _core.toNano)("0.1"),
|
|
89
|
+
sendMode: _core.SendMode.PAY_GAS_SEPARATELY,
|
|
90
|
+
body: messageBody
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async sendUpgradeContract(provider, via, newCode) {
|
|
94
|
+
const messageBody = (0, _core.beginCell)().storeUint(4, 32) // OP_UPGRADE_CONTRACT
|
|
95
|
+
.storeRef(newCode).endCell();
|
|
96
|
+
await provider.internal(via, {
|
|
97
|
+
value: (0, _core.toNano)("0.1"),
|
|
98
|
+
sendMode: _core.SendMode.PAY_GAS_SEPARATELY,
|
|
99
|
+
body: messageBody
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async getPriceUnsafe(provider, priceFeedId) {
|
|
103
|
+
const result = await provider.get("get_price_unsafe", [
|
|
104
|
+
{
|
|
105
|
+
type: "int",
|
|
106
|
+
value: BigInt(priceFeedId)
|
|
107
|
+
}
|
|
108
|
+
]);
|
|
109
|
+
const price = result.stack.readNumber();
|
|
110
|
+
const conf = result.stack.readNumber();
|
|
111
|
+
const expo = result.stack.readNumber();
|
|
112
|
+
const publishTime = result.stack.readNumber();
|
|
113
|
+
return {
|
|
114
|
+
price,
|
|
115
|
+
conf,
|
|
116
|
+
expo,
|
|
117
|
+
publishTime
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
async getPriceNoOlderThan(provider, timePeriod, priceFeedId) {
|
|
121
|
+
const result = await provider.get("get_price_no_older_than", [
|
|
122
|
+
{
|
|
123
|
+
type: "int",
|
|
124
|
+
value: BigInt(timePeriod)
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
type: "int",
|
|
128
|
+
value: BigInt(priceFeedId)
|
|
129
|
+
}
|
|
130
|
+
]);
|
|
131
|
+
const price = result.stack.readNumber();
|
|
132
|
+
const conf = result.stack.readNumber();
|
|
133
|
+
const expo = result.stack.readNumber();
|
|
134
|
+
const publishTime = result.stack.readNumber();
|
|
135
|
+
return {
|
|
136
|
+
price,
|
|
137
|
+
conf,
|
|
138
|
+
expo,
|
|
139
|
+
publishTime
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
async getEmaPriceUnsafe(provider, priceFeedId) {
|
|
143
|
+
const result = await provider.get("get_ema_price_unsafe", [
|
|
144
|
+
{
|
|
145
|
+
type: "int",
|
|
146
|
+
value: BigInt(priceFeedId)
|
|
147
|
+
}
|
|
148
|
+
]);
|
|
149
|
+
const price = result.stack.readNumber();
|
|
150
|
+
const conf = result.stack.readNumber();
|
|
151
|
+
const expo = result.stack.readNumber();
|
|
152
|
+
const publishTime = result.stack.readNumber();
|
|
153
|
+
return {
|
|
154
|
+
price,
|
|
155
|
+
conf,
|
|
156
|
+
expo,
|
|
157
|
+
publishTime
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
async getEmaPriceNoOlderThan(provider, timePeriod, priceFeedId) {
|
|
161
|
+
const result = await provider.get("get_ema_price_no_older_than", [
|
|
162
|
+
{
|
|
163
|
+
type: "int",
|
|
164
|
+
value: BigInt(timePeriod)
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
type: "int",
|
|
168
|
+
value: BigInt(priceFeedId)
|
|
169
|
+
}
|
|
170
|
+
]);
|
|
171
|
+
const price = result.stack.readNumber();
|
|
172
|
+
const conf = result.stack.readNumber();
|
|
173
|
+
const expo = result.stack.readNumber();
|
|
174
|
+
const publishTime = result.stack.readNumber();
|
|
175
|
+
return {
|
|
176
|
+
price,
|
|
177
|
+
conf,
|
|
178
|
+
expo,
|
|
179
|
+
publishTime
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
async getUpdateFee(provider, vm) {
|
|
183
|
+
const result = await provider.get("get_update_fee", [
|
|
184
|
+
{
|
|
185
|
+
type: "slice",
|
|
186
|
+
cell: createCellChain(vm)
|
|
187
|
+
}
|
|
188
|
+
]);
|
|
189
|
+
return result.stack.readNumber();
|
|
190
|
+
}
|
|
191
|
+
async getSingleUpdateFee(provider) {
|
|
192
|
+
const result = await provider.get("get_single_update_fee", []);
|
|
193
|
+
return result.stack.readNumber();
|
|
194
|
+
}
|
|
195
|
+
async getLastExecutedGovernanceSequence(provider) {
|
|
196
|
+
const result = await provider.get("get_last_executed_governance_sequence", []);
|
|
197
|
+
return result.stack.readNumber();
|
|
198
|
+
}
|
|
199
|
+
async getChainId(provider) {
|
|
200
|
+
const result = await provider.get("get_chain_id", []);
|
|
201
|
+
return result.stack.readNumber();
|
|
202
|
+
}
|
|
203
|
+
async getDataSources(provider) {
|
|
204
|
+
const result = await provider.get("get_data_sources", []);
|
|
205
|
+
return parseDataSources(result.stack.readCell());
|
|
206
|
+
}
|
|
207
|
+
async getGovernanceDataSource(provider) {
|
|
208
|
+
const result = await provider.get("get_governance_data_source", []);
|
|
209
|
+
return parseDataSource(result.stack.readCell());
|
|
210
|
+
}
|
|
211
|
+
async getGuardianSet(provider, index) {
|
|
212
|
+
const result = await provider.get("get_guardian_set", [
|
|
213
|
+
{
|
|
214
|
+
type: "int",
|
|
215
|
+
value: BigInt(index)
|
|
216
|
+
}
|
|
217
|
+
]);
|
|
218
|
+
const expirationTime = result.stack.readNumber();
|
|
219
|
+
const keys = parseGuardianSetKeys(result.stack.readCell());
|
|
220
|
+
const keyCount = result.stack.readNumber();
|
|
221
|
+
return {
|
|
222
|
+
expirationTime,
|
|
223
|
+
keys,
|
|
224
|
+
keyCount
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function createCellChain(buffer) {
|
|
229
|
+
const chunks = bufferToChunks(buffer, 127);
|
|
230
|
+
let lastCell;
|
|
231
|
+
// Iterate through chunks in reverse order
|
|
232
|
+
for(let i = chunks.length - 1; i >= 0; i--){
|
|
233
|
+
const chunk = chunks[i];
|
|
234
|
+
const cellBuilder = (0, _core.beginCell)();
|
|
235
|
+
const buffer = Buffer.from(chunk);
|
|
236
|
+
cellBuilder.storeBuffer(buffer);
|
|
237
|
+
if (lastCell) {
|
|
238
|
+
cellBuilder.storeRef(lastCell);
|
|
239
|
+
}
|
|
240
|
+
lastCell = cellBuilder.endCell();
|
|
241
|
+
}
|
|
242
|
+
// lastCell will be the root cell of our chain
|
|
243
|
+
if (!lastCell) {
|
|
244
|
+
throw new Error("Failed to create cell chain");
|
|
245
|
+
}
|
|
246
|
+
return lastCell;
|
|
247
|
+
}
|
|
248
|
+
function bufferToChunks(buff, chunkSizeBytes = 127) {
|
|
249
|
+
const chunks = [];
|
|
250
|
+
const uint8Array = new Uint8Array(buff.buffer, buff.byteOffset, buff.byteLength);
|
|
251
|
+
for(let offset = 0; offset < uint8Array.length; offset += chunkSizeBytes){
|
|
252
|
+
const remainingBytes = Math.min(chunkSizeBytes, uint8Array.length - offset);
|
|
253
|
+
const chunk = uint8Array.subarray(offset, offset + remainingBytes);
|
|
254
|
+
chunks.push(chunk);
|
|
255
|
+
}
|
|
256
|
+
return chunks;
|
|
257
|
+
}
|
|
258
|
+
function parseDataSources(cell) {
|
|
259
|
+
const dataSources = [];
|
|
260
|
+
const slice = cell.beginParse();
|
|
261
|
+
const dict = slice.loadDictDirect(_core.Dictionary.Keys.Uint(8), _core.Dictionary.Values.Cell());
|
|
262
|
+
for (const [, value] of dict){
|
|
263
|
+
const dataSource = parseDataSource(value);
|
|
264
|
+
if (dataSource) {
|
|
265
|
+
dataSources.push(dataSource);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return dataSources;
|
|
269
|
+
}
|
|
270
|
+
function parseDataSource(cell) {
|
|
271
|
+
const slice = cell.beginParse();
|
|
272
|
+
if (slice.remainingBits === 0) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const emitterChain = slice.loadUint(16);
|
|
276
|
+
const emitterAddress = slice.loadUintBig(256).toString(16).padStart(64, "0");
|
|
277
|
+
return {
|
|
278
|
+
emitterChain,
|
|
279
|
+
emitterAddress
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function parseGuardianSetKeys(cell) {
|
|
283
|
+
const keys = [];
|
|
284
|
+
function parseCell(c) {
|
|
285
|
+
let slice = c.beginParse();
|
|
286
|
+
while(slice.remainingRefs > 0 || slice.remainingBits >= 160){
|
|
287
|
+
if (slice.remainingBits >= 160) {
|
|
288
|
+
const bitsToSkip = slice.remainingBits - 160;
|
|
289
|
+
slice = slice.skip(bitsToSkip);
|
|
290
|
+
const key = slice.loadBits(160);
|
|
291
|
+
keys.push("0x" + key.toString());
|
|
292
|
+
}
|
|
293
|
+
if (slice.remainingRefs > 0) {
|
|
294
|
+
parseCell(slice.loadRef());
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
parseCell(cell);
|
|
299
|
+
return keys;
|
|
300
|
+
}
|
|
301
|
+
function calculateUpdatePriceFeedsFee(numUpdates) {
|
|
302
|
+
return (UPDATE_PRICE_FEEDS_BASE_GAS + UPDATE_PRICE_FEEDS_PER_UPDATE_GAS * numUpdates) * GAS_PRICE_FACTOR;
|
|
303
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
import { Address, Cell
|
|
3
|
-
import { ContractProvider } from "@ton/ton";
|
|
4
|
-
export declare const PYTH_CONTRACT_ADDRESS_MAINNET = "
|
|
1
|
+
import type { Contract, Sender } from "@ton/core";
|
|
2
|
+
import { Address, Cell } from "@ton/core";
|
|
3
|
+
import type { ContractProvider } from "@ton/ton";
|
|
4
|
+
export declare const PYTH_CONTRACT_ADDRESS_MAINNET = "EQBgtfuGIzWLiOzpZO48_psYvco4xRtkAbdbmTwy0_o95LtZ";
|
|
5
5
|
export declare const PYTH_CONTRACT_ADDRESS_TESTNET = "EQB4ZnrI5qsP_IUJgVJNwEGKLzZWsQOFhiaqDbD7pTt_f9oU";
|
|
6
6
|
export declare const UPDATE_PRICE_FEEDS_BASE_GAS = 300000n;
|
|
7
7
|
export declare const UPDATE_PRICE_FEEDS_PER_UPDATE_GAS = 90000n;
|
|
8
8
|
export declare const GAS_PRICE_FACTOR = 400n;
|
|
9
|
-
export
|
|
9
|
+
export type DataSource = {
|
|
10
10
|
emitterChain: number;
|
|
11
11
|
emitterAddress: string;
|
|
12
|
-
}
|
|
12
|
+
};
|
|
13
13
|
export declare class PythContract implements Contract {
|
|
14
14
|
readonly address: Address;
|
|
15
15
|
readonly init?: {
|
|
@@ -55,7 +55,7 @@ export declare class PythContract implements Contract {
|
|
|
55
55
|
getLastExecutedGovernanceSequence(provider: ContractProvider): Promise<number>;
|
|
56
56
|
getChainId(provider: ContractProvider): Promise<number>;
|
|
57
57
|
getDataSources(provider: ContractProvider): Promise<DataSource[]>;
|
|
58
|
-
getGovernanceDataSource(provider: ContractProvider): Promise<DataSource | null>;
|
|
58
|
+
getGovernanceDataSource(provider: ContractProvider): Promise<DataSource | null | undefined>;
|
|
59
59
|
getGuardianSet(provider: ContractProvider, index: number): Promise<{
|
|
60
60
|
expirationTime: number;
|
|
61
61
|
keys: string[];
|
|
@@ -64,7 +64,6 @@ export declare class PythContract implements Contract {
|
|
|
64
64
|
}
|
|
65
65
|
export declare function createCellChain(buffer: Buffer): Cell;
|
|
66
66
|
export declare function parseDataSources(cell: Cell): DataSource[];
|
|
67
|
-
export declare function parseDataSource(cell: Cell): DataSource | null;
|
|
67
|
+
export declare function parseDataSource(cell: Cell): DataSource | null | undefined;
|
|
68
68
|
export declare function parseGuardianSetKeys(cell: Cell): string[];
|
|
69
69
|
export declare function calculateUpdatePriceFeedsFee(numUpdates: bigint): bigint;
|
|
70
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "commonjs" }
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Contract, Sender } from "@ton/core";
|
|
2
|
+
import { Address, Cell } from "@ton/core";
|
|
3
|
+
import type { ContractProvider } from "@ton/ton";
|
|
4
|
+
export declare const PYTH_CONTRACT_ADDRESS_MAINNET = "EQBgtfuGIzWLiOzpZO48_psYvco4xRtkAbdbmTwy0_o95LtZ";
|
|
5
|
+
export declare const PYTH_CONTRACT_ADDRESS_TESTNET = "EQB4ZnrI5qsP_IUJgVJNwEGKLzZWsQOFhiaqDbD7pTt_f9oU";
|
|
6
|
+
export declare const UPDATE_PRICE_FEEDS_BASE_GAS = 300000n;
|
|
7
|
+
export declare const UPDATE_PRICE_FEEDS_PER_UPDATE_GAS = 90000n;
|
|
8
|
+
export declare const GAS_PRICE_FACTOR = 400n;
|
|
9
|
+
export type DataSource = {
|
|
10
|
+
emitterChain: number;
|
|
11
|
+
emitterAddress: string;
|
|
12
|
+
};
|
|
13
|
+
export declare class PythContract implements Contract {
|
|
14
|
+
readonly address: Address;
|
|
15
|
+
readonly init?: {
|
|
16
|
+
code: Cell;
|
|
17
|
+
data: Cell;
|
|
18
|
+
} | undefined;
|
|
19
|
+
constructor(address: Address, init?: {
|
|
20
|
+
code: Cell;
|
|
21
|
+
data: Cell;
|
|
22
|
+
} | undefined);
|
|
23
|
+
static createFromAddress(address: Address): PythContract;
|
|
24
|
+
getCurrentGuardianSetIndex(provider: ContractProvider): Promise<number>;
|
|
25
|
+
sendUpdateGuardianSet(provider: ContractProvider, via: Sender, vm: Buffer): Promise<void>;
|
|
26
|
+
sendUpdatePriceFeeds(provider: ContractProvider, via: Sender, updateData: Buffer, updateFee: bigint): Promise<void>;
|
|
27
|
+
sendExecuteGovernanceAction(provider: ContractProvider, via: Sender, governanceAction: Buffer): Promise<void>;
|
|
28
|
+
sendUpgradeContract(provider: ContractProvider, via: Sender, newCode: Cell): Promise<void>;
|
|
29
|
+
getPriceUnsafe(provider: ContractProvider, priceFeedId: string): Promise<{
|
|
30
|
+
price: number;
|
|
31
|
+
conf: number;
|
|
32
|
+
expo: number;
|
|
33
|
+
publishTime: number;
|
|
34
|
+
}>;
|
|
35
|
+
getPriceNoOlderThan(provider: ContractProvider, timePeriod: number, priceFeedId: string): Promise<{
|
|
36
|
+
price: number;
|
|
37
|
+
conf: number;
|
|
38
|
+
expo: number;
|
|
39
|
+
publishTime: number;
|
|
40
|
+
}>;
|
|
41
|
+
getEmaPriceUnsafe(provider: ContractProvider, priceFeedId: string): Promise<{
|
|
42
|
+
price: number;
|
|
43
|
+
conf: number;
|
|
44
|
+
expo: number;
|
|
45
|
+
publishTime: number;
|
|
46
|
+
}>;
|
|
47
|
+
getEmaPriceNoOlderThan(provider: ContractProvider, timePeriod: number, priceFeedId: string): Promise<{
|
|
48
|
+
price: number;
|
|
49
|
+
conf: number;
|
|
50
|
+
expo: number;
|
|
51
|
+
publishTime: number;
|
|
52
|
+
}>;
|
|
53
|
+
getUpdateFee(provider: ContractProvider, vm: Buffer): Promise<number>;
|
|
54
|
+
getSingleUpdateFee(provider: ContractProvider): Promise<number>;
|
|
55
|
+
getLastExecutedGovernanceSequence(provider: ContractProvider): Promise<number>;
|
|
56
|
+
getChainId(provider: ContractProvider): Promise<number>;
|
|
57
|
+
getDataSources(provider: ContractProvider): Promise<DataSource[]>;
|
|
58
|
+
getGovernanceDataSource(provider: ContractProvider): Promise<DataSource | null | undefined>;
|
|
59
|
+
getGuardianSet(provider: ContractProvider, index: number): Promise<{
|
|
60
|
+
expirationTime: number;
|
|
61
|
+
keys: string[];
|
|
62
|
+
keyCount: number;
|
|
63
|
+
}>;
|
|
64
|
+
}
|
|
65
|
+
export declare function createCellChain(buffer: Buffer): Cell;
|
|
66
|
+
export declare function parseDataSources(cell: Cell): DataSource[];
|
|
67
|
+
export declare function parseDataSource(cell: Cell): DataSource | null | undefined;
|
|
68
|
+
export declare function parseGuardianSetKeys(cell: Cell): string[];
|
|
69
|
+
export declare function calculateUpdatePriceFeedsFee(numUpdates: bigint): bigint;
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const core_1 = require("@ton/core");
|
|
5
|
-
exports.PYTH_CONTRACT_ADDRESS_MAINNET = "EQBU6k8HH6yX4Jf3d18swWbnYr31D3PJI7PgjXT-flsKHqql";
|
|
6
|
-
exports.PYTH_CONTRACT_ADDRESS_TESTNET = "EQB4ZnrI5qsP_IUJgVJNwEGKLzZWsQOFhiaqDbD7pTt_f9oU";
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { beginCell, Dictionary, SendMode, toNano } from "@ton/core";
|
|
2
|
+
export const PYTH_CONTRACT_ADDRESS_MAINNET = "EQBgtfuGIzWLiOzpZO48_psYvco4xRtkAbdbmTwy0_o95LtZ";
|
|
3
|
+
export const PYTH_CONTRACT_ADDRESS_TESTNET = "EQB4ZnrI5qsP_IUJgVJNwEGKLzZWsQOFhiaqDbD7pTt_f9oU";
|
|
7
4
|
// This is defined in target_chains/ton/contracts/common/gas.fc
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
export const UPDATE_PRICE_FEEDS_BASE_GAS = 300_000n;
|
|
6
|
+
export const UPDATE_PRICE_FEEDS_PER_UPDATE_GAS = 90_000n;
|
|
10
7
|
// Current settings in basechain are as follows: 1 unit of gas costs 400 nanotons
|
|
11
|
-
|
|
12
|
-
class PythContract {
|
|
8
|
+
export const GAS_PRICE_FACTOR = 400n;
|
|
9
|
+
export class PythContract {
|
|
13
10
|
address;
|
|
14
11
|
init;
|
|
15
|
-
constructor(address, init)
|
|
12
|
+
constructor(address, init){
|
|
16
13
|
this.address = address;
|
|
17
14
|
this.init = init;
|
|
18
15
|
}
|
|
@@ -24,52 +21,47 @@ class PythContract {
|
|
|
24
21
|
return result.stack.readNumber();
|
|
25
22
|
}
|
|
26
23
|
async sendUpdateGuardianSet(provider, via, vm) {
|
|
27
|
-
const messageBody = (
|
|
28
|
-
|
|
29
|
-
.storeRef(createCellChain(vm))
|
|
30
|
-
.endCell();
|
|
24
|
+
const messageBody = beginCell().storeUint(1, 32) // OP_UPDATE_GUARDIAN_SET
|
|
25
|
+
.storeRef(createCellChain(vm)).endCell();
|
|
31
26
|
await provider.internal(via, {
|
|
32
|
-
value:
|
|
33
|
-
sendMode:
|
|
34
|
-
body: messageBody
|
|
27
|
+
value: toNano("0.1"),
|
|
28
|
+
sendMode: SendMode.PAY_GAS_SEPARATELY,
|
|
29
|
+
body: messageBody
|
|
35
30
|
});
|
|
36
31
|
}
|
|
37
32
|
async sendUpdatePriceFeeds(provider, via, updateData, updateFee) {
|
|
38
|
-
const messageBody = (
|
|
39
|
-
|
|
40
|
-
.storeRef(createCellChain(updateData))
|
|
41
|
-
.endCell();
|
|
33
|
+
const messageBody = beginCell().storeUint(2, 32) // OP_UPDATE_PRICE_FEEDS
|
|
34
|
+
.storeRef(createCellChain(updateData)).endCell();
|
|
42
35
|
await provider.internal(via, {
|
|
43
36
|
value: updateFee,
|
|
44
|
-
sendMode:
|
|
45
|
-
body: messageBody
|
|
37
|
+
sendMode: SendMode.PAY_GAS_SEPARATELY,
|
|
38
|
+
body: messageBody
|
|
46
39
|
});
|
|
47
40
|
}
|
|
48
41
|
async sendExecuteGovernanceAction(provider, via, governanceAction) {
|
|
49
|
-
const messageBody = (
|
|
50
|
-
|
|
51
|
-
.storeRef(createCellChain(governanceAction))
|
|
52
|
-
.endCell();
|
|
42
|
+
const messageBody = beginCell().storeUint(3, 32) // OP_EXECUTE_GOVERNANCE_ACTION
|
|
43
|
+
.storeRef(createCellChain(governanceAction)).endCell();
|
|
53
44
|
await provider.internal(via, {
|
|
54
|
-
value:
|
|
55
|
-
sendMode:
|
|
56
|
-
body: messageBody
|
|
45
|
+
value: toNano("0.1"),
|
|
46
|
+
sendMode: SendMode.PAY_GAS_SEPARATELY,
|
|
47
|
+
body: messageBody
|
|
57
48
|
});
|
|
58
49
|
}
|
|
59
50
|
async sendUpgradeContract(provider, via, newCode) {
|
|
60
|
-
const messageBody = (
|
|
61
|
-
|
|
62
|
-
.storeRef(newCode)
|
|
63
|
-
.endCell();
|
|
51
|
+
const messageBody = beginCell().storeUint(4, 32) // OP_UPGRADE_CONTRACT
|
|
52
|
+
.storeRef(newCode).endCell();
|
|
64
53
|
await provider.internal(via, {
|
|
65
|
-
value:
|
|
66
|
-
sendMode:
|
|
67
|
-
body: messageBody
|
|
54
|
+
value: toNano("0.1"),
|
|
55
|
+
sendMode: SendMode.PAY_GAS_SEPARATELY,
|
|
56
|
+
body: messageBody
|
|
68
57
|
});
|
|
69
58
|
}
|
|
70
59
|
async getPriceUnsafe(provider, priceFeedId) {
|
|
71
60
|
const result = await provider.get("get_price_unsafe", [
|
|
72
|
-
{
|
|
61
|
+
{
|
|
62
|
+
type: "int",
|
|
63
|
+
value: BigInt(priceFeedId)
|
|
64
|
+
}
|
|
73
65
|
]);
|
|
74
66
|
const price = result.stack.readNumber();
|
|
75
67
|
const conf = result.stack.readNumber();
|
|
@@ -79,13 +71,19 @@ class PythContract {
|
|
|
79
71
|
price,
|
|
80
72
|
conf,
|
|
81
73
|
expo,
|
|
82
|
-
publishTime
|
|
74
|
+
publishTime
|
|
83
75
|
};
|
|
84
76
|
}
|
|
85
77
|
async getPriceNoOlderThan(provider, timePeriod, priceFeedId) {
|
|
86
78
|
const result = await provider.get("get_price_no_older_than", [
|
|
87
|
-
{
|
|
88
|
-
|
|
79
|
+
{
|
|
80
|
+
type: "int",
|
|
81
|
+
value: BigInt(timePeriod)
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
type: "int",
|
|
85
|
+
value: BigInt(priceFeedId)
|
|
86
|
+
}
|
|
89
87
|
]);
|
|
90
88
|
const price = result.stack.readNumber();
|
|
91
89
|
const conf = result.stack.readNumber();
|
|
@@ -95,12 +93,15 @@ class PythContract {
|
|
|
95
93
|
price,
|
|
96
94
|
conf,
|
|
97
95
|
expo,
|
|
98
|
-
publishTime
|
|
96
|
+
publishTime
|
|
99
97
|
};
|
|
100
98
|
}
|
|
101
99
|
async getEmaPriceUnsafe(provider, priceFeedId) {
|
|
102
100
|
const result = await provider.get("get_ema_price_unsafe", [
|
|
103
|
-
{
|
|
101
|
+
{
|
|
102
|
+
type: "int",
|
|
103
|
+
value: BigInt(priceFeedId)
|
|
104
|
+
}
|
|
104
105
|
]);
|
|
105
106
|
const price = result.stack.readNumber();
|
|
106
107
|
const conf = result.stack.readNumber();
|
|
@@ -110,13 +111,19 @@ class PythContract {
|
|
|
110
111
|
price,
|
|
111
112
|
conf,
|
|
112
113
|
expo,
|
|
113
|
-
publishTime
|
|
114
|
+
publishTime
|
|
114
115
|
};
|
|
115
116
|
}
|
|
116
117
|
async getEmaPriceNoOlderThan(provider, timePeriod, priceFeedId) {
|
|
117
118
|
const result = await provider.get("get_ema_price_no_older_than", [
|
|
118
|
-
{
|
|
119
|
-
|
|
119
|
+
{
|
|
120
|
+
type: "int",
|
|
121
|
+
value: BigInt(timePeriod)
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
type: "int",
|
|
125
|
+
value: BigInt(priceFeedId)
|
|
126
|
+
}
|
|
120
127
|
]);
|
|
121
128
|
const price = result.stack.readNumber();
|
|
122
129
|
const conf = result.stack.readNumber();
|
|
@@ -126,12 +133,15 @@ class PythContract {
|
|
|
126
133
|
price,
|
|
127
134
|
conf,
|
|
128
135
|
expo,
|
|
129
|
-
publishTime
|
|
136
|
+
publishTime
|
|
130
137
|
};
|
|
131
138
|
}
|
|
132
139
|
async getUpdateFee(provider, vm) {
|
|
133
140
|
const result = await provider.get("get_update_fee", [
|
|
134
|
-
{
|
|
141
|
+
{
|
|
142
|
+
type: "slice",
|
|
143
|
+
cell: createCellChain(vm)
|
|
144
|
+
}
|
|
135
145
|
]);
|
|
136
146
|
return result.stack.readNumber();
|
|
137
147
|
}
|
|
@@ -157,7 +167,10 @@ class PythContract {
|
|
|
157
167
|
}
|
|
158
168
|
async getGuardianSet(provider, index) {
|
|
159
169
|
const result = await provider.get("get_guardian_set", [
|
|
160
|
-
{
|
|
170
|
+
{
|
|
171
|
+
type: "int",
|
|
172
|
+
value: BigInt(index)
|
|
173
|
+
}
|
|
161
174
|
]);
|
|
162
175
|
const expirationTime = result.stack.readNumber();
|
|
163
176
|
const keys = parseGuardianSetKeys(result.stack.readCell());
|
|
@@ -165,18 +178,17 @@ class PythContract {
|
|
|
165
178
|
return {
|
|
166
179
|
expirationTime,
|
|
167
180
|
keys,
|
|
168
|
-
keyCount
|
|
181
|
+
keyCount
|
|
169
182
|
};
|
|
170
183
|
}
|
|
171
184
|
}
|
|
172
|
-
|
|
173
|
-
function createCellChain(buffer) {
|
|
185
|
+
export function createCellChain(buffer) {
|
|
174
186
|
const chunks = bufferToChunks(buffer, 127);
|
|
175
|
-
let lastCell
|
|
187
|
+
let lastCell;
|
|
176
188
|
// Iterate through chunks in reverse order
|
|
177
|
-
for
|
|
189
|
+
for(let i = chunks.length - 1; i >= 0; i--){
|
|
178
190
|
const chunk = chunks[i];
|
|
179
|
-
const cellBuilder =
|
|
191
|
+
const cellBuilder = beginCell();
|
|
180
192
|
const buffer = Buffer.from(chunk);
|
|
181
193
|
cellBuilder.storeBuffer(buffer);
|
|
182
194
|
if (lastCell) {
|
|
@@ -190,22 +202,21 @@ function createCellChain(buffer) {
|
|
|
190
202
|
}
|
|
191
203
|
return lastCell;
|
|
192
204
|
}
|
|
193
|
-
exports.createCellChain = createCellChain;
|
|
194
205
|
function bufferToChunks(buff, chunkSizeBytes = 127) {
|
|
195
206
|
const chunks = [];
|
|
196
207
|
const uint8Array = new Uint8Array(buff.buffer, buff.byteOffset, buff.byteLength);
|
|
197
|
-
for
|
|
208
|
+
for(let offset = 0; offset < uint8Array.length; offset += chunkSizeBytes){
|
|
198
209
|
const remainingBytes = Math.min(chunkSizeBytes, uint8Array.length - offset);
|
|
199
210
|
const chunk = uint8Array.subarray(offset, offset + remainingBytes);
|
|
200
211
|
chunks.push(chunk);
|
|
201
212
|
}
|
|
202
213
|
return chunks;
|
|
203
214
|
}
|
|
204
|
-
function parseDataSources(cell) {
|
|
215
|
+
export function parseDataSources(cell) {
|
|
205
216
|
const dataSources = [];
|
|
206
217
|
const slice = cell.beginParse();
|
|
207
|
-
const dict = slice.loadDictDirect(
|
|
208
|
-
for (const [, value] of dict)
|
|
218
|
+
const dict = slice.loadDictDirect(Dictionary.Keys.Uint(8), Dictionary.Values.Cell());
|
|
219
|
+
for (const [, value] of dict){
|
|
209
220
|
const dataSource = parseDataSource(value);
|
|
210
221
|
if (dataSource) {
|
|
211
222
|
dataSources.push(dataSource);
|
|
@@ -213,22 +224,23 @@ function parseDataSources(cell) {
|
|
|
213
224
|
}
|
|
214
225
|
return dataSources;
|
|
215
226
|
}
|
|
216
|
-
|
|
217
|
-
function parseDataSource(cell) {
|
|
227
|
+
export function parseDataSource(cell) {
|
|
218
228
|
const slice = cell.beginParse();
|
|
219
229
|
if (slice.remainingBits === 0) {
|
|
220
|
-
return
|
|
230
|
+
return;
|
|
221
231
|
}
|
|
222
232
|
const emitterChain = slice.loadUint(16);
|
|
223
233
|
const emitterAddress = slice.loadUintBig(256).toString(16).padStart(64, "0");
|
|
224
|
-
return {
|
|
234
|
+
return {
|
|
235
|
+
emitterChain,
|
|
236
|
+
emitterAddress
|
|
237
|
+
};
|
|
225
238
|
}
|
|
226
|
-
|
|
227
|
-
function parseGuardianSetKeys(cell) {
|
|
239
|
+
export function parseGuardianSetKeys(cell) {
|
|
228
240
|
const keys = [];
|
|
229
241
|
function parseCell(c) {
|
|
230
242
|
let slice = c.beginParse();
|
|
231
|
-
while
|
|
243
|
+
while(slice.remainingRefs > 0 || slice.remainingBits >= 160){
|
|
232
244
|
if (slice.remainingBits >= 160) {
|
|
233
245
|
const bitsToSkip = slice.remainingBits - 160;
|
|
234
246
|
slice = slice.skip(bitsToSkip);
|
|
@@ -243,10 +255,6 @@ function parseGuardianSetKeys(cell) {
|
|
|
243
255
|
parseCell(cell);
|
|
244
256
|
return keys;
|
|
245
257
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
return ((exports.UPDATE_PRICE_FEEDS_BASE_GAS +
|
|
249
|
-
exports.UPDATE_PRICE_FEEDS_PER_UPDATE_GAS * numUpdates) *
|
|
250
|
-
exports.GAS_PRICE_FACTOR);
|
|
258
|
+
export function calculateUpdatePriceFeedsFee(numUpdates) {
|
|
259
|
+
return (UPDATE_PRICE_FEEDS_BASE_GAS + UPDATE_PRICE_FEEDS_PER_UPDATE_GAS * numUpdates) * GAS_PRICE_FACTOR;
|
|
251
260
|
}
|
|
252
|
-
exports.calculateUpdatePriceFeedsFee = calculateUpdatePriceFeedsFee;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "module" }
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pythnetwork/pyth-ton-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Pyth Network TON Utilities",
|
|
5
5
|
"homepage": "https://pyth.network",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Pyth Data Association"
|
|
8
8
|
},
|
|
9
|
-
"main": "
|
|
10
|
-
"types": "
|
|
9
|
+
"main": "./dist/cjs/index.cjs",
|
|
10
|
+
"types": "./dist/cjs/index.d.ts",
|
|
11
11
|
"files": [
|
|
12
|
-
"
|
|
12
|
+
"dist/**/*"
|
|
13
13
|
],
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -19,32 +19,49 @@
|
|
|
19
19
|
"publishConfig": {
|
|
20
20
|
"access": "public"
|
|
21
21
|
},
|
|
22
|
-
"scripts": {
|
|
23
|
-
"build": "tsc",
|
|
24
|
-
"format": "prettier --write \"src/**/*.ts\"",
|
|
25
|
-
"test:lint": "eslint src/",
|
|
26
|
-
"prepublishOnly": "pnpm run build && pnpm run test:lint",
|
|
27
|
-
"preversion": "pnpm run test:lint",
|
|
28
|
-
"version": "pnpm run format && git add -A src"
|
|
29
|
-
},
|
|
30
22
|
"keywords": [
|
|
31
23
|
"pyth",
|
|
32
24
|
"oracle"
|
|
33
25
|
],
|
|
34
26
|
"license": "Apache-2.0",
|
|
35
27
|
"devDependencies": {
|
|
28
|
+
"@cprussin/eslint-config": "^4.0.2",
|
|
36
29
|
"@ton/core": "^0.59.0",
|
|
37
30
|
"@ton/crypto": "^3.3.0",
|
|
38
31
|
"@ton/ton": "^15.1.0",
|
|
39
32
|
"@types/node": "^18.11.18",
|
|
40
|
-
"
|
|
41
|
-
"@typescript-eslint/parser": "^5.21.0",
|
|
42
|
-
"eslint": "^8.14.0",
|
|
33
|
+
"eslint": "^9.23.0",
|
|
43
34
|
"jest": "^29.4.1",
|
|
44
|
-
"prettier": "^
|
|
35
|
+
"prettier": "^3.5.3",
|
|
45
36
|
"ts-jest": "^29.0.5",
|
|
46
|
-
"ts-node": "^10.9.2"
|
|
47
|
-
|
|
37
|
+
"ts-node": "^10.9.2"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22.14.0"
|
|
48
41
|
},
|
|
49
|
-
"
|
|
50
|
-
|
|
42
|
+
"type": "module",
|
|
43
|
+
"exports": {
|
|
44
|
+
".": {
|
|
45
|
+
"require": {
|
|
46
|
+
"types": "./dist/cjs/index.d.ts",
|
|
47
|
+
"default": "./dist/cjs/index.cjs"
|
|
48
|
+
},
|
|
49
|
+
"import": {
|
|
50
|
+
"types": "./dist/esm/index.d.ts",
|
|
51
|
+
"default": "./dist/esm/index.mjs"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"./package.json": "./package.json"
|
|
55
|
+
},
|
|
56
|
+
"module": "./dist/esm/index.mjs",
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "ts-duality",
|
|
59
|
+
"test:lint": "eslint src/ --max-warnings 0",
|
|
60
|
+
"test:format": "prettier --check \"src/**/*.ts\"",
|
|
61
|
+
"fix:lint": "eslint src/ --fix --max-warnings 0",
|
|
62
|
+
"fix:format": "prettier --write \"src/**/*.ts\"",
|
|
63
|
+
"preversion": "pnpm run test:lint",
|
|
64
|
+
"version": "pnpm run test:format && git add -A src",
|
|
65
|
+
"clean": "rm -rf ./dist"
|
|
66
|
+
}
|
|
67
|
+
}
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,OAAO,EAEP,IAAI,EACJ,QAAQ,EAER,MAAM,EAGP,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,eAAO,MAAM,6BAA6B,qDACU,CAAC;AACrD,eAAO,MAAM,6BAA6B,qDACU,CAAC;AAErD,eAAO,MAAM,2BAA2B,UAAU,CAAC;AACnD,eAAO,MAAM,iCAAiC,SAAS,CAAC;AAExD,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,YAAa,YAAW,QAAQ;IAEzC,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,IAAI,CAAC;cAAU,IAAI;cAAQ,IAAI;;gBAD/B,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC;cAAU,IAAI;cAAQ,IAAI;iBAAE;IAG5C,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO;IAInC,0BAA0B,CAAC,QAAQ,EAAE,gBAAgB;IAMrD,qBAAqB,CACzB,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM;IAcN,oBAAoB,CACxB,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM;IAcb,2BAA2B,CAC/B,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,MAAM;IAcpB,mBAAmB,CACvB,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,IAAI;IAcT,cAAc,CAAC,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM;;;;;;IAkB9D,mBAAmB,CACvB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM;;;;;;IAoBf,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM;;;;;;IAkBjE,sBAAsB,CAC1B,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM;;;;;;IAoBf,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM;IAQnD,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB;IAM7C,iCAAiC,CAAC,QAAQ,EAAE,gBAAgB;IAS5D,UAAU,CAAC,QAAQ,EAAE,gBAAgB;IAMrC,cAAc,CAAC,QAAQ,EAAE,gBAAgB;IAKzC,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB;IAKlD,cAAc,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM;;;;;CAe/D;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAsBpD;AAmBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,EAAE,CAczD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CAQ7D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAoBzD;AAED,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,UAM9D"}
|