@invisible-labs/sdk 0.8.0-devnet → 0.10.0-devnet
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 +17 -3
- package/dist/.invisible-sdk-build-target.json +2 -2
- package/dist/{chunk-MZKJU3UA.js → chunk-6AGC3IOB.js} +16 -6
- package/dist/chunk-6AGC3IOB.js.map +1 -0
- package/dist/{chunk-HJFMDMPY.js → chunk-6AKBRYKO.js} +3 -3
- package/dist/{chunk-HJFMDMPY.js.map → chunk-6AKBRYKO.js.map} +1 -1
- package/dist/{chunk-DCTYBUY3.js → chunk-AIKC2XQS.js} +3 -3
- package/dist/{chunk-DCTYBUY3.js.map → chunk-AIKC2XQS.js.map} +1 -1
- package/dist/{chunk-Y7AK6RBV.js → chunk-ANQMIQYS.js} +587 -19
- package/dist/chunk-ANQMIQYS.js.map +1 -0
- package/dist/{chunk-MPNVF727.js → chunk-DFBH5XLM.js} +569 -78
- package/dist/chunk-DFBH5XLM.js.map +1 -0
- package/dist/{chunk-EBWTAXNT.js → chunk-EPWTRF5U.js} +3 -3
- package/dist/{chunk-EBWTAXNT.js.map → chunk-EPWTRF5U.js.map} +1 -1
- package/dist/{chunk-IG6JJFR2.js → chunk-HWRMSK7E.js} +8 -6
- package/dist/chunk-HWRMSK7E.js.map +1 -0
- package/dist/{chunk-K67FTCQU.js → chunk-JNNVPZEU.js} +3 -3
- package/dist/chunk-JNNVPZEU.js.map +1 -0
- package/dist/{chunk-QRN46R3F.js → chunk-RWKG7N7I.js} +10 -3
- package/dist/chunk-RWKG7N7I.js.map +1 -0
- package/dist/coordinator-T2B7253V.js +4 -0
- package/dist/{coordinator-E2TS6NR2.js.map → coordinator-T2B7253V.js.map} +1 -1
- package/dist/dkgWorker.js +1 -1
- package/dist/events.js +3 -3
- package/dist/frostRuntime-JESDHN6O.js +4 -0
- package/dist/{frostRuntime-6FTPKUCP.js.map → frostRuntime-JESDHN6O.js.map} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/dist/lp.d.ts +48 -1
- package/dist/lp.js +360 -82
- package/dist/lp.js.map +1 -1
- package/dist/stats.js +1 -1
- package/dist/storage.js +2 -2
- package/dist/{types.generated-YhFu9ZBR.d.ts → types.generated-CtMxCo9F.d.ts} +80 -2
- package/dist/user.d.ts +25 -11
- package/dist/user.js +124 -37
- package/dist/user.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-IG6JJFR2.js.map +0 -1
- package/dist/chunk-K67FTCQU.js.map +0 -1
- package/dist/chunk-MPNVF727.js.map +0 -1
- package/dist/chunk-MZKJU3UA.js.map +0 -1
- package/dist/chunk-QRN46R3F.js.map +0 -1
- package/dist/chunk-Y7AK6RBV.js.map +0 -1
- package/dist/coordinator-E2TS6NR2.js +0 -4
- package/dist/frostRuntime-6FTPKUCP.js +0 -4
package/dist/lp.js
CHANGED
|
@@ -1,10 +1,104 @@
|
|
|
1
|
-
import { isValidLpPositionId,
|
|
2
|
-
import { publicKey, assertAttested, lamports } from './chunk-
|
|
3
|
-
import { requestEnvelope, CoordinatorMessageType } from './chunk-
|
|
4
|
-
import { getSessionState } from './chunk-
|
|
5
|
-
import { CommandError, WalletError, TransportError, PolicyValidationError, RoutingError, LpLifecycleError } from './chunk-
|
|
1
|
+
import { isValidLpPositionId, LP_MAX_TOTAL_SHARDS, LP_MAX_INITIAL_SHARDS, LP_MAX_REFILL_BATCH_SIZE, LP_SHARD_PAGE_SIZE, LP_DEFAULT_REFILL_BATCH_SIZE, LP_DEFAULT_TARGET_SHARDS } from './chunk-HWRMSK7E.js';
|
|
2
|
+
import { publicKey, assertAttested, lamports } from './chunk-EPWTRF5U.js';
|
|
3
|
+
import { requestEnvelope, CoordinatorMessageType } from './chunk-6AGC3IOB.js';
|
|
4
|
+
import { getSessionState } from './chunk-6AKBRYKO.js';
|
|
5
|
+
import { CommandError, WalletError, TransportError, PolicyValidationError, RoutingError, LpLifecycleError } from './chunk-RWKG7N7I.js';
|
|
6
6
|
import './chunk-VR6T6OJS.js';
|
|
7
7
|
|
|
8
|
+
// src/lp/actorSync.ts
|
|
9
|
+
function normalizeLpActorSync(sync) {
|
|
10
|
+
const total = sync.totalNetFundsLamports;
|
|
11
|
+
if (total === void 0) return sync;
|
|
12
|
+
const available = sync.redeemablePrincipalLamports + sync.redeemableFeeLamports;
|
|
13
|
+
if (sync.redeemableProjectionAvailable === true && Number.isSafeInteger(total) && total >= 0 && Number.isSafeInteger(sync.redeemablePrincipalLamports) && sync.redeemablePrincipalLamports >= 0 && Number.isSafeInteger(sync.redeemableFeeLamports) && sync.redeemableFeeLamports >= 0 && Number.isSafeInteger(available) && available >= 0 && total >= available) {
|
|
14
|
+
return sync;
|
|
15
|
+
}
|
|
16
|
+
return { ...sync, totalNetFundsLamports: void 0 };
|
|
17
|
+
}
|
|
18
|
+
function mergeLpActorSync(previous, next) {
|
|
19
|
+
if (next === void 0) return void 0;
|
|
20
|
+
if (previous?.lpPositionId === next.lpPositionId && (next.stateVersion < previous.stateVersion || next.stateVersion === previous.stateVersion && next.updatedAtMs < previous.updatedAtMs)) {
|
|
21
|
+
return normalizeLpActorSync(previous);
|
|
22
|
+
}
|
|
23
|
+
return normalizeLpActorSync(next);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/lp/feePolicy.ts
|
|
27
|
+
var LP_FEE_POLICY_VERSION = 1;
|
|
28
|
+
var LP_PARTNER_COMMISSION_BPS = 6e3;
|
|
29
|
+
var LP_BASIS_POINT_DENOMINATOR = 10000n;
|
|
30
|
+
var LP_FEE_POLICY_HASHES = {
|
|
31
|
+
internal: "53479c39d822899c0abe21990aeff40ea74681277b2744ef86234152cc94ca5a",
|
|
32
|
+
partner: "3e1a307504043bc0b25f03ccffdff1b42cd2b38699f000f7eb70ce9433a5b2a7"
|
|
33
|
+
};
|
|
34
|
+
var LP_ECONOMIC_UNSIGNED_PATTERN = /^(0|[1-9][0-9]*)$/;
|
|
35
|
+
var LP_ECONOMIC_SIGNED_PATTERN = /^(0|-?[1-9][0-9]*)$/;
|
|
36
|
+
var LP_ECONOMIC_UNSIGNED_MAX = (1n << 128n) - 1n;
|
|
37
|
+
var LP_ECONOMIC_SIGNED_MIN = -(1n << 127n);
|
|
38
|
+
var LP_ECONOMIC_SIGNED_MAX = (1n << 127n) - 1n;
|
|
39
|
+
var LP_FEE_POLICY_INVALID_MESSAGE = "Coordinator LP fee policy evidence is missing or invalid";
|
|
40
|
+
function validateLpFeePolicy(value) {
|
|
41
|
+
if (typeof value !== "object" || value === null) {
|
|
42
|
+
throw new CommandError("REJECTED_STATE", LP_FEE_POLICY_INVALID_MESSAGE);
|
|
43
|
+
}
|
|
44
|
+
const policy = value;
|
|
45
|
+
if (policy.version !== LP_FEE_POLICY_VERSION || policy.profile !== "internal" && policy.profile !== "partner" || policy.commission_bps !== (policy.profile === "partner" ? LP_PARTNER_COMMISSION_BPS : 0) || typeof policy.policy_hash !== "string" || policy.policy_hash !== LP_FEE_POLICY_HASHES[policy.profile]) {
|
|
46
|
+
throw new CommandError("REJECTED_STATE", LP_FEE_POLICY_INVALID_MESSAGE);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
version: LP_FEE_POLICY_VERSION,
|
|
50
|
+
profile: policy.profile,
|
|
51
|
+
commission_bps: policy.profile === "partner" ? LP_PARTNER_COMMISSION_BPS : 0,
|
|
52
|
+
policy_hash: policy.policy_hash
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function requireLpFeePolicyCapability(version) {
|
|
56
|
+
if (version !== LP_FEE_POLICY_VERSION) {
|
|
57
|
+
throw new RoutingError(
|
|
58
|
+
"VERSION_NOT_SUPPORTED",
|
|
59
|
+
"Coordinator does not support the LP fee policy contract"
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function validateLpPositionFeePolicy(position, previous) {
|
|
64
|
+
if (position.feePolicy === void 0) {
|
|
65
|
+
if (previous?.feePolicy !== void 0 || position.actorSync?.feePolicy !== void 0 || position.actorSync?.feeBasisRevision !== void 0 || position.actorSync?.grossFeeLamports !== void 0 || position.actorSync?.protocolCommissionLamports !== void 0 || position.actorSync?.waivedProtocolCommissionLamports !== void 0) {
|
|
66
|
+
throw new CommandError("REJECTED_STATE", LP_FEE_POLICY_INVALID_MESSAGE);
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
requireLpFeePolicyCapability(position.lpFeePolicyVersion);
|
|
71
|
+
const policy = validateLpFeePolicy(position.feePolicy);
|
|
72
|
+
const sync = position.actorSync;
|
|
73
|
+
const actorPolicy = validateLpFeePolicy(sync?.feePolicy);
|
|
74
|
+
if (JSON.stringify(policy) !== JSON.stringify(actorPolicy) || previous !== void 0 && (previous.feePolicy === void 0 || JSON.stringify(policy) !== JSON.stringify(validateLpFeePolicy(previous.feePolicy))) || sync?.lpPositionId !== position.id || sync?.redeemableProjectionAvailable !== true || !Number.isSafeInteger(sync.feeBasisRevision) || sync.feeBasisRevision < 0 || !Number.isSafeInteger(sync.grossFeeLamports) || sync.grossFeeLamports < 0 || !Number.isSafeInteger(sync.protocolCommissionLamports) || sync.protocolCommissionLamports < 0 || !Number.isSafeInteger(sync.waivedProtocolCommissionLamports) || sync.waivedProtocolCommissionLamports < 0 || sync.economicReturn === void 0) {
|
|
75
|
+
throw new CommandError("REJECTED_STATE", LP_FEE_POLICY_INVALID_MESSAGE);
|
|
76
|
+
}
|
|
77
|
+
if (BigInt(sync.protocolCommissionLamports) + BigInt(sync.waivedProtocolCommissionLamports) !== BigInt(sync.grossFeeLamports) * BigInt(policy.commission_bps) / LP_BASIS_POINT_DENOMINATOR) {
|
|
78
|
+
throw new CommandError("REJECTED_STATE", LP_FEE_POLICY_INVALID_MESSAGE);
|
|
79
|
+
}
|
|
80
|
+
for (const history of sync.redemptionHistory ?? []) {
|
|
81
|
+
if (history.feePolicyHash !== policy.policy_hash || !Number.isSafeInteger(history.feeBasisRevision) || history.feeBasisRevision < 0) {
|
|
82
|
+
throw new CommandError("REJECTED_STATE", LP_FEE_POLICY_INVALID_MESSAGE);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const summary = sync.economicReturn;
|
|
86
|
+
const totals = [
|
|
87
|
+
summary.providerRewardLamports,
|
|
88
|
+
summary.sourceExpenseCompensationLamports,
|
|
89
|
+
summary.chargedReimbursementLossLamports
|
|
90
|
+
];
|
|
91
|
+
if (!totals.every(
|
|
92
|
+
(value) => typeof value === "string" && LP_ECONOMIC_UNSIGNED_PATTERN.test(value) && BigInt(value) <= LP_ECONOMIC_UNSIGNED_MAX
|
|
93
|
+
) || typeof summary.netEconomicReturnLamports !== "string" || !LP_ECONOMIC_SIGNED_PATTERN.test(summary.netEconomicReturnLamports)) {
|
|
94
|
+
throw new CommandError("REJECTED_STATE", LP_FEE_POLICY_INVALID_MESSAGE);
|
|
95
|
+
}
|
|
96
|
+
const net = BigInt(summary.netEconomicReturnLamports);
|
|
97
|
+
if (net < LP_ECONOMIC_SIGNED_MIN || net > LP_ECONOMIC_SIGNED_MAX || net !== BigInt(summary.providerRewardLamports) - BigInt(summary.chargedReimbursementLossLamports) - BigInt(sync.protocolCommissionLamports)) {
|
|
98
|
+
throw new CommandError("REJECTED_STATE", LP_FEE_POLICY_INVALID_MESSAGE);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
8
102
|
// src/lp/positionCode.ts
|
|
9
103
|
var LEGACY_CODE_PREFIX = "ilp1";
|
|
10
104
|
var CODE_PREFIX = "ilp2";
|
|
@@ -231,6 +325,12 @@ var COMMAND_TTL_MS = 3e4;
|
|
|
231
325
|
var LP_POSITION_OPEN_COMMAND_TTL_MS = 55e3;
|
|
232
326
|
var LP_POSITION_OPEN_REQUEST_TIMEOUT_MS = 2e4;
|
|
233
327
|
var LP_COMMAND_REQUEST_TIMEOUT_MS = COMMAND_TTL_MS;
|
|
328
|
+
var LP_POSITION_HYDRATION_TIMEOUT_MS = LP_COMMAND_REQUEST_TIMEOUT_MS;
|
|
329
|
+
var LP_POSITION_SNAPSHOT_MAX_ATTEMPTS = 3;
|
|
330
|
+
var LP_SHARD_SNAPSHOT_CHANGED_MESSAGE = "LP shard snapshot changed";
|
|
331
|
+
var LP_SHARD_PAGE_INVALID_MESSAGE = "coordinator LP shard page is invalid";
|
|
332
|
+
var LP_POSITION_OPEN_IDENTITY_MISMATCH_MESSAGE = "Coordinator returned a different LP position identity or creation intent";
|
|
333
|
+
var LP_SHARD_SNAPSHOT_HASH_PATTERN = /^[0-9a-f]{64}$/;
|
|
234
334
|
var LP_CREATION_CHALLENGE_REQUEST_TIMEOUT_MS = 3e4;
|
|
235
335
|
var LP_CREATION_WALLET_SIGNATURE_TIMEOUT_MS = 45e3;
|
|
236
336
|
var LP_CREATION_PROOF_REQUEST_TIMEOUT_MS = 15e3;
|
|
@@ -325,6 +425,16 @@ async function authorizePositionCreation(session, intent, signer) {
|
|
|
325
425
|
"Coordinator returned an unexpected LP creation authorization response"
|
|
326
426
|
);
|
|
327
427
|
}
|
|
428
|
+
requireLpFeePolicyCapability(challenge.value.lp_fee_policy_version);
|
|
429
|
+
const feePolicy = validateLpFeePolicy(challenge.value.fee_policy);
|
|
430
|
+
const consentLine = `LP Fee Policy: ${feePolicy.policy_hash}`;
|
|
431
|
+
const policyResource = `&fee_policy_hash=${feePolicy.policy_hash}&fee_policy_version=${feePolicy.version}`;
|
|
432
|
+
if (!challenge.value.message.split("\n").includes(consentLine) || !challenge.value.message.includes(policyResource)) {
|
|
433
|
+
throw new CommandError(
|
|
434
|
+
"REJECTED_STATE",
|
|
435
|
+
"Coordinator LP creation challenge does not bind the authorized fee policy"
|
|
436
|
+
);
|
|
437
|
+
}
|
|
328
438
|
const localAuthorizationDeadlineMs = challengeRequestStartedAtMs + challenge.value.valid_for_ms;
|
|
329
439
|
const walletTimeoutMs = lpCreationAuthorizationStepTimeout(
|
|
330
440
|
localAuthorizationDeadlineMs,
|
|
@@ -396,7 +506,11 @@ async function authorizePositionCreation(session, intent, signer) {
|
|
|
396
506
|
LP_CREATION_AUTHORIZATION_MARGIN_MS,
|
|
397
507
|
LP_CREATION_MIN_STEP_TIMEOUT_MS
|
|
398
508
|
);
|
|
399
|
-
|
|
509
|
+
requireLpFeePolicyCapability(authorization.value.lp_fee_policy_version);
|
|
510
|
+
if (JSON.stringify(validateLpFeePolicy(authorization.value.fee_policy)) !== JSON.stringify(feePolicy)) {
|
|
511
|
+
throw new CommandError("REJECTED_STATE", "Coordinator changed the authorized LP fee policy");
|
|
512
|
+
}
|
|
513
|
+
return { authorizationId: authorization.value.authorization_id, feePolicy };
|
|
400
514
|
}
|
|
401
515
|
function lpCreationAuthorizationStepTimeout(localDeadlineMs, reservedMs, maximumTimeoutMs) {
|
|
402
516
|
const availableMs = localDeadlineMs - Date.now() - reservedMs;
|
|
@@ -487,6 +601,7 @@ async function openPosition(session, input, auth, reconnectSession) {
|
|
|
487
601
|
case: "positionOpen",
|
|
488
602
|
value: {
|
|
489
603
|
creation_authorization_id: input.creationAuthorizationId,
|
|
604
|
+
fee_policy: input.feePolicy,
|
|
490
605
|
auth_public_key: Uint8Array.from(input.authPublicKey),
|
|
491
606
|
refill_public_key: Uint8Array.from(input.refillPublicKey),
|
|
492
607
|
redemption_commitment: Uint8Array.from(input.withdrawalCommitment),
|
|
@@ -506,6 +621,7 @@ async function openPosition(session, input, auth, reconnectSession) {
|
|
|
506
621
|
timeoutMs: LP_POSITION_OPEN_REQUEST_TIMEOUT_MS
|
|
507
622
|
};
|
|
508
623
|
let response;
|
|
624
|
+
let responseSession = session;
|
|
509
625
|
try {
|
|
510
626
|
response = await requestForPosition(
|
|
511
627
|
session,
|
|
@@ -517,17 +633,27 @@ async function openPosition(session, input, auth, reconnectSession) {
|
|
|
517
633
|
);
|
|
518
634
|
} catch (error) {
|
|
519
635
|
if (!isAmbiguousLpPositionOpenFailure(error)) throw error;
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
636
|
+
responseSession = reconnectSession === void 0 ? session : await reconnectSessionWithinDeadline(reconnectSession, commandDeadlineMs);
|
|
637
|
+
}
|
|
638
|
+
const position = await hydratePositionResponse(
|
|
639
|
+
responseSession,
|
|
640
|
+
auth.lpPositionId,
|
|
641
|
+
auth,
|
|
642
|
+
response,
|
|
643
|
+
{
|
|
644
|
+
deadlineMs: commandDeadlineMs
|
|
645
|
+
}
|
|
646
|
+
);
|
|
647
|
+
if (position.authPublicKey !== bytesToHex(Uint8Array.from(input.authPublicKey)) || position.refillPublicKey !== bytesToHex(Uint8Array.from(input.refillPublicKey)) || position.withdrawalCommitment !== bytesToHex(Uint8Array.from(input.withdrawalCommitment)) || position.committedLamports !== input.committedLamports || position.targetShardCount !== input.shardCount || position.refillThreshold !== input.refillThreshold || position.createdAt !== input.createdAtMs) {
|
|
648
|
+
throw new CommandError("REJECTED_STATE", LP_POSITION_OPEN_IDENTITY_MISMATCH_MESSAGE);
|
|
649
|
+
}
|
|
650
|
+
if (input.feePolicy !== void 0 && position.feePolicy?.policy_hash !== input.feePolicy.policy_hash) {
|
|
651
|
+
throw new CommandError(
|
|
652
|
+
"REJECTED_STATE",
|
|
653
|
+
"Coordinator opened the LP position with a different fee policy"
|
|
528
654
|
);
|
|
529
655
|
}
|
|
530
|
-
return
|
|
656
|
+
return position;
|
|
531
657
|
}
|
|
532
658
|
async function reconnectSessionWithinDeadline(reconnectSession, deadlineMs) {
|
|
533
659
|
const remainingMs = deadlineMs - Date.now();
|
|
@@ -561,37 +687,131 @@ function isAmbiguousCoordinatorRequestFailure(error) {
|
|
|
561
687
|
return error instanceof TransportError || error instanceof CommandError && error.code === "REJECTED_STALE_JOB";
|
|
562
688
|
}
|
|
563
689
|
async function getPosition(session, lpPositionId, auth, options = {}) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
const page = expectPosition(response);
|
|
581
|
-
const mergedPosition = position === void 0 ? page : mergePositionHistoryPages(position, page);
|
|
582
|
-
position = mergedPosition;
|
|
583
|
-
const actorSync = page.actorSync;
|
|
584
|
-
if (actorSync?.redemptionHistoryHasMore !== true) return mergedPosition;
|
|
585
|
-
const nextCursor = actorSync.redemptionHistoryNextCursor;
|
|
586
|
-
if (nextCursor === void 0 || seenCursors.has(nextCursor)) {
|
|
587
|
-
throw new CommandError(
|
|
588
|
-
"REJECTED_STATE",
|
|
589
|
-
"coordinator LP actor sync returned an invalid redemption history cursor"
|
|
690
|
+
return hydratePositionResponse(session, lpPositionId, auth, void 0, options);
|
|
691
|
+
}
|
|
692
|
+
async function hydratePositionResponse(session, lpPositionId, auth, initialResponse, options = {}) {
|
|
693
|
+
const boundedOptions = {
|
|
694
|
+
...options,
|
|
695
|
+
deadlineMs: options.deadlineMs ?? Date.now() + LP_POSITION_HYDRATION_TIMEOUT_MS
|
|
696
|
+
};
|
|
697
|
+
for (let attempt = 0; attempt < LP_POSITION_SNAPSHOT_MAX_ATTEMPTS; attempt += 1) {
|
|
698
|
+
try {
|
|
699
|
+
const response = initialResponse ?? await requestForPosition(
|
|
700
|
+
session,
|
|
701
|
+
lpPositionId,
|
|
702
|
+
auth,
|
|
703
|
+
"position_get",
|
|
704
|
+
{ case: "positionGet", value: {} },
|
|
705
|
+
boundedOptions
|
|
590
706
|
);
|
|
707
|
+
if (response.case !== "position")
|
|
708
|
+
throw new CommandError("REJECTED_STATE", LP_SHARD_PAGE_INVALID_MESSAGE);
|
|
709
|
+
const first = response.value;
|
|
710
|
+
let full = first;
|
|
711
|
+
if (first.shards_snapshot_hash !== void 0 || first.shards_total_count !== void 0 || first.shards_next_index !== void 0) {
|
|
712
|
+
assertShardPage(first, first, lpPositionId, auth, 0);
|
|
713
|
+
const shards = [...first.shards];
|
|
714
|
+
let nextIndex = first.shards_next_index;
|
|
715
|
+
while (nextIndex !== void 0) {
|
|
716
|
+
const nextResponse = await requestForPosition(
|
|
717
|
+
session,
|
|
718
|
+
lpPositionId,
|
|
719
|
+
auth,
|
|
720
|
+
"position_get",
|
|
721
|
+
{
|
|
722
|
+
case: "positionGet",
|
|
723
|
+
value: {
|
|
724
|
+
shard_start_index: nextIndex,
|
|
725
|
+
shards_snapshot_hash: first.shards_snapshot_hash
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
boundedOptions
|
|
729
|
+
);
|
|
730
|
+
if (nextResponse.case !== "position")
|
|
731
|
+
throw new CommandError("REJECTED_STATE", LP_SHARD_PAGE_INVALID_MESSAGE);
|
|
732
|
+
assertShardPage(first, nextResponse.value, lpPositionId, auth, nextIndex);
|
|
733
|
+
shards.push(...nextResponse.value.shards);
|
|
734
|
+
nextIndex = nextResponse.value.shards_next_index;
|
|
735
|
+
}
|
|
736
|
+
if (shards.length !== first.shards_total_count)
|
|
737
|
+
throw new CommandError("REJECTED_STATE", LP_SHARD_PAGE_INVALID_MESSAGE);
|
|
738
|
+
full = { ...first, shards };
|
|
739
|
+
} else if (first.target_shard_count > LP_MAX_TOTAL_SHARDS || first.lp_position_id !== lpPositionId || first.shards.length > LP_MAX_INITIAL_SHARDS || first.status !== "dkg_pending" && first.target_shard_count > LP_MAX_INITIAL_SHARDS && first.shards.length !== first.target_shard_count || first.status === "dkg_pending" && first.target_shard_count > LP_MAX_INITIAL_SHARDS && first.target_shard_count - first.shards.length > LP_MAX_REFILL_BATCH_SIZE) {
|
|
740
|
+
throw new CommandError("REJECTED_STATE", LP_SHARD_PAGE_INVALID_MESSAGE);
|
|
741
|
+
}
|
|
742
|
+
let position = mapPosition(full);
|
|
743
|
+
let historyPage = first;
|
|
744
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
745
|
+
while (historyPage.actor_sync?.redemption_history_has_more === true) {
|
|
746
|
+
const cursor = historyPage.actor_sync.redemption_history_next_cursor;
|
|
747
|
+
if (cursor === void 0 || seenCursors.has(cursor)) {
|
|
748
|
+
throw new CommandError(
|
|
749
|
+
"REJECTED_STATE",
|
|
750
|
+
"coordinator LP actor sync returned an invalid redemption history cursor"
|
|
751
|
+
);
|
|
752
|
+
}
|
|
753
|
+
seenCursors.add(cursor);
|
|
754
|
+
const nextResponse = await requestForPosition(
|
|
755
|
+
session,
|
|
756
|
+
lpPositionId,
|
|
757
|
+
auth,
|
|
758
|
+
"position_get",
|
|
759
|
+
{
|
|
760
|
+
case: "positionGet",
|
|
761
|
+
value: {
|
|
762
|
+
redemption_history_cursor: cursor,
|
|
763
|
+
...first.shards_snapshot_hash === void 0 ? {} : { shard_start_index: 0, shards_snapshot_hash: first.shards_snapshot_hash }
|
|
764
|
+
}
|
|
765
|
+
},
|
|
766
|
+
boundedOptions
|
|
767
|
+
);
|
|
768
|
+
if (nextResponse.case !== "position")
|
|
769
|
+
throw new CommandError("REJECTED_STATE", LP_SHARD_PAGE_INVALID_MESSAGE);
|
|
770
|
+
historyPage = nextResponse.value;
|
|
771
|
+
if (first.shards_snapshot_hash !== void 0)
|
|
772
|
+
assertShardPage(first, historyPage, lpPositionId, auth, 0);
|
|
773
|
+
const historyView = mapPosition(historyPage);
|
|
774
|
+
validateLpPositionFeePolicy(historyView, position);
|
|
775
|
+
const merged = mergePositionHistoryPages(position, historyView);
|
|
776
|
+
position = first.shards_snapshot_hash === void 0 ? merged : {
|
|
777
|
+
...position,
|
|
778
|
+
actorSync: position.actorSync === void 0 ? void 0 : {
|
|
779
|
+
...position.actorSync,
|
|
780
|
+
redemptionHistory: merged.actorSync?.redemptionHistory,
|
|
781
|
+
redemptionHistoryHasMore: historyView.actorSync?.redemptionHistoryHasMore ?? false,
|
|
782
|
+
redemptionHistoryNextCursor: historyView.actorSync?.redemptionHistoryNextCursor
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
lpPositionPageRequestOptions(boundedOptions);
|
|
787
|
+
return position;
|
|
788
|
+
} catch (error) {
|
|
789
|
+
if (!(error instanceof CommandError) || !error.message.includes(LP_SHARD_SNAPSHOT_CHANGED_MESSAGE) || attempt + 1 >= LP_POSITION_SNAPSHOT_MAX_ATTEMPTS)
|
|
790
|
+
throw error;
|
|
791
|
+
initialResponse = void 0;
|
|
792
|
+
lpPositionPageRequestOptions(boundedOptions);
|
|
591
793
|
}
|
|
592
|
-
seenCursors.add(nextCursor);
|
|
593
|
-
cursor = nextCursor;
|
|
594
794
|
}
|
|
795
|
+
throw new CommandError("REJECTED_STATE", LP_SHARD_SNAPSHOT_CHANGED_MESSAGE);
|
|
796
|
+
}
|
|
797
|
+
function assertShardPage(first, page, lpPositionId, auth, startIndex) {
|
|
798
|
+
const total = first.shards_total_count;
|
|
799
|
+
const invalid = () => {
|
|
800
|
+
throw new CommandError("REJECTED_STATE", LP_SHARD_PAGE_INVALID_MESSAGE);
|
|
801
|
+
};
|
|
802
|
+
if (total === void 0 || !Number.isInteger(total) || total < 1 || total > LP_MAX_TOTAL_SHARDS || total > first.target_shard_count || first.status !== "dkg_pending" && total !== first.target_shard_count || first.shards_snapshot_hash === void 0 || !LP_SHARD_SNAPSHOT_HASH_PATTERN.test(first.shards_snapshot_hash) || page.lp_position_id !== lpPositionId || page.shards_snapshot_hash !== first.shards_snapshot_hash || page.shards_total_count !== total || page.target_shard_count !== first.target_shard_count || page.status !== "dkg_pending" && total !== page.target_shard_count || page.created_at_ms !== first.created_at_ms || page.committed_lamports !== first.committed_lamports || page.earned_lamports !== first.earned_lamports || page.refill_threshold !== first.refill_threshold || page.fee_policy?.policy_hash !== first.fee_policy?.policy_hash || page.lp_fee_policy_version !== first.lp_fee_policy_version || bytesToHex(page.auth_public_key) !== bytesToHex(auth.authPublicKey) || bytesToHex(page.refill_public_key) !== bytesToHex(first.refill_public_key) || bytesToHex(page.redemption_commitment) !== bytesToHex(first.redemption_commitment) || page.shards.length !== Math.min(LP_SHARD_PAGE_SIZE, total - startIndex) || page.shards.length === 0)
|
|
803
|
+
invalid();
|
|
804
|
+
for (const [offset, shard] of page.shards.entries()) {
|
|
805
|
+
const index = startIndex + offset;
|
|
806
|
+
if (shard.index !== index || shard.lp_position_id !== lpPositionId || shard.shard_id !== `${lpPositionId}:shard:${index}`)
|
|
807
|
+
invalid();
|
|
808
|
+
}
|
|
809
|
+
const end = startIndex + page.shards.length;
|
|
810
|
+
if (total === void 0) invalid();
|
|
811
|
+
if (end < total ? page.shards_next_index !== end : page.shards_next_index !== void 0)
|
|
812
|
+
invalid();
|
|
813
|
+
if (page.status !== first.status)
|
|
814
|
+
throw new CommandError("REJECTED_STATE", LP_SHARD_SNAPSHOT_CHANGED_MESSAGE);
|
|
595
815
|
}
|
|
596
816
|
function lpPositionPageRequestOptions(options) {
|
|
597
817
|
if (options.deadlineMs === void 0) return options;
|
|
@@ -614,7 +834,7 @@ async function finalizeDkgBatch(session, input, auth) {
|
|
|
614
834
|
finalized_at_ms: input.finalizedAtMs
|
|
615
835
|
}
|
|
616
836
|
});
|
|
617
|
-
return
|
|
837
|
+
return hydratePositionResponse(session, auth.lpPositionId, auth, response);
|
|
618
838
|
}
|
|
619
839
|
async function refillPosition(session, input, auth) {
|
|
620
840
|
const response = await requestForPosition(session, input.lpPositionId, auth, "refill", {
|
|
@@ -626,14 +846,14 @@ async function refillPosition(session, input, auth) {
|
|
|
626
846
|
authorized_at_ms: input.authorizedAtMs
|
|
627
847
|
}
|
|
628
848
|
});
|
|
629
|
-
return
|
|
849
|
+
return hydratePositionResponse(session, auth.lpPositionId, auth, response);
|
|
630
850
|
}
|
|
631
851
|
async function reconcileFunding(session, lpPositionId, auth) {
|
|
632
852
|
const response = await requestForPosition(session, lpPositionId, auth, "reconcile_funding", {
|
|
633
853
|
case: "reconcileFunding",
|
|
634
854
|
value: {}
|
|
635
855
|
});
|
|
636
|
-
return
|
|
856
|
+
return hydratePositionResponse(session, auth.lpPositionId, auth, response);
|
|
637
857
|
}
|
|
638
858
|
async function planFunding(session, input, auth) {
|
|
639
859
|
const response = await requestForPosition(session, input.lpPositionId, auth, "funding_plan", {
|
|
@@ -707,13 +927,21 @@ async function executeWithdrawal(session, input, auth) {
|
|
|
707
927
|
deposit_principal_lamports: input.withdrawalMode === "max_available" ? 0 : input.depositPrincipalLamports,
|
|
708
928
|
earned_fee_lamports: input.withdrawalMode === "max_available" ? 0 : input.earnedFeeLamports,
|
|
709
929
|
withdrawal_mode: input.withdrawalMode,
|
|
710
|
-
requested_at_ms: input.requestedAtMs
|
|
930
|
+
requested_at_ms: input.requestedAtMs,
|
|
931
|
+
fee_policy_hash: input.feePolicyHash,
|
|
932
|
+
fee_basis_revision: input.feeBasisRevision
|
|
711
933
|
}
|
|
712
934
|
});
|
|
713
935
|
if (response.case !== "withdrawalExecution") {
|
|
714
936
|
throw new Error("Unexpected LP withdrawal execution response");
|
|
715
937
|
}
|
|
716
938
|
const execution = response.value;
|
|
939
|
+
if (execution.fee_policy_hash !== input.feePolicyHash || execution.fee_basis_revision !== input.feeBasisRevision) {
|
|
940
|
+
throw new PolicyValidationError(
|
|
941
|
+
"INVALID_WITHDRAWAL_PLAN",
|
|
942
|
+
"Coordinator accepted a different LP fee policy or fee basis"
|
|
943
|
+
);
|
|
944
|
+
}
|
|
717
945
|
if (BigInt(execution.accepted_lamports) !== BigInt(execution.accepted_deposit_principal_lamports) + BigInt(execution.accepted_earned_fee_lamports)) {
|
|
718
946
|
throw new PolicyValidationError(
|
|
719
947
|
"INVALID_WITHDRAWAL_PLAN",
|
|
@@ -727,6 +955,8 @@ async function executeWithdrawal(session, input, auth) {
|
|
|
727
955
|
);
|
|
728
956
|
}
|
|
729
957
|
return {
|
|
958
|
+
feePolicyHash: execution.fee_policy_hash,
|
|
959
|
+
feeBasisRevision: execution.fee_basis_revision,
|
|
730
960
|
withdrawalId: execution.withdrawal_id,
|
|
731
961
|
txSignatures: [...execution.tx_signatures],
|
|
732
962
|
acceptedLamports: execution.accepted_lamports,
|
|
@@ -738,7 +968,7 @@ function request(session, auth, action, payload) {
|
|
|
738
968
|
return requestForPosition(session, auth.lpPositionId, auth, action, payload);
|
|
739
969
|
}
|
|
740
970
|
async function requestForPosition(session, lpPositionId, auth, action, payload, options = {}) {
|
|
741
|
-
const timeoutMs = options.timeoutMs ?? LP_COMMAND_REQUEST_TIMEOUT_MS;
|
|
971
|
+
const timeoutMs = lpPositionPageRequestOptions(options).timeoutMs ?? LP_COMMAND_REQUEST_TIMEOUT_MS;
|
|
742
972
|
assertAuthMatchesPosition(lpPositionId, auth);
|
|
743
973
|
const protocol = await loadProtocol();
|
|
744
974
|
const state = getSessionState(session);
|
|
@@ -773,12 +1003,10 @@ function assertAuthMatchesPosition(lpPositionId, auth) {
|
|
|
773
1003
|
"LP Position Code does not match the target LP position"
|
|
774
1004
|
);
|
|
775
1005
|
}
|
|
776
|
-
function expectPosition(response) {
|
|
777
|
-
if (response.case !== "position") throw new Error("Unexpected LP position response");
|
|
778
|
-
return mapPosition(response.value);
|
|
779
|
-
}
|
|
780
1006
|
function mapPosition(position) {
|
|
781
|
-
|
|
1007
|
+
const mapped = {
|
|
1008
|
+
feePolicy: position.fee_policy === void 0 ? void 0 : validateLpFeePolicy(position.fee_policy),
|
|
1009
|
+
lpFeePolicyVersion: position.lp_fee_policy_version,
|
|
782
1010
|
id: position.lp_position_id,
|
|
783
1011
|
status: position.status,
|
|
784
1012
|
targetShardCount: position.target_shard_count,
|
|
@@ -793,6 +1021,8 @@ function mapPosition(position) {
|
|
|
793
1021
|
redemptionPermission: mapLpRedemptionPermission(position.redemption_permission),
|
|
794
1022
|
...position.actor_sync === void 0 ? {} : { actorSync: mapLpActorSync(position.actor_sync) }
|
|
795
1023
|
};
|
|
1024
|
+
validateLpPositionFeePolicy(mapped);
|
|
1025
|
+
return mapped;
|
|
796
1026
|
}
|
|
797
1027
|
function mapLpRedemptionPermission(permission) {
|
|
798
1028
|
if (permission === void 0) {
|
|
@@ -822,10 +1052,22 @@ function mapLpActorSync(actorSync) {
|
|
|
822
1052
|
);
|
|
823
1053
|
}
|
|
824
1054
|
const redeemableProjectionAvailable = redeemableBucketCount === redeemableBucketValues.length;
|
|
825
|
-
return {
|
|
1055
|
+
return normalizeLpActorSync({
|
|
1056
|
+
...actorSync.economic_return === void 0 ? {} : {
|
|
1057
|
+
economicReturn: mapLpEconomicReturn(
|
|
1058
|
+
actorSync.economic_return,
|
|
1059
|
+
actorSync.protocol_commission_lamports ?? 0
|
|
1060
|
+
)
|
|
1061
|
+
},
|
|
1062
|
+
feePolicy: actorSync.fee_policy === void 0 ? void 0 : validateLpFeePolicy(actorSync.fee_policy),
|
|
1063
|
+
feeBasisRevision: actorSync.fee_basis_revision,
|
|
1064
|
+
grossFeeLamports: actorSync.gross_fee_lamports,
|
|
1065
|
+
protocolCommissionLamports: actorSync.protocol_commission_lamports,
|
|
1066
|
+
waivedProtocolCommissionLamports: actorSync.waived_protocol_commission_lamports,
|
|
826
1067
|
lpPositionId: actorSync.lp_position_id,
|
|
827
1068
|
status: actorSync.status,
|
|
828
1069
|
sourceLiquidityUse: actorSync.source_liquidity_use,
|
|
1070
|
+
totalNetFundsLamports: actorSync.total_net_funds_lamports,
|
|
829
1071
|
redeemableProjectionAvailable,
|
|
830
1072
|
redeemablePrincipalLamports: actorSync.redeemable_principal_lamports ?? 0,
|
|
831
1073
|
redeemableFeeLamports: actorSync.redeemable_fee_lamports ?? 0,
|
|
@@ -851,6 +1093,33 @@ function mapLpActorSync(actorSync) {
|
|
|
851
1093
|
...actorSync.redemption_history_next_cursor === void 0 ? {} : { redemptionHistoryNextCursor: actorSync.redemption_history_next_cursor },
|
|
852
1094
|
stateVersion: actorSync.state_version,
|
|
853
1095
|
updatedAtMs: actorSync.updated_at_ms
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
var LP_ECONOMIC_UNSIGNED_TOTAL_MAX = (1n << 128n) - 1n;
|
|
1099
|
+
var LP_ECONOMIC_SIGNED_TOTAL_MIN = -(1n << 127n);
|
|
1100
|
+
var LP_ECONOMIC_SIGNED_TOTAL_MAX = (1n << 127n) - 1n;
|
|
1101
|
+
var LP_ECONOMIC_UNSIGNED_DECIMAL = /^(0|[1-9][0-9]*)$/;
|
|
1102
|
+
var LP_ECONOMIC_SIGNED_DECIMAL = /^(0|-?[1-9][0-9]*)$/;
|
|
1103
|
+
function mapLpEconomicReturn(summary, protocolCommissionLamports) {
|
|
1104
|
+
const unsigned = [
|
|
1105
|
+
summary.provider_reward_lamports,
|
|
1106
|
+
summary.source_expense_compensation_lamports,
|
|
1107
|
+
summary.charged_reimbursement_loss_lamports
|
|
1108
|
+
];
|
|
1109
|
+
const valid = unsigned.every(
|
|
1110
|
+
(value) => typeof value === "string" && LP_ECONOMIC_UNSIGNED_DECIMAL.test(value) && BigInt(value) <= LP_ECONOMIC_UNSIGNED_TOTAL_MAX
|
|
1111
|
+
) && typeof summary.net_economic_return_lamports === "string" && LP_ECONOMIC_SIGNED_DECIMAL.test(summary.net_economic_return_lamports);
|
|
1112
|
+
if (!valid)
|
|
1113
|
+
throw new CommandError("REJECTED_STATE", "coordinator LP economic return totals are invalid");
|
|
1114
|
+
const net = BigInt(summary.net_economic_return_lamports);
|
|
1115
|
+
if (net < LP_ECONOMIC_SIGNED_TOTAL_MIN || net > LP_ECONOMIC_SIGNED_TOTAL_MAX || net !== BigInt(summary.provider_reward_lamports) - BigInt(summary.charged_reimbursement_loss_lamports) - BigInt(protocolCommissionLamports)) {
|
|
1116
|
+
throw new CommandError("REJECTED_STATE", "coordinator LP economic return invariant is invalid");
|
|
1117
|
+
}
|
|
1118
|
+
return {
|
|
1119
|
+
providerRewardLamports: summary.provider_reward_lamports,
|
|
1120
|
+
sourceExpenseCompensationLamports: summary.source_expense_compensation_lamports,
|
|
1121
|
+
chargedReimbursementLossLamports: summary.charged_reimbursement_loss_lamports,
|
|
1122
|
+
netEconomicReturnLamports: summary.net_economic_return_lamports
|
|
854
1123
|
};
|
|
855
1124
|
}
|
|
856
1125
|
function mergePositionHistoryPages(first, next) {
|
|
@@ -874,6 +1143,8 @@ function mergePositionHistoryPages(first, next) {
|
|
|
874
1143
|
}
|
|
875
1144
|
function mapLpRedemptionHistory(history) {
|
|
876
1145
|
return {
|
|
1146
|
+
feePolicyHash: history.fee_policy_hash,
|
|
1147
|
+
feeBasisRevision: history.fee_basis_revision,
|
|
877
1148
|
redemptionId: history.redemption_id,
|
|
878
1149
|
state: history.state,
|
|
879
1150
|
...history.withdrawal_mode === void 0 ? {} : { withdrawalMode: history.withdrawal_mode },
|
|
@@ -955,7 +1226,7 @@ function randomBytes(length) {
|
|
|
955
1226
|
return bytes;
|
|
956
1227
|
}
|
|
957
1228
|
function loadProtocol() {
|
|
958
|
-
protocolPromise ??= import('./coordinator-
|
|
1229
|
+
protocolPromise ??= import('./coordinator-T2B7253V.js');
|
|
959
1230
|
return protocolPromise;
|
|
960
1231
|
}
|
|
961
1232
|
|
|
@@ -1253,6 +1524,7 @@ function isLpPositionAuthMissingError(error) {
|
|
|
1253
1524
|
return error instanceof LpPositionAuthMissingError || error instanceof Error && error.message === LP_MISSING_POSITION_CODE_MESSAGE;
|
|
1254
1525
|
}
|
|
1255
1526
|
function previewLpWithdrawalPlan(position, args = {}) {
|
|
1527
|
+
validateLpPositionFeePolicy(position);
|
|
1256
1528
|
const claim = resolveWithdrawalClaim(position, args);
|
|
1257
1529
|
return {
|
|
1258
1530
|
...claim,
|
|
@@ -1285,11 +1557,13 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1285
1557
|
return auth;
|
|
1286
1558
|
};
|
|
1287
1559
|
const rememberPosition = (position) => {
|
|
1560
|
+
validateLpPositionFeePolicy(position, state.positions.get(position.id));
|
|
1288
1561
|
const snapshot = clonePosition(position);
|
|
1289
1562
|
const previous = state.positions.get(snapshot.id);
|
|
1290
|
-
const merged =
|
|
1563
|
+
const merged = {
|
|
1291
1564
|
...snapshot,
|
|
1292
|
-
|
|
1565
|
+
actorSync: mergeLpActorSync(previous?.actorSync, snapshot.actorSync),
|
|
1566
|
+
redemptionPermission: previous === void 0 ? snapshot.redemptionPermission : mergeLpRedemptionPermission(
|
|
1293
1567
|
previous.redemptionPermission,
|
|
1294
1568
|
snapshot.redemptionPermission
|
|
1295
1569
|
)
|
|
@@ -1327,7 +1601,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1327
1601
|
const current = rememberPosition(await client.getPosition(positionId, auth));
|
|
1328
1602
|
options.onPosition?.(current);
|
|
1329
1603
|
const startIndex = current.shards.length;
|
|
1330
|
-
const remaining = current.targetShardCount - startIndex;
|
|
1604
|
+
const remaining = Math.min(current.targetShardCount - startIndex, LP_MAX_INITIAL_SHARDS);
|
|
1331
1605
|
if (remaining <= 0) return current;
|
|
1332
1606
|
emitDkgProgress(options, current, startIndex, remaining, 0);
|
|
1333
1607
|
let expectedAddresses = null;
|
|
@@ -1357,7 +1631,9 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1357
1631
|
);
|
|
1358
1632
|
options.onPosition?.(position);
|
|
1359
1633
|
emitDkgProgress(options, position, startIndex, remaining, remaining);
|
|
1360
|
-
|
|
1634
|
+
rememberPosition(position);
|
|
1635
|
+
if (position.shards.length < position.targetShardCount) continue;
|
|
1636
|
+
return position;
|
|
1361
1637
|
} catch (error) {
|
|
1362
1638
|
const reconciled = await tryRefreshCompletedDkgWindow({
|
|
1363
1639
|
client,
|
|
@@ -1387,7 +1663,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1387
1663
|
async createPosition(args) {
|
|
1388
1664
|
assertNoUnsupportedFeePolicy(args.feePolicy);
|
|
1389
1665
|
const shardCount = args.shardCount ?? LP_DEFAULT_TARGET_SHARDS;
|
|
1390
|
-
assertShardCount(shardCount,
|
|
1666
|
+
assertShardCount(shardCount, LP_MAX_INITIAL_SHARDS, "shardCount");
|
|
1391
1667
|
assertAttested(currentSession);
|
|
1392
1668
|
const committedLamports = args.committedLamports ?? DEFAULT_SHARD_FUNDING_LAMPORTS;
|
|
1393
1669
|
const refillThreshold = args.refillThreshold ?? Math.ceil(shardCount * DEFAULT_REFILL_THRESHOLD_RATIO);
|
|
@@ -1408,6 +1684,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1408
1684
|
{
|
|
1409
1685
|
lpPositionId: positionId,
|
|
1410
1686
|
creationAuthorizationId: creationAuthorization.authorizationId,
|
|
1687
|
+
feePolicy: creationAuthorization.feePolicy,
|
|
1411
1688
|
authPublicKey: Array.from(auth.authPublicKey),
|
|
1412
1689
|
refillPublicKey: Array.from(auth.refillPublicKey),
|
|
1413
1690
|
withdrawalCommitment: Array.from(auth.withdrawalCommitment),
|
|
@@ -1448,11 +1725,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1448
1725
|
const auth = requireAuth(positionId);
|
|
1449
1726
|
const current = await refreshPosition2(positionId);
|
|
1450
1727
|
args.onPosition?.(current);
|
|
1451
|
-
const refillShardCount = resolveLpRefillShardCount(
|
|
1452
|
-
current,
|
|
1453
|
-
requestedShardCount,
|
|
1454
|
-
args.shardCount === void 0
|
|
1455
|
-
);
|
|
1728
|
+
const refillShardCount = resolveLpRefillShardCount(current, requestedShardCount);
|
|
1456
1729
|
const authorizedPosition = rememberPosition(
|
|
1457
1730
|
await client.refillPosition(
|
|
1458
1731
|
{
|
|
@@ -1572,6 +1845,8 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1572
1845
|
const existingRedemption = findOpenRedemptionHistory(before, args);
|
|
1573
1846
|
if (existingRedemption !== void 0) {
|
|
1574
1847
|
const execution2 = {
|
|
1848
|
+
feePolicyHash: existingRedemption.feePolicyHash,
|
|
1849
|
+
feeBasisRevision: existingRedemption.feeBasisRevision,
|
|
1575
1850
|
withdrawalId: existingRedemption.redemptionId,
|
|
1576
1851
|
txSignatures: [...existingRedemption.txSignatures],
|
|
1577
1852
|
acceptedLamports: existingRedemption.acceptedLamports,
|
|
@@ -1616,6 +1891,8 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1616
1891
|
earnedFeeLamports: args.withdrawalMode === "max_available" ? 0 : preview.earnedFeeLamports,
|
|
1617
1892
|
withdrawalMode: args.withdrawalMode,
|
|
1618
1893
|
requestedAtMs,
|
|
1894
|
+
feePolicyHash: before.feePolicy?.policy_hash,
|
|
1895
|
+
feeBasisRevision: before.actorSync?.feeBasisRevision,
|
|
1619
1896
|
allowManyToOne: args.allowManyToOne === true || preview?.sourceCount === 1
|
|
1620
1897
|
},
|
|
1621
1898
|
auth
|
|
@@ -1744,6 +2021,7 @@ async function tryRefreshCompletedDkgWindow({
|
|
|
1744
2021
|
const position = await client.getPosition(positionId, auth).catch(() => null);
|
|
1745
2022
|
if (position === null) return null;
|
|
1746
2023
|
if (!hasCompletedDkgWindow(position, startIndex, total, expectedAddresses)) return null;
|
|
2024
|
+
validateLpPositionFeePolicy(position, state.positions.get(position.id));
|
|
1747
2025
|
state.positions.set(position.id, clonePosition(position));
|
|
1748
2026
|
return position;
|
|
1749
2027
|
}
|
|
@@ -1785,21 +2063,12 @@ function assertShardCount(value, max, field) {
|
|
|
1785
2063
|
);
|
|
1786
2064
|
}
|
|
1787
2065
|
}
|
|
1788
|
-
function resolveLpRefillShardCount(position, requestedShardCount
|
|
1789
|
-
const
|
|
1790
|
-
if (
|
|
1791
|
-
throw new PolicyValidationError(
|
|
1792
|
-
"INVALID_AMOUNT",
|
|
1793
|
-
`LP refill target_shard_count is already at ${LP_MAX_TARGET_SHARDS}`
|
|
1794
|
-
);
|
|
1795
|
-
}
|
|
1796
|
-
const refillShardCount = capDefaultBatch ? Math.min(requestedShardCount, remainingShardCapacity) : requestedShardCount;
|
|
1797
|
-
if (position.shards.length + refillShardCount > LP_MAX_TARGET_SHARDS) {
|
|
1798
|
-
throw new PolicyValidationError(
|
|
1799
|
-
"INVALID_AMOUNT",
|
|
1800
|
-
`LP refill target_shard_count must be <= ${LP_MAX_TARGET_SHARDS}`
|
|
1801
|
-
);
|
|
2066
|
+
function resolveLpRefillShardCount(position, requestedShardCount) {
|
|
2067
|
+
const nextTarget = position.shards.length + requestedShardCount;
|
|
2068
|
+
if (!Number.isSafeInteger(nextTarget) || nextTarget > LP_MAX_TOTAL_SHARDS) {
|
|
2069
|
+
throw new PolicyValidationError("INVALID_AMOUNT", "LP refill target_shard_count overflows u32");
|
|
1802
2070
|
}
|
|
2071
|
+
const refillShardCount = requestedShardCount;
|
|
1803
2072
|
return refillShardCount;
|
|
1804
2073
|
}
|
|
1805
2074
|
function isLpPositionReadyForInitialFunding(position) {
|
|
@@ -1851,7 +2120,9 @@ function hasActorSyncLpActivity(sync) {
|
|
|
1851
2120
|
}
|
|
1852
2121
|
function resolveRedeemablePrincipalLamports(sync, legacyAvailableLamports, actorRedeemablePrincipalLamports, actorRedeemableFeeLamports) {
|
|
1853
2122
|
if (sync?.redeemableProjectionAvailable !== true) return legacyAvailableLamports;
|
|
1854
|
-
if (legacyAvailableLamports <= 0)
|
|
2123
|
+
if (sync.feePolicy !== void 0 || legacyAvailableLamports <= 0) {
|
|
2124
|
+
return actorRedeemablePrincipalLamports;
|
|
2125
|
+
}
|
|
1855
2126
|
if (actorRedeemablePrincipalLamports >= legacyAvailableLamports || hasActorSyncLpActivity(sync)) {
|
|
1856
2127
|
return actorRedeemablePrincipalLamports;
|
|
1857
2128
|
}
|
|
@@ -1956,6 +2227,8 @@ function buildLpRedemptionRecord({
|
|
|
1956
2227
|
nowMs
|
|
1957
2228
|
}) {
|
|
1958
2229
|
return {
|
|
2230
|
+
feePolicyHash: execution.feePolicyHash,
|
|
2231
|
+
feeBasisRevision: execution.feeBasisRevision,
|
|
1959
2232
|
redemptionId: execution.withdrawalId,
|
|
1960
2233
|
lpPositionId: position.id,
|
|
1961
2234
|
requestedAt: nowMs,
|
|
@@ -2004,7 +2277,7 @@ function reconcileLpRedemptionFromActorSync(record, position) {
|
|
|
2004
2277
|
function reconcileLpRedemptionFromHistory(record, history) {
|
|
2005
2278
|
const observedStateVersion = record.coordinatorStateVersion ?? 0;
|
|
2006
2279
|
if (history.stateVersion < observedStateVersion) return record;
|
|
2007
|
-
if (record.acceptedLamports !== void 0 && history.acceptedLamports !== record.acceptedLamports || history.detailsTruncated !== true && !sameStringList(history.destinationAddresses, record.destinationAddresses)) {
|
|
2280
|
+
if (history.feePolicyHash !== record.feePolicyHash || history.feeBasisRevision !== record.feeBasisRevision || record.acceptedLamports !== void 0 && history.acceptedLamports !== record.acceptedLamports || history.detailsTruncated !== true && !sameStringList(history.destinationAddresses, record.destinationAddresses)) {
|
|
2008
2281
|
return {
|
|
2009
2282
|
...record,
|
|
2010
2283
|
status: "failed",
|
|
@@ -2017,6 +2290,7 @@ function reconcileLpRedemptionFromHistory(record, history) {
|
|
|
2017
2290
|
...record,
|
|
2018
2291
|
coordinatorStateVersion: history.stateVersion,
|
|
2019
2292
|
redeemedLamports: history.landedLamports,
|
|
2293
|
+
networkFeeLossLamports: history.networkFeeLossLamports,
|
|
2020
2294
|
txSignatures,
|
|
2021
2295
|
destinationCount: history.destinationCount,
|
|
2022
2296
|
txSignatureCount: history.txSignatureCount,
|
|
@@ -2053,6 +2327,8 @@ function hydrateLpRedemptionsFromPosition(state, position) {
|
|
|
2053
2327
|
}
|
|
2054
2328
|
function lpWithdrawalRecordFromHistory(position, history) {
|
|
2055
2329
|
const record = {
|
|
2330
|
+
feePolicyHash: history.feePolicyHash,
|
|
2331
|
+
feeBasisRevision: history.feeBasisRevision,
|
|
2056
2332
|
redemptionId: history.redemptionId,
|
|
2057
2333
|
lpPositionId: position.id,
|
|
2058
2334
|
requestedAt: history.createdAtMs,
|
|
@@ -2063,6 +2339,7 @@ function lpWithdrawalRecordFromHistory(position, history) {
|
|
|
2063
2339
|
landedBaselineLamports: 0,
|
|
2064
2340
|
landedFeeBaselineLamports: 0,
|
|
2065
2341
|
redeemedLamports: history.landedLamports,
|
|
2342
|
+
networkFeeLossLamports: history.networkFeeLossLamports,
|
|
2066
2343
|
txSignatures: [...history.txSignatures],
|
|
2067
2344
|
txSignatureBaseline: [],
|
|
2068
2345
|
coordinatorStateVersion: history.stateVersion,
|
|
@@ -2081,6 +2358,7 @@ function uniqueStrings(values) {
|
|
|
2081
2358
|
function clonePosition(position) {
|
|
2082
2359
|
return {
|
|
2083
2360
|
...position,
|
|
2361
|
+
feePolicy: position.feePolicy === void 0 ? void 0 : { ...position.feePolicy },
|
|
2084
2362
|
shards: position.shards.map((shard) => ({ ...shard })),
|
|
2085
2363
|
actorSync: position.actorSync === void 0 ? void 0 : {
|
|
2086
2364
|
...position.actorSync,
|
|
@@ -2193,6 +2471,6 @@ function listPositions(session) {
|
|
|
2193
2471
|
return defaultLpLifecycleClient(session).listPositions();
|
|
2194
2472
|
}
|
|
2195
2473
|
|
|
2196
|
-
export { LP_COMMAND_REQUEST_TIMEOUT_MS, LP_DKG_ABORT_CLEANUP_TIMEOUT_MS, LP_DKG_ABORT_REQUEST_TIMEOUT_MS, LP_DKG_WORKER_REQUEST_TIMEOUT_MESSAGE, LP_DKG_WORKER_REQUEST_TIMEOUT_MS, LP_FEE_SOURCE_COUNT_UNAVAILABLE_MESSAGE, LP_MISSING_POSITION_CODE_MESSAGE, LP_REDEMPTION_RECONCILING_MESSAGE, bytesToHex, completeDkgBatch, confirmPositionCodeSaved, createLpCoordinatorClient, createLpDkgBatch, createLpLifecycleClient, createPosition, defaultLpLifecycleClient, deriveLpPositionCodeAuth, generateLpPositionCode, isLpPositionAuthMissingError, isLpRedemptionReconcilingError, listPositions, normalizeLpPositionCode, prepareInitialFunding, prepareTopUp2 as prepareTopUp, previewLpWithdrawalPlan, reconcileFunding2 as reconcileFunding, recoverPosition, refill, refreshPosition, signLpCommandBytes, waitForTopUp, waitForWithdrawalConfirmation, withdrawFees, withdrawPosition };
|
|
2474
|
+
export { LP_COMMAND_REQUEST_TIMEOUT_MS, LP_DKG_ABORT_CLEANUP_TIMEOUT_MS, LP_DKG_ABORT_REQUEST_TIMEOUT_MS, LP_DKG_WORKER_REQUEST_TIMEOUT_MESSAGE, LP_DKG_WORKER_REQUEST_TIMEOUT_MS, LP_FEE_SOURCE_COUNT_UNAVAILABLE_MESSAGE, LP_MISSING_POSITION_CODE_MESSAGE, LP_REDEMPTION_RECONCILING_MESSAGE, bytesToHex, completeDkgBatch, confirmPositionCodeSaved, createLpCoordinatorClient, createLpDkgBatch, createLpLifecycleClient, createPosition, defaultLpLifecycleClient, deriveLpPositionCodeAuth, generateLpPositionCode, isLpPositionAuthMissingError, isLpRedemptionReconcilingError, listPositions, mergeLpActorSync, normalizeLpActorSync, normalizeLpPositionCode, prepareInitialFunding, prepareTopUp2 as prepareTopUp, previewLpWithdrawalPlan, reconcileFunding2 as reconcileFunding, recoverPosition, refill, refreshPosition, signLpCommandBytes, validateLpPositionFeePolicy, waitForTopUp, waitForWithdrawalConfirmation, withdrawFees, withdrawPosition };
|
|
2197
2475
|
//# sourceMappingURL=lp.js.map
|
|
2198
2476
|
//# sourceMappingURL=lp.js.map
|