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

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.
@@ -585,47 +585,85 @@ export class TokenEscrow {
585
585
  }, { programAddress: this.programId });
586
586
  }
587
587
  /**
588
- * Submit an Arweave attestor's Ed25519 signature to release escrowed vault
589
- * tokens. The on-chain handler delivers liquid tokens directly to
590
- * `claimantTokenAccount`.
588
+ * **Use {@link claimVaultArweaveIx} instead** this single-send wrapper
589
+ * cannot work end-to-end for the Arweave attested vault-claim path,
590
+ * because the on-chain `claim_vault_arweave_attested` handler requires
591
+ * an Ed25519Program native sigverify ix at idx-1 of the claim ix
592
+ * (introspected via `instructions_sysvar`). That sigverify ix carries
593
+ * the attestor's Ed25519 signature over the canonical claim message
594
+ * and is built by the *integrator* (who calls the off-chain attestor
595
+ * service for the signature, per ADR-017) — the SDK has no attestor
596
+ * URL or client to do this for the caller.
591
597
  *
592
- * **Vaults are only claimable after `vault_end_timestamp`.** Active
593
- * (still-locked) vault claims are rejected on-chain with `VaultStillLocked`
594
- * (ADR-022 / BD-107: the former active re-lock path was removed because its
595
- * sibling-`vaulted_transfer` introspection had no 1:1 claim↔re-lock binding
596
- * → reuse / relayer skim). This method pre-flights the same gate and throws
597
- * a clear `vault still locked until <ISO>` error rather than building a tx
598
- * that will fail on-chain. To revive "claim early, stay locked" see the
599
- * restoration playbook in the contracts repo
600
- * (`docs/RESTORE_ACTIVE_VAULT_RELOCK.md`).
598
+ * Calling this method instead of composing via
599
+ * {@link claimVaultArweaveIx} will hit `MissingAttestation` on-chain.
600
+ * It is kept only for ABI continuity; new code must use
601
+ * {@link claimVaultArweaveIx} and prepend the attestor sigverify ix.
602
+ *
603
+ * @deprecated cannot succeed alone see {@link claimVaultArweaveIx}.
601
604
  */
