@invisible-labs/sdk 0.6.0-devnet.4 → 0.6.0-devnet.5
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 +70 -13
- package/dist/.invisible-sdk-build-target.json +2 -2
- package/dist/{chunk-UADJCUPK.js → chunk-3MDHAS4D.js} +6 -5
- package/dist/chunk-3MDHAS4D.js.map +1 -0
- package/dist/{chunk-E4DCEDAG.js → chunk-3TGQ4CZ3.js} +178 -2
- package/dist/chunk-3TGQ4CZ3.js.map +1 -0
- package/dist/chunk-DCTYBUY3.js +258 -0
- package/dist/chunk-DCTYBUY3.js.map +1 -0
- package/dist/{chunk-NHEHCUS5.js → chunk-EBWTAXNT.js} +3 -3
- package/dist/{chunk-NHEHCUS5.js.map → chunk-EBWTAXNT.js.map} +1 -1
- package/dist/{chunk-V5HXJRBW.js → chunk-HJFMDMPY.js} +3 -3
- package/dist/chunk-HJFMDMPY.js.map +1 -0
- package/dist/{chunk-GHBQF3A7.js → chunk-QRN46R3F.js} +5 -2
- package/dist/chunk-QRN46R3F.js.map +1 -0
- package/dist/chunk-Y7AK6RBV.js +4189 -0
- package/dist/chunk-Y7AK6RBV.js.map +1 -0
- package/dist/{coordinator-ZNLGAYXD.js → coordinator-PEWHNZ7I.js} +3 -3
- package/dist/{coordinator-ZNLGAYXD.js.map → coordinator-PEWHNZ7I.js.map} +1 -1
- package/dist/events.js +3 -3
- package/dist/index.d.ts +14 -4
- package/dist/index.js +74 -11
- package/dist/index.js.map +1 -1
- package/dist/lp.d.ts +33 -9
- package/dist/lp.js +305 -45
- package/dist/lp.js.map +1 -1
- package/dist/presets.d.ts +6 -2
- package/dist/presets.js +8 -8
- package/dist/presets.js.map +1 -1
- package/dist/stats.js +1 -1
- package/dist/storage.js +2 -243
- package/dist/storage.js.map +1 -1
- package/dist/{types.generated-DJBTjLpP.d.ts → types.generated-YhFu9ZBR.d.ts} +29 -4
- package/dist/user.d.ts +31 -4
- package/dist/user.js +409 -57
- package/dist/user.js.map +1 -1
- package/package.json +4 -1
- package/dist/chunk-5NNEO7IK.js +0 -1150
- package/dist/chunk-5NNEO7IK.js.map +0 -1
- package/dist/chunk-BRDLLGCZ.js +0 -59
- package/dist/chunk-BRDLLGCZ.js.map +0 -1
- package/dist/chunk-DIA6U2CV.js +0 -1927
- package/dist/chunk-DIA6U2CV.js.map +0 -1
- package/dist/chunk-E4DCEDAG.js.map +0 -1
- package/dist/chunk-GHBQF3A7.js.map +0 -1
- package/dist/chunk-UADJCUPK.js.map +0 -1
- package/dist/chunk-V5HXJRBW.js.map +0 -1
package/dist/lp.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isValidLpPositionId, LP_DEFAULT_REFILL_BATCH_SIZE, LP_DEFAULT_TARGET_SHARDS, LP_MAX_TARGET_SHARDS, LP_MAX_REFILL_BATCH_SIZE } from './chunk-4X5OCCQW.js';
|
|
2
|
-
import { publicKey, assertAttested, lamports } from './chunk-
|
|
3
|
-
import { requestEnvelope } from './chunk-
|
|
4
|
-
import { getSessionState } from './chunk-
|
|
5
|
-
import { CommandError,
|
|
2
|
+
import { publicKey, assertAttested, lamports } from './chunk-EBWTAXNT.js';
|
|
3
|
+
import { requestEnvelope, CoordinatorMessageType } from './chunk-3MDHAS4D.js';
|
|
4
|
+
import { getSessionState } from './chunk-HJFMDMPY.js';
|
|
5
|
+
import { CommandError, WalletError, TransportError, PolicyValidationError, RoutingError, LpLifecycleError } from './chunk-QRN46R3F.js';
|
|
6
6
|
import './chunk-VR6T6OJS.js';
|
|
7
7
|
|
|
8
8
|
// src/lp/positionCode.ts
|
|
@@ -228,59 +228,206 @@ function validateDestinationAddresses(destinationAddresses) {
|
|
|
228
228
|
|
|
229
229
|
// src/lp/coordinatorClient.ts
|
|
230
230
|
var COMMAND_TTL_MS = 3e4;
|
|
231
|
-
var
|
|
231
|
+
var LP_POSITION_OPEN_COMMAND_TTL_MS = 55e3;
|
|
232
|
+
var LP_POSITION_OPEN_REQUEST_TIMEOUT_MS = 2e4;
|
|
233
|
+
var LP_COMMAND_REQUEST_TIMEOUT_MS = COMMAND_TTL_MS;
|
|
234
|
+
var LP_CREATION_CHALLENGE_REQUEST_TIMEOUT_MS = 3e4;
|
|
235
|
+
var LP_CREATION_WALLET_SIGNATURE_TIMEOUT_MS = 45e3;
|
|
236
|
+
var LP_CREATION_PROOF_REQUEST_TIMEOUT_MS = 15e3;
|
|
237
|
+
var LP_CREATION_PROOF_RETRY_TIMEOUT_MS = 15e3;
|
|
238
|
+
var LP_CREATION_AUTHORIZATION_MARGIN_MS = 15e3;
|
|
239
|
+
var LP_CREATION_MIN_STEP_TIMEOUT_MS = 1;
|
|
232
240
|
var LP_DKG_ABORT_REQUEST_TIMEOUT_MS = 1e4;
|
|
233
241
|
var encoder2 = new TextEncoder();
|
|
234
242
|
var protocolPromise = null;
|
|
235
|
-
function createLpCoordinatorClient(session) {
|
|
243
|
+
function createLpCoordinatorClient(session, options = {}) {
|
|
244
|
+
const sessionRef = { current: session };
|
|
245
|
+
const reconnectSession = options.reconnectSession === void 0 ? void 0 : async () => {
|
|
246
|
+
const nextSession = await options.reconnectSession();
|
|
247
|
+
sessionRef.current = nextSession;
|
|
248
|
+
return nextSession;
|
|
249
|
+
};
|
|
236
250
|
return {
|
|
251
|
+
authorizePositionCreation(intent, signer) {
|
|
252
|
+
return authorizePositionCreation(sessionRef.current, intent, signer);
|
|
253
|
+
},
|
|
237
254
|
initDkg(input, auth) {
|
|
238
|
-
return initDkg(
|
|
255
|
+
return initDkg(sessionRef.current, input, auth);
|
|
239
256
|
},
|
|
240
257
|
abortDkgSessions(lpPositionId, auth) {
|
|
241
|
-
return abortDkgSessions(
|
|
258
|
+
return abortDkgSessions(sessionRef.current, lpPositionId, auth);
|
|
242
259
|
},
|
|
243
260
|
dkgRound1(input, auth) {
|
|
244
|
-
return dkgRound1(
|
|
261
|
+
return dkgRound1(sessionRef.current, input, auth);
|
|
245
262
|
},
|
|
246
263
|
dkgRound2(input, auth) {
|
|
247
|
-
return dkgRound2(
|
|
264
|
+
return dkgRound2(sessionRef.current, input, auth);
|
|
248
265
|
},
|
|
249
266
|
openPosition(input, auth) {
|
|
250
|
-
return openPosition(
|
|
267
|
+
return openPosition(sessionRef.current, input, auth, reconnectSession);
|
|
251
268
|
},
|
|
252
|
-
getPosition(lpPositionId, auth,
|
|
253
|
-
return getPosition(
|
|
269
|
+
getPosition(lpPositionId, auth, options2) {
|
|
270
|
+
return getPosition(sessionRef.current, lpPositionId, auth, options2);
|
|
254
271
|
},
|
|
255
272
|
finalizeDkgBatch(input, auth) {
|
|
256
|
-
return finalizeDkgBatch(
|
|
273
|
+
return finalizeDkgBatch(sessionRef.current, input, auth);
|
|
257
274
|
},
|
|
258
275
|
refillPosition(input, auth) {
|
|
259
|
-
return refillPosition(
|
|
276
|
+
return refillPosition(sessionRef.current, input, auth);
|
|
260
277
|
},
|
|
261
278
|
reconcileFunding(lpPositionId, auth) {
|
|
262
|
-
return reconcileFunding(
|
|
279
|
+
return reconcileFunding(sessionRef.current, lpPositionId, auth);
|
|
263
280
|
},
|
|
264
281
|
planFunding(input, auth) {
|
|
265
|
-
return planFunding(
|
|
282
|
+
return planFunding(sessionRef.current, input, auth);
|
|
266
283
|
},
|
|
267
284
|
confirmFunding(input, auth) {
|
|
268
|
-
return confirmFunding(
|
|
285
|
+
return confirmFunding(sessionRef.current, input, auth);
|
|
269
286
|
},
|
|
270
287
|
prepareTopUp(lpPositionId, auth) {
|
|
271
|
-
return prepareTopUp(
|
|
288
|
+
return prepareTopUp(sessionRef.current, lpPositionId, auth);
|
|
272
289
|
},
|
|
273
290
|
getTopUpStatus(input, auth) {
|
|
274
|
-
return getTopUpStatus(
|
|
291
|
+
return getTopUpStatus(sessionRef.current, input, auth);
|
|
275
292
|
},
|
|
276
293
|
makeAvailable(input, auth) {
|
|
277
|
-
return makeAvailable(
|
|
294
|
+
return makeAvailable(sessionRef.current, input, auth);
|
|
278
295
|
},
|
|
279
296
|
executeWithdrawal(input, auth) {
|
|
280
|
-
return executeWithdrawal(
|
|
297
|
+
return executeWithdrawal(sessionRef.current, input, auth);
|
|
281
298
|
}
|
|
282
299
|
};
|
|
283
300
|
}
|
|
301
|
+
async function authorizePositionCreation(session, intent, signer) {
|
|
302
|
+
const signerPublicKey = publicKey(signer.publicKey);
|
|
303
|
+
const challengeRequestStartedAtMs = Date.now();
|
|
304
|
+
const challengeEnvelope = await requestEnvelope(
|
|
305
|
+
session,
|
|
306
|
+
CoordinatorMessageType.LpCreateAuthorization,
|
|
307
|
+
{
|
|
308
|
+
case: "challenge",
|
|
309
|
+
value: {
|
|
310
|
+
public_key: signerPublicKey,
|
|
311
|
+
intent: {
|
|
312
|
+
committed_lamports: intent.committedLamports,
|
|
313
|
+
shard_count: intent.shardCount,
|
|
314
|
+
shard_amount_lamports: intent.shardAmountLamports,
|
|
315
|
+
refill_threshold: intent.refillThreshold
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
{ timeoutMs: LP_CREATION_CHALLENGE_REQUEST_TIMEOUT_MS }
|
|
320
|
+
);
|
|
321
|
+
const challenge = challengeEnvelope.payload;
|
|
322
|
+
if (challenge.case !== "challenge") {
|
|
323
|
+
throw new CommandError(
|
|
324
|
+
"REJECTED_STATE",
|
|
325
|
+
"Coordinator returned an unexpected LP creation authorization response"
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
const localAuthorizationDeadlineMs = challengeRequestStartedAtMs + challenge.value.valid_for_ms;
|
|
329
|
+
const walletTimeoutMs = lpCreationAuthorizationStepTimeout(
|
|
330
|
+
localAuthorizationDeadlineMs,
|
|
331
|
+
LP_CREATION_PROOF_REQUEST_TIMEOUT_MS + LP_CREATION_PROOF_RETRY_TIMEOUT_MS + LP_CREATION_AUTHORIZATION_MARGIN_MS,
|
|
332
|
+
LP_CREATION_WALLET_SIGNATURE_TIMEOUT_MS
|
|
333
|
+
);
|
|
334
|
+
const signature = await signLpCreationMessageWithTimeout(
|
|
335
|
+
signer,
|
|
336
|
+
encoder2.encode(challenge.value.message),
|
|
337
|
+
walletTimeoutMs
|
|
338
|
+
);
|
|
339
|
+
if (!(signature instanceof Uint8Array) || signature.length !== 64) {
|
|
340
|
+
throw new WalletError(
|
|
341
|
+
"WALLET_INVALID_SIGNATURE",
|
|
342
|
+
"Solana wallet returned an invalid LP creation signature"
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
const proofPayload = {
|
|
346
|
+
case: "proof",
|
|
347
|
+
value: {
|
|
348
|
+
authorization_id: challenge.value.authorization_id,
|
|
349
|
+
public_key: signerPublicKey,
|
|
350
|
+
message: challenge.value.message,
|
|
351
|
+
signature
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
let proofEnvelope;
|
|
355
|
+
try {
|
|
356
|
+
const proofTimeoutMs = lpCreationAuthorizationStepTimeout(
|
|
357
|
+
localAuthorizationDeadlineMs,
|
|
358
|
+
LP_CREATION_PROOF_RETRY_TIMEOUT_MS + LP_CREATION_AUTHORIZATION_MARGIN_MS,
|
|
359
|
+
LP_CREATION_PROOF_REQUEST_TIMEOUT_MS
|
|
360
|
+
);
|
|
361
|
+
proofEnvelope = await requestEnvelope(
|
|
362
|
+
session,
|
|
363
|
+
CoordinatorMessageType.LpCreateAuthorization,
|
|
364
|
+
proofPayload,
|
|
365
|
+
{ timeoutMs: proofTimeoutMs }
|
|
366
|
+
);
|
|
367
|
+
} catch (error) {
|
|
368
|
+
if (!isAmbiguousCoordinatorRequestFailure(error)) throw error;
|
|
369
|
+
const proofRetryTimeoutMs = lpCreationAuthorizationStepTimeout(
|
|
370
|
+
localAuthorizationDeadlineMs,
|
|
371
|
+
LP_CREATION_AUTHORIZATION_MARGIN_MS,
|
|
372
|
+
LP_CREATION_PROOF_RETRY_TIMEOUT_MS
|
|
373
|
+
);
|
|
374
|
+
proofEnvelope = await requestEnvelope(
|
|
375
|
+
session,
|
|
376
|
+
CoordinatorMessageType.LpCreateAuthorization,
|
|
377
|
+
proofPayload,
|
|
378
|
+
{ timeoutMs: proofRetryTimeoutMs }
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
const authorization = proofEnvelope.payload;
|
|
382
|
+
if (authorization.case !== "authorized") {
|
|
383
|
+
throw new CommandError(
|
|
384
|
+
"REJECTED_STATE",
|
|
385
|
+
"Coordinator returned an unexpected LP creation authorization proof response"
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
if (authorization.value.authorization_id !== challenge.value.authorization_id) {
|
|
389
|
+
throw new CommandError(
|
|
390
|
+
"REJECTED_STATE",
|
|
391
|
+
"Coordinator returned an LP creation authorization for a different challenge"
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
lpCreationAuthorizationStepTimeout(
|
|
395
|
+
localAuthorizationDeadlineMs,
|
|
396
|
+
LP_CREATION_AUTHORIZATION_MARGIN_MS,
|
|
397
|
+
LP_CREATION_MIN_STEP_TIMEOUT_MS
|
|
398
|
+
);
|
|
399
|
+
return { authorizationId: authorization.value.authorization_id };
|
|
400
|
+
}
|
|
401
|
+
function lpCreationAuthorizationStepTimeout(localDeadlineMs, reservedMs, maximumTimeoutMs) {
|
|
402
|
+
const availableMs = localDeadlineMs - Date.now() - reservedMs;
|
|
403
|
+
if (availableMs < LP_CREATION_MIN_STEP_TIMEOUT_MS) {
|
|
404
|
+
throw new CommandError(
|
|
405
|
+
"REJECTED_EXPIRED",
|
|
406
|
+
"LP creation authorization expired; request a fresh coordinator challenge"
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
return Math.min(availableMs, maximumTimeoutMs);
|
|
410
|
+
}
|
|
411
|
+
async function signLpCreationMessageWithTimeout(signer, message, timeoutMs) {
|
|
412
|
+
let timeoutId;
|
|
413
|
+
try {
|
|
414
|
+
return await Promise.race([
|
|
415
|
+
signer.signMessage(message),
|
|
416
|
+
new Promise((_resolve, reject) => {
|
|
417
|
+
timeoutId = setTimeout(() => {
|
|
418
|
+
reject(
|
|
419
|
+
new WalletError(
|
|
420
|
+
"WALLET_USER_REJECTED",
|
|
421
|
+
"Solana wallet did not sign the LP creation challenge before it expired"
|
|
422
|
+
)
|
|
423
|
+
);
|
|
424
|
+
}, timeoutMs);
|
|
425
|
+
})
|
|
426
|
+
]);
|
|
427
|
+
} finally {
|
|
428
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
284
431
|
async function initDkg(session, input, auth) {
|
|
285
432
|
const response = await requestForPosition(session, input.lpPositionId, auth, "dkg_init", {
|
|
286
433
|
case: "dkgInit",
|
|
@@ -335,10 +482,11 @@ async function dkgRound2(session, input, auth) {
|
|
|
335
482
|
index: response.value.index
|
|
336
483
|
};
|
|
337
484
|
}
|
|
338
|
-
async function openPosition(session, input, auth) {
|
|
339
|
-
const
|
|
485
|
+
async function openPosition(session, input, auth, reconnectSession) {
|
|
486
|
+
const payload = {
|
|
340
487
|
case: "positionOpen",
|
|
341
488
|
value: {
|
|
489
|
+
creation_authorization_id: input.creationAuthorizationId,
|
|
342
490
|
auth_public_key: Uint8Array.from(input.authPublicKey),
|
|
343
491
|
refill_public_key: Uint8Array.from(input.refillPublicKey),
|
|
344
492
|
redemption_commitment: Uint8Array.from(input.withdrawalCommitment),
|
|
@@ -349,9 +497,69 @@ async function openPosition(session, input, auth) {
|
|
|
349
497
|
addresses: input.addresses,
|
|
350
498
|
created_at_ms: input.createdAtMs
|
|
351
499
|
}
|
|
352
|
-
}
|
|
500
|
+
};
|
|
501
|
+
const commandDeadlineMs = Date.now() + LP_POSITION_OPEN_COMMAND_TTL_MS;
|
|
502
|
+
const commandOptions = {
|
|
503
|
+
commandNonce: randomBytes(32),
|
|
504
|
+
commandExpiresAtMs: commandDeadlineMs,
|
|
505
|
+
deadlineMs: commandDeadlineMs,
|
|
506
|
+
timeoutMs: LP_POSITION_OPEN_REQUEST_TIMEOUT_MS
|
|
507
|
+
};
|
|
508
|
+
let response;
|
|
509
|
+
try {
|
|
510
|
+
response = await requestForPosition(
|
|
511
|
+
session,
|
|
512
|
+
input.lpPositionId,
|
|
513
|
+
auth,
|
|
514
|
+
"position_open",
|
|
515
|
+
payload,
|
|
516
|
+
commandOptions
|
|
517
|
+
);
|
|
518
|
+
} catch (error) {
|
|
519
|
+
if (!isAmbiguousLpPositionOpenFailure(error)) throw error;
|
|
520
|
+
const replaySession = reconnectSession === void 0 ? session : await reconnectSessionWithinDeadline(reconnectSession, commandDeadlineMs);
|
|
521
|
+
response = await requestForPosition(
|
|
522
|
+
replaySession,
|
|
523
|
+
input.lpPositionId,
|
|
524
|
+
auth,
|
|
525
|
+
"position_open",
|
|
526
|
+
payload,
|
|
527
|
+
commandOptions
|
|
528
|
+
);
|
|
529
|
+
}
|
|
353
530
|
return expectPosition(response);
|
|
354
531
|
}
|
|
532
|
+
async function reconnectSessionWithinDeadline(reconnectSession, deadlineMs) {
|
|
533
|
+
const remainingMs = deadlineMs - Date.now();
|
|
534
|
+
if (remainingMs <= 0) {
|
|
535
|
+
throw new CommandError(
|
|
536
|
+
"REJECTED_EXPIRED",
|
|
537
|
+
"LP position-open command expired before coordinator reconnect"
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
let timer;
|
|
541
|
+
try {
|
|
542
|
+
return await new Promise((resolve, reject) => {
|
|
543
|
+
timer = setTimeout(() => {
|
|
544
|
+
reject(
|
|
545
|
+
new CommandError(
|
|
546
|
+
"REJECTED_EXPIRED",
|
|
547
|
+
"LP position-open command expired during coordinator reconnect"
|
|
548
|
+
)
|
|
549
|
+
);
|
|
550
|
+
}, remainingMs);
|
|
551
|
+
Promise.resolve().then(reconnectSession).then(resolve, reject);
|
|
552
|
+
});
|
|
553
|
+
} finally {
|
|
554
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function isAmbiguousLpPositionOpenFailure(error) {
|
|
558
|
+
return isAmbiguousCoordinatorRequestFailure(error);
|
|
559
|
+
}
|
|
560
|
+
function isAmbiguousCoordinatorRequestFailure(error) {
|
|
561
|
+
return error instanceof TransportError || error instanceof CommandError && error.code === "REJECTED_STALE_JOB";
|
|
562
|
+
}
|
|
355
563
|
async function getPosition(session, lpPositionId, auth, options = {}) {
|
|
356
564
|
let cursor;
|
|
357
565
|
let position;
|
|
@@ -541,8 +749,8 @@ async function requestForPosition(session, lpPositionId, auth, action, payload,
|
|
|
541
749
|
const command = {
|
|
542
750
|
lp_position_id: lpPositionId,
|
|
543
751
|
action,
|
|
544
|
-
nonce: randomBytes(32),
|
|
545
|
-
expires_at_ms: Date.now() + Math.min(COMMAND_TTL_MS, timeoutMs),
|
|
752
|
+
nonce: options.commandNonce === void 0 ? randomBytes(32) : new Uint8Array(options.commandNonce),
|
|
753
|
+
expires_at_ms: options.commandExpiresAtMs ?? Date.now() + Math.min(COMMAND_TTL_MS, timeoutMs),
|
|
546
754
|
coordinator_attestation_hash: await coordinatorAttestationHash(
|
|
547
755
|
attestation.binaryHash,
|
|
548
756
|
attestation.pubkeyHex
|
|
@@ -582,9 +790,20 @@ function mapPosition(position) {
|
|
|
582
790
|
refillThreshold: position.refill_threshold,
|
|
583
791
|
shards: position.shards.map(mapShard),
|
|
584
792
|
createdAt: position.created_at_ms,
|
|
793
|
+
redemptionPermission: mapLpRedemptionPermission(position.redemption_permission),
|
|
585
794
|
...position.actor_sync === void 0 ? {} : { actorSync: mapLpActorSync(position.actor_sync) }
|
|
586
795
|
};
|
|
587
796
|
}
|
|
797
|
+
function mapLpRedemptionPermission(permission) {
|
|
798
|
+
if (permission === void 0) {
|
|
799
|
+
return { state: "unknown", grantRevision: 0, observedAtMs: 0 };
|
|
800
|
+
}
|
|
801
|
+
return {
|
|
802
|
+
state: permission.state,
|
|
803
|
+
grantRevision: permission.grant_revision,
|
|
804
|
+
observedAtMs: permission.observed_at_ms
|
|
805
|
+
};
|
|
806
|
+
}
|
|
588
807
|
function mapLpActorSync(actorSync) {
|
|
589
808
|
const redeemableBucketValues = [
|
|
590
809
|
actorSync.redeemable_principal_lamports,
|
|
@@ -736,7 +955,7 @@ function randomBytes(length) {
|
|
|
736
955
|
return bytes;
|
|
737
956
|
}
|
|
738
957
|
function loadProtocol() {
|
|
739
|
-
protocolPromise ??= import('./coordinator-
|
|
958
|
+
protocolPromise ??= import('./coordinator-PEWHNZ7I.js');
|
|
740
959
|
return protocolPromise;
|
|
741
960
|
}
|
|
742
961
|
|
|
@@ -1011,6 +1230,7 @@ var WITHDRAWAL_MISSING_RECORD_MESSAGE = "LP withdrawal record is missing";
|
|
|
1011
1230
|
var WITHDRAWAL_RECORD_MISMATCH_MESSAGE = "LP withdrawal record does not match this confirmation request";
|
|
1012
1231
|
var WITHDRAWAL_NO_LAMPORTS_MESSAGE = "LP redemption did not land any lamports on-chain";
|
|
1013
1232
|
var WITHDRAWAL_HISTORY_MISMATCH_MESSAGE = "LP redemption history does not match this request";
|
|
1233
|
+
var LP_REDEMPTION_PERMISSION_UNAVAILABLE_MESSAGE = "LP redemption is unavailable until the coordinator confirms permission";
|
|
1014
1234
|
var LP_WITHDRAWAL_UNRESOLVED_FUNDING_MESSAGE = "LP position has unresolved funding shards before redemption";
|
|
1015
1235
|
var UNSUPPORTED_FEE_POLICY_MESSAGE = "LP fee policy overrides are not advertised by the coordinator";
|
|
1016
1236
|
var LP_FEE_SOURCE_COUNT_UNAVAILABLE_MESSAGE = "LP earned-fee source count is not available; pass allowManyToOne: true to acknowledge many-to-one withdrawal risk";
|
|
@@ -1050,7 +1270,13 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1050
1270
|
redemptions: /* @__PURE__ */ new Map(),
|
|
1051
1271
|
topUps: /* @__PURE__ */ new Map()
|
|
1052
1272
|
};
|
|
1053
|
-
|
|
1273
|
+
let currentSession = session;
|
|
1274
|
+
const reconnectSession = runtime.reconnectSession === void 0 ? void 0 : async () => {
|
|
1275
|
+
const nextSession = await runtime.reconnectSession();
|
|
1276
|
+
currentSession = nextSession;
|
|
1277
|
+
return nextSession;
|
|
1278
|
+
};
|
|
1279
|
+
const client = runtime.coordinatorClient ?? createLpCoordinatorClient(session, { reconnectSession });
|
|
1054
1280
|
const nowMs = runtime.nowMs ?? Date.now;
|
|
1055
1281
|
const sleep2 = runtime.sleep ?? defaultSleep;
|
|
1056
1282
|
const requireAuth = (positionId) => {
|
|
@@ -1060,9 +1286,17 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1060
1286
|
};
|
|
1061
1287
|
const rememberPosition = (position) => {
|
|
1062
1288
|
const snapshot = clonePosition(position);
|
|
1063
|
-
state.positions.
|
|
1064
|
-
|
|
1065
|
-
|
|
1289
|
+
const previous = state.positions.get(snapshot.id);
|
|
1290
|
+
const merged = previous === void 0 ? snapshot : {
|
|
1291
|
+
...snapshot,
|
|
1292
|
+
redemptionPermission: mergeLpRedemptionPermission(
|
|
1293
|
+
previous.redemptionPermission,
|
|
1294
|
+
snapshot.redemptionPermission
|
|
1295
|
+
)
|
|
1296
|
+
};
|
|
1297
|
+
state.positions.set(merged.id, merged);
|
|
1298
|
+
hydrateLpRedemptionsFromPosition(state, merged);
|
|
1299
|
+
return merged;
|
|
1066
1300
|
};
|
|
1067
1301
|
const rememberAuth = (auth) => {
|
|
1068
1302
|
state.authByPosition.set(auth.lpPositionId, auth);
|
|
@@ -1086,7 +1320,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1086
1320
|
}
|
|
1087
1321
|
};
|
|
1088
1322
|
const completeDkgBatch2 = async (positionId, options = {}) => {
|
|
1089
|
-
assertAttested(
|
|
1323
|
+
assertAttested(currentSession);
|
|
1090
1324
|
const auth = requireAuth(positionId);
|
|
1091
1325
|
let activeSessionRetryStartedAtMs = null;
|
|
1092
1326
|
for (; ; ) {
|
|
@@ -1150,33 +1384,44 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1150
1384
|
}
|
|
1151
1385
|
};
|
|
1152
1386
|
return {
|
|
1153
|
-
async createPosition(args
|
|
1387
|
+
async createPosition(args) {
|
|
1154
1388
|
assertNoUnsupportedFeePolicy(args.feePolicy);
|
|
1155
1389
|
const shardCount = args.shardCount ?? LP_DEFAULT_TARGET_SHARDS;
|
|
1156
1390
|
assertShardCount(shardCount, LP_MAX_TARGET_SHARDS, "shardCount");
|
|
1157
|
-
assertAttested(
|
|
1391
|
+
assertAttested(currentSession);
|
|
1392
|
+
const committedLamports = args.committedLamports ?? DEFAULT_SHARD_FUNDING_LAMPORTS;
|
|
1393
|
+
const refillThreshold = args.refillThreshold ?? Math.ceil(shardCount * DEFAULT_REFILL_THRESHOLD_RATIO);
|
|
1394
|
+
const creationAuthorization = await client.authorizePositionCreation(
|
|
1395
|
+
{
|
|
1396
|
+
committedLamports,
|
|
1397
|
+
shardCount,
|
|
1398
|
+
shardAmountLamports: DEFAULT_SHARD_FUNDING_LAMPORTS,
|
|
1399
|
+
refillThreshold
|
|
1400
|
+
},
|
|
1401
|
+
args.wallet
|
|
1402
|
+
);
|
|
1158
1403
|
const positionId = runtime.idFactory?.() ?? generateId(LP_ID_PREFIX);
|
|
1159
1404
|
const auth = await generateLpPositionCode(positionId);
|
|
1160
1405
|
rememberAuth(auth);
|
|
1161
|
-
args.onPositionCode?.({ positionId, lpPositionCode: auth.code });
|
|
1162
|
-
const committedLamports = args.committedLamports ?? DEFAULT_SHARD_FUNDING_LAMPORTS;
|
|
1163
1406
|
const position = rememberPosition(
|
|
1164
1407
|
await client.openPosition(
|
|
1165
1408
|
{
|
|
1166
1409
|
lpPositionId: positionId,
|
|
1410
|
+
creationAuthorizationId: creationAuthorization.authorizationId,
|
|
1167
1411
|
authPublicKey: Array.from(auth.authPublicKey),
|
|
1168
1412
|
refillPublicKey: Array.from(auth.refillPublicKey),
|
|
1169
1413
|
withdrawalCommitment: Array.from(auth.withdrawalCommitment),
|
|
1170
1414
|
committedLamports,
|
|
1171
1415
|
shardCount,
|
|
1172
1416
|
shardAmountLamports: DEFAULT_SHARD_FUNDING_LAMPORTS,
|
|
1173
|
-
refillThreshold
|
|
1417
|
+
refillThreshold,
|
|
1174
1418
|
addresses: [],
|
|
1175
1419
|
createdAtMs: nowMs()
|
|
1176
1420
|
},
|
|
1177
1421
|
auth
|
|
1178
1422
|
)
|
|
1179
1423
|
);
|
|
1424
|
+
args.onPositionCode?.({ positionId, lpPositionCode: auth.code });
|
|
1180
1425
|
return { positionId, lpPositionCode: auth.code, position };
|
|
1181
1426
|
},
|
|
1182
1427
|
async recoverPosition(args) {
|
|
@@ -1199,7 +1444,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1199
1444
|
async refill(positionId, args = {}) {
|
|
1200
1445
|
const requestedShardCount = args.shardCount ?? LP_DEFAULT_REFILL_BATCH_SIZE;
|
|
1201
1446
|
assertShardCount(requestedShardCount, LP_MAX_REFILL_BATCH_SIZE, "shardCount");
|
|
1202
|
-
assertAttested(
|
|
1447
|
+
assertAttested(currentSession);
|
|
1203
1448
|
const auth = requireAuth(positionId);
|
|
1204
1449
|
const current = await refreshPosition2(positionId);
|
|
1205
1450
|
args.onPosition?.(current);
|
|
@@ -1231,7 +1476,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1231
1476
|
});
|
|
1232
1477
|
},
|
|
1233
1478
|
async prepareInitialFunding(positionId) {
|
|
1234
|
-
assertAttested(
|
|
1479
|
+
assertAttested(currentSession);
|
|
1235
1480
|
const auth = requireAuth(positionId);
|
|
1236
1481
|
const currentPosition = rememberPosition(await client.getPosition(positionId, auth));
|
|
1237
1482
|
if (!isLpPositionReadyForInitialFunding(currentPosition)) return null;
|
|
@@ -1260,7 +1505,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1260
1505
|
return fundingPlanFromShard(position, plannedShard);
|
|
1261
1506
|
},
|
|
1262
1507
|
async prepareTopUp(positionId) {
|
|
1263
|
-
assertAttested(
|
|
1508
|
+
assertAttested(currentSession);
|
|
1264
1509
|
const auth = requireAuth(positionId);
|
|
1265
1510
|
const request2 = await client.prepareTopUp(positionId, auth);
|
|
1266
1511
|
state.topUps.set(request2.topUpId, request2);
|
|
@@ -1308,16 +1553,22 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1308
1553
|
}
|
|
1309
1554
|
},
|
|
1310
1555
|
async reconcileFunding(positionId) {
|
|
1311
|
-
assertAttested(
|
|
1556
|
+
assertAttested(currentSession);
|
|
1312
1557
|
const auth = requireAuth(positionId);
|
|
1313
1558
|
return rememberPosition(await client.reconcileFunding(positionId, auth));
|
|
1314
1559
|
},
|
|
1315
1560
|
async withdrawPosition(positionId, args) {
|
|
1316
1561
|
validateExplicitWithdrawalInput(args);
|
|
1317
1562
|
validateWithdrawalDestinations(args);
|
|
1318
|
-
assertAttested(
|
|
1563
|
+
assertAttested(currentSession);
|
|
1319
1564
|
const auth = requireAuth(positionId);
|
|
1320
1565
|
const before = rememberPosition(await client.reconcileFunding(positionId, auth));
|
|
1566
|
+
if (before.redemptionPermission?.state !== "enabled") {
|
|
1567
|
+
throw new PolicyValidationError(
|
|
1568
|
+
"INVALID_REDEMPTION_PLAN",
|
|
1569
|
+
LP_REDEMPTION_PERMISSION_UNAVAILABLE_MESSAGE
|
|
1570
|
+
);
|
|
1571
|
+
}
|
|
1321
1572
|
const existingRedemption = findOpenRedemptionHistory(before, args);
|
|
1322
1573
|
if (existingRedemption !== void 0) {
|
|
1323
1574
|
const execution2 = {
|
|
@@ -1452,7 +1703,7 @@ function createLpLifecycleClient(session, runtime = {}) {
|
|
|
1452
1703
|
},
|
|
1453
1704
|
async withdrawFees(_positionId, args) {
|
|
1454
1705
|
publicKey(args.destination);
|
|
1455
|
-
assertAttested(
|
|
1706
|
+
assertAttested(currentSession);
|
|
1456
1707
|
throw new RoutingError(
|
|
1457
1708
|
"VERSION_NOT_SUPPORTED",
|
|
1458
1709
|
"LP fee withdrawal is not advertised by the coordinator"
|
|
@@ -1841,6 +2092,15 @@ function clonePosition(position) {
|
|
|
1841
2092
|
}
|
|
1842
2093
|
};
|
|
1843
2094
|
}
|
|
2095
|
+
function mergeLpRedemptionPermission(existing, next) {
|
|
2096
|
+
const current = existing ?? { state: "unknown", grantRevision: 0, observedAtMs: 0 };
|
|
2097
|
+
const incoming = next ?? { state: "unknown", grantRevision: 0, observedAtMs: 0 };
|
|
2098
|
+
if (incoming.state === "unknown") return incoming;
|
|
2099
|
+
if (current.state === "enabled" && incoming.state !== "enabled") return current;
|
|
2100
|
+
if (incoming.grantRevision > current.grantRevision) return incoming;
|
|
2101
|
+
if (incoming.grantRevision < current.grantRevision) return current;
|
|
2102
|
+
return incoming.observedAtMs > current.observedAtMs ? incoming : current;
|
|
2103
|
+
}
|
|
1844
2104
|
function generateId(prefix) {
|
|
1845
2105
|
return `${prefix}_${Array.from(randomBytes2(8)).map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
1846
2106
|
}
|
|
@@ -1884,7 +2144,7 @@ function defaultSleep(delayMs) {
|
|
|
1884
2144
|
}
|
|
1885
2145
|
|
|
1886
2146
|
// src/lp/index.ts
|
|
1887
|
-
function createPosition(session, args
|
|
2147
|
+
function createPosition(session, args) {
|
|
1888
2148
|
return defaultLpLifecycleClient(session).createPosition(args);
|
|
1889
2149
|
}
|
|
1890
2150
|
function recoverPosition(session, args) {
|