@invisible-labs/sdk 0.9.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.
@@ -146,6 +146,12 @@ type RuntimeMeasurements = {
146
146
  readonly rtmr2: string;
147
147
  readonly rtmr3: string;
148
148
  };
149
+ type LpFeePolicy = {
150
+ readonly version: 1;
151
+ readonly profile: "internal" | "partner";
152
+ readonly commission_bps: 0 | 6000;
153
+ readonly policy_hash: string;
154
+ };
149
155
  type LpPositionView = {
150
156
  readonly id: string;
151
157
  readonly status: "dkg_pending" | "active" | "withdrawing" | "closed";
@@ -165,6 +171,74 @@ type LpPositionView = {
165
171
  readonly grantRevision: number;
166
172
  readonly observedAtMs: number;
167
173
  };
174
+ readonly feePolicy?: LpFeePolicy;
175
+ readonly lpFeePolicyVersion?: 1;
176
+ readonly actorSync?: {
177
+ readonly economicReturn?: {
178
+ readonly providerRewardLamports: string;
179
+ readonly sourceExpenseCompensationLamports: string;
180
+ readonly chargedReimbursementLossLamports: string;
181
+ readonly netEconomicReturnLamports: string;
182
+ };
183
+ readonly lpPositionId: string;
184
+ readonly status: "idle" | "settling" | "reimbursement_due";
185
+ readonly sourceLiquidityUse: "not_materialized" | "available" | "locked_for_payout" | "pending_finality" | "spent" | "released";
186
+ readonly redeemablePrincipalLamports?: number;
187
+ readonly redeemableFeeLamports?: number;
188
+ readonly lifetimeEarnedLamports?: number;
189
+ readonly redeemablePrincipalSourceCount?: number;
190
+ readonly redeemableFeeSourceCount?: number;
191
+ readonly redeemableSourceCount?: number;
192
+ readonly pendingReservationCount: number;
193
+ readonly reservedPayoutLamports: number;
194
+ readonly estimatedNetworkFeeLamports: number;
195
+ readonly reimbursementDueCount: number;
196
+ readonly reimbursementDueSourceCount: number;
197
+ readonly reimbursementDuePayoutLamports: number;
198
+ readonly reimbursementDueNetworkFeeLamports: number;
199
+ readonly withdrawalRequestedLamports: number;
200
+ readonly withdrawalLandedLamports: number;
201
+ readonly withdrawalLandedFeeLamports: number;
202
+ readonly withdrawalCanceledLamports: number;
203
+ readonly withdrawalNetworkFeeLossLamports: number;
204
+ readonly withdrawalTxHashes: readonly string[];
205
+ readonly redemptionHistory?: readonly {
206
+ readonly redemptionId: string;
207
+ readonly state: "requested" | "match_requested" | "reserved" | "pending" | "confirmed" | "rejected";
208
+ readonly withdrawalMode?: "exact" | "max_available";
209
+ readonly acceptedLamports: number;
210
+ readonly acceptedDepositPrincipalLamports: number;
211
+ readonly acceptedEarnedFeeLamports: number;
212
+ readonly landedLamports: number;
213
+ readonly landedDepositPrincipalLamports: number;
214
+ readonly landedEarnedFeeLamports: number;
215
+ readonly canceledLamports: number;
216
+ readonly canceledDepositPrincipalLamports: number;
217
+ readonly canceledEarnedFeeLamports: number;
218
+ readonly networkFeeLamports: number;
219
+ readonly networkFeeLossLamports: number;
220
+ readonly failedAttempts: number;
221
+ readonly destinationAddresses: readonly string[];
222
+ readonly destinationCount: number;
223
+ readonly txSignatures: readonly string[];
224
+ readonly txSignatureCount: number;
225
+ readonly detailsTruncated: boolean;
226
+ readonly stateVersion: number;
227
+ readonly createdAtMs: number;
228
+ readonly updatedAtMs: number;
229
+ readonly feePolicyHash?: string;
230
+ readonly feeBasisRevision?: number;
231
+ }[];
232
+ readonly redemptionHistoryHasMore?: boolean;
233
+ readonly redemptionHistoryNextCursor?: string;
234
+ readonly stateVersion: number;
235
+ readonly updatedAtMs: number;
236
+ readonly feePolicy?: LpFeePolicy;
237
+ readonly feeBasisRevision?: number;
238
+ readonly grossFeeLamports?: number;
239
+ readonly protocolCommissionLamports?: number;
240
+ readonly redeemableProjectionAvailable: boolean;
241
+ };
168
242
  };
169
243
  type PayoutDestination = {
170
244
  readonly address: string;
package/dist/user.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CommandError, P as PayoutPolicy } from './types.generated-DrM2M4DZ.js';
2
- export { I as InvalidDepositAmountError } from './types.generated-DrM2M4DZ.js';
1
+ import { C as CommandError, P as PayoutPolicy } from './types.generated-CtMxCo9F.js';
2
+ export { I as InvalidDepositAmountError } from './types.generated-CtMxCo9F.js';
3
3
  import { S as Session } from './session-DFuy54C-.js';
4
4
 
5
5
  /**
@@ -141,6 +141,7 @@ type RunSwapParams = {
141
141
  /** No automatic policy: absent this callback, initialization busy is returned to the caller. */
142
142
  onInitializationRetry?: (retry: InitializationRetry) => Promise<void>;
143
143
  amountLamports: number;
144
+ batchExclusionId?: string;
144
145
  payoutSpec: PayoutSpec;
145
146
  payoutDeadlineMs?: number;
146
147
  onPolicySnapshot?: (policy: SpendingPolicySnapshot) => void;
@@ -307,8 +308,12 @@ interface ContractRequestArgs {
307
308
  /**
308
309
  * Where and how the output is delivered. V0 normal-user requests support
309
310
  * exactly one payout destination and validate the policy locally before
310
- * submission. `batchExclusionId` is rejected in V0; its planned V1 meaning
311
- * is campaign-scoped batch exclusion, never a stable actor identity.
311
+ * submission. Reuse the same `batchExclusionId` for each contract belonging
312
+ * to one user so liquidity from their own deposits, including deposits that
313
+ * later reimbursed an LP, cannot fund their own payout. The payout waits
314
+ * when no other liquidity is available.
315
+ * This opaque value is not proof of identity; integrators are responsible
316
+ * for assigning and retaining it.
312
317
  * `destinations[*].minDelayMs` and `destinations[*].maxDelayMs` are also
313
318
  * rejected in V0 because the current runtime does not honor them.
314
319
  * `totalDeadlineMs` selects the payout window: use `0` for instant payout,
package/dist/user.js CHANGED
@@ -1,9 +1,9 @@
1
- import { scheduledPayoutWindowSeconds, ErrorCode } from './chunk-QF5TSUQE.js';
2
- import { validatePayoutPolicyShape, formatAjvErrors, persistTransferStatus, createSession, disabledClientPersistence, readPersistedTransferForResume, persistTransferReady, createExponentialBackoff, persistTransferTerminal, persistTransferRecoveryCode, persistTransferAllocation, persistTransferDkgMetadata } from './chunk-EOPZVOVP.js';
3
- export { getPersistedTransfer, listPersistedTransfers, purgePersistedTransfers, removePersistedTransfer } from './chunk-EOPZVOVP.js';
1
+ import { scheduledPayoutWindowSeconds, ErrorCode } from './chunk-DFBH5XLM.js';
2
+ import { validatePayoutPolicyShape, formatAjvErrors, persistTransferStatus, createSession, disabledClientPersistence, readPersistedTransferForResume, persistTransferReady, createExponentialBackoff, persistTransferTerminal, persistTransferRecoveryCode, persistTransferAllocation, persistTransferDkgMetadata } from './chunk-ANQMIQYS.js';
3
+ export { getPersistedTransfer, listPersistedTransfers, purgePersistedTransfers, removePersistedTransfer } from './chunk-ANQMIQYS.js';
4
4
  import { PRODUCT_MAX_ENTRY_LAMPORTS, PRODUCT_MIN_ENTRY_LAMPORTS } from './chunk-HWRMSK7E.js';
5
5
  import { assertAttested, publicKey, solanaAddressFromPublicKeyBytes } from './chunk-EPWTRF5U.js';
6
- import { requestEnvelope, CoordinatorMessageType, onEnvelope, closeProtocolRuntime, EnvelopeKind } from './chunk-ISIWWGSR.js';
6
+ import { requestEnvelope, CoordinatorMessageType, onEnvelope, closeProtocolRuntime, EnvelopeKind } from './chunk-6AGC3IOB.js';
7
7
  import { getSessionState } from './chunk-6AKBRYKO.js';
8
8
  import './chunk-AIKC2XQS.js';
9
9
  import { PolicyValidationError, CommandError, StorageError, TransportError, normalizeError, InvalidDepositAmountError, AttestationError, RoutingError } from './chunk-RWKG7N7I.js';
@@ -27,7 +27,6 @@ Math.max(...SUPPORTED_TOTAL_DEADLINE_MS);
27
27
  var SHARE_SUM_TOLERANCE = 0.01;
28
28
  var CURRENT_USER_PAYOUT_DESTINATION_LIMIT = 1;
29
29
  var CURRENT_USER_PAYOUT_DESTINATION_LIMIT_MESSAGE = "current V0 normal-user SDK and coordinator support exactly one payout destination; multi-address receive is not supported yet";
30
- var CURRENT_USER_BATCH_EXCLUSION_ID_UNSUPPORTED_MESSAGE = "batchExclusionId is not supported in V0 normal-user payout requests; V1 defines it as campaign-scoped batch exclusion, never a stable actor identity";
31
30
  var CURRENT_USER_MIN_DELAY_UNSUPPORTED_MESSAGE = "destinations[*].minDelayMs is not supported in V0 normal-user payout requests";
32
31
  var CURRENT_USER_MAX_DELAY_UNSUPPORTED_MESSAGE = "destinations[*].maxDelayMs is not supported in V0 normal-user payout requests";
33
32
  var CURRENT_USER_PAYOUT_FRAGMENT_LIMIT = 1;
@@ -91,12 +90,6 @@ function validatePayoutPolicy(input, ctx = {}) {
91
90
  return policy;
92
91
  }
93
92
  function assertCurrentUserUnsupportedPayoutFeatures(policy) {
94
- if (policy.batchExclusionId !== void 0) {
95
- throw new PolicyValidationError(
96
- "INVALID_PAYOUT_PLAN",
97
- CURRENT_USER_BATCH_EXCLUSION_ID_UNSUPPORTED_MESSAGE
98
- );
99
- }
100
93
  for (const destination of policy.destinations) {
101
94
  if (destination.minDelayMs !== void 0) {
102
95
  throw new PolicyValidationError(
@@ -172,7 +165,7 @@ function recoveryCodeFromUserInput(input) {
172
165
  var protocolPromise = null;
173
166
  var frostRuntimePromise = null;
174
167
  function loadProtocol() {
175
- protocolPromise ??= import('./coordinator-DHL3AP7V.js');
168
+ protocolPromise ??= import('./coordinator-T2B7253V.js');
176
169
  return protocolPromise;
177
170
  }
178
171
  function loadFrostRuntime() {
@@ -196,6 +189,10 @@ var SWAP_STATUS_RETRY_JITTER_RATIO = 0.2;
196
189
  var DEFAULT_REFUND_OUTCOME_POLL_BUDGET_MS = 5 * 60 * 1e3;
197
190
  var REFUND_OUTCOME_POLL_INTERVAL_MS = 3e3;
198
191
  var INITIALIZATION_PUSH_TIMEOUT_MS = 3e4;
192
+ var CONTRACT_ADMISSION_BUSY_MAX_ATTEMPTS = 6;
193
+ var CONTRACT_ADMISSION_BUSY_INITIAL_DELAY_MS = 250;
194
+ var CONTRACT_ADMISSION_BUSY_MAX_DELAY_MS = 4e3;
195
+ var CONTRACT_ADMISSION_BUSY_JITTER_RATIO = 0.2;
199
196
  var REFUND_OUTCOME_PER_POLL_TIMEOUT_MS = 5e3;
200
197
  var UNBOUND_RECONCILIATION_KEY = "__unbound__";
201
198
  var REQUEST_TIMEOUT_MESSAGE = "coordinator request timed out";
@@ -982,6 +979,9 @@ var UserCoordinatorSession = class {
982
979
  {
983
980
  actor: "user",
984
981
  amount_lamports: params.amountLamports,
982
+ ...params.batchExclusionId !== void 0 && {
983
+ batch_exclusion_id: params.batchExclusionId
984
+ },
985
985
  payout_spec: params.payoutSpec,
986
986
  sync_commitment: syncCommitment,
987
987
  resume_commitment: resumeCommitment,
@@ -1550,11 +1550,24 @@ var UserCoordinatorSession = class {
1550
1550
  }
1551
1551
  }
1552
1552
  async requestContract(payload, signal) {
1553
- if (signal?.aborted) throw createRequestAbortError();
1554
- return this.request(CoordinatorMessageType.ContractRequest, payload, {
1555
- swapId: null,
1556
- requireNonNullResponseSwapId: true
1553
+ const busyBackoff = createExponentialBackoff({
1554
+ initialDelayMs: CONTRACT_ADMISSION_BUSY_INITIAL_DELAY_MS,
1555
+ maxDelayMs: CONTRACT_ADMISSION_BUSY_MAX_DELAY_MS,
1556
+ jitterRatio: CONTRACT_ADMISSION_BUSY_JITTER_RATIO
1557
1557
  });
1558
+ for (let attempt = 1; ; attempt += 1) {
1559
+ if (signal?.aborted) throw createRequestAbortError();
1560
+ try {
1561
+ return await this.request(CoordinatorMessageType.ContractRequest, payload, {
1562
+ swapId: null,
1563
+ requireNonNullResponseSwapId: true
1564
+ });
1565
+ } catch (error) {
1566
+ if (!(error instanceof CommandError) || error.coordinatorCode !== ErrorCode.ERR_PRESEAL_ADMISSION_BUSY || error.failedReqId === void 0 || attempt >= CONTRACT_ADMISSION_BUSY_MAX_ATTEMPTS)
1567
+ throw error;
1568
+ await abortableDelay(busyBackoff.nextDelayMs(), signal);
1569
+ }
1570
+ }
1558
1571
  }
1559
1572
  awaitPush(type, swapId, timeoutMs = 3e4) {
1560
1573
  return new Promise((resolve, reject) => {
@@ -1835,6 +1848,21 @@ function bytesToHex(bytes) {
1835
1848
  function delay(ms) {
1836
1849
  return new Promise((resolve) => setTimeout(resolve, ms));
1837
1850
  }
1851
+ function abortableDelay(ms, signal) {
1852
+ if (signal === void 0) return delay(ms);
1853
+ if (signal.aborted) return Promise.reject(createRequestAbortError());
1854
+ return new Promise((resolve, reject) => {
1855
+ const onAbort = () => {
1856
+ clearTimeout(timer);
1857
+ reject(createRequestAbortError());
1858
+ };
1859
+ const timer = setTimeout(() => {
1860
+ signal.removeEventListener("abort", onAbort);
1861
+ resolve();
1862
+ }, ms);
1863
+ signal.addEventListener("abort", onAbort, { once: true });
1864
+ });
1865
+ }
1838
1866
  function payoutWindowMsFromSpec(payoutSpec) {
1839
1867
  if (payoutSpec.mode === "instant") return void 0;
1840
1868
  return payoutSpec.window_seconds * 1e3;
@@ -1938,6 +1966,9 @@ async function contractRequest(session, args) {
1938
1966
  return contractRequestOnSession(session, {
1939
1967
  amountLamports: args.amountLamports,
1940
1968
  payoutSpec: wirePayoutSpec,
1969
+ ...payoutPolicy.batchExclusionId !== void 0 && {
1970
+ batchExclusionId: payoutPolicy.batchExclusionId
1971
+ },
1941
1972
  ...args.syncSecret !== void 0 && { syncSecret: args.syncSecret },
1942
1973
  ...args.recoveryCommitment !== void 0 && {
1943
1974
  recoveryCommitment: args.recoveryCommitment