@omegax/protocol-sdk 0.4.3 → 0.5.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.
package/NOTICE ADDED
@@ -0,0 +1,5 @@
1
+ OmegaX Health Protocol SDK
2
+ Copyright (c) 2026 OMEGAX HEALTH FZCO and contributors
3
+
4
+ Licensed under the Apache License, Version 2.0.
5
+ This product includes software developed by OMEGAX HEALTH FZCO.
package/README.md CHANGED
@@ -5,9 +5,9 @@ TypeScript SDK for OmegaX protocol integrations on Solana.
5
5
  ## Network status
6
6
 
7
7
  - Current live network: **devnet beta**
8
- - Mainnet support: **coming soon**
8
+ - Public integration target: **devnet beta**
9
9
  - Protocol UI: https://protocol.omegax.health
10
- - Protocol repository: `omegaxhealth_protocol`
10
+ - Protocol repository: `omegax-protocol`
11
11
  - Governance token:
12
12
  - Mainnet CA: `4Aar9R14YMbEie6yh8WcH1gWXrBtfucoFjw6SpjXpump`
13
13
  - Devnet: governance token distribution is via the protocol faucet
@@ -16,7 +16,7 @@ It supports:
16
16
 
17
17
  - Oracle lifecycle, staking, attestation voting, and reward claims
18
18
  - Pool creation, configuration, enrollment, funding, and reward claims
19
- - Coverage product and policy lifecycle (subscribe, premium, claim, settlement)
19
+ - Policy series and policy position lifecycle (subscribe, premium, claim, settlement)
20
20
  - Deterministic PDA/seed derivation and account readers
21
21
  - Unsigned claim-intent building + signed message validation
22
22
  - RPC helpers for send/simulate/status workflows
@@ -38,6 +38,11 @@ It supports:
38
38
  npm install @omegax/protocol-sdk