602
- async claimVaultArweave(args) {
603
- const escrow = await this.requireVaultEscrow(args.depositor, args.assetId);
604
- if (escrow.recipientProtocol !== 'arweave') {
605
- throw new Error(`escrow recipient is ${escrow.recipientProtocol}, not arweave`);
605
+ async claimVaultArweave(_args) {
606
+ throw new Error('claimVaultArweave cannot complete the Arweave attested vault-claim ' +
607
+ 'in a single SDK call: the on-chain handler requires an ' +
608
+ 'Ed25519Program sigverify ix at idx-1 of the claim ix, which ' +
609
+ 'must carry the attestor service’s signature over the canonical ' +
610
+ 'claim message (ADR-017). The SDK does not know your attestor URL. ' +
611
+ 'Use claimVaultArweaveIx() instead and bundle the sigverify ix ' +
612
+ 'yourself: ' +
613
+ '[createAtaIx?, ed25519SigverifyIx, claimVaultArweaveIx, ...]. ' +
614
+ 'See ar-io-solana-escrow-app/src/pages/ClaimPage.tsx for the ' +
615
+ 'reference composition, and ADR-022 / VaultStillLocked for the ' +
616
+ 'still-locked rejection (use isVaultClaimable() to pre-flight).');
617
+ }
618
+ /**
619
+ * Build a `claim_vault_arweave_attested` instruction (without sending).
620
+ * Mirror of {@link claimTokensArweaveIx} for the vault-claim path:
621
+ * returns the bare claim ix so the caller can prepend the attestor's
622
+ * Ed25519Program sigverify ix and submit the bundle in one tx.
623
+ *
624
+ * The on-chain handler:
625
+ * - Reads the preceding Ed25519Program native sigverify ix from
626
+ * `instructions_sysvar` to confirm the attestor signed the canonical
627
+ * claim message.
628
+ * - Rejects with `VaultStillLocked` if `clock < vault_end_timestamp`
629
+ * (ADR-022). Callers should pre-flight with {@link isVaultClaimable}
630
+ * (non-throwing) or {@link assertVaultClaimable} (throws with the
631
+ * unlock timestamp) before composing the tx.
632
+ * - On the expired path, transfers the escrowed amount liquid to
633
+ * `claimantTokenAccount` and closes the escrow PDA.
634
+ *
635
+ * Composition (frontend pattern):
636
+ * ```ts
637
+ * const escrow = await tokenEscrow.requireVaultEscrow(depositor, assetId);
638
+ * assertVaultClaimable(escrow); // pre-flight
639
+ * const canonical = canonicalMessage({ ... }); // build message
640
+ * const attestation = await attestor.attest({ ... }); // attestor service
641
+ * const ed25519Ix = buildEd25519SigverifyIx(
642
+ * attestation.attestorPubkey, attestation.signature, canonical,
643
+ * );
644
+ * const claimIx = await tokenEscrow.claimVaultArweaveIx({
645
+ * depositor, assetId, claimant, claimantTokenAccount,
646
+ * escrowTokenAccount, messageNonce: escrow.nonce,
647
+ * });
648
+ * // Idempotent-create the claimant ATA if it's the canonical derivation.
649
+ * await sendTx([createAtaIx?, ed25519Ix, claimIx]);
650
+ * ```
651
+ */
652
+ async claimVaultArweaveIx(args) {
653
+ if (args.messageNonce.length !== 32) {
654
+ throw new Error('messageNonce must be 32 bytes');
606
655
  }
607
- // ADR-022 / VaultStillLocked: pre-flight the on-chain lock gate.
608
- assertVaultClaimable(escrow);
609
- const signer = this.requireSigner('claimVaultArweave');
656
+ const signer = this.requireSigner('claimVaultArweaveIx');
610
657
  const [escrowPda] = await getEscrowVaultPDA(args.depositor, args.assetId, this.programId);
611
- // `args.signature` and `args.saltLen` are no longer fed to the
612
- // builder — the on-chain `claim_vault_arweave_attested` ix verifies
613
- // the attestor's Ed25519 signature via instruction-introspection
614
- // of a preceding sigverify ix. See doc on `claimArweaveIx`.
615
- const claimIx = getClaimVaultArweaveAttestedInstruction({
658
+ return getClaimVaultArweaveAttestedInstruction({
616
659
  escrow: escrowPda,
617
660
  escrowTokenAccount: args.escrowTokenAccount,
618
661
  claimantTokenAccount: args.claimantTokenAccount,
619
662
  claimant: args.claimant,
620
663
  depositor: args.depositor,
621
664
  payer: signer,
622
- messageNonce: escrow.nonce,
665
+ messageNonce: args.messageNonce,
623
666
  }, { programAddress: this.programId });
624
- const createClaimantAtaIx = await this._createClaimantAtaIfCanonical(args.claimant, args.claimantTokenAccount, escrow.arioMint);
625
- const ixs = createClaimantAtaIx
626
- ? [createClaimantAtaIx, claimIx]
627
- : [claimIx];
628
- return this.send(ixs, 400_000);
629
667
  }
630
668
  /**
631
669
  * Submit an Ethereum ECDSA signature to release escrowed vault tokens. See
@@ -68,7 +68,13 @@ export { SolanaANTWriteable } from './ant-writeable.js';
68
68
  export { SolanaANTRegistryReadable } from './ant-registry-readable.js';
69
69
  export { SolanaANTRegistryWriteable } from './ant-registry-writeable.js';
70
70
  // ANT-escrow client (trustless multi-protocol custody — Arweave RSA-PSS / Ethereum ECDSA)
71
- export { ANTEscrow, TokenEscrow } from './escrow.js';
71
+ export { ANTEscrow, TokenEscrow,
72
+ // Vault-claim pre-flight helpers (ADR-022 / VaultStillLocked).
73
+ // Exported so downstream UIs can gate their Submit buttons using the
74
+ // SAME forward CLOCK_SKEW_TOLERANCE_SECONDS buffer the SDK's
75
+ // assertVaultClaimable throws use — keeping pre-flight and UI gates
76
+ // in lock-step so users never see a raw on-chain error.
77
+ assertVaultClaimable, isVaultClaimable, CLOCK_SKEW_TOLERANCE_SECONDS, } from './escrow.js';
72
78
  // Canonical claim-message helper (byte-equivalent to Rust impl)
73
79
  export { canonicalMessage, canonicalMessageV2, bytesToHexLower, } from './canonical-message.js';
74
80
  // ANT spawn (mint MPL Core asset + initialize ario-ant state in one tx)
@@ -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.19';
17
+ export const version = '4.0.0-solana.20';
@@ -336,21 +336,24 @@ export declare class TokenEscrow {
336
336
  messageNonce: Uint8Array;
337
337
  }): Promise<Instruction>;
338
338
  /**
339
- * Submit an Arweave attestor's Ed25519 signature to release escrowed vault
340
- * tokens. The on-chain handler delivers liquid tokens directly to
341
- * `claimantTokenAccount`.
339
+ * **Use {@link claimVaultArweaveIx} instead** this single-send wrapper
340
+ * cannot work end-to-end for the Arweave attested vault-claim path,
341
+ * because the on-chain `claim_vault_arweave_attested` handler requires
342
+ * an Ed25519Program native sigverify ix at idx-1 of the claim ix
343
+ * (introspected via `instructions_sysvar`). That sigverify ix carries
344
+ * the attestor's Ed25519 signature over the canonical claim message
345
+ * and is built by the *integrator* (who calls the off-chain attestor
346
+ * service for the signature, per ADR-017) — the SDK has no attestor
347
+ * URL or client to do this for the caller.
342
348
  *
343
- * **Vaults are only claimable after `vault_end_timestamp`.** Active
344
- * (still-locked) vault claims are rejected on-chain with `VaultStillLocked`
345
- * (ADR-022 / BD-107: the former active re-lock path was removed because its
346
- * sibling-`vaulted_transfer` introspection had no 1:1 claim↔re-lock binding
347
- * → reuse / relayer skim). This method pre-flights the same gate and throws
348
- * a clear `vault still locked until <ISO>` error rather than building a tx
349
- * that will fail on-chain. To revive "claim early, stay locked" see the
350
- * restoration playbook in the contracts repo
351
- * (`docs/RESTORE_ACTIVE_VAULT_RELOCK.md`).
349
+ * Calling this method instead of composing via
350
+ * {@link claimVaultArweaveIx} will hit `MissingAttestation` on-chain.
351
+ * It is kept only for ABI continuity; new code must use
352
+ * {@link claimVaultArweaveIx} and prepend the attestor sigverify ix.
353
+ *
354
+ * @deprecated cannot succeed alone see {@link claimVaultArweaveIx}.
352
355
  */
353
- claimVaultArweave(args: {
356
+ claimVaultArweave(_args: {
354
357
  depositor: Address;
355
358
  assetId: Uint8Array;
356
359
  claimant: Address;
@@ -359,6 +362,49 @@ export declare class TokenEscrow {
359
362
  signature: Uint8Array;
360
363
  saltLen?: number;
361
364
  }): Promise<string>;
365
+ /**
366
+ * Build a `claim_vault_arweave_attested` instruction (without sending).
367
+ * Mirror of {@link claimTokensArweaveIx} for the vault-claim path:
368
+ * returns the bare claim ix so the caller can prepend the attestor's
369
+ * Ed25519Program sigverify ix and submit the bundle in one tx.
370
+ *
371
+ * The on-chain handler:
372
+ * - Reads the preceding Ed25519Program native sigverify ix from
373
+ * `instructions_sysvar` to confirm the attestor signed the canonical
374
+ * claim message.
375
+ * - Rejects with `VaultStillLocked` if `clock < vault_end_timestamp`
376
+ * (ADR-022). Callers should pre-flight with {@link isVaultClaimable}
377
+ * (non-throwing) or {@link assertVaultClaimable} (throws with the
378
+ * unlock timestamp) before composing the tx.
379
+ * - On the expired path, transfers the escrowed amount liquid to
380
+ * `claimantTokenAccount` and closes the escrow PDA.
381
+ *
382
+ * Composition (frontend pattern):
383
+ * ```ts
384
+ * const escrow = await tokenEscrow.requireVaultEscrow(depositor, assetId);
385
+ * assertVaultClaimable(escrow); // pre-flight
386
+ * const canonical = canonicalMessage({ ... }); // build message
387
+ * const attestation = await attestor.attest({ ... }); // attestor service
388
+ * const ed25519Ix = buildEd25519SigverifyIx(
389
+ * attestation.attestorPubkey, attestation.signature, canonical,
390
+ * );
391
+ * const claimIx = await tokenEscrow.claimVaultArweaveIx({
392
+ * depositor, assetId, claimant, claimantTokenAccount,
393
+ * escrowTokenAccount, messageNonce: escrow.nonce,
394
+ * });
395
+ * // Idempotent-create the claimant ATA if it's the canonical derivation.
396
+ * await sendTx([createAtaIx?, ed25519Ix, claimIx]);
397
+ * ```
398
+ */
399
+ claimVaultArweaveIx(args: {
400
+ depositor: Address;
401
+ assetId: Uint8Array;
402
+ claimant: Address;
403
+ claimantTokenAccount: Address;
404
+ escrowTokenAccount: Address;
405
+ /** 32-byte nonce from the on-chain EscrowToken PDA (`escrow.nonce`). */
406
+ messageNonce: Uint8Array;
407
+ }): Promise<Instruction>;
362
408
  /**
363
409
  * Submit an Ethereum ECDSA signature to release escrowed vault tokens. See
364
410
  * {@link claimVaultArweave} — same lock semantics: vaults are only claimable
@@ -51,7 +51,7 @@ export type { SolanaANTRegistryConfig } from './ant-registry-readable.js';
51
51
  export { SolanaANTRegistryWriteable } from './ant-registry-writeable.js';
52
52
  export type { SolanaANTRegistryWriteableConfig } from './ant-registry-writeable.js';
53
53
  export type { AclMaintenanceOp, AclMaintenanceRole, } from '../types/ant-registry.js';
54
- export { ANTEscrow, TokenEscrow } from './escrow.js';
54
+ export { ANTEscrow, TokenEscrow, assertVaultClaimable, isVaultClaimable, CLOCK_SKEW_TOLERANCE_SECONDS, } from './escrow.js';
55
55
  export type { ANTEscrowConfig, EscrowAntState, EscrowAssetType, EscrowProtocol, EscrowTokenState, } from './escrow.js';
56
56
  export { canonicalMessage, canonicalMessageV2, bytesToHexLower, } from './canonical-message.js';
57
57
  export type { CanonicalMessageInput, CanonicalMessageV2Input, EscrowNetwork, } from './canonical-message.js';
@@ -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.18";
16
+ export declare const version = "4.0.0-solana.19";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/sdk",
3
- "version": "4.0.0-solana.19",
3
+ "version": "4.0.0-solana.20",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ar-io/ar-io-sdk.git"