@lightconexyz/lightcone-sdk 0.6.1 → 0.7.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/README.md +6 -2
- package/dist/auth/client.d.ts.map +1 -1
- package/dist/auth/client.js +2 -0
- package/dist/auth/client.js.map +1 -1
- package/dist/auth/index.d.ts +15 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +10 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/client.d.ts +17 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +36 -13
- package/dist/client.js.map +1 -1
- package/dist/context.d.ts +7 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +60 -6
- package/dist/context.js.map +1 -1
- package/dist/domain/admin/client.d.ts +11 -1
- package/dist/domain/admin/client.d.ts.map +1 -1
- package/dist/domain/admin/client.js +39 -4
- package/dist/domain/admin/client.js.map +1 -1
- package/dist/domain/admin/wire.d.ts +37 -12
- package/dist/domain/admin/wire.d.ts.map +1 -1
- package/dist/domain/admin/wire.js.map +1 -1
- package/dist/domain/market/client.js +1 -1
- package/dist/domain/market/client.js.map +1 -1
- package/dist/domain/market/convert.js +1 -1
- package/dist/domain/market/convert.js.map +1 -1
- package/dist/domain/market/index.d.ts +8 -1
- package/dist/domain/market/index.d.ts.map +1 -1
- package/dist/domain/market/index.js +12 -0
- package/dist/domain/market/index.js.map +1 -1
- package/dist/domain/market/outcome.d.ts +1 -0
- package/dist/domain/market/outcome.d.ts.map +1 -1
- package/dist/domain/market/outcome.js +1 -0
- package/dist/domain/market/outcome.js.map +1 -1
- package/dist/domain/market/tokens.d.ts +2 -0
- package/dist/domain/market/tokens.d.ts.map +1 -1
- package/dist/domain/market/tokens.js +6 -1
- package/dist/domain/market/tokens.js.map +1 -1
- package/dist/domain/market/wire.d.ts +23 -2
- package/dist/domain/market/wire.d.ts.map +1 -1
- package/dist/domain/market/wire.js +5 -0
- package/dist/domain/market/wire.js.map +1 -1
- package/dist/domain/metrics/client.d.ts +3 -3
- package/dist/domain/metrics/client.d.ts.map +1 -1
- package/dist/domain/metrics/client.js +4 -4
- package/dist/domain/metrics/client.js.map +1 -1
- package/dist/domain/metrics/wire.d.ts +5 -1
- package/dist/domain/metrics/wire.d.ts.map +1 -1
- package/dist/domain/metrics/wire.js.map +1 -1
- package/dist/domain/notification/client.d.ts +2 -2
- package/dist/domain/notification/client.d.ts.map +1 -1
- package/dist/domain/notification/client.js +3 -3
- package/dist/domain/notification/client.js.map +1 -1
- package/dist/domain/notification/index.d.ts +3 -1
- package/dist/domain/notification/index.d.ts.map +1 -1
- package/dist/domain/notification/index.js.map +1 -1
- package/dist/domain/order/client.d.ts +12 -10
- package/dist/domain/order/client.d.ts.map +1 -1
- package/dist/domain/order/client.js +20 -13
- package/dist/domain/order/client.js.map +1 -1
- package/dist/domain/order/convert.d.ts +1 -1
- package/dist/domain/order/convert.d.ts.map +1 -1
- package/dist/domain/order/convert.js +2 -2
- package/dist/domain/order/convert.js.map +1 -1
- package/dist/domain/order/index.d.ts +2 -1
- package/dist/domain/order/index.d.ts.map +1 -1
- package/dist/domain/order/index.js +11 -3
- package/dist/domain/order/index.js.map +1 -1
- package/dist/domain/orderbook/client.d.ts +6 -2
- package/dist/domain/orderbook/client.d.ts.map +1 -1
- package/dist/domain/orderbook/client.js +17 -0
- package/dist/domain/orderbook/client.js.map +1 -1
- package/dist/domain/position/builders.d.ts +11 -8
- package/dist/domain/position/builders.d.ts.map +1 -1
- package/dist/domain/position/builders.js +31 -25
- package/dist/domain/position/builders.js.map +1 -1
- package/dist/domain/position/client.d.ts +21 -15
- package/dist/domain/position/client.d.ts.map +1 -1
- package/dist/domain/position/client.js +43 -22
- package/dist/domain/position/client.js.map +1 -1
- package/dist/domain/referral/client.d.ts +2 -2
- package/dist/domain/referral/client.d.ts.map +1 -1
- package/dist/domain/referral/client.js +3 -3
- package/dist/domain/referral/client.js.map +1 -1
- package/dist/domain/trade/client.d.ts +1 -0
- package/dist/domain/trade/client.d.ts.map +1 -1
- package/dist/domain/trade/client.js +14 -0
- package/dist/domain/trade/client.js.map +1 -1
- package/dist/domain/trade/wire.d.ts +6 -0
- package/dist/domain/trade/wire.d.ts.map +1 -1
- package/dist/domain/trade/wire.js.map +1 -1
- package/dist/env.d.ts +6 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +19 -9
- package/dist/env.js.map +1 -1
- package/dist/http/client.d.ts +7 -7
- package/dist/http/client.d.ts.map +1 -1
- package/dist/http/client.js +15 -12
- package/dist/http/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/prelude.d.ts +8 -7
- package/dist/prelude.d.ts.map +1 -1
- package/dist/prelude.js +7 -6
- package/dist/prelude.js.map +1 -1
- package/dist/privy/index.d.ts +1 -1
- package/dist/privy/index.js.map +1 -1
- package/dist/program/accounts.d.ts +12 -7
- package/dist/program/accounts.d.ts.map +1 -1
- package/dist/program/accounts.js +38 -16
- package/dist/program/accounts.js.map +1 -1
- package/dist/program/builder.d.ts +0 -4
- package/dist/program/builder.d.ts.map +1 -1
- package/dist/program/builder.js +0 -8
- package/dist/program/builder.js.map +1 -1
- package/dist/program/constants.d.ts +20 -7
- package/dist/program/constants.d.ts.map +1 -1
- package/dist/program/constants.js +21 -8
- package/dist/program/constants.js.map +1 -1
- package/dist/program/error.d.ts +25 -1
- package/dist/program/error.d.ts.map +1 -1
- package/dist/program/error.js +72 -0
- package/dist/program/error.js.map +1 -1
- package/dist/program/index.d.ts +7 -7
- package/dist/program/index.d.ts.map +1 -1
- package/dist/program/index.js +36 -9
- package/dist/program/index.js.map +1 -1
- package/dist/program/instructions.d.ts +184 -71
- package/dist/program/instructions.d.ts.map +1 -1
- package/dist/program/instructions.js +573 -140
- package/dist/program/instructions.js.map +1 -1
- package/dist/program/orders.js +2 -2
- package/dist/program/orders.js.map +1 -1
- package/dist/program/pda.d.ts +21 -3
- package/dist/program/pda.d.ts.map +1 -1
- package/dist/program/pda.js +43 -6
- package/dist/program/pda.js.map +1 -1
- package/dist/program/types.d.ts +139 -21
- package/dist/program/types.d.ts.map +1 -1
- package/dist/program/types.js.map +1 -1
- package/dist/program/utils.d.ts +31 -2
- package/dist/program/utils.d.ts.map +1 -1
- package/dist/program/utils.js +132 -5
- package/dist/program/utils.js.map +1 -1
- package/dist/rpc.d.ts +6 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +9 -7
- package/dist/rpc.js.map +1 -1
- package/dist/rpcFailover.d.ts +22 -0
- package/dist/rpcFailover.d.ts.map +1 -0
- package/dist/rpcFailover.js +71 -0
- package/dist/rpcFailover.js.map +1 -0
- package/dist/shared/fmt/constants.d.ts +5 -0
- package/dist/shared/fmt/constants.d.ts.map +1 -0
- package/dist/shared/fmt/constants.js +25 -0
- package/dist/shared/fmt/constants.js.map +1 -0
- package/dist/shared/fmt/decimal.d.ts +7 -0
- package/dist/shared/fmt/decimal.d.ts.map +1 -1
- package/dist/shared/fmt/decimal.js +28 -20
- package/dist/shared/fmt/decimal.js.map +1 -1
- package/dist/shared/fmt/num.d.ts +7 -0
- package/dist/shared/fmt/num.d.ts.map +1 -1
- package/dist/shared/fmt/num.js +27 -15
- package/dist/shared/fmt/num.js.map +1 -1
- package/dist/ws/client.node.js +1 -1
- package/dist/ws/client.node.js.map +1 -1
- package/package.json +1 -1
package/dist/program/utils.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.fromBeBytes = fromBeBytes;
|
|
|
7
7
|
exports.toU8 = toU8;
|
|
8
8
|
exports.toU64Le = toU64Le;
|
|
9
9
|
exports.toU32Le = toU32Le;
|
|
10
|
+
exports.toI16Le = toI16Le;
|
|
10
11
|
exports.toI64Le = toI64Le;
|
|
11
12
|
exports.fromI64Le = fromI64Le;
|
|
12
13
|
exports.keccak256 = keccak256;
|
|
@@ -15,14 +16,20 @@ exports.getAssociatedTokenAddress = getAssociatedTokenAddress;
|
|
|
15
16
|
exports.getConditionalTokenAta = getConditionalTokenAta;
|
|
16
17
|
exports.getDepositTokenAta = getDepositTokenAta;
|
|
17
18
|
exports.serializeString = serializeString;
|
|
19
|
+
exports.serializeStringU32 = serializeStringU32;
|
|
20
|
+
exports.serializeConditionalMetadata = serializeConditionalMetadata;
|
|
18
21
|
exports.deserializeString = deserializeString;
|
|
19
22
|
exports.validateOutcomes = validateOutcomes;
|
|
20
23
|
exports.validateOutcomeIndex = validateOutcomeIndex;
|
|
24
|
+
exports.validateFeePair = validateFeePair;
|
|
21
25
|
exports.validate32Bytes = validate32Bytes;
|
|
26
|
+
exports.winnerTakesAllPayoutNumerators = winnerTakesAllPayoutNumerators;
|
|
27
|
+
exports.scalarToPayoutNumerators = scalarToPayoutNumerators;
|
|
22
28
|
const web3_js_1 = require("@solana/web3.js");
|
|
23
29
|
const js_sha3_1 = require("js-sha3");
|
|
24
30
|
const error_1 = require("./error");
|
|
25
31
|
const constants_1 = require("./constants");
|
|
32
|
+
const U32_MAX = 0xffffffffn;
|
|
26
33
|
// ============================================================================
|
|
27
34
|
// BUFFER UTILITIES - Little Endian
|
|
28
35
|
// ============================================================================
|
|
@@ -98,6 +105,17 @@ function toU32Le(value) {
|
|
|
98
105
|
buffer.writeUInt32LE(value, 0);
|
|
99
106
|
return buffer;
|
|
100
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Convert a number to i16 little-endian buffer
|
|
110
|
+
*/
|
|
111
|
+
function toI16Le(value) {
|
|
112
|
+
if (!Number.isInteger(value) || value < -32768 || value > 32767) {
|
|
113
|
+
throw error_1.ProgramSdkError.serialization(`i16 value out of range: ${value}`);
|
|
114
|
+
}
|
|
115
|
+
const buffer = Buffer.alloc(2);
|
|
116
|
+
buffer.writeInt16LE(value, 0);
|
|
117
|
+
return buffer;
|
|
118
|
+
}
|
|
101
119
|
/**
|
|
102
120
|
* Convert a bigint to i64 little-endian buffer (signed)
|
|
103
121
|
*/
|
|
@@ -150,18 +168,18 @@ function deriveConditionId(oracle, questionId, numOutcomes) {
|
|
|
150
168
|
* Derive Associated Token Address
|
|
151
169
|
* @param mint - The token mint
|
|
152
170
|
* @param owner - The owner of the ATA
|
|
153
|
-
* @param token2022 -
|
|
171
|
+
* @param token2022 - Deprecated. Conditional tokens now use SPL Token.
|
|
154
172
|
*/
|
|
155
173
|
function getAssociatedTokenAddress(mint, owner, token2022 = false) {
|
|
156
|
-
const tokenProgramId =
|
|
174
|
+
const tokenProgramId = constants_1.TOKEN_PROGRAM_ID;
|
|
157
175
|
const [address] = web3_js_1.PublicKey.findProgramAddressSync([owner.toBuffer(), tokenProgramId.toBuffer(), mint.toBuffer()], constants_1.ASSOCIATED_TOKEN_PROGRAM_ID);
|
|
158
176
|
return address;
|
|
159
177
|
}
|
|
160
178
|
/**
|
|
161
|
-
* Get ATA for a conditional token (
|
|
179
|
+
* Get ATA for a conditional token (SPL Token)
|
|
162
180
|
*/
|
|
163
181
|
function getConditionalTokenAta(mint, owner) {
|
|
164
|
-
return getAssociatedTokenAddress(mint, owner,
|
|
182
|
+
return getAssociatedTokenAddress(mint, owner, false);
|
|
165
183
|
}
|
|
166
184
|
/**
|
|
167
185
|
* Get ATA for a deposit token (SPL Token)
|
|
@@ -181,6 +199,28 @@ function serializeString(str) {
|
|
|
181
199
|
lengthBuffer.writeUInt16LE(strBuffer.length, 0);
|
|
182
200
|
return Buffer.concat([lengthBuffer, strBuffer]);
|
|
183
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Serialize a string with u32 length prefix (little-endian), enforcing max UTF-8 bytes.
|
|
204
|
+
*/
|
|
205
|
+
function serializeStringU32(str, maxBytes) {
|
|
206
|
+
const strBuffer = Buffer.from(str, "utf-8");
|
|
207
|
+
if (strBuffer.length > maxBytes) {
|
|
208
|
+
throw error_1.ProgramSdkError.invalidDataLength("string", maxBytes, strBuffer.length);
|
|
209
|
+
}
|
|
210
|
+
const lengthBuffer = Buffer.alloc(4);
|
|
211
|
+
lengthBuffer.writeUInt32LE(strBuffer.length, 0);
|
|
212
|
+
return Buffer.concat([lengthBuffer, strBuffer]);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Serialize conditional metadata instruction strings.
|
|
216
|
+
*/
|
|
217
|
+
function serializeConditionalMetadata(name, symbol, uri) {
|
|
218
|
+
return Buffer.concat([
|
|
219
|
+
serializeStringU32(name, 32),
|
|
220
|
+
serializeStringU32(symbol, 10),
|
|
221
|
+
serializeStringU32(uri, 200),
|
|
222
|
+
]);
|
|
223
|
+
}
|
|
184
224
|
/**
|
|
185
225
|
* Deserialize a string with u16 length prefix
|
|
186
226
|
* @returns [string, bytesConsumed]
|
|
@@ -197,7 +237,7 @@ function deserializeString(buffer, offset) {
|
|
|
197
237
|
* Validate that a number is within the valid outcomes range
|
|
198
238
|
*/
|
|
199
239
|
function validateOutcomes(numOutcomes) {
|
|
200
|
-
if (numOutcomes <
|
|
240
|
+
if (!Number.isInteger(numOutcomes) || numOutcomes < constants_1.MIN_OUTCOMES || numOutcomes > constants_1.MAX_OUTCOMES) {
|
|
201
241
|
throw error_1.ProgramSdkError.invalidOutcomeCount(numOutcomes);
|
|
202
242
|
}
|
|
203
243
|
}
|
|
@@ -209,6 +249,22 @@ function validateOutcomeIndex(outcomeIndex, numOutcomes) {
|
|
|
209
249
|
throw error_1.ProgramSdkError.invalidOutcomeIndex(outcomeIndex, numOutcomes - 1);
|
|
210
250
|
}
|
|
211
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Validate a maker/taker fee pair against program rules.
|
|
254
|
+
*/
|
|
255
|
+
function validateFeePair(makerFeeBps, takerFeeBps) {
|
|
256
|
+
if (!Number.isInteger(makerFeeBps) ||
|
|
257
|
+
!Number.isInteger(takerFeeBps) ||
|
|
258
|
+
makerFeeBps < -500 ||
|
|
259
|
+
makerFeeBps > 500 ||
|
|
260
|
+
takerFeeBps < -500 ||
|
|
261
|
+
takerFeeBps > 500) {
|
|
262
|
+
throw error_1.ProgramSdkError.invalidFeeRange();
|
|
263
|
+
}
|
|
264
|
+
if (makerFeeBps + takerFeeBps < 0) {
|
|
265
|
+
throw error_1.ProgramSdkError.invalidFeeSum();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
212
268
|
/**
|
|
213
269
|
* Validate that a buffer is exactly 32 bytes
|
|
214
270
|
*/
|
|
@@ -217,4 +273,75 @@ function validate32Bytes(buffer, name) {
|
|
|
217
273
|
throw error_1.ProgramSdkError.invalidDataLength(name, 32, buffer.length);
|
|
218
274
|
}
|
|
219
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Build a winner-takes-all payout vector for a binary or multi-outcome market.
|
|
278
|
+
*/
|
|
279
|
+
function winnerTakesAllPayoutNumerators(winningOutcome, numOutcomes) {
|
|
280
|
+
validateOutcomes(numOutcomes);
|
|
281
|
+
validateOutcomeIndex(winningOutcome, numOutcomes);
|
|
282
|
+
const payoutNumerators = Array(numOutcomes).fill(0);
|
|
283
|
+
payoutNumerators[winningOutcome] = 1;
|
|
284
|
+
return payoutNumerators;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Convert a two-sided scalar resolution into program payout numerators.
|
|
288
|
+
*
|
|
289
|
+
* All values are integer fixed-point BigInts. The resolved value is clamped to
|
|
290
|
+
* [minValue, maxValue], reduced by GCD, and checked against the program's u32
|
|
291
|
+
* payout representation.
|
|
292
|
+
*/
|
|
293
|
+
function scalarToPayoutNumerators(params) {
|
|
294
|
+
validateOutcomes(params.numOutcomes);
|
|
295
|
+
validateOutcomeIndex(params.lowerOutcomeIndex, params.numOutcomes);
|
|
296
|
+
validateOutcomeIndex(params.upperOutcomeIndex, params.numOutcomes);
|
|
297
|
+
if (params.lowerOutcomeIndex === params.upperOutcomeIndex) {
|
|
298
|
+
throw error_1.ProgramSdkError.duplicateScalarOutcomes();
|
|
299
|
+
}
|
|
300
|
+
const range = params.maxValue - params.minValue;
|
|
301
|
+
if (range <= 0n) {
|
|
302
|
+
throw error_1.ProgramSdkError.invalidScalarRange();
|
|
303
|
+
}
|
|
304
|
+
const clamped = params.resolvedValue < params.minValue
|
|
305
|
+
? params.minValue
|
|
306
|
+
: params.resolvedValue > params.maxValue
|
|
307
|
+
? params.maxValue
|
|
308
|
+
: params.resolvedValue;
|
|
309
|
+
const numerators = Array(params.numOutcomes).fill(0n);
|
|
310
|
+
numerators[params.lowerOutcomeIndex] = params.maxValue - clamped;
|
|
311
|
+
numerators[params.upperOutcomeIndex] = clamped - params.minValue;
|
|
312
|
+
return reduceAndFitPayoutNumerators(numerators);
|
|
313
|
+
}
|
|
314
|
+
function reduceAndFitPayoutNumerators(numerators) {
|
|
315
|
+
const nonZero = numerators.filter((n) => n > 0n);
|
|
316
|
+
if (nonZero.length === 0) {
|
|
317
|
+
throw error_1.ProgramSdkError.invalidPayoutNumerators();
|
|
318
|
+
}
|
|
319
|
+
const gcd = nonZero.reduce((acc, value) => gcdBigInt(acc, value));
|
|
320
|
+
let sum = 0n;
|
|
321
|
+
const reduced = numerators.map((numerator) => {
|
|
322
|
+
const value = numerator === 0n ? 0n : numerator / gcd;
|
|
323
|
+
if (value > U32_MAX) {
|
|
324
|
+
throw error_1.ProgramSdkError.payoutVectorExceedsU32();
|
|
325
|
+
}
|
|
326
|
+
sum += value;
|
|
327
|
+
return Number(value);
|
|
328
|
+
});
|
|
329
|
+
if (sum === 0n) {
|
|
330
|
+
throw error_1.ProgramSdkError.invalidPayoutNumerators();
|
|
331
|
+
}
|
|
332
|
+
if (sum > U32_MAX) {
|
|
333
|
+
throw error_1.ProgramSdkError.payoutVectorExceedsU32();
|
|
334
|
+
}
|
|
335
|
+
return reduced;
|
|
336
|
+
}
|
|
337
|
+
function gcdBigInt(a, b) {
|
|
338
|
+
let left = a;
|
|
339
|
+
let right = b;
|
|
340
|
+
while (right !== 0n) {
|
|
341
|
+
const remainder = left % right;
|
|
342
|
+
left = right;
|
|
343
|
+
right = remainder;
|
|
344
|
+
}
|
|
345
|
+
return left;
|
|
346
|
+
}
|
|
220
347
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/program/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { PublicKey } from \"@solana/web3.js\";\nimport { keccak_256 } from \"js-sha3\";\nimport { ProgramSdkError } from \"./error\";\nimport {\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n} from \"./constants\";\n\n// ============================================================================\n// BUFFER UTILITIES - Little Endian\n// ============================================================================\n\n/**\n * Convert a bigint to little-endian bytes\n * @param value - The value to convert\n * @param bytes - Number of bytes in the output\n */\nexport function toLeBytes(value: bigint, bytes: number): Buffer {\n const buffer = Buffer.alloc(bytes);\n let remaining = value;\n for (let i = 0; i < bytes; i++) {\n buffer[i] = Number(remaining & 0xffn);\n remaining = remaining >> 8n;\n }\n return buffer;\n}\n\n/**\n * Convert little-endian bytes to bigint\n * @param buffer - The buffer to convert\n */\nexport function fromLeBytes(buffer: Buffer): bigint {\n let result = 0n;\n for (let i = buffer.length - 1; i >= 0; i--) {\n result = (result << 8n) | BigInt(buffer[i]);\n }\n return result;\n}\n\n/**\n * Convert a bigint to big-endian bytes\n * @param value - The value to convert\n * @param bytes - Number of bytes in the output\n */\nexport function toBeBytes(value: bigint, bytes: number): Buffer {\n const buffer = Buffer.alloc(bytes);\n let remaining = value;\n for (let i = bytes - 1; i >= 0; i--) {\n buffer[i] = Number(remaining & 0xffn);\n remaining = remaining >> 8n;\n }\n return buffer;\n}\n\n/**\n * Convert big-endian bytes to bigint\n * @param buffer - The buffer to convert\n */\nexport function fromBeBytes(buffer: Buffer): bigint {\n let result = 0n;\n for (let i = 0; i < buffer.length; i++) {\n result = (result << 8n) | BigInt(buffer[i]);\n }\n return result;\n}\n\n/**\n * Convert a number to u8 buffer\n */\nexport function toU8(value: number): Buffer {\n const buffer = Buffer.alloc(1);\n buffer[0] = value & 0xff;\n return buffer;\n}\n\n/**\n * Convert a bigint to u64 little-endian buffer\n */\nexport function toU64Le(value: bigint): Buffer {\n return toLeBytes(value, 8);\n}\n\n/**\n * Convert a number to u32 little-endian buffer\n */\nexport function toU32Le(value: number): Buffer {\n const buffer = Buffer.alloc(4);\n buffer.writeUInt32LE(value, 0);\n return buffer;\n}\n\n/**\n * Convert a bigint to i64 little-endian buffer (signed)\n */\nexport function toI64Le(value: bigint): Buffer {\n // For negative values, we need to handle two's complement\n if (value < 0n) {\n // Add 2^64 to get two's complement representation\n value = value + (1n << 64n);\n }\n return toLeBytes(value, 8);\n}\n\n/**\n * Convert a buffer to i64 (signed)\n */\nexport function fromI64Le(buffer: Buffer): bigint {\n const unsigned = fromLeBytes(buffer);\n // Check if the high bit is set (negative number)\n if (unsigned >= 1n << 63n) {\n return unsigned - (1n << 64n);\n }\n return unsigned;\n}\n\n// ============================================================================\n// KECCAK256 HASHING\n// ============================================================================\n\n/**\n * Compute keccak256 hash of data\n * @param data - The data to hash\n * @returns 32-byte hash buffer\n */\nexport function keccak256(data: Buffer): Buffer {\n return Buffer.from(keccak_256.arrayBuffer(data));\n}\n\n/**\n * Derive condition ID from oracle, question ID, and number of outcomes\n * This matches the on-chain derivation: keccak256(oracle || questionId || numOutcomes)\n */\nexport function deriveConditionId(\n oracle: PublicKey,\n questionId: Buffer,\n numOutcomes: number\n): Buffer {\n const data = Buffer.concat([\n oracle.toBuffer(),\n questionId,\n toU8(numOutcomes),\n ]);\n return keccak256(data);\n}\n\n// ============================================================================\n// ASSOCIATED TOKEN ADDRESS HELPERS\n// ============================================================================\n\n/**\n * Derive Associated Token Address\n * @param mint - The token mint\n * @param owner - The owner of the ATA\n * @param token2022 - Whether to use Token-2022 program\n */\nexport function getAssociatedTokenAddress(\n mint: PublicKey,\n owner: PublicKey,\n token2022: boolean = false\n): PublicKey {\n const tokenProgramId = token2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID;\n\n const [address] = PublicKey.findProgramAddressSync(\n [owner.toBuffer(), tokenProgramId.toBuffer(), mint.toBuffer()],\n ASSOCIATED_TOKEN_PROGRAM_ID\n );\n\n return address;\n}\n\n/**\n * Get ATA for a conditional token (always Token-2022)\n */\nexport function getConditionalTokenAta(\n mint: PublicKey,\n owner: PublicKey\n): PublicKey {\n return getAssociatedTokenAddress(mint, owner, true);\n}\n\n/**\n * Get ATA for a deposit token (SPL Token)\n */\nexport function getDepositTokenAta(\n mint: PublicKey,\n owner: PublicKey\n): PublicKey {\n return getAssociatedTokenAddress(mint, owner, false);\n}\n\n// ============================================================================\n// STRING SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a string with u16 length prefix (little-endian)\n */\nexport function serializeString(str: string): Buffer {\n const strBuffer = Buffer.from(str, \"utf-8\");\n const lengthBuffer = Buffer.alloc(2);\n lengthBuffer.writeUInt16LE(strBuffer.length, 0);\n return Buffer.concat([lengthBuffer, strBuffer]);\n}\n\n/**\n * Deserialize a string with u16 length prefix\n * @returns [string, bytesConsumed]\n */\nexport function deserializeString(\n buffer: Buffer,\n offset: number\n): [string, number] {\n const length = buffer.readUInt16LE(offset);\n const str = buffer.toString(\"utf-8\", offset + 2, offset + 2 + length);\n return [str, 2 + length];\n}\n\n// ============================================================================\n// VALIDATION HELPERS\n// ============================================================================\n\n/**\n * Validate that a number is within the valid outcomes range\n */\nexport function validateOutcomes(numOutcomes: number): void {\n if (numOutcomes < 2 || numOutcomes > 6) {\n throw ProgramSdkError.invalidOutcomeCount(numOutcomes);\n }\n}\n\n/**\n * Validate that an outcome index is valid for a market\n */\nexport function validateOutcomeIndex(\n outcomeIndex: number,\n numOutcomes: number\n): void {\n if (outcomeIndex < 0 || outcomeIndex >= numOutcomes) {\n throw ProgramSdkError.invalidOutcomeIndex(outcomeIndex, numOutcomes - 1);\n }\n}\n\n/**\n * Validate that a buffer is exactly 32 bytes\n */\nexport function validate32Bytes(buffer: Buffer, name: string): void {\n if (buffer.length !== 32) {\n throw ProgramSdkError.invalidDataLength(name, 32, buffer.length);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/program/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { PublicKey } from \"@solana/web3.js\";\nimport { keccak_256 } from \"js-sha3\";\nimport { ProgramSdkError } from \"./error\";\nimport {\n MAX_OUTCOMES,\n MIN_OUTCOMES,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n} from \"./constants\";\nimport type { ScalarResolutionParams } from \"./types\";\n\nconst U32_MAX = 0xffffffffn;\n\n// ============================================================================\n// BUFFER UTILITIES - Little Endian\n// ============================================================================\n\n/**\n * Convert a bigint to little-endian bytes\n * @param value - The value to convert\n * @param bytes - Number of bytes in the output\n */\nexport function toLeBytes(value: bigint, bytes: number): Buffer {\n const buffer = Buffer.alloc(bytes);\n let remaining = value;\n for (let i = 0; i < bytes; i++) {\n buffer[i] = Number(remaining & 0xffn);\n remaining = remaining >> 8n;\n }\n return buffer;\n}\n\n/**\n * Convert little-endian bytes to bigint\n * @param buffer - The buffer to convert\n */\nexport function fromLeBytes(buffer: Buffer): bigint {\n let result = 0n;\n for (let i = buffer.length - 1; i >= 0; i--) {\n result = (result << 8n) | BigInt(buffer[i]);\n }\n return result;\n}\n\n/**\n * Convert a bigint to big-endian bytes\n * @param value - The value to convert\n * @param bytes - Number of bytes in the output\n */\nexport function toBeBytes(value: bigint, bytes: number): Buffer {\n const buffer = Buffer.alloc(bytes);\n let remaining = value;\n for (let i = bytes - 1; i >= 0; i--) {\n buffer[i] = Number(remaining & 0xffn);\n remaining = remaining >> 8n;\n }\n return buffer;\n}\n\n/**\n * Convert big-endian bytes to bigint\n * @param buffer - The buffer to convert\n */\nexport function fromBeBytes(buffer: Buffer): bigint {\n let result = 0n;\n for (let i = 0; i < buffer.length; i++) {\n result = (result << 8n) | BigInt(buffer[i]);\n }\n return result;\n}\n\n/**\n * Convert a number to u8 buffer\n */\nexport function toU8(value: number): Buffer {\n const buffer = Buffer.alloc(1);\n buffer[0] = value & 0xff;\n return buffer;\n}\n\n/**\n * Convert a bigint to u64 little-endian buffer\n */\nexport function toU64Le(value: bigint): Buffer {\n return toLeBytes(value, 8);\n}\n\n/**\n * Convert a number to u32 little-endian buffer\n */\nexport function toU32Le(value: number): Buffer {\n const buffer = Buffer.alloc(4);\n buffer.writeUInt32LE(value, 0);\n return buffer;\n}\n\n/**\n * Convert a number to i16 little-endian buffer\n */\nexport function toI16Le(value: number): Buffer {\n if (!Number.isInteger(value) || value < -32768 || value > 32767) {\n throw ProgramSdkError.serialization(`i16 value out of range: ${value}`);\n }\n const buffer = Buffer.alloc(2);\n buffer.writeInt16LE(value, 0);\n return buffer;\n}\n\n/**\n * Convert a bigint to i64 little-endian buffer (signed)\n */\nexport function toI64Le(value: bigint): Buffer {\n // For negative values, we need to handle two's complement\n if (value < 0n) {\n // Add 2^64 to get two's complement representation\n value = value + (1n << 64n);\n }\n return toLeBytes(value, 8);\n}\n\n/**\n * Convert a buffer to i64 (signed)\n */\nexport function fromI64Le(buffer: Buffer): bigint {\n const unsigned = fromLeBytes(buffer);\n // Check if the high bit is set (negative number)\n if (unsigned >= 1n << 63n) {\n return unsigned - (1n << 64n);\n }\n return unsigned;\n}\n\n// ============================================================================\n// KECCAK256 HASHING\n// ============================================================================\n\n/**\n * Compute keccak256 hash of data\n * @param data - The data to hash\n * @returns 32-byte hash buffer\n */\nexport function keccak256(data: Buffer): Buffer {\n return Buffer.from(keccak_256.arrayBuffer(data));\n}\n\n/**\n * Derive condition ID from oracle, question ID, and number of outcomes\n * This matches the on-chain derivation: keccak256(oracle || questionId || numOutcomes)\n */\nexport function deriveConditionId(\n oracle: PublicKey,\n questionId: Buffer,\n numOutcomes: number\n): Buffer {\n const data = Buffer.concat([\n oracle.toBuffer(),\n questionId,\n toU8(numOutcomes),\n ]);\n return keccak256(data);\n}\n\n// ============================================================================\n// ASSOCIATED TOKEN ADDRESS HELPERS\n// ============================================================================\n\n/**\n * Derive Associated Token Address\n * @param mint - The token mint\n * @param owner - The owner of the ATA\n * @param token2022 - Deprecated. Conditional tokens now use SPL Token.\n */\nexport function getAssociatedTokenAddress(\n mint: PublicKey,\n owner: PublicKey,\n token2022: boolean = false\n): PublicKey {\n const tokenProgramId = TOKEN_PROGRAM_ID;\n\n const [address] = PublicKey.findProgramAddressSync(\n [owner.toBuffer(), tokenProgramId.toBuffer(), mint.toBuffer()],\n ASSOCIATED_TOKEN_PROGRAM_ID\n );\n\n return address;\n}\n\n/**\n * Get ATA for a conditional token (SPL Token)\n */\nexport function getConditionalTokenAta(\n mint: PublicKey,\n owner: PublicKey\n): PublicKey {\n return getAssociatedTokenAddress(mint, owner, false);\n}\n\n/**\n * Get ATA for a deposit token (SPL Token)\n */\nexport function getDepositTokenAta(\n mint: PublicKey,\n owner: PublicKey\n): PublicKey {\n return getAssociatedTokenAddress(mint, owner, false);\n}\n\n// ============================================================================\n// STRING SERIALIZATION\n// ============================================================================\n\n/**\n * Serialize a string with u16 length prefix (little-endian)\n */\nexport function serializeString(str: string): Buffer {\n const strBuffer = Buffer.from(str, \"utf-8\");\n const lengthBuffer = Buffer.alloc(2);\n lengthBuffer.writeUInt16LE(strBuffer.length, 0);\n return Buffer.concat([lengthBuffer, strBuffer]);\n}\n\n/**\n * Serialize a string with u32 length prefix (little-endian), enforcing max UTF-8 bytes.\n */\nexport function serializeStringU32(str: string, maxBytes: number): Buffer {\n const strBuffer = Buffer.from(str, \"utf-8\");\n if (strBuffer.length > maxBytes) {\n throw ProgramSdkError.invalidDataLength(\"string\", maxBytes, strBuffer.length);\n }\n const lengthBuffer = Buffer.alloc(4);\n lengthBuffer.writeUInt32LE(strBuffer.length, 0);\n return Buffer.concat([lengthBuffer, strBuffer]);\n}\n\n/**\n * Serialize conditional metadata instruction strings.\n */\nexport function serializeConditionalMetadata(\n name: string,\n symbol: string,\n uri: string\n): Buffer {\n return Buffer.concat([\n serializeStringU32(name, 32),\n serializeStringU32(symbol, 10),\n serializeStringU32(uri, 200),\n ]);\n}\n\n/**\n * Deserialize a string with u16 length prefix\n * @returns [string, bytesConsumed]\n */\nexport function deserializeString(\n buffer: Buffer,\n offset: number\n): [string, number] {\n const length = buffer.readUInt16LE(offset);\n const str = buffer.toString(\"utf-8\", offset + 2, offset + 2 + length);\n return [str, 2 + length];\n}\n\n// ============================================================================\n// VALIDATION HELPERS\n// ============================================================================\n\n/**\n * Validate that a number is within the valid outcomes range\n */\nexport function validateOutcomes(numOutcomes: number): void {\n if (!Number.isInteger(numOutcomes) || numOutcomes < MIN_OUTCOMES || numOutcomes > MAX_OUTCOMES) {\n throw ProgramSdkError.invalidOutcomeCount(numOutcomes);\n }\n}\n\n/**\n * Validate that an outcome index is valid for a market\n */\nexport function validateOutcomeIndex(\n outcomeIndex: number,\n numOutcomes: number\n): void {\n if (outcomeIndex < 0 || outcomeIndex >= numOutcomes) {\n throw ProgramSdkError.invalidOutcomeIndex(outcomeIndex, numOutcomes - 1);\n }\n}\n\n/**\n * Validate a maker/taker fee pair against program rules.\n */\nexport function validateFeePair(makerFeeBps: number, takerFeeBps: number): void {\n if (\n !Number.isInteger(makerFeeBps) ||\n !Number.isInteger(takerFeeBps) ||\n makerFeeBps < -500 ||\n makerFeeBps > 500 ||\n takerFeeBps < -500 ||\n takerFeeBps > 500\n ) {\n throw ProgramSdkError.invalidFeeRange();\n }\n if (makerFeeBps + takerFeeBps < 0) {\n throw ProgramSdkError.invalidFeeSum();\n }\n}\n\n/**\n * Validate that a buffer is exactly 32 bytes\n */\nexport function validate32Bytes(buffer: Buffer, name: string): void {\n if (buffer.length !== 32) {\n throw ProgramSdkError.invalidDataLength(name, 32, buffer.length);\n }\n}\n\n/**\n * Build a winner-takes-all payout vector for a binary or multi-outcome market.\n */\nexport function winnerTakesAllPayoutNumerators(\n winningOutcome: number,\n numOutcomes: number\n): number[] {\n validateOutcomes(numOutcomes);\n validateOutcomeIndex(winningOutcome, numOutcomes);\n\n const payoutNumerators = Array<number>(numOutcomes).fill(0);\n payoutNumerators[winningOutcome] = 1;\n return payoutNumerators;\n}\n\n/**\n * Convert a two-sided scalar resolution into program payout numerators.\n *\n * All values are integer fixed-point BigInts. The resolved value is clamped to\n * [minValue, maxValue], reduced by GCD, and checked against the program's u32\n * payout representation.\n */\nexport function scalarToPayoutNumerators(\n params: ScalarResolutionParams\n): number[] {\n validateOutcomes(params.numOutcomes);\n validateOutcomeIndex(params.lowerOutcomeIndex, params.numOutcomes);\n validateOutcomeIndex(params.upperOutcomeIndex, params.numOutcomes);\n\n if (params.lowerOutcomeIndex === params.upperOutcomeIndex) {\n throw ProgramSdkError.duplicateScalarOutcomes();\n }\n\n const range = params.maxValue - params.minValue;\n if (range <= 0n) {\n throw ProgramSdkError.invalidScalarRange();\n }\n\n const clamped =\n params.resolvedValue < params.minValue\n ? params.minValue\n : params.resolvedValue > params.maxValue\n ? params.maxValue\n : params.resolvedValue;\n\n const numerators = Array<bigint>(params.numOutcomes).fill(0n);\n numerators[params.lowerOutcomeIndex] = params.maxValue - clamped;\n numerators[params.upperOutcomeIndex] = clamped - params.minValue;\n\n return reduceAndFitPayoutNumerators(numerators);\n}\n\nfunction reduceAndFitPayoutNumerators(numerators: bigint[]): number[] {\n const nonZero = numerators.filter((n) => n > 0n);\n if (nonZero.length === 0) {\n throw ProgramSdkError.invalidPayoutNumerators();\n }\n\n const gcd = nonZero.reduce((acc, value) => gcdBigInt(acc, value));\n let sum = 0n;\n const reduced = numerators.map((numerator) => {\n const value = numerator === 0n ? 0n : numerator / gcd;\n if (value > U32_MAX) {\n throw ProgramSdkError.payoutVectorExceedsU32();\n }\n sum += value;\n return Number(value);\n });\n\n if (sum === 0n) {\n throw ProgramSdkError.invalidPayoutNumerators();\n }\n if (sum > U32_MAX) {\n throw ProgramSdkError.payoutVectorExceedsU32();\n }\n\n return reduced;\n}\n\nfunction gcdBigInt(a: bigint, b: bigint): bigint {\n let left = a;\n let right = b;\n while (right !== 0n) {\n const remainder = left % right;\n left = right;\n right = remainder;\n }\n return left;\n}\n"]}
|
package/dist/rpc.d.ts
CHANGED
|
@@ -4,7 +4,12 @@ import type { Exchange, GlobalDepositToken } from "./program/types";
|
|
|
4
4
|
export declare class Rpc {
|
|
5
5
|
private readonly client;
|
|
6
6
|
constructor(client: ClientContext);
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Get the currently-active Connection, or throw if not configured.
|
|
9
|
+
*
|
|
10
|
+
* Prefer the typed methods (getExchange, etc.) — they include automatic
|
|
11
|
+
* failover. Direct use of inner() bypasses the retry/failover wrapper.
|
|
12
|
+
*/
|
|
8
13
|
inner(): Connection;
|
|
9
14
|
getExchangePda(): PublicKey;
|
|
10
15
|
getGlobalDepositTokenPda(mint: PublicKey): PublicKey;
|
package/dist/rpc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAY/C,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,qBAAa,GAAG;IACF,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAElD
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAY/C,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,qBAAa,GAAG;IACF,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAElD;;;;;OAKG;IACH,KAAK,IAAI,UAAU;IAMnB,cAAc,IAAI,SAAS;IAI3B,wBAAwB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS;IAIpD,uBAAuB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS;IAM9D,kBAAkB,IAAI,OAAO,CAAC;QAClC,SAAS,EAAE,MAAM,CAAC;QAClB,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;IAMI,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;IAYhC,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAa1E"}
|
package/dist/rpc.js
CHANGED
|
@@ -10,7 +10,12 @@ class Rpc {
|
|
|
10
10
|
constructor(client) {
|
|
11
11
|
this.client = client;
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Get the currently-active Connection, or throw if not configured.
|
|
15
|
+
*
|
|
16
|
+
* Prefer the typed methods (getExchange, etc.) — they include automatic
|
|
17
|
+
* failover. Direct use of inner() bypasses the retry/failover wrapper.
|
|
18
|
+
*/
|
|
14
19
|
inner() {
|
|
15
20
|
return (0, context_1.requireConnection)(this.client);
|
|
16
21
|
}
|
|
@@ -26,22 +31,19 @@ class Rpc {
|
|
|
26
31
|
}
|
|
27
32
|
// ── Account fetchers (async, require Connection) ──────────────────────
|
|
28
33
|
async getLatestBlockhash() {
|
|
29
|
-
|
|
30
|
-
return connection.getLatestBlockhash();
|
|
34
|
+
return (0, context_1.connectionWithFailover)(this.client, (connection) => connection.getLatestBlockhash());
|
|
31
35
|
}
|
|
32
36
|
async getExchange() {
|
|
33
|
-
const connection = (0, context_1.requireConnection)(this.client);
|
|
34
37
|
const pda = this.getExchangePda();
|
|
35
|
-
const accountInfo = await connection.getAccountInfo(pda);
|
|
38
|
+
const accountInfo = await (0, context_1.connectionWithFailover)(this.client, (connection) => connection.getAccountInfo(pda));
|
|
36
39
|
if (!accountInfo) {
|
|
37
40
|
throw error_1.ProgramSdkError.accountNotFound("Exchange");
|
|
38
41
|
}
|
|
39
42
|
return (0, accounts_1.deserializeExchange)(accountInfo.data);
|
|
40
43
|
}
|
|
41
44
|
async getGlobalDepositToken(mint) {
|
|
42
|
-
const connection = (0, context_1.requireConnection)(this.client);
|
|
43
45
|
const pda = this.getGlobalDepositTokenPda(mint);
|
|
44
|
-
const accountInfo = await connection.getAccountInfo(pda);
|
|
46
|
+
const accountInfo = await (0, context_1.connectionWithFailover)(this.client, (connection) => connection.getAccountInfo(pda));
|
|
45
47
|
if (!accountInfo) {
|
|
46
48
|
throw error_1.ProgramSdkError.accountNotFound(`GlobalDepositToken for mint ${mint.toBase58()}`);
|
|
47
49
|
}
|
package/dist/rpc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":";;;AAEA,
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":";;;AAEA,uCAAsE;AACtE,2CAAkD;AAClD,uCAIuB;AACvB,iDAG4B;AAG5B,MAAa,GAAG;IACe;IAA7B,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAEtD;;;;;OAKG;IACH,KAAK;QACH,OAAO,IAAA,2BAAiB,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,yEAAyE;IAEzE,cAAc;QACZ,OAAO,IAAA,oBAAc,EAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,wBAAwB,CAAC,IAAe;QACtC,OAAO,IAAA,8BAAwB,EAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,uBAAuB,CAAC,IAAe,EAAE,IAAe;QACtD,OAAO,IAAA,6BAAuB,EAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,yEAAyE;IAEzE,KAAK,CAAC,kBAAkB;QAItB,OAAO,IAAA,gCAAsB,EAAC,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,CACxD,UAAU,CAAC,kBAAkB,EAAE,CAChC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAClC,MAAM,WAAW,GAAG,MAAM,IAAA,gCAAsB,EAC9C,IAAI,CAAC,MAAM,EACX,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,CAC/C,CAAC;QACF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,uBAAe,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,IAAA,8BAAmB,EAAC,WAAW,CAAC,IAAc,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,IAAe;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,MAAM,IAAA,gCAAsB,EAC9C,IAAI,CAAC,MAAM,EACX,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,CAC/C,CAAC;QACF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,uBAAe,CAAC,eAAe,CACnC,+BAA+B,IAAI,CAAC,QAAQ,EAAE,EAAE,CACjD,CAAC;QACJ,CAAC;QACD,OAAO,IAAA,wCAA6B,EAAC,WAAW,CAAC,IAAc,CAAC,CAAC;IACnE,CAAC;CACF;AA/DD,kBA+DC","sourcesContent":["import type { Connection, PublicKey } from \"@solana/web3.js\";\nimport type { ClientContext } from \"./context\";\nimport { requireConnection, connectionWithFailover } from \"./context\";\nimport { ProgramSdkError } from \"./program/error\";\nimport {\n getExchangePda,\n getGlobalDepositTokenPda,\n getUserGlobalDepositPda,\n} from \"./program/pda\";\nimport {\n deserializeExchange,\n deserializeGlobalDepositToken,\n} from \"./program/accounts\";\nimport type { Exchange, GlobalDepositToken } from \"./program/types\";\n\nexport class Rpc {\n constructor(private readonly client: ClientContext) {}\n\n /**\n * Get the currently-active Connection, or throw if not configured.\n *\n * Prefer the typed methods (getExchange, etc.) — they include automatic\n * failover. Direct use of inner() bypasses the retry/failover wrapper.\n */\n inner(): Connection {\n return requireConnection(this.client);\n }\n\n // ── PDA helpers (sync, no Connection needed) ──────────────────────────\n\n getExchangePda(): PublicKey {\n return getExchangePda(this.client.programId)[0];\n }\n\n getGlobalDepositTokenPda(mint: PublicKey): PublicKey {\n return getGlobalDepositTokenPda(mint, this.client.programId)[0];\n }\n\n getUserGlobalDepositPda(user: PublicKey, mint: PublicKey): PublicKey {\n return getUserGlobalDepositPda(user, mint, this.client.programId)[0];\n }\n\n // ── Account fetchers (async, require Connection) ──────────────────────\n\n async getLatestBlockhash(): Promise<{\n blockhash: string;\n lastValidBlockHeight: number;\n }> {\n return connectionWithFailover(this.client, (connection) =>\n connection.getLatestBlockhash()\n );\n }\n\n async getExchange(): Promise<Exchange> {\n const pda = this.getExchangePda();\n const accountInfo = await connectionWithFailover(\n this.client,\n (connection) => connection.getAccountInfo(pda)\n );\n if (!accountInfo) {\n throw ProgramSdkError.accountNotFound(\"Exchange\");\n }\n return deserializeExchange(accountInfo.data as Buffer);\n }\n\n async getGlobalDepositToken(mint: PublicKey): Promise<GlobalDepositToken> {\n const pda = this.getGlobalDepositTokenPda(mint);\n const accountInfo = await connectionWithFailover(\n this.client,\n (connection) => connection.getAccountInfo(pda)\n );\n if (!accountInfo) {\n throw ProgramSdkError.accountNotFound(\n `GlobalDepositToken for mint ${mint.toBase58()}`\n );\n }\n return deserializeGlobalDepositToken(accountInfo.data as Buffer);\n }\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC failover: automatic switch to a backup Solana RPC endpoint on
|
|
3
|
+
* infrastructure errors, with 120 s cooldown recovery to primary.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors rust/src/rpc_failover.rs.
|
|
6
|
+
*/
|
|
7
|
+
export declare const FAST_RETRY_DELAY_MS = 100;
|
|
8
|
+
export declare const COOLDOWN_DURATION_MS = 120000;
|
|
9
|
+
export declare enum ActiveRpc {
|
|
10
|
+
Primary = "primary",
|
|
11
|
+
Backup = "backup"
|
|
12
|
+
}
|
|
13
|
+
export declare class RpcFailoverState {
|
|
14
|
+
active: ActiveRpc;
|
|
15
|
+
private flippedToBackupAt?;
|
|
16
|
+
maybeRecoverToPrimary(): void;
|
|
17
|
+
flipToBackup(): void;
|
|
18
|
+
flipToPrimary(): void;
|
|
19
|
+
}
|
|
20
|
+
export declare function isInfrastructureError(err: unknown): boolean;
|
|
21
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=rpcFailover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpcFailover.d.ts","sourceRoot":"","sources":["../src/rpcFailover.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,oBAAoB,SAAU,CAAC;AAE5C,oBAAY,SAAS;IACnB,OAAO,YAAY;IACnB,MAAM,WAAW;CAClB;AAED,qBAAa,gBAAgB;IAC3B,MAAM,EAAE,SAAS,CAAqB;IACtC,OAAO,CAAC,iBAAiB,CAAC,CAAS;IAEnC,qBAAqB,IAAI,IAAI;IAY7B,YAAY,IAAI,IAAI;IAKpB,aAAa,IAAI,IAAI;CAItB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAkC3D;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RPC failover: automatic switch to a backup Solana RPC endpoint on
|
|
4
|
+
* infrastructure errors, with 120 s cooldown recovery to primary.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors rust/src/rpc_failover.rs.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RpcFailoverState = exports.ActiveRpc = exports.COOLDOWN_DURATION_MS = exports.FAST_RETRY_DELAY_MS = void 0;
|
|
10
|
+
exports.isInfrastructureError = isInfrastructureError;
|
|
11
|
+
exports.sleep = sleep;
|
|
12
|
+
exports.FAST_RETRY_DELAY_MS = 100;
|
|
13
|
+
exports.COOLDOWN_DURATION_MS = 120_000;
|
|
14
|
+
var ActiveRpc;
|
|
15
|
+
(function (ActiveRpc) {
|
|
16
|
+
ActiveRpc["Primary"] = "primary";
|
|
17
|
+
ActiveRpc["Backup"] = "backup";
|
|
18
|
+
})(ActiveRpc || (exports.ActiveRpc = ActiveRpc = {}));
|
|
19
|
+
class RpcFailoverState {
|
|
20
|
+
active = ActiveRpc.Primary;
|
|
21
|
+
flippedToBackupAt;
|
|
22
|
+
maybeRecoverToPrimary() {
|
|
23
|
+
if (this.active === ActiveRpc.Backup &&
|
|
24
|
+
this.flippedToBackupAt !== undefined) {
|
|
25
|
+
if (Date.now() - this.flippedToBackupAt >= exports.COOLDOWN_DURATION_MS) {
|
|
26
|
+
this.active = ActiveRpc.Primary;
|
|
27
|
+
this.flippedToBackupAt = undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
flipToBackup() {
|
|
32
|
+
this.active = ActiveRpc.Backup;
|
|
33
|
+
this.flippedToBackupAt = Date.now();
|
|
34
|
+
}
|
|
35
|
+
flipToPrimary() {
|
|
36
|
+
this.active = ActiveRpc.Primary;
|
|
37
|
+
this.flippedToBackupAt = undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.RpcFailoverState = RpcFailoverState;
|
|
41
|
+
function isInfrastructureError(err) {
|
|
42
|
+
if (err instanceof TypeError) {
|
|
43
|
+
const message = err.message.toLowerCase();
|
|
44
|
+
if (message.includes("fetch") ||
|
|
45
|
+
message.includes("network") ||
|
|
46
|
+
message.includes("failed")) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (err instanceof Error) {
|
|
51
|
+
const message = err.message.toLowerCase();
|
|
52
|
+
if (message.includes("timeout") || message.includes("timed out")) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (message.includes("502") ||
|
|
56
|
+
message.includes("503") ||
|
|
57
|
+
message.includes("504")) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
if (message.includes("econnrefused") ||
|
|
61
|
+
message.includes("econnreset") ||
|
|
62
|
+
message.includes("enotfound")) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
function sleep(ms) {
|
|
69
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=rpcFailover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpcFailover.js","sourceRoot":"","sources":["../src/rpcFailover.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAqCH,sDAkCC;AAED,sBAEC;AAzEY,QAAA,mBAAmB,GAAG,GAAG,CAAC;AAC1B,QAAA,oBAAoB,GAAG,OAAO,CAAC;AAE5C,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,gCAAmB,CAAA;IACnB,8BAAiB,CAAA;AACnB,CAAC,EAHW,SAAS,yBAAT,SAAS,QAGpB;AAED,MAAa,gBAAgB;IAC3B,MAAM,GAAc,SAAS,CAAC,OAAO,CAAC;IAC9B,iBAAiB,CAAU;IAEnC,qBAAqB;QACnB,IACE,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;YAChC,IAAI,CAAC,iBAAiB,KAAK,SAAS,EACpC,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB,IAAI,4BAAoB,EAAE,CAAC;gBAChE,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;gBAChC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACtC,CAAC;IAED,aAAa;QACX,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;IACrC,CAAC;CACF;AAzBD,4CAyBC;AAED,SAAgB,qBAAqB,CAAC,GAAY;IAChD,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC1C,IACE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;YACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAC1B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACjE,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IACE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;YACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;YACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EACvB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IACE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;YAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;YAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAC7B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["/**\n * RPC failover: automatic switch to a backup Solana RPC endpoint on\n * infrastructure errors, with 120 s cooldown recovery to primary.\n *\n * Mirrors rust/src/rpc_failover.rs.\n */\n\nexport const FAST_RETRY_DELAY_MS = 100;\nexport const COOLDOWN_DURATION_MS = 120_000;\n\nexport enum ActiveRpc {\n Primary = \"primary\",\n Backup = \"backup\",\n}\n\nexport class RpcFailoverState {\n active: ActiveRpc = ActiveRpc.Primary;\n private flippedToBackupAt?: number;\n\n maybeRecoverToPrimary(): void {\n if (\n this.active === ActiveRpc.Backup &&\n this.flippedToBackupAt !== undefined\n ) {\n if (Date.now() - this.flippedToBackupAt >= COOLDOWN_DURATION_MS) {\n this.active = ActiveRpc.Primary;\n this.flippedToBackupAt = undefined;\n }\n }\n }\n\n flipToBackup(): void {\n this.active = ActiveRpc.Backup;\n this.flippedToBackupAt = Date.now();\n }\n\n flipToPrimary(): void {\n this.active = ActiveRpc.Primary;\n this.flippedToBackupAt = undefined;\n }\n}\n\nexport function isInfrastructureError(err: unknown): boolean {\n if (err instanceof TypeError) {\n const message = err.message.toLowerCase();\n if (\n message.includes(\"fetch\") ||\n message.includes(\"network\") ||\n message.includes(\"failed\")\n ) {\n return true;\n }\n }\n\n if (err instanceof Error) {\n const message = err.message.toLowerCase();\n if (message.includes(\"timeout\") || message.includes(\"timed out\")) {\n return true;\n }\n if (\n message.includes(\"502\") ||\n message.includes(\"503\") ||\n message.includes(\"504\")\n ) {\n return true;\n }\n if (\n message.includes(\"econnrefused\") ||\n message.includes(\"econnreset\") ||\n message.includes(\"enotfound\")\n ) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const DISPLAY_DECIMAL_TIERS: readonly [readonly ["10000", 0], readonly ["1000", 1], readonly ["100", 2], readonly ["10", 3], readonly ["0.1", 4]];
|
|
2
|
+
export declare const SMALL_VALUE_DECIMALS = 5;
|
|
3
|
+
export declare function displayDecimalsBy(matchesTier: (threshold: string) => boolean): number;
|
|
4
|
+
export declare function isFormattedZero(input: string): boolean;
|
|
5
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/shared/fmt/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,sHAMxB,CAAC;AAEX,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAQrF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SMALL_VALUE_DECIMALS = exports.DISPLAY_DECIMAL_TIERS = void 0;
|
|
4
|
+
exports.displayDecimalsBy = displayDecimalsBy;
|
|
5
|
+
exports.isFormattedZero = isFormattedZero;
|
|
6
|
+
exports.DISPLAY_DECIMAL_TIERS = [
|
|
7
|
+
["10000", 0],
|
|
8
|
+
["1000", 1],
|
|
9
|
+
["100", 2],
|
|
10
|
+
["10", 3],
|
|
11
|
+
["0.1", 4],
|
|
12
|
+
];
|
|
13
|
+
exports.SMALL_VALUE_DECIMALS = 5;
|
|
14
|
+
function displayDecimalsBy(matchesTier) {
|
|
15
|
+
for (const [threshold, decimals] of exports.DISPLAY_DECIMAL_TIERS) {
|
|
16
|
+
if (matchesTier(threshold)) {
|
|
17
|
+
return decimals;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return exports.SMALL_VALUE_DECIMALS;
|
|
21
|
+
}
|
|
22
|
+
function isFormattedZero(input) {
|
|
23
|
+
return /^-?0(?:\.0+)?$/.test(input);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/shared/fmt/constants.ts"],"names":[],"mappings":";;;AAUA,8CAQC;AAED,0CAEC;AAtBY,QAAA,qBAAqB,GAAG;IACnC,CAAC,OAAO,EAAE,CAAC,CAAC;IACZ,CAAC,MAAM,EAAE,CAAC,CAAC;IACX,CAAC,KAAK,EAAE,CAAC,CAAC;IACV,CAAC,IAAI,EAAE,CAAC,CAAC;IACT,CAAC,KAAK,EAAE,CAAC,CAAC;CACF,CAAC;AAEE,QAAA,oBAAoB,GAAG,CAAC,CAAC;AAEtC,SAAgB,iBAAiB,CAAC,WAA2C;IAC3E,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,6BAAqB,EAAE,CAAC;QAC1D,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,4BAAoB,CAAC;AAC9B,CAAC;AAED,SAAgB,eAAe,CAAC,KAAa;IAC3C,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC","sourcesContent":["export const DISPLAY_DECIMAL_TIERS = [\n [\"10000\", 0],\n [\"1000\", 1],\n [\"100\", 2],\n [\"10\", 3],\n [\"0.1\", 4],\n] as const;\n\nexport const SMALL_VALUE_DECIMALS = 5;\n\nexport function displayDecimalsBy(matchesTier: (threshold: string) => boolean): number {\n for (const [threshold, decimals] of DISPLAY_DECIMAL_TIERS) {\n if (matchesTier(threshold)) {\n return decimals;\n }\n }\n\n return SMALL_VALUE_DECIMALS;\n}\n\nexport function isFormattedZero(input: string): boolean {\n return /^-?0(?:\\.0+)?$/.test(input);\n}\n"]}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import Decimal from "decimal.js";
|
|
2
2
|
export declare function display(value: Decimal): string;
|
|
3
3
|
export declare function abbrNumber(value: Decimal, digits?: number, showSign?: boolean): string;
|
|
4
|
+
/**
|
|
5
|
+
* Format a Decimal as a percentage with exactly 2 decimal places (truncated).
|
|
6
|
+
*
|
|
7
|
+
* When padding is true (default), always shows 2 decimal places (e.g. "12.30").
|
|
8
|
+
* When false, trailing zeros are trimmed (e.g. "12.3").
|
|
9
|
+
*/
|
|
10
|
+
export declare function displayPct(value: Decimal, padding?: boolean): string;
|
|
4
11
|
export declare function toBaseUnits(value: Decimal, decimals: number): bigint | null;
|
|
5
12
|
//# sourceMappingURL=decimal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decimal.d.ts","sourceRoot":"","sources":["../../../src/shared/fmt/decimal.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"decimal.d.ts","sourceRoot":"","sources":["../../../src/shared/fmt/decimal.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,YAAY,CAAC;AAQjC,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAI9C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,SAAI,EAAE,QAAQ,UAAO,GAAG,MAAM,CAkB9E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAWpE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM3E"}
|
|
@@ -5,28 +5,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.display = display;
|
|
7
7
|
exports.abbrNumber = abbrNumber;
|
|
8
|
+
exports.displayPct = displayPct;
|
|
8
9
|
exports.toBaseUnits = toBaseUnits;
|
|
9
10
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
11
|
+
const constants_1 = require("./constants");
|
|
10
12
|
const num_1 = require("./num");
|
|
13
|
+
function displayDecimals(value) {
|
|
14
|
+
return (0, constants_1.displayDecimalsBy)((threshold) => value.greaterThanOrEqualTo(new decimal_js_1.default(threshold)));
|
|
15
|
+
}
|
|
11
16
|
function display(value) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const abs = value.abs();
|
|
16
|
-
if (abs.greaterThanOrEqualTo(100)) {
|
|
17
|
-
return (0, num_1.displayFormattedString)(value.toDecimalPlaces(0).toString());
|
|
18
|
-
}
|
|
19
|
-
if (abs.greaterThanOrEqualTo(1)) {
|
|
20
|
-
return (0, num_1.displayFormattedString)(value.toDecimalPlaces(2).toString());
|
|
21
|
-
}
|
|
22
|
-
const asString = abs.toFixed(20).replace(/0+$/, "");
|
|
23
|
-
const match = /^0\.(0+)(\d+)/.exec(asString);
|
|
24
|
-
if (match && match[1].length > 5) {
|
|
25
|
-
const sign = value.isNegative() ? "-" : "";
|
|
26
|
-
const significant = match[2].slice(0, 4).replace(/0+$/, "");
|
|
27
|
-
return `${sign}0.0(${match[1].length})${significant || "0"}`;
|
|
28
|
-
}
|
|
29
|
-
return (0, num_1.displayFormattedString)(value.toSignificantDigits(8).toString());
|
|
17
|
+
const decimals = displayDecimals(value.abs());
|
|
18
|
+
const formatted = value.toFixed(decimals);
|
|
19
|
+
return (0, constants_1.isFormattedZero)(formatted) ? "0" : (0, num_1.displayFormattedString)(formatted);
|
|
30
20
|
}
|
|
31
21
|
function abbrNumber(value, digits = 2, showSign = true) {
|
|
32
22
|
const sign = showSign && value.isNegative() ? "-" : "";
|
|
@@ -39,10 +29,28 @@ function abbrNumber(value, digits = 2, showSign = true) {
|
|
|
39
29
|
];
|
|
40
30
|
for (const [threshold, suffix] of units) {
|
|
41
31
|
if (abs.greaterThanOrEqualTo(threshold)) {
|
|
42
|
-
return `${sign}${abs.div(threshold).
|
|
32
|
+
return `${sign}${abs.div(threshold).toFixed(digits)}${suffix}`;
|
|
43
33
|
}
|
|
44
34
|
}
|
|
45
|
-
return `${sign}${abs.
|
|
35
|
+
return `${sign}${abs.toFixed(digits)}`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Format a Decimal as a percentage with exactly 2 decimal places (truncated).
|
|
39
|
+
*
|
|
40
|
+
* When padding is true (default), always shows 2 decimal places (e.g. "12.30").
|
|
41
|
+
* When false, trailing zeros are trimmed (e.g. "12.3").
|
|
42
|
+
*/
|
|
43
|
+
function displayPct(value, padding) {
|
|
44
|
+
const pad = padding ?? true;
|
|
45
|
+
const truncated = value.toDecimalPlaces(2, decimal_js_1.default.ROUND_DOWN);
|
|
46
|
+
if (pad) {
|
|
47
|
+
return (0, num_1.displayFormattedString)(truncated.toFixed(2));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const formatted = truncated.toFixed(2);
|
|
51
|
+
const trimmed = formatted.replace(/\.?0+$/, "");
|
|
52
|
+
return (0, num_1.displayFormattedString)(trimmed);
|
|
53
|
+
}
|
|
46
54
|
}
|
|
47
55
|
function toBaseUnits(value, decimals) {
|
|
48
56
|
const scaled = value.mul(new decimal_js_1.default(10).pow(decimals));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decimal.js","sourceRoot":"","sources":["../../../src/shared/fmt/decimal.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"decimal.js","sourceRoot":"","sources":["../../../src/shared/fmt/decimal.ts"],"names":[],"mappings":"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","sourcesContent":["import Decimal from \"decimal.js\";\nimport { displayDecimalsBy, isFormattedZero } from \"./constants\";\nimport { displayFormattedString } from \"./num\";\n\nfunction displayDecimals(value: Decimal): number {\n return displayDecimalsBy((threshold) => value.greaterThanOrEqualTo(new Decimal(threshold)));\n}\n\nexport function display(value: Decimal): string {\n const decimals = displayDecimals(value.abs());\n const formatted = value.toFixed(decimals);\n return isFormattedZero(formatted) ? \"0\" : displayFormattedString(formatted);\n}\n\nexport function abbrNumber(value: Decimal, digits = 2, showSign = true): string {\n const sign = showSign && value.isNegative() ? \"-\" : \"\";\n const abs = value.abs();\n\n const units: Array<[Decimal, string]> = [\n [new Decimal(\"1000000000000\"), \"t\"],\n [new Decimal(\"1000000000\"), \"b\"],\n [new Decimal(\"1000000\"), \"m\"],\n [new Decimal(\"1000\"), \"k\"],\n ];\n\n for (const [threshold, suffix] of units) {\n if (abs.greaterThanOrEqualTo(threshold)) {\n return `${sign}${abs.div(threshold).toFixed(digits)}${suffix}`;\n }\n }\n\n return `${sign}${abs.toFixed(digits)}`;\n}\n\n/**\n * Format a Decimal as a percentage with exactly 2 decimal places (truncated).\n *\n * When padding is true (default), always shows 2 decimal places (e.g. \"12.30\").\n * When false, trailing zeros are trimmed (e.g. \"12.3\").\n */\nexport function displayPct(value: Decimal, padding?: boolean): string {\n const pad = padding ?? true;\n const truncated = value.toDecimalPlaces(2, Decimal.ROUND_DOWN);\n\n if (pad) {\n return displayFormattedString(truncated.toFixed(2));\n } else {\n const formatted = truncated.toFixed(2);\n const trimmed = formatted.replace(/\\.?0+$/, \"\");\n return displayFormattedString(trimmed);\n }\n}\n\nexport function toBaseUnits(value: Decimal, decimals: number): bigint | null {\n const scaled = value.mul(new Decimal(10).pow(decimals));\n if (!scaled.isInteger() || scaled.isNegative()) {\n return null;\n }\n return BigInt(scaled.toFixed(0));\n}\n"]}
|