@ar.io/sdk 4.0.0-solana.17 → 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.17';
17
+ export const version = '4.0.0-solana.19';
@@ -16,15 +16,13 @@
16
16
  * Borsh codec, and account-meta wiring derived from the on-chain IDL.
17
17
  */
18
18
  import { type Address, type Commitment, type Instruction, type TransactionSigner } from '@solana/kit';
19
+ import { type EscrowAnt, type EscrowToken } from '@ar.io/solana-contracts/ant-escrow';
19
20
  import type { ILogger } from '../common/logger.js';
20
21
  import type { SolanaRpc, SolanaRpcSubscriptions } from './types.js';
21
22
  export type EscrowProtocol = 'arweave' | 'ethereum';
22
23
  export interface EscrowAntState {
23
- version: {
24
- major: number;
25
- minor: number;
26
- patch: number;
27
- };
24
+ /** On-chain schema version, as decoded by the generated client. */
25
+ version: EscrowAnt['version'];
28
26
  bump: number;
29
27
  depositor: Address;
30
28
  antMint: Address;
@@ -172,11 +170,8 @@ export declare class ANTEscrow {
172
170
  }
173
171
  export type EscrowAssetType = 'token' | 'vault';
174
172
  export interface EscrowTokenState {
175
- version: {
176
- major: number;
177
- minor: number;
178
- patch: number;
179
- };
173
+ /** On-chain schema version, as decoded by the generated client. */
174
+ version: EscrowToken['version'];
180
175
  bump: number;
181
176
  depositor: Address;
182
177
  assetType: EscrowAssetType;
@@ -190,10 +185,33 @@ export interface EscrowTokenState {
190
185
  vaultEndTimestamp: bigint;
191
186
  vaultRevocable: boolean;
192
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;
193
209
  /**
194
210
  * Pre-flight the on-chain `VaultStillLocked` gate (ADR-022): refuse to build
195
- * a claim tx while the vault is still locked. Surfaces the unlock timestamp
196
- * 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.
197
215
  *
198
216
  * Exported for unit-testability; not part of the public SDK surface — call the
199
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.16";
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.17",
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"