@oobe-protocol-labs/synapse-sap-sdk 0.6.3 → 0.8.0

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.
Files changed (132) hide show
  1. package/dist/cjs/constants/seeds.js +9 -0
  2. package/dist/cjs/constants/seeds.js.map +1 -1
  3. package/dist/cjs/core/client.js +55 -0
  4. package/dist/cjs/core/client.js.map +1 -1
  5. package/dist/cjs/idl/synapse_agent_sap.json +8571 -4106
  6. package/dist/cjs/index.js +29 -3
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/modules/escrow-v2.js +220 -0
  9. package/dist/cjs/modules/escrow-v2.js.map +1 -0
  10. package/dist/cjs/modules/escrow.js +4 -0
  11. package/dist/cjs/modules/escrow.js.map +1 -1
  12. package/dist/cjs/modules/index.js +9 -1
  13. package/dist/cjs/modules/index.js.map +1 -1
  14. package/dist/cjs/modules/receipt.js +144 -0
  15. package/dist/cjs/modules/receipt.js.map +1 -0
  16. package/dist/cjs/modules/staking.js +94 -0
  17. package/dist/cjs/modules/staking.js.map +1 -0
  18. package/dist/cjs/modules/subscription.js +96 -0
  19. package/dist/cjs/modules/subscription.js.map +1 -0
  20. package/dist/cjs/pda/index.js +166 -1
  21. package/dist/cjs/pda/index.js.map +1 -1
  22. package/dist/cjs/registries/x402.js +88 -51
  23. package/dist/cjs/registries/x402.js.map +1 -1
  24. package/dist/cjs/types/enums.js +96 -1
  25. package/dist/cjs/types/enums.js.map +1 -1
  26. package/dist/cjs/types/index.js +6 -1
  27. package/dist/cjs/types/index.js.map +1 -1
  28. package/dist/cjs/types/instructions.js.map +1 -1
  29. package/dist/cjs/utils/escrow-validation.js +219 -0
  30. package/dist/cjs/utils/escrow-validation.js.map +1 -0
  31. package/dist/cjs/utils/index.js +12 -1
  32. package/dist/cjs/utils/index.js.map +1 -1
  33. package/dist/cjs/utils/merchant-validator.js +246 -0
  34. package/dist/cjs/utils/merchant-validator.js.map +1 -0
  35. package/dist/cjs/utils/x402-direct.js +231 -0
  36. package/dist/cjs/utils/x402-direct.js.map +1 -0
  37. package/dist/esm/constants/seeds.js +9 -0
  38. package/dist/esm/constants/seeds.js.map +1 -1
  39. package/dist/esm/core/client.js +55 -0
  40. package/dist/esm/core/client.js.map +1 -1
  41. package/dist/esm/idl/synapse_agent_sap.json +8571 -4106
  42. package/dist/esm/index.js +5 -3
  43. package/dist/esm/index.js.map +1 -1
  44. package/dist/esm/modules/escrow-v2.js +216 -0
  45. package/dist/esm/modules/escrow-v2.js.map +1 -0
  46. package/dist/esm/modules/escrow.js +4 -0
  47. package/dist/esm/modules/escrow.js.map +1 -1
  48. package/dist/esm/modules/index.js +4 -0
  49. package/dist/esm/modules/index.js.map +1 -1
  50. package/dist/esm/modules/receipt.js +140 -0
  51. package/dist/esm/modules/receipt.js.map +1 -0
  52. package/dist/esm/modules/staking.js +90 -0
  53. package/dist/esm/modules/staking.js.map +1 -0
  54. package/dist/esm/modules/subscription.js +92 -0
  55. package/dist/esm/modules/subscription.js.map +1 -0
  56. package/dist/esm/pda/index.js +157 -0
  57. package/dist/esm/pda/index.js.map +1 -1
  58. package/dist/esm/registries/x402.js +89 -52
  59. package/dist/esm/registries/x402.js.map +1 -1
  60. package/dist/esm/types/enums.js +95 -0
  61. package/dist/esm/types/enums.js.map +1 -1
  62. package/dist/esm/types/index.js +1 -1
  63. package/dist/esm/types/index.js.map +1 -1
  64. package/dist/esm/types/instructions.js.map +1 -1
  65. package/dist/esm/utils/escrow-validation.js +212 -0
  66. package/dist/esm/utils/escrow-validation.js.map +1 -0
  67. package/dist/esm/utils/index.js +4 -0
  68. package/dist/esm/utils/index.js.map +1 -1
  69. package/dist/esm/utils/merchant-validator.js +241 -0
  70. package/dist/esm/utils/merchant-validator.js.map +1 -0
  71. package/dist/esm/utils/x402-direct.js +228 -0
  72. package/dist/esm/utils/x402-direct.js.map +1 -0
  73. package/dist/types/constants/seeds.d.ts +9 -0
  74. package/dist/types/constants/seeds.d.ts.map +1 -1
  75. package/dist/types/core/client.d.ts +43 -0
  76. package/dist/types/core/client.d.ts.map +1 -1
  77. package/dist/types/index.d.ts +6 -4
  78. package/dist/types/index.d.ts.map +1 -1
  79. package/dist/types/modules/escrow-v2.d.ts +58 -0
  80. package/dist/types/modules/escrow-v2.d.ts.map +1 -0
  81. package/dist/types/modules/escrow.d.ts +4 -0
  82. package/dist/types/modules/escrow.d.ts.map +1 -1
  83. package/dist/types/modules/index.d.ts +4 -0
  84. package/dist/types/modules/index.d.ts.map +1 -1
  85. package/dist/types/modules/receipt.d.ts +77 -0
  86. package/dist/types/modules/receipt.d.ts.map +1 -0
  87. package/dist/types/modules/staking.d.ts +32 -0
  88. package/dist/types/modules/staking.d.ts.map +1 -0
  89. package/dist/types/modules/subscription.d.ts +33 -0
  90. package/dist/types/modules/subscription.d.ts.map +1 -0
  91. package/dist/types/pda/index.d.ts +114 -0
  92. package/dist/types/pda/index.d.ts.map +1 -1
  93. package/dist/types/plugin/schemas.d.ts +2 -2
  94. package/dist/types/registries/x402.d.ts +14 -12
  95. package/dist/types/registries/x402.d.ts.map +1 -1
  96. package/dist/types/types/accounts.d.ts +201 -1
  97. package/dist/types/types/accounts.d.ts.map +1 -1
  98. package/dist/types/types/enums.d.ts +115 -0
  99. package/dist/types/types/enums.d.ts.map +1 -1
  100. package/dist/types/types/index.d.ts +4 -4
  101. package/dist/types/types/index.d.ts.map +1 -1
  102. package/dist/types/types/instructions.d.ts +34 -0
  103. package/dist/types/types/instructions.d.ts.map +1 -1
  104. package/dist/types/utils/escrow-validation.d.ts +145 -0
  105. package/dist/types/utils/escrow-validation.d.ts.map +1 -0
  106. package/dist/types/utils/index.d.ts +6 -0
  107. package/dist/types/utils/index.d.ts.map +1 -1
  108. package/dist/types/utils/merchant-validator.d.ts +176 -0
  109. package/dist/types/utils/merchant-validator.d.ts.map +1 -0
  110. package/dist/types/utils/x402-direct.d.ts +114 -0
  111. package/dist/types/utils/x402-direct.d.ts.map +1 -0
  112. package/package.json +2 -2
  113. package/src/constants/seeds.ts +9 -0
  114. package/src/core/client.ts +59 -0
  115. package/src/idl/synapse_agent_sap.json +8571 -4106
  116. package/src/index.ts +54 -0
  117. package/src/modules/escrow-v2.ts +375 -0
  118. package/src/modules/escrow.ts +4 -0
  119. package/src/modules/index.ts +4 -0
  120. package/src/modules/receipt.ts +207 -0
  121. package/src/modules/staking.ts +122 -0
  122. package/src/modules/subscription.ts +147 -0
  123. package/src/pda/index.ts +228 -0
  124. package/src/registries/x402.ts +108 -69
  125. package/src/types/accounts.ts +241 -1
  126. package/src/types/enums.ts +119 -0
  127. package/src/types/index.ts +20 -0
  128. package/src/types/instructions.ts +40 -0
  129. package/src/utils/escrow-validation.ts +301 -0
  130. package/src/utils/index.ts +28 -0
  131. package/src/utils/merchant-validator.ts +359 -0
  132. package/src/utils/x402-direct.ts +370 -0
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @module staking
3
+ * @description Agent staking lifecycle — init, deposit, request unstake,
4
+ * complete unstake, and fetch stake accounts.
5
+ *
6
+ * @category Modules
7
+ * @since v0.7.0
8
+ * @packageDocumentation
9
+ */
10
+
11
+ import {
12
+ SystemProgram,
13
+ type PublicKey,
14
+ type TransactionSignature,
15
+ } from "@solana/web3.js";
16
+ import { BN } from "@coral-xyz/anchor";
17
+ import { BaseModule } from "./base";
18
+ import { deriveAgent, deriveStake } from "../pda";
19
+ import type { AgentStakeData } from "../types";
20
+
21
+ /**
22
+ * @name StakingModule
23
+ * @description Manages agent stake accounts — init, deposit, unstake, and fetch.
24
+ *
25
+ * @category Modules
26
+ * @since v0.7.0
27
+ * @extends BaseModule
28
+ */
29
+ export class StakingModule extends BaseModule {
30
+ // ── PDA helpers ──────────────────────────────────────
31
+
32
+ deriveStake(agentPda: PublicKey): readonly [PublicKey, number] {
33
+ return deriveStake(agentPda);
34
+ }
35
+
36
+ // ── Instructions ─────────────────────────────────────
37
+
38
+ async initStake(
39
+ agentWallet: PublicKey,
40
+ initialDeposit: BN | number | bigint,
41
+ ): Promise<TransactionSignature> {
42
+ const [agentPda] = deriveAgent(agentWallet);
43
+ const [stakePda] = this.deriveStake(agentPda);
44
+
45
+ return this.methods
46
+ .initStake(this.bn(initialDeposit))
47
+ .accounts({
48
+ wallet: this.walletPubkey,
49
+ agent: agentPda,
50
+ stake: stakePda,
51
+ systemProgram: SystemProgram.programId,
52
+ })
53
+ .rpc();
54
+ }
55
+
56
+ async deposit(
57
+ agentWallet: PublicKey,
58
+ amount: BN | number | bigint,
59
+ ): Promise<TransactionSignature> {
60
+ const [agentPda] = deriveAgent(agentWallet);
61
+ const [stakePda] = this.deriveStake(agentPda);
62
+
63
+ return this.methods
64
+ .depositStake(this.bn(amount))
65
+ .accounts({
66
+ wallet: this.walletPubkey,
67
+ agent: agentPda,
68
+ stake: stakePda,
69
+ systemProgram: SystemProgram.programId,
70
+ })
71
+ .rpc();
72
+ }
73
+
74
+ async requestUnstake(
75
+ agentWallet: PublicKey,
76
+ amount: BN | number | bigint,
77
+ ): Promise<TransactionSignature> {
78
+ const [agentPda] = deriveAgent(agentWallet);
79
+ const [stakePda] = this.deriveStake(agentPda);
80
+
81
+ return this.methods
82
+ .requestUnstake(this.bn(amount))
83
+ .accounts({
84
+ wallet: this.walletPubkey,
85
+ agent: agentPda,
86
+ stake: stakePda,
87
+ })
88
+ .rpc();
89
+ }
90
+
91
+ async completeUnstake(
92
+ agentWallet: PublicKey,
93
+ ): Promise<TransactionSignature> {
94
+ const [agentPda] = deriveAgent(agentWallet);
95
+ const [stakePda] = this.deriveStake(agentPda);
96
+
97
+ return this.methods
98
+ .completeUnstake()
99
+ .accounts({
100
+ wallet: this.walletPubkey,
101
+ agent: agentPda,
102
+ stake: stakePda,
103
+ })
104
+ .rpc();
105
+ }
106
+
107
+ // ── Fetchers ─────────────────────────────────────────
108
+
109
+ async fetch(agentPda: PublicKey): Promise<AgentStakeData> {
110
+ const [pda] = this.deriveStake(agentPda);
111
+ return this.fetchAccount<AgentStakeData>("agentStake", pda);
112
+ }
113
+
114
+ async fetchNullable(agentPda: PublicKey): Promise<AgentStakeData | null> {
115
+ const [pda] = this.deriveStake(agentPda);
116
+ return this.fetchAccountNullable<AgentStakeData>("agentStake", pda);
117
+ }
118
+
119
+ async fetchByPda(stakePda: PublicKey): Promise<AgentStakeData> {
120
+ return this.fetchAccount<AgentStakeData>("agentStake", stakePda);
121
+ }
122
+ }
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @module subscription
3
+ * @description Agent subscription lifecycle — create, fund, cancel,
4
+ * close, and fetch subscription accounts.
5
+ *
6
+ * @category Modules
7
+ * @since v0.7.0
8
+ * @packageDocumentation
9
+ */
10
+
11
+ import {
12
+ SystemProgram,
13
+ type PublicKey,
14
+ type TransactionSignature,
15
+ } from "@solana/web3.js";
16
+ import { BN } from "@coral-xyz/anchor";
17
+ import { BaseModule } from "./base";
18
+ import { deriveAgent, deriveSubscription } from "../pda";
19
+ import type { SubscriptionData, CreateSubscriptionArgs } from "../types";
20
+
21
+ /**
22
+ * @name SubscriptionModule
23
+ * @description Manages recurring subscriptions between subscribers and agents.
24
+ *
25
+ * @category Modules
26
+ * @since v0.7.0
27
+ * @extends BaseModule
28
+ */
29
+ export class SubscriptionModule extends BaseModule {
30
+ // ── PDA helpers ──────────────────────────────────────
31
+
32
+ private toNum(v: BN | number | bigint): number {
33
+ return BN.isBN(v) ? v.toNumber() : Number(v);
34
+ }
35
+
36
+ deriveSubscription(
37
+ agentPda: PublicKey,
38
+ subscriber?: PublicKey,
39
+ subId: BN | number | bigint = 0,
40
+ ): readonly [PublicKey, number] {
41
+ return deriveSubscription(
42
+ agentPda,
43
+ subscriber ?? this.walletPubkey,
44
+ this.toNum(subId),
45
+ );
46
+ }
47
+
48
+ // ── Instructions ─────────────────────────────────────
49
+
50
+ async create(
51
+ agentWallet: PublicKey,
52
+ args: CreateSubscriptionArgs,
53
+ ): Promise<TransactionSignature> {
54
+ const [agentPda] = deriveAgent(agentWallet);
55
+ const [subPda] = this.deriveSubscription(agentPda, undefined, args.subId);
56
+
57
+ return this.methods
58
+ .createSubscription(
59
+ this.bn(args.subId),
60
+ this.bn(args.pricePerInterval),
61
+ args.billingInterval,
62
+ this.bn(args.initialFund),
63
+ )
64
+ .accounts({
65
+ subscriber: this.walletPubkey,
66
+ agent: agentPda,
67
+ subscription: subPda,
68
+ systemProgram: SystemProgram.programId,
69
+ })
70
+ .rpc();
71
+ }
72
+
73
+ async fund(
74
+ agentWallet: PublicKey,
75
+ subId: BN | number | bigint,
76
+ amount: BN | number | bigint,
77
+ ): Promise<TransactionSignature> {
78
+ const [agentPda] = deriveAgent(agentWallet);
79
+ const [subPda] = this.deriveSubscription(agentPda, undefined, subId);
80
+
81
+ return this.methods
82
+ .fundSubscription(this.bn(amount))
83
+ .accounts({
84
+ subscriber: this.walletPubkey,
85
+ subscription: subPda,
86
+ systemProgram: SystemProgram.programId,
87
+ })
88
+ .rpc();
89
+ }
90
+
91
+ async cancel(
92
+ agentWallet: PublicKey,
93
+ subId: BN | number | bigint = 0,
94
+ ): Promise<TransactionSignature> {
95
+ const [agentPda] = deriveAgent(agentWallet);
96
+ const [subPda] = this.deriveSubscription(agentPda, undefined, subId);
97
+
98
+ return this.methods
99
+ .cancelSubscription()
100
+ .accounts({
101
+ subscriber: this.walletPubkey,
102
+ agentWallet,
103
+ subscription: subPda,
104
+ })
105
+ .rpc();
106
+ }
107
+
108
+ async close(
109
+ agentWallet: PublicKey,
110
+ subId: BN | number | bigint = 0,
111
+ ): Promise<TransactionSignature> {
112
+ const [agentPda] = deriveAgent(agentWallet);
113
+ const [subPda] = this.deriveSubscription(agentPda, undefined, subId);
114
+
115
+ return this.methods
116
+ .closeSubscription()
117
+ .accounts({
118
+ subscriber: this.walletPubkey,
119
+ subscription: subPda,
120
+ })
121
+ .rpc();
122
+ }
123
+
124
+ // ── Fetchers ─────────────────────────────────────────
125
+
126
+ async fetch(
127
+ agentPda: PublicKey,
128
+ subscriber?: PublicKey,
129
+ subId: BN | number | bigint = 0,
130
+ ): Promise<SubscriptionData> {
131
+ const [pda] = this.deriveSubscription(agentPda, subscriber, subId);
132
+ return this.fetchAccount<SubscriptionData>("subscriptionAccount", pda);
133
+ }
134
+
135
+ async fetchNullable(
136
+ agentPda: PublicKey,
137
+ subscriber?: PublicKey,
138
+ subId: BN | number | bigint = 0,
139
+ ): Promise<SubscriptionData | null> {
140
+ const [pda] = this.deriveSubscription(agentPda, subscriber, subId);
141
+ return this.fetchAccountNullable<SubscriptionData>("subscriptionAccount", pda);
142
+ }
143
+
144
+ async fetchByPda(subPda: PublicKey): Promise<SubscriptionData> {
145
+ return this.fetchAccount<SubscriptionData>("subscriptionAccount", subPda);
146
+ }
147
+ }
package/src/pda/index.ts CHANGED
@@ -79,6 +79,22 @@ const u32le = (n: number): Buffer => {
79
79
  return buf;
80
80
  };
81
81
 
82
+ /**
83
+ * Encode an unsigned 64-bit integer as a little-endian `Buffer`.
84
+ *
85
+ * @name u64le
86
+ * @description Produces an 8-byte LE buffer for u64 PDA seed segments (e.g., escrow nonce, sub_id).
87
+ * @param n - The number or bigint to encode.
88
+ * @returns {Buffer} 8-byte little-endian buffer.
89
+ * @category PDA
90
+ * @since v0.5.0
91
+ */
92
+ const u64le = (n: number | bigint): Buffer => {
93
+ const buf = Buffer.alloc(8);
94
+ buf.writeBigUInt64LE(BigInt(n), 0);
95
+ return buf;
96
+ };
97
+
82
98
  // ═════════════════════════════════════════════
83
99
  // Core PDAs
84
100
  // ═════════════════════════════════════════════
@@ -421,6 +437,7 @@ export const deriveTool = (
421
437
  * @returns {PdaResult} `[pda, bump]` tuple.
422
438
  * @category PDA
423
439
  * @since v0.1.0
440
+ * @deprecated Since v0.7.0 — Use {@link deriveEscrowV2} for V2 escrows with nonce support.
424
441
  * @see EscrowAccount
425
442
  */
426
443
  export const deriveEscrow = (
@@ -650,3 +667,214 @@ export const deriveMemoryChunk = (
650
667
  ],
651
668
  programId,
652
669
  );
670
+
671
+ // ═════════════════════════════════════════════
672
+ // Escrow V2
673
+ // ═════════════════════════════════════════════
674
+
675
+ /**
676
+ * Derive the **EscrowAccountV2** PDA.
677
+ *
678
+ * Seeds: `["sap_escrow_v2", agent_pda, depositor_wallet, nonce_u64_le]`
679
+ *
680
+ * @name deriveEscrowV2
681
+ * @description Computes the V2 escrow PDA supporting nonce-based multi-escrow.
682
+ * @param agentPda - The agent's PDA.
683
+ * @param depositor - The depositor's wallet.
684
+ * @param nonce - Escrow nonce (u64) allowing multiple escrows per pair.
685
+ * @param programId - Override program ID.
686
+ * @returns {PdaResult} `[pda, bump]` tuple.
687
+ * @category PDA
688
+ * @since v0.5.0
689
+ */
690
+ export const deriveEscrowV2 = (
691
+ agentPda: PublicKey,
692
+ depositor: PublicKey,
693
+ nonce: number | bigint = 0,
694
+ programId = SAP_PROGRAM_ID,
695
+ ): PdaResult =>
696
+ findPda(
697
+ [
698
+ toSeedBuf(SEEDS.ESCROW_V2),
699
+ agentPda.toBuffer(),
700
+ depositor.toBuffer(),
701
+ u64le(nonce),
702
+ ],
703
+ programId,
704
+ );
705
+
706
+ /**
707
+ * Derive the **PendingSettlement** PDA.
708
+ *
709
+ * Seeds: `["sap_pending", escrow_v2_pda, settlement_index_u64_le]`
710
+ *
711
+ * @name derivePendingSettlement
712
+ * @param escrowV2Pda - The parent V2 escrow PDA.
713
+ * @param settlementIndex - The monotonic settlement index (u64).
714
+ * @param programId - Override program ID.
715
+ * @returns {PdaResult} `[pda, bump]` tuple.
716
+ * @category PDA
717
+ * @since v0.5.0
718
+ */
719
+ export const derivePendingSettlement = (
720
+ escrowV2Pda: PublicKey,
721
+ settlementIndex: number | bigint,
722
+ programId = SAP_PROGRAM_ID,
723
+ ): PdaResult =>
724
+ findPda(
725
+ [
726
+ toSeedBuf(SEEDS.PENDING),
727
+ escrowV2Pda.toBuffer(),
728
+ u64le(settlementIndex),
729
+ ],
730
+ programId,
731
+ );
732
+
733
+ /**
734
+ * Derive the **DisputeRecord** PDA.
735
+ *
736
+ * Seeds: `["sap_dispute", pending_settlement_pda]`
737
+ *
738
+ * @name deriveDispute
739
+ * @param pendingSettlementPda - The parent pending settlement PDA.
740
+ * @param programId - Override program ID.
741
+ * @returns {PdaResult} `[pda, bump]` tuple.
742
+ * @category PDA
743
+ * @since v0.5.0
744
+ */
745
+ export const deriveDispute = (
746
+ pendingSettlementPda: PublicKey,
747
+ programId = SAP_PROGRAM_ID,
748
+ ): PdaResult =>
749
+ findPda(
750
+ [toSeedBuf(SEEDS.DISPUTE), pendingSettlementPda.toBuffer()],
751
+ programId,
752
+ );
753
+
754
+ /**
755
+ * Derive the **AgentStake** PDA.
756
+ *
757
+ * Seeds: `["sap_stake", agent_pda]`
758
+ *
759
+ * @name deriveStake
760
+ * @param agentPda - The agent's PDA.
761
+ * @param programId - Override program ID.
762
+ * @returns {PdaResult} `[pda, bump]` tuple.
763
+ * @category PDA
764
+ * @since v0.5.0
765
+ */
766
+ export const deriveStake = (
767
+ agentPda: PublicKey,
768
+ programId = SAP_PROGRAM_ID,
769
+ ): PdaResult =>
770
+ findPda([toSeedBuf(SEEDS.STAKE), agentPda.toBuffer()], programId);
771
+
772
+ /**
773
+ * Derive the **Subscription** PDA.
774
+ *
775
+ * Seeds: `["sap_sub", agent_pda, subscriber_wallet, sub_id_u64_le]`
776
+ *
777
+ * @name deriveSubscription
778
+ * @param agentPda - The agent's PDA.
779
+ * @param subscriber - The subscriber's wallet.
780
+ * @param subId - Subscription ID (u64).
781
+ * @param programId - Override program ID.
782
+ * @returns {PdaResult} `[pda, bump]` tuple.
783
+ * @category PDA
784
+ * @since v0.5.0
785
+ */
786
+ export const deriveSubscription = (
787
+ agentPda: PublicKey,
788
+ subscriber: PublicKey,
789
+ subId: number | bigint = 0,
790
+ programId = SAP_PROGRAM_ID,
791
+ ): PdaResult =>
792
+ findPda(
793
+ [
794
+ toSeedBuf(SEEDS.SUBSCRIPTION),
795
+ agentPda.toBuffer(),
796
+ subscriber.toBuffer(),
797
+ u64le(subId),
798
+ ],
799
+ programId,
800
+ );
801
+
802
+ /**
803
+ * Derive the **CounterShard** PDA.
804
+ *
805
+ * Seeds: `["sap_shard", shard_index_u8]`
806
+ *
807
+ * @name deriveShard
808
+ * @param shardIndex - The shard index (0–7).
809
+ * @param programId - Override program ID.
810
+ * @returns {PdaResult} `[pda, bump]` tuple.
811
+ * @category PDA
812
+ * @since v0.5.0
813
+ */
814
+ export const deriveShard = (
815
+ shardIndex: number,
816
+ programId = SAP_PROGRAM_ID,
817
+ ): PdaResult =>
818
+ findPda(
819
+ [toSeedBuf(SEEDS.SHARD), Buffer.from([shardIndex])],
820
+ programId,
821
+ );
822
+
823
+ /**
824
+ * Derive the **IndexPage** PDA.
825
+ *
826
+ * Seeds: `["sap_idx_page", parent_index_pda, page_index_u8]`
827
+ *
828
+ * @name deriveIndexPage
829
+ * @param parentIndexPda - The parent index PDA (CapabilityIndex, ProtocolIndex, etc.).
830
+ * @param pageIndex - The page index (0–255).
831
+ * @param programId - Override program ID.
832
+ * @returns {PdaResult} `[pda, bump]` tuple.
833
+ * @category PDA
834
+ * @since v0.5.0
835
+ */
836
+ export const deriveIndexPage = (
837
+ parentIndexPda: PublicKey,
838
+ pageIndex: number,
839
+ programId = SAP_PROGRAM_ID,
840
+ ): PdaResult =>
841
+ findPda(
842
+ [
843
+ toSeedBuf(SEEDS.INDEX_PAGE),
844
+ parentIndexPda.toBuffer(),
845
+ Buffer.from([pageIndex]),
846
+ ],
847
+ programId,
848
+ );
849
+
850
+ // ═════════════════════════════════════════════
851
+ // Receipt Batch (v0.7)
852
+ // ═════════════════════════════════════════════
853
+
854
+ /**
855
+ * Derive the **ReceiptBatch** PDA.
856
+ *
857
+ * Seeds: `["sap_receipt", escrow_v2_pda, batch_index_u32_le]`
858
+ *
859
+ * @name deriveReceiptBatch
860
+ * @description Computes the receipt batch PDA storing a merkle root of call receipts.
861
+ * @param escrowV2Pda - The parent V2 escrow PDA.
862
+ * @param batchIndex - Zero-based batch index (u32).
863
+ * @param programId - Override program ID.
864
+ * @returns {PdaResult} `[pda, bump]` tuple.
865
+ * @category PDA
866
+ * @since v0.7.0
867
+ */
868
+ export const deriveReceiptBatch = (
869
+ escrowV2Pda: PublicKey,
870
+ batchIndex: number,
871
+ programId = SAP_PROGRAM_ID,
872
+ ): PdaResult =>
873
+ findPda(
874
+ [
875
+ toSeedBuf(SEEDS.RECEIPT),
876
+ escrowV2Pda.toBuffer(),
877
+ u32le(batchIndex),
878
+ ],
879
+ programId,
880
+ );