@ar.io/sdk 4.0.0-solana.18 → 4.0.0-solana.19

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.
@@ -274,10 +274,36 @@ export class ANTEscrow {
274
274
  }
275
275
  }
276
276
  }
277
+ /**
278
+ * Forward clock-skew buffer (seconds) added to `vault_end_timestamp` before
279
+ * the SDK considers a vault claimable. The SDK reads wall-clock time
280
+ * (`Date.now()`) while the on-chain gate reads Solana cluster time, and
281
+ * the two can disagree by several seconds. The buffer biases every skew
282
+ * race into the *friendly* direction: the SDK rejects when the chain
283
+ * would actually accept (user retries 30s later, succeeds), never the
284
+ * reverse (user submits a doomed tx and sees the raw on-chain error).
285
+ *
286
+ * 30s is conservative — Solana cluster clock typically drifts <2s vs
287
+ * wall clock — but matches the order of magnitude of the previously-used
288
+ * `60s` introspection tolerance in the removed `vault_introspect` module.
289
+ */
290
+ export const CLOCK_SKEW_TOLERANCE_SECONDS = 30n;
291
+ /**
292
+ * Returns `true` when a vault escrow is past its unlock timestamp by at
293
+ * least {@link CLOCK_SKEW_TOLERANCE_SECONDS}. Non-throwing companion to
294
+ * {@link assertVaultClaimable} for UI gating (e.g. enabling/disabling a
295
+ * Submit button without showing an error).
296
+ */
297
+ export function isVaultClaimable(escrow) {
298
+ const nowSeconds = BigInt(Math.floor(Date.now() / 1000));
299
+ return nowSeconds >= escrow.vaultEndTimestamp + CLOCK_SKEW_TOLERANCE_SECONDS;
300
+ }
277
301
  /**
278
302
  * Pre-flight the on-chain `VaultStillLocked` gate (ADR-022): refuse to build
279
- * a claim tx while the vault is still locked. Surfaces the unlock timestamp
280
- * so callers / UIs can show "claimable after <date>" instead of a doomed tx.
303
+ * a claim tx while the vault is still locked, with a small forward
304
+ * {@link CLOCK_SKEW_TOLERANCE_SECONDS} buffer so wall/cluster clock skew
305
+ * biases into the friendly direction. Surfaces the unlock timestamp so
306
+ * callers / UIs can show "claimable after <date>" instead of a doomed tx.
281
307
  *
282
308
  * Exported for unit-testability; not part of the public SDK surface — call the
283
309
  * high-level `claimVaultArweave` / `claimVaultEthereum` instead, which invoke
@@ -286,14 +312,15 @@ export class ANTEscrow {
286
312
  * @internal
287
313
  */
288
314
  export function assertVaultClaimable(escrow) {
289
- const nowSeconds = BigInt(Math.floor(Date.now() / 1000));
290
- if (escrow.vaultEndTimestamp > nowSeconds) {
315
+ if (!isVaultClaimable(escrow)) {
291
316
  const unlockIso = new Date(Number(escrow.vaultEndTimestamp) * 1000).toISOString();
292
317
  throw new Error(`Vault escrow is still locked until ${unlockIso} ` +
293
- `(vault_end_timestamp=${escrow.vaultEndTimestamp}). ` +
294
- `Active (still-locked) vault claims are not supported (ADR-022 / ` +
295
- `VaultStillLocked) wait until after the unlock timestamp, then ` +
296
- `claim again to receive the tokens liquid.`);
318
+ `(vault_end_timestamp=${escrow.vaultEndTimestamp}; ` +
319
+ `the SDK adds a ${CLOCK_SKEW_TOLERANCE_SECONDS}s clock-skew buffer ` +
320
+ `before allowing a claim). Active (still-locked) vault claims are ` +
321
+ `rejected on-chain with VaultStillLocked (ADR-022) wait until ` +
322
+ `after the unlock timestamp + buffer, then claim again to receive ` +
323
+ `the tokens liquid.`);
297
324
  }
298
325
  }
299
326
  /** Map the Codama-generated `EscrowToken` raw decoded type to our public
@@ -14,4 +14,4 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
17
- export const version = '4.0.0-solana.18';
17
+ export const version = '4.0.0-solana.19';
@@ -185,10 +185,33 @@ export interface EscrowTokenState {
185
185
  vaultEndTimestamp: bigint;
186
186
  vaultRevocable: boolean;
187
187
  }
188
+ /**
189
+ * Forward clock-skew buffer (seconds) added to `vault_end_timestamp` before
190
+ * the SDK considers a vault claimable. The SDK reads wall-clock time
191
+ * (`Date.now()`) while the on-chain gate reads Solana cluster time, and
192
+ * the two can disagree by several seconds. The buffer biases every skew
193
+ * race into the *friendly* direction: the SDK rejects when the chain
194
+ * would actually accept (user retries 30s later, succeeds), never the
195
+ * reverse (user submits a doomed tx and sees the raw on-chain error).
196
+ *
197
+ * 30s is conservative — Solana cluster clock typically drifts <2s vs
198
+ * wall clock — but matches the order of magnitude of the previously-used
199
+ * `60s` introspection tolerance in the removed `vault_introspect` module.
200
+ */
201
+ export declare const CLOCK_SKEW_TOLERANCE_SECONDS = 30n;
202
+ /**
203
+ * Returns `true` when a vault escrow is past its unlock timestamp by at
204
+ * least {@link CLOCK_SKEW_TOLERANCE_SECONDS}. Non-throwing companion to
205
+ * {@link assertVaultClaimable} for UI gating (e.g. enabling/disabling a
206
+ * Submit button without showing an error).
207
+ */
208
+ export declare function isVaultClaimable(escrow: EscrowTokenState): boolean;
188
209
  /**
189
210
  * Pre-flight the on-chain `VaultStillLocked` gate (ADR-022): refuse to build
190
- * a claim tx while the vault is still locked. Surfaces the unlock timestamp
191
- * so callers / UIs can show "claimable after <date>" instead of a doomed tx.
211
+ * a claim tx while the vault is still locked, with a small forward
212
+ * {@link CLOCK_SKEW_TOLERANCE_SECONDS} buffer so wall/cluster clock skew
213
+ * biases into the friendly direction. Surfaces the unlock timestamp so
214
+ * callers / UIs can show "claimable after <date>" instead of a doomed tx.
192
215
  *
193
216
  * Exported for unit-testability; not part of the public SDK surface — call the
194
217
  * high-level `claimVaultArweave` / `claimVaultEthereum` instead, which invoke
@@ -13,4 +13,4 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- export declare const version = "4.0.0-solana.17";
16
+ export declare const version = "4.0.0-solana.18";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/sdk",
3
- "version": "4.0.0-solana.18",
3
+ "version": "4.0.0-solana.19",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ar-io/ar-io-sdk.git"