39
39
  ```
40
40
 
41
+ ## Breaking change in `0.5.0`
42
+
43
+ - Legacy and `V2` exported names were removed from the public SDK surface.
44
+ - Use the current canonical protocol builders, readers, and PDA helpers only.
45
+
41
46
  ## Support matrix
42
47
 
43
48
  - Node.js `>=20`
@@ -49,7 +54,7 @@ npm install @omegax/protocol-sdk
49
54
  - Builders create **unsigned** transactions. Your app signs and submits them.
50
55
  - `programId` is explicit in SDK flows and should be passed from your runtime config.
51
56
  - Use `createProtocolClient(connection, programId)` for protocol operations.
52
- - `createConnection({ network: 'mainnet' })` is available but warns that mainnet is coming soon.
57
+ - Keep integrations pointed at `devnet` until OmegaX announces public mainnet availability.
53
58
 
54
59
  ## Quickstart
55
60
 
@@ -76,7 +81,8 @@ const tx = protocol.buildSubmitRewardClaimTx!({
76
81
  claimant: '<claimant-pubkey>',
77
82
  poolAddress: '<pool-pubkey>',
78
83
  member: '<member-pubkey>',
79
- cycleId: 'cycle-2026-01',
84
+ seriesRefHashHex: '<32-byte-hex>',
85
+ cycleHashHex: '<32-byte-hex>',
80
86
  ruleHashHex: '<32-byte-hex>',
81
87
  intentHashHex: '<32-byte-hex>',
82
88
  payoutAmount: 1n,
@@ -98,30 +104,31 @@ const result = await rpc.broadcastSignedTx({ signedTxBase64: signed });
98
104
 
99
105
  ### Pool creator / operator
100
106
 
101
- - Create and configure pools: `buildCreatePoolV2Tx`, `buildSetPoolStatusTx`, `buildSetPoolTermsHashTx`
102
- - Configure oracle policy/rules: `buildSetPoolOraclePolicyTx`, `buildSetPoolOutcomeRuleTx`, `buildSetPoolOracleTx`
107
+ - Create and configure pools: `buildCreatePoolTx`, `buildSetPoolStatusTx`, `buildSetPoolTermsHashTx`
108
+ - Configure oracle policy/rules: `buildSetPoolOraclePolicyTx`, `buildSetPolicySeriesOutcomeRuleTx`, `buildSetPoolOracleTx`
103
109
  - Fund payout liquidity: `buildFundPoolSolTx`, `buildFundPoolSplTx`
104
- - Manage coverage products: `buildRegisterCoverageProductV2Tx`, `buildUpdateCoverageProductV2Tx`
110
+ - Manage policy series: `buildCreatePolicySeriesTx`, `buildUpdatePolicySeriesTx`
105
111
 
106
112
  ### Pool participant / member
107
113
 
108
114
  - Enroll: `buildEnrollMemberOpenTx`, `buildEnrollMemberTokenGateTx`, `buildEnrollMemberInvitePermitTx`
109
115
  - Authorize claim delegation: `buildSetClaimDelegateTx`
110
- - Claim rewards: `buildSubmitRewardClaimTx` (and legacy `buildSubmitClaimTx`)
111
- - Participate in coverage: `buildSubscribeCoverageProductV2Tx`, `buildCreateCoveragePolicyTx`, `buildIssueCoveragePolicyFromProductV2Tx`
116
+ - Claim rewards: `buildSubmitRewardClaimTx`
117
+ - Participate in policy series: `buildSubscribePolicySeriesTx`, `buildIssuePolicyPositionTx`, `buildPayPremiumSolTx`, `buildPayPremiumSplTx`
112
118
 
113
119
  ### Oracle operator
114
120
 
115
- - Register/update oracle: `buildRegisterOracleV2Tx`, `buildUpdateOracleProfileV2Tx`, `buildUpdateOracleMetadataTx`
121
+ - Register/update oracle: `buildRegisterOracleTx`, `buildUpdateOracleProfileTx`, `buildUpdateOracleMetadataTx`
116
122
  - Stake lifecycle: `buildStakeOracleTx`, `buildRequestUnstakeTx`, `buildFinalizeUnstakeTx`, `buildSlashOracleTx`
117
123
  - Outcome + premium attestations: `buildSubmitOutcomeAttestationVoteTx`, `buildAttestPremiumPaidOffchainTx`
118
- - Claim oracle rewards: `buildClaimOracleV2Tx`
124
+ - Claim oracle rewards: `buildClaimOracleTx`
119
125
 
120
126
  ### Coverage claims
121
127
 
122
128
  - Submit claim: `buildSubmitCoverageClaimTx`
129
+ - Claim approved payout: `buildClaimApprovedCoveragePayoutTx`
123
130
  - Settle claim: `buildSettleCoverageClaimTx`
124
- - Premium payment: `buildPayPremiumOnchainTx`
131
+ - Premium payment: `buildPayPremiumSolTx`, `buildPayPremiumSplTx`
125
132
  - Optional policy NFT mint: `buildMintPolicyNftTx`
126
133
 
127
134
  ## Module imports
@@ -146,11 +153,15 @@ Available subpaths: `claims`, `protocol`, `protocol_seeds`, `rpc`, `oracle`, `ty
146
153
  - `/docs/RELEASE.md` — versioning, CI gates, tag/publish flow
147
154
  - `/docs/DOCS_SYNC_WORKFLOW.md` — exact cross-repo docs sync workflow (`omegax-docs`)
148
155
  - `/docs/CROSS_REPO_RELEASE_ORDER.md` — commit message templates and release ordering
149
- - `/PROTOCOL_V2_PARITY_CHECKLIST.md` — protocol parity checklist
156
+ - `/PROTOCOL_PARITY_CHECKLIST.md` — protocol parity checklist
150
157
 
151
158
  ## Protocol parity
152
159
 
153
- The SDK includes a strict instruction-account parity test against an Anchor IDL.
160
+ The SDK includes:
161
+
162
+ - a strict instruction-account parity test against an Anchor IDL
163
+ - a live protocol-contract parity check when a local `omegax-protocol` workspace is present
164
+ - a local protocol compatibility gate that runs an SDK smoke test plus the full protocol surface matrix through an SDK adapter
154
165
 
155
166
  - Default fixture path: `tests/fixtures/omegax_protocol.idl.json`
156
167
  - Optional local override:
@@ -165,6 +176,32 @@ Refresh the fixture:
165
176
  npm run sync:idl-fixture
166
177
  ```
167
178
 
179
+ For the normal local workspace layout, this reads from:
180
+
181
+ - `../omegax-protocol/idl/omegax_protocol.json`
182
+
183
+ Run the full local compatibility gate before pushing SDK changes that may affect protocol behavior:
184
+
185
+ ```bash
186
+ npm run verify:protocol:local
187
+ ```
188
+
189
+ This verifies the current local `omegax-protocol` workspace state, including staged, unstaged, and untracked source changes, and records the exact workspace fingerprint it tested.
190
+
191
+ For targeted localnet-only verification:
192
+
193
+ ```bash
194
+ npm run test:protocol:localnet
195
+ ```
196
+
197
+ If you changed SDK builders that are consumed by the oracle service, refresh the local dependency there after rebuilding the SDK:
198
+
199
+ ```bash
200
+ cd ../omegaxhealth_services/services/protocol-oracle-service
201
+ npm run sdk:refresh
202
+ npm run sdk:check
203
+ ```
204
+
168
205
  Latest fixture sync metadata:
169
206
 
170
207
  - Source commit: `e32313b5c49fb06a609252f845845fcf2d49e98d`
@@ -179,12 +216,33 @@ npm pack --dry-run
179
216
  npm audit --omit=dev
180
217
  ```
181
218
 
219
+ ## Cross-repo sync
220
+
221
+ Keep the repos aligned in this order:
222
+
223
+ 1. `omegax-protocol`
224
+ 2. `omegax-sdk`
225
+ 3. `protocol-oracle-service`
226
+ 4. `omegaxhealth_flutter` if the service DTO changed
227
+
228
+ Practical rule:
229
+
230
+ - protocol interface changes start in `omegax-protocol`
231
+ - SDK mirrors the protocol interface and exposes the supported client surface
232
+ - the oracle service refreshes the local SDK package and owns the app-facing Seeker DTO
233
+ - Flutter only follows the service contract
234
+
182
235
  ## OSS docs
183
236
 
184
237
  - `CONTRIBUTING.md`
185
238
  - `SECURITY.md`
186
239
  - `CODE_OF_CONDUCT.md`
240
+ - `AUTHORS.md`
187
241
 
188
242
  ## License
189
243
 
190
- Apache-2.0
244
+ This SDK is licensed under Apache-2.0.
245
+
246
+ The on-chain OmegaX protocol program lives in the separate `omegax-protocol` repository and is licensed independently under AGPL-3.0-or-later.
247
+
248
+ Maintained by OMEGAX HEALTH FZCO with open-source contributors. Project initiated by Marino Sabijan, MD.
package/dist/claims.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import type { BuildUnsignedClaimTxParams, BuildUnsignedRewardClaimTxParams, ClaimFailureCode, ClaimFailureDetail, ClaimIntent, RewardClaimIntent, ValidateSignedClaimTxReason, ValidateSignedClaimTxParams, ValidateSignedClaimTxResult } from './types.js';
2
- export declare function buildUnsignedClaimTx(params: BuildUnsignedClaimTxParams): ClaimIntent;
1
+ import type { BuildUnsignedRewardClaimTxParams, ClaimFailureCode, ClaimFailureDetail, RewardClaimIntent, ValidateSignedClaimTxReason, ValidateSignedClaimTxParams, ValidateSignedClaimTxResult } from './types.js';
3
2
  export declare function buildUnsignedRewardClaimTx(params: BuildUnsignedRewardClaimTxParams): RewardClaimIntent;
4
3
  export declare function validateSignedClaimTx(params: ValidateSignedClaimTxParams): ValidateSignedClaimTxResult;
5
4
  export declare function mapValidationReasonToClaimFailure(reason: ValidateSignedClaimTxReason | null): ClaimFailureCode | null;
package/dist/claims.js CHANGED
@@ -1,10 +1,12 @@
1
- import bs58 from 'bs58';
2
1
  import nacl from 'tweetnacl';
3
2
  import { PublicKey, SystemProgram, Transaction, TransactionInstruction, } from '@solana/web3.js';
4
- import { anchorDiscriminator, encodeU64Le, fromHex, hashStringTo32, } from './utils.js';
5
- import { deriveClaimDelegatePda, deriveClaimPda, deriveClaimV2Pda, deriveConfigV2Pda, deriveOutcomeAggregatePda, derivePoolOraclePolicyPda, derivePoolTermsPda, deriveCycleWindowPda, deriveCycleOutcomePda, deriveMembershipPda, } from './protocol_seeds.js';
6
- const SUBMIT_CLAIM_DISCRIMINATOR = anchorDiscriminator('global', 'submit_claim');
3
+ import { anchorDiscriminator, encodeU64Le, fromHex, } from './utils.js';
4
+ import { decodeSolanaTransaction, solanaTransactionFirstSignature, solanaTransactionIntentMessageBytes, solanaTransactionMessageBytes, solanaTransactionRequiredSigner, solanaTransactionSignerSignature, } from './transactions.js';
5
+ import { deriveClaimPda, deriveConfigPda, deriveOutcomeAggregatePda, derivePoolCompliancePolicyPda, derivePoolOraclePolicyPda, derivePoolTreasuryReservePda, derivePoolTermsPda, deriveMembershipPda, ZERO_PUBKEY, } from './protocol_seeds.js';
7
6
  const SUBMIT_REWARD_CLAIM_DISCRIMINATOR = anchorDiscriminator('global', 'submit_reward_claim');
7
+ function bytesEqual(left, right) {
8
+ return left.length === right.length && left.every((value, index) => value === right[index]);
9
+ }
8
10
  function validateRewardClaimOptionalAccounts(params) {
9
11
  const providedCount = [
10
12
  params.poolAssetVault,
@@ -15,17 +17,8 @@ function validateRewardClaimOptionalAccounts(params) {
15
17
  throw new Error('poolAssetVault, poolVaultTokenAccount, and recipientTokenAccount must be provided together');
16
18
  }
17
19
  }
18
- function serializeSubmitClaimPayload(params) {
19
- const cycleHash = hashStringTo32(params.cycleId);
20
- const intentHash = hashStringTo32(params.intentId);
21
- return Buffer.concat([
22
- SUBMIT_CLAIM_DISCRIMINATOR,
23
- Buffer.from(cycleHash),
24
- Buffer.from(intentHash),
25
- ]);
26
- }
27
20
  function serializeSubmitRewardClaimPayload(params) {
28
- const cycleHash = hashStringTo32(params.cycleId);
21
+ const cycleHash = fromHex(params.cycleHashHex, 32);
29
22
  const ruleHash = fromHex(params.ruleHashHex, 32);
30
23
  const intentHash = fromHex(params.intentHashHex, 32);
31
24
  return Buffer.concat([
@@ -38,98 +31,17 @@ function serializeSubmitRewardClaimPayload(params) {
38
31
  new PublicKey(params.recipient).toBuffer(),
39
32
  ]);
40
33
  }
41
- export function buildUnsignedClaimTx(params) {
42
- const claimant = new PublicKey(params.claimantWallet);
43
- const programId = new PublicKey(params.programId);
44
- const poolAddress = new PublicKey(params.poolAddress);
45
- const cycleHash = hashStringTo32(params.cycleId);
46
- const [membershipPda] = deriveMembershipPda({
47
- programId,
48
- poolAddress,
49
- member: claimant,
50
- });
51
- const [cycleOutcomePda] = deriveCycleOutcomePda({
52
- programId,
53
- poolAddress,
54
- member: claimant,
55
- cycleHash,
56
- });
57
- const [claimPda] = deriveClaimPda({
58
- programId,
59
- poolAddress,
60
- member: claimant,
61
- cycleHash,
62
- });
63
- const [cycleWindowPda] = deriveCycleWindowPda({
64
- programId,
65
- poolAddress,
66
- cycleHash,
67
- });
68
- const instruction = new TransactionInstruction({
69
- keys: [
70
- {
71
- pubkey: claimant,
72
- isSigner: true,
73
- isWritable: true,
74
- },
75
- {
76
- pubkey: poolAddress,
77
- isSigner: false,
78
- isWritable: true,
79
- },
80
- {
81
- pubkey: membershipPda,
82
- isSigner: false,
83
- isWritable: false,
84
- },
85
- {
86
- pubkey: cycleOutcomePda,
87
- isSigner: false,
88
- isWritable: true,
89
- },
90
- {
91
- pubkey: cycleWindowPda,
92
- isSigner: false,
93
- isWritable: false,
94
- },
95
- {
96
- pubkey: claimPda,
97
- isSigner: false,
98
- isWritable: true,
99
- },
100
- {
101
- pubkey: SystemProgram.programId,
102
- isSigner: false,
103
- isWritable: false,
104
- },
105
- ],
106
- programId,
107
- data: serializeSubmitClaimPayload(params),
108
- });
109
- const tx = new Transaction({
110
- recentBlockhash: params.recentBlockhash,
111
- feePayer: claimant,
112
- }).add(instruction);
113
- const unsignedTxBase64 = tx
114
- .serialize({ requireAllSignatures: false, verifySignatures: false })
115
- .toString('base64');
116
- return {
117
- intentId: params.intentId,
118
- unsignedTxBase64,
119
- requiredSigner: claimant.toBase58(),
120
- expiresAtIso: params.expiresAtIso,
121
- attestationRefs: params.attestationRefs,
122
- };
123
- }
124
34
  export function buildUnsignedRewardClaimTx(params) {
125
35
  validateRewardClaimOptionalAccounts(params);
126
36
  const claimant = new PublicKey(params.claimantWallet);
127
37
  const member = new PublicKey(params.member);
128
38
  const programId = new PublicKey(params.programId);
129
39
  const poolAddress = new PublicKey(params.poolAddress);
130
- const cycleHash = hashStringTo32(params.cycleId);
40
+ const payoutMint = new PublicKey(params.payoutMint ?? ZERO_PUBKEY);
41
+ const cycleHash = fromHex(params.cycleHashHex, 32);
131
42
  const ruleHash = fromHex(params.ruleHashHex, 32);
132
- const [configV2Pda] = deriveConfigV2Pda(programId);
43
+ const seriesRefHash = fromHex(params.seriesRefHashHex, 32);
44
+ const [configPda] = deriveConfigPda(programId);
133
45
  const [poolTermsPda] = derivePoolTermsPda({
134
46
  programId,
135
47
  poolAddress,
@@ -138,6 +50,11 @@ export function buildUnsignedRewardClaimTx(params) {
138
50
  programId,
139
51
  poolAddress,
140
52
  });
53
+ const [poolTreasuryReservePda] = derivePoolTreasuryReservePda({
54
+ programId,
55
+ poolAddress,
56
+ paymentMint: payoutMint,
57
+ });
141
58
  const [membershipPda] = deriveMembershipPda({
142
59
  programId,
143
60
  poolAddress,
@@ -146,24 +63,29 @@ export function buildUnsignedRewardClaimTx(params) {
146
63
  const [aggregatePda] = deriveOutcomeAggregatePda({
147
64
  programId,
148
65
  poolAddress,
66
+ seriesRefHash,
149
67
  member,
150
68
  cycleHash,
151
69
  ruleHash,
152
70
  });
153
- const [claimRecordV2Pda] = deriveClaimV2Pda({
71
+ const [claimRecordPda] = deriveClaimPda({
154
72
  programId,
155
73
  poolAddress,
74
+ seriesRefHash,
156
75
  member,
157
76
  cycleHash,
158
77
  ruleHash,
159
78
  });
160
- const [claimDelegatePda] = deriveClaimDelegatePda({
161
- programId,
162
- poolAddress,
163
- member,
164
- });
165
79
  const optionPlaceholder = programId;
166
- const claimDelegateAccount = params.claimDelegate ? claimDelegatePda : optionPlaceholder;
80
+ const memberCycleAccount = params.memberCycle
81
+ ? new PublicKey(params.memberCycle)
82
+ : optionPlaceholder;
83
+ const cohortSettlementRootAccount = params.cohortSettlementRoot
84
+ ? new PublicKey(params.cohortSettlementRoot)
85
+ : optionPlaceholder;
86
+ const claimDelegateAccount = params.claimDelegate
87
+ ? new PublicKey(params.claimDelegate)
88
+ : optionPlaceholder;
167
89
  const poolAssetVaultAccount = params.poolAssetVault
168
90
  ? new PublicKey(params.poolAssetVault)
169
91
  : optionPlaceholder;
@@ -173,24 +95,39 @@ export function buildUnsignedRewardClaimTx(params) {
173
95
  const recipientTokenAccount = params.recipientTokenAccount
174
96
  ? new PublicKey(params.recipientTokenAccount)
175
97
  : optionPlaceholder;
98
+ const keys = [
99
+ { pubkey: claimant, isSigner: true, isWritable: true },
100
+ { pubkey: configPda, isSigner: false, isWritable: false },
101
+ { pubkey: poolAddress, isSigner: false, isWritable: true },
102
+ { pubkey: poolTermsPda, isSigner: false, isWritable: false },
103
+ { pubkey: poolOraclePolicyPda, isSigner: false, isWritable: false },
104
+ { pubkey: poolTreasuryReservePda, isSigner: false, isWritable: true },
105
+ { pubkey: membershipPda, isSigner: false, isWritable: false },
106
+ { pubkey: aggregatePda, isSigner: false, isWritable: true },
107
+ { pubkey: memberCycleAccount, isSigner: false, isWritable: false },
108
+ {
109
+ pubkey: cohortSettlementRootAccount,
110
+ isSigner: false,
111
+ isWritable: params.cohortSettlementRoot != null,
112
+ },
113
+ { pubkey: new PublicKey(params.recipientSystemAccount), isSigner: false, isWritable: true },
114
+ { pubkey: claimDelegateAccount, isSigner: false, isWritable: false },
115
+ { pubkey: poolAssetVaultAccount, isSigner: false, isWritable: false },
116
+ { pubkey: poolVaultTokenAccount, isSigner: false, isWritable: params.poolVaultTokenAccount != null },
117
+ { pubkey: recipientTokenAccount, isSigner: false, isWritable: params.recipientTokenAccount != null },
118
+ { pubkey: claimRecordPda, isSigner: false, isWritable: true },
119
+ { pubkey: new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'), isSigner: false, isWritable: false },
120
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
121
+ {
122
+ pubkey: params.includePoolCompliancePolicy
123
+ ? derivePoolCompliancePolicyPda({ programId, poolAddress })[0]
124
+ : programId,
125
+ isSigner: false,
126
+ isWritable: false,
127
+ },
128
+ ];
176
129
  const instruction = new TransactionInstruction({
177
- keys: [
178
- { pubkey: claimant, isSigner: true, isWritable: true },
179
- { pubkey: configV2Pda, isSigner: false, isWritable: false },
180
- { pubkey: poolAddress, isSigner: false, isWritable: true },
181
- { pubkey: poolTermsPda, isSigner: false, isWritable: false },
182
- { pubkey: poolOraclePolicyPda, isSigner: false, isWritable: false },
183
- { pubkey: membershipPda, isSigner: false, isWritable: false },
184
- { pubkey: aggregatePda, isSigner: false, isWritable: true },
185
- { pubkey: new PublicKey(params.recipientSystemAccount), isSigner: false, isWritable: true },
186
- { pubkey: claimDelegateAccount, isSigner: false, isWritable: false },
187
- { pubkey: poolAssetVaultAccount, isSigner: false, isWritable: false },
188
- { pubkey: poolVaultTokenAccount, isSigner: false, isWritable: params.poolVaultTokenAccount != null },
189
- { pubkey: recipientTokenAccount, isSigner: false, isWritable: params.recipientTokenAccount != null },
190
- { pubkey: claimRecordV2Pda, isSigner: false, isWritable: true },
191
- { pubkey: new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'), isSigner: false, isWritable: false },
192
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
193
- ],
130
+ keys,
194
131
  programId,
195
132
  data: serializeSubmitRewardClaimPayload(params),
196
133
  });
@@ -207,18 +144,10 @@ export function buildUnsignedRewardClaimTx(params) {
207
144
  requiredSigner: claimant.toBase58(),
208
145
  };
209
146
  }
210
- function firstSignatureBase58(tx) {
211
- if (tx.signatures.length === 0)
212
- return null;
213
- const first = tx.signatures[0];
214
- if (!first?.signature)
215
- return null;
216
- return bs58.encode(first.signature);
217
- }
218
147
  export function validateSignedClaimTx(params) {
219
148
  let tx;
220
149
  try {
221
- tx = Transaction.from(Buffer.from(params.signedTxBase64, 'base64'));
150
+ tx = decodeSolanaTransaction(params.signedTxBase64);
222
151
  }
223
152
  catch {
224
153
  return {
@@ -230,30 +159,33 @@ export function validateSignedClaimTx(params) {
230
159
  }
231
160
  if (typeof params.expectedUnsignedTxBase64 === 'string' && params.expectedUnsignedTxBase64.length > 0) {
232
161
  try {
233
- const expectedUnsignedTx = Transaction.from(Buffer.from(params.expectedUnsignedTxBase64, 'base64'));
234
- const signedMessageBytes = tx.serializeMessage();
235
- const expectedMessageBytes = expectedUnsignedTx.serializeMessage();
236
- if (signedMessageBytes.length !== expectedMessageBytes.length
237
- || !signedMessageBytes.every((value, index) => value === expectedMessageBytes[index])) {
238
- return {
239
- valid: false,
240
- txSignature: firstSignatureBase58(tx),
241
- reason: 'intent_message_mismatch',
242
- signer: tx.feePayer?.toBase58() ?? null,
243
- };
162
+ const expectedUnsignedTx = decodeSolanaTransaction(params.expectedUnsignedTxBase64);
163
+ const signedMessageBytes = solanaTransactionMessageBytes(tx);
164
+ const expectedMessageBytes = solanaTransactionMessageBytes(expectedUnsignedTx);
165
+ if (!bytesEqual(signedMessageBytes, expectedMessageBytes)) {
166
+ const signedIntentBytes = solanaTransactionIntentMessageBytes(tx);
167
+ const expectedIntentBytes = solanaTransactionIntentMessageBytes(expectedUnsignedTx);
168
+ if (!bytesEqual(signedIntentBytes, expectedIntentBytes)) {
169
+ return {
170
+ valid: false,
171
+ txSignature: solanaTransactionFirstSignature(tx),
172
+ reason: 'intent_message_mismatch',
173
+ signer: solanaTransactionRequiredSigner(tx),
174
+ };
175
+ }
244
176
  }
245
177
  }
246
178
  catch {
247
179
  return {
248
180
  valid: false,
249
- txSignature: firstSignatureBase58(tx),
181
+ txSignature: solanaTransactionFirstSignature(tx),
250
182
  reason: 'intent_message_mismatch',
251
- signer: tx.feePayer?.toBase58() ?? null,
183
+ signer: solanaTransactionRequiredSigner(tx),
252
184
  };
253
185
  }
254
186
  }
255
187
  const expectedSigner = params.requiredSigner.trim();
256
- const signer = tx.feePayer?.toBase58() ?? null;
188
+ const signer = solanaTransactionRequiredSigner(tx);
257
189
  if (!signer) {
258
190
  return {
259
191
  valid: false,
@@ -265,32 +197,32 @@ export function validateSignedClaimTx(params) {
265
197
  if (signer !== expectedSigner) {
266
198
  return {
267
199
  valid: false,
268
- txSignature: firstSignatureBase58(tx),
200
+ txSignature: solanaTransactionFirstSignature(tx),
269
201
  reason: 'required_signer_mismatch',
270
202
  signer,
271
203
  };
272
204
  }
273
- const expectedPubkey = tx.signatures.find((s) => s.publicKey.toBase58() === expectedSigner);
274
- if (!expectedPubkey || !expectedPubkey.signature) {
205
+ const requiredSignature = solanaTransactionSignerSignature(tx, expectedSigner);
206
+ if (!requiredSignature) {
275
207
  return {
276
208
  valid: false,
277
- txSignature: firstSignatureBase58(tx),
209
+ txSignature: solanaTransactionFirstSignature(tx),
278
210
  reason: 'missing_required_signature',
279
211
  signer,
280
212
  };
281
213
  }
282
- const ok = nacl.sign.detached.verify(tx.serializeMessage(), expectedPubkey.signature, new PublicKey(expectedSigner).toBytes());
214
+ const ok = nacl.sign.detached.verify(solanaTransactionMessageBytes(tx), requiredSignature, new PublicKey(expectedSigner).toBytes());
283
215
  if (!ok) {
284
216
  return {
285
217
  valid: false,
286
- txSignature: firstSignatureBase58(tx),
218
+ txSignature: solanaTransactionFirstSignature(tx),
287
219
  reason: 'invalid_required_signature',
288
220
  signer,
289
221
  };
290
222
  }
291
223
  return {
292
224
  valid: true,
293
- txSignature: firstSignatureBase58(tx),
225
+ txSignature: solanaTransactionFirstSignature(tx),
294
226
  reason: null,
295
227
  signer,
296
228
  };
package/dist/index.d.ts CHANGED
@@ -3,5 +3,6 @@ export * from './utils.js';
3
3
  export * from './oracle.js';
4
4
  export * from './claims.js';
5
5
  export * from './rpc.js';
6
+ export * from './transactions.js';
6
7
  export * from './protocol_seeds.js';
7
8
  export * from './protocol.js';
package/dist/index.js CHANGED
@@ -3,5 +3,6 @@ export * from './utils.js';
3
3
  export * from './oracle.js';
4
4
  export * from './claims.js';
5
5
  export * from './rpc.js';
6
+ export * from './transactions.js';
6
7
  export * from './protocol_seeds.js';
7
8
  export * from './protocol.js';
@@ -1,7 +1,10 @@
1
- import { Connection } from '@solana/web3.js';
1
+ import { AddressLookupTableAccount, Connection, Transaction, VersionedTransaction } from '@solana/web3.js';
2
2
  import type { ProtocolClient, ProtocolCycleQuoteFields } from './types.js';
3
3
  export declare const PROTOCOL_PROGRAM_ID = "Bn6eixac1QEEVErGBvBjxAd6pgB9e2q4XHvAkinQ5y1B";
4
4
  export declare function buildCycleQuoteMessage(fields: ProtocolCycleQuoteFields): Buffer;
5
+ export declare function buildCycleQuoteHash(input: ProtocolCycleQuoteFields | Uint8Array): Buffer;
6
+ export declare function buildCycleQuoteSignatureMessage(input: ProtocolCycleQuoteFields | Uint8Array): Buffer;
7
+ export declare function compileTransactionToV0(transaction: Transaction, lookupTableAccounts: AddressLookupTableAccount[]): VersionedTransaction;
5
8
  export declare function createProtocolClient(connection: Connection, programIdInput: string): ProtocolClient;
6
9
  export declare function derivePoolAddress(params: {
7
10
  programId: string;