@omegax/protocol-sdk 0.4.3 → 0.4.4

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/dist/claims.js CHANGED
@@ -1,7 +1,7 @@
1
- import bs58 from 'bs58';
2
1
  import nacl from 'tweetnacl';
3
2
  import { PublicKey, SystemProgram, Transaction, TransactionInstruction, } from '@solana/web3.js';
4
3
  import { anchorDiscriminator, encodeU64Le, fromHex, hashStringTo32, } from './utils.js';
4
+ import { decodeSolanaTransaction, solanaTransactionFirstSignature, solanaTransactionMessageBytes, solanaTransactionRequiredSigner, solanaTransactionSignerSignature, } from './transactions.js';
5
5
  import { deriveClaimDelegatePda, deriveClaimPda, deriveClaimV2Pda, deriveConfigV2Pda, deriveOutcomeAggregatePda, derivePoolOraclePolicyPda, derivePoolTermsPda, deriveCycleWindowPda, deriveCycleOutcomePda, deriveMembershipPda, } from './protocol_seeds.js';
6
6
  const SUBMIT_CLAIM_DISCRIMINATOR = anchorDiscriminator('global', 'submit_claim');
7
7
  const SUBMIT_REWARD_CLAIM_DISCRIMINATOR = anchorDiscriminator('global', 'submit_reward_claim');
@@ -207,18 +207,10 @@ export function buildUnsignedRewardClaimTx(params) {
207
207
  requiredSigner: claimant.toBase58(),
208
208
  };
209
209
  }
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
210
  export function validateSignedClaimTx(params) {
219
211
  let tx;
220
212
  try {
221
- tx = Transaction.from(Buffer.from(params.signedTxBase64, 'base64'));
213
+ tx = decodeSolanaTransaction(params.signedTxBase64);
222
214
  }
223
215
  catch {
224
216
  return {
@@ -230,30 +222,30 @@ export function validateSignedClaimTx(params) {
230
222
  }
231
223
  if (typeof params.expectedUnsignedTxBase64 === 'string' && params.expectedUnsignedTxBase64.length > 0) {
232
224
  try {
233
- const expectedUnsignedTx = Transaction.from(Buffer.from(params.expectedUnsignedTxBase64, 'base64'));
234
- const signedMessageBytes = tx.serializeMessage();
235
- const expectedMessageBytes = expectedUnsignedTx.serializeMessage();
225
+ const expectedUnsignedTx = decodeSolanaTransaction(params.expectedUnsignedTxBase64);
226
+ const signedMessageBytes = solanaTransactionMessageBytes(tx);
227
+ const expectedMessageBytes = solanaTransactionMessageBytes(expectedUnsignedTx);
236
228
  if (signedMessageBytes.length !== expectedMessageBytes.length
237
229
  || !signedMessageBytes.every((value, index) => value === expectedMessageBytes[index])) {
238
230
  return {
239
231
  valid: false,
240
- txSignature: firstSignatureBase58(tx),
232
+ txSignature: solanaTransactionFirstSignature(tx),
241
233
  reason: 'intent_message_mismatch',
242
- signer: tx.feePayer?.toBase58() ?? null,
234
+ signer: solanaTransactionRequiredSigner(tx),
243
235
  };
244
236
  }
245
237
  }
246
238
  catch {
247
239
  return {
248
240
  valid: false,
249
- txSignature: firstSignatureBase58(tx),
241
+ txSignature: solanaTransactionFirstSignature(tx),
250
242
  reason: 'intent_message_mismatch',
251
- signer: tx.feePayer?.toBase58() ?? null,
243
+ signer: solanaTransactionRequiredSigner(tx),
252
244
  };
253
245
  }
254
246
  }
255
247
  const expectedSigner = params.requiredSigner.trim();
256
- const signer = tx.feePayer?.toBase58() ?? null;
248
+ const signer = solanaTransactionRequiredSigner(tx);
257
249
  if (!signer) {
258
250
  return {
259
251
  valid: false,
@@ -265,32 +257,32 @@ export function validateSignedClaimTx(params) {
265
257
  if (signer !== expectedSigner) {
266
258
  return {
267
259
  valid: false,
268
- txSignature: firstSignatureBase58(tx),
260
+ txSignature: solanaTransactionFirstSignature(tx),
269
261
  reason: 'required_signer_mismatch',
270
262
  signer,
271
263
  };
272
264
  }
273
- const expectedPubkey = tx.signatures.find((s) => s.publicKey.toBase58() === expectedSigner);
274
- if (!expectedPubkey || !expectedPubkey.signature) {
265
+ const requiredSignature = solanaTransactionSignerSignature(tx, expectedSigner);
266
+ if (!requiredSignature) {
275
267
  return {
276
268
  valid: false,
277
- txSignature: firstSignatureBase58(tx),
269
+ txSignature: solanaTransactionFirstSignature(tx),
278
270
  reason: 'missing_required_signature',
279
271
  signer,
280
272
  };
281
273
  }
282
- const ok = nacl.sign.detached.verify(tx.serializeMessage(), expectedPubkey.signature, new PublicKey(expectedSigner).toBytes());
274
+ const ok = nacl.sign.detached.verify(solanaTransactionMessageBytes(tx), requiredSignature, new PublicKey(expectedSigner).toBytes());
283
275
  if (!ok) {
284
276
  return {
285
277
  valid: false,
286
- txSignature: firstSignatureBase58(tx),
278
+ txSignature: solanaTransactionFirstSignature(tx),
287
279
  reason: 'invalid_required_signature',
288
280
  signer,
289
281
  };
290
282
  }
291
283
  return {
292
284
  valid: true,
293
- txSignature: firstSignatureBase58(tx),
285
+ txSignature: solanaTransactionFirstSignature(tx),
294
286
  reason: null,
295
287
  signer,
296
288
  };
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;
package/dist/protocol.js CHANGED
@@ -1,6 +1,7 @@
1
- import { Ed25519Program, PublicKey, SYSVAR_INSTRUCTIONS_PUBKEY, SystemProgram, Transaction, TransactionInstruction, } from '@solana/web3.js';
1
+ import { ComputeBudgetProgram, Ed25519Program, PublicKey, SYSVAR_INSTRUCTIONS_PUBKEY, SystemProgram, Transaction, TransactionMessage, TransactionInstruction, VersionedTransaction, } from '@solana/web3.js';
2
+ import { blake3 } from '@noble/hashes/blake3.js';
2
3
  import { anchorDiscriminator, encodeI64Le, encodeString, encodeU16Le, encodeU64Le, fromHex, hashStringTo32, readI64Le, readString, readU16Le, readU64Le, toHex, } from './utils.js';
3
- import { asPubkey, deriveClaimPda, deriveClaimDelegatePda, deriveClaimV2Pda, deriveConfigPda, deriveConfigV2Pda, deriveCoverageClaimPda, deriveCoverageProductPda, deriveCoverageNftPda, deriveCoveragePolicyPda, deriveCycleOutcomePda, deriveCycleWindowPda, deriveEnrollmentReplayPda, deriveAttestationVotePda, deriveCycleQuoteReplayPda, deriveInviteIssuerPda, deriveMemberCyclePda, deriveMembershipPda, deriveOracleStakePda, deriveOracleProfilePda, deriveOutcomeAggregatePda, deriveOraclePda, derivePoolAssetVaultPda, derivePoolOraclePermissionSetPda, derivePoolOracleFeeVaultPda, derivePoolTermsPda, derivePoolOraclePolicyPda, derivePoolOraclePda, derivePoolPda, derivePoolRulePda, deriveProtocolFeeVaultPda, derivePremiumLedgerPda, derivePremiumReplayPda, derivePoolTreasuryReservePda, deriveReplayPda, deriveSchemaPda, ZERO_PUBKEY, } from './protocol_seeds.js';
4
+ import { asPubkey, deriveClaimPda, deriveClaimDelegatePda, deriveClaimV2Pda, deriveConfigPda, deriveConfigV2Pda, deriveCoverageClaimPda, deriveCoverageProductPda, deriveCoverageProductPaymentOptionPda, deriveCoverageNftPda, deriveCoveragePolicyPda, deriveCycleOutcomePda, deriveCycleWindowPda, deriveEnrollmentReplayPda, deriveAttestationVotePda, deriveCycleQuoteReplayPda, deriveInviteIssuerPda, deriveMemberCyclePda, deriveMembershipPda, deriveOracleStakePda, deriveOracleProfilePda, deriveOutcomeAggregatePda, deriveOraclePda, derivePoolAssetVaultPda, derivePoolOraclePermissionSetPda, derivePoolOracleFeeVaultPda, derivePoolTermsPda, derivePoolOraclePolicyPda, derivePoolOraclePda, derivePoolPda, derivePoolRulePda, deriveProtocolFeeVaultPda, derivePremiumLedgerPda, derivePremiumReplayPda, derivePoolTreasuryReservePda, deriveReplayPda, deriveSchemaPda, ZERO_PUBKEY, } from './protocol_seeds.js';
4
5
  const MAX_POOL_ID_SEED_BYTES = 32;
5
6
  const MAX_ORACLE_SUPPORTED_SCHEMAS = 16;
6
7
  export const PROTOCOL_PROGRAM_ID = 'Bn6eixac1QEEVErGBvBjxAd6pgB9e2q4XHvAkinQ5y1B';
@@ -31,6 +32,7 @@ const IX_FINALIZE_UNSTAKE = anchorDiscriminator('global', 'finalize_unstake');
31
32
  const IX_SLASH_ORACLE = anchorDiscriminator('global', 'slash_oracle');
32
33
  const IX_CREATE_POOL_V2 = anchorDiscriminator('global', 'create_pool_v2');
33
34
  const IX_SET_POOL_ORACLE_POLICY = anchorDiscriminator('global', 'set_pool_oracle_policy');
35
+ const IX_SET_POOL_ORACLE_PERMISSIONS = anchorDiscriminator('global', 'set_pool_oracle_permissions');
34
36
  const IX_SET_POOL_COVERAGE_RESERVE_FLOOR = anchorDiscriminator('global', 'set_pool_coverage_reserve_floor');
35
37
  const IX_SET_POOL_TERMS_HASH = anchorDiscriminator('global', 'set_pool_terms_hash');
36
38
  const IX_REGISTER_OUTCOME_SCHEMA = anchorDiscriminator('global', 'register_outcome_schema');
@@ -45,6 +47,7 @@ const IX_FUND_POOL_SOL = anchorDiscriminator('global', 'fund_pool_sol');
45
47
  const IX_FUND_POOL_SPL = anchorDiscriminator('global', 'fund_pool_spl');
46
48
  const IX_SUBMIT_REWARD_CLAIM = anchorDiscriminator('global', 'submit_reward_claim');
47
49
  const IX_REGISTER_COVERAGE_PRODUCT_V2 = anchorDiscriminator('global', 'register_coverage_product_v2');
50
+ const IX_UPSERT_COVERAGE_PRODUCT_PAYMENT_OPTION = anchorDiscriminator('global', 'upsert_coverage_product_payment_option');
48
51
  const IX_UPDATE_COVERAGE_PRODUCT_V2 = anchorDiscriminator('global', 'update_coverage_product_v2');
49
52
  const IX_SUBSCRIBE_COVERAGE_PRODUCT_V2 = anchorDiscriminator('global', 'subscribe_coverage_product_v2');
50
53
  const IX_ISSUE_COVERAGE_POLICY_FROM_PRODUCT_V2 = anchorDiscriminator('global', 'issue_coverage_policy_from_product_v2');
@@ -91,6 +94,7 @@ const ACCOUNT_CLAIM_RECORD_V2 = anchorDiscriminator('account', 'ClaimRecordV2');
91
94
  const ACCOUNT_COVERAGE_CLAIM_RECORD = anchorDiscriminator('account', 'CoverageClaimRecord');
92
95
  const ACCOUNT_COVERAGE_POLICY_POSITION_NFT = anchorDiscriminator('account', 'CoveragePolicyPositionNft');
93
96
  const ACCOUNT_COVERAGE_PRODUCT = anchorDiscriminator('account', 'CoverageProduct');
97
+ const ACCOUNT_COVERAGE_PRODUCT_PAYMENT_OPTION = anchorDiscriminator('account', 'CoverageProductPaymentOption');
94
98
  const ACCOUNT_ENROLLMENT_PERMIT_REPLAY = anchorDiscriminator('account', 'EnrollmentPermitReplay');
95
99
  const ACCOUNT_ATTESTATION_VOTE = anchorDiscriminator('account', 'AttestationVote');
96
100
  const ACCOUNT_COVERAGE_POLICY = anchorDiscriminator('account', 'CoveragePolicy');
@@ -179,6 +183,35 @@ export function buildCycleQuoteMessage(fields) {
179
183
  Buffer.from(fromHex(fields.quoteMetaHashHex, 32)),
180
184
  ]);
181
185
  }
186
+ function asCycleQuoteMessage(input) {
187
+ if (input instanceof Uint8Array) {
188
+ return Buffer.from(input);
189
+ }
190
+ return buildCycleQuoteMessage(input);
191
+ }
192
+ export function buildCycleQuoteHash(input) {
193
+ return Buffer.from(blake3(asCycleQuoteMessage(input)));
194
+ }
195
+ export function buildCycleQuoteSignatureMessage(input) {
196
+ return Buffer.concat([
197
+ Buffer.from('omegax:cycle_quote_sig:v1', 'utf8'),
198
+ buildCycleQuoteHash(input),
199
+ ]);
200
+ }
201
+ export function compileTransactionToV0(transaction, lookupTableAccounts) {
202
+ if (!transaction.feePayer) {
203
+ throw new Error('transaction fee payer is required to compile a v0 transaction');
204
+ }
205
+ if (!transaction.recentBlockhash) {
206
+ throw new Error('transaction recentBlockhash is required to compile a v0 transaction');
207
+ }
208
+ const message = new TransactionMessage({
209
+ payerKey: transaction.feePayer,
210
+ recentBlockhash: transaction.recentBlockhash,
211
+ instructions: transaction.instructions,
212
+ }).compileToV0Message(lookupTableAccounts);
213
+ return new VersionedTransaction(message);
214
+ }
182
215
  function hasDiscriminator(data, discriminator) {
183
216
  if (data.length < 8)
184
217
  return false;
@@ -1198,6 +1231,32 @@ function decodeCoverageProductAccount(address, data) {
1198
1231
  bump,
1199
1232
  };
1200
1233
  }
1234
+ function decodeCoverageProductPaymentOptionAccount(address, data) {
1235
+ if (!hasDiscriminator(data, ACCOUNT_COVERAGE_PRODUCT_PAYMENT_OPTION)) {
1236
+ throw new Error('account discriminator mismatch for CoverageProductPaymentOption');
1237
+ }
1238
+ let offset = 8;
1239
+ const pool = pubkeyFromData(data, offset);
1240
+ offset += 32;
1241
+ const productIdHash = data.subarray(offset, offset + 32);
1242
+ offset += 32;
1243
+ const paymentMint = pubkeyFromData(data, offset);
1244
+ offset += 32;
1245
+ const paymentAmount = readU64Le(data, offset);
1246
+ offset += 8;
1247
+ const active = data.readUInt8(offset) === 1;
1248
+ offset += 1;
1249
+ const bump = data.readUInt8(offset);
1250
+ return {
1251
+ address,
1252
+ pool,
1253
+ productIdHashHex: toHex(productIdHash),
1254
+ paymentMint,
1255
+ paymentAmount,
1256
+ active,
1257
+ bump,
1258
+ };
1259
+ }
1201
1260
  function decodeCoveragePolicyPositionNftAccount(address, data) {
1202
1261
  if (!hasDiscriminator(data, ACCOUNT_COVERAGE_POLICY_POSITION_NFT)) {
1203
1262
  throw new Error('account discriminator mismatch for CoveragePolicyPositionNft');
@@ -1541,6 +1600,12 @@ function encodeSetPoolOraclePolicyData(params) {
1541
1600
  Buffer.from([params.allowDelegateClaim ? 1 : 0]),
1542
1601
  ]);
1543
1602
  }
1603
+ function encodeSetPoolOraclePermissionsData(params) {
1604
+ const permissions = params.permissions >>> 0;
1605
+ const out = Buffer.alloc(4);
1606
+ out.writeUInt32LE(permissions, 0);
1607
+ return Buffer.concat([IX_SET_POOL_ORACLE_PERMISSIONS, out]);
1608
+ }
1544
1609
  function encodeSetPoolCoverageReserveFloorData(params) {
1545
1610
  return Buffer.concat([
1546
1611
  IX_SET_POOL_COVERAGE_RESERVE_FLOOR,
@@ -1661,6 +1726,14 @@ function encodeRegisterCoverageProductV2Data(params) {
1661
1726
  Buffer.from([params.active ? 1 : 0]),
1662
1727
  ]);
1663
1728
  }
1729
+ function encodeUpsertCoverageProductPaymentOptionData(params) {
1730
+ return Buffer.concat([
1731
+ IX_UPSERT_COVERAGE_PRODUCT_PAYMENT_OPTION,
1732
+ asPubkey(params.paymentMint).toBuffer(),
1733
+ encodeU64Le(params.paymentAmount),
1734
+ Buffer.from([params.active ? 1 : 0]),
1735
+ ]);
1736
+ }
1664
1737
  function encodeUpdateCoverageProductV2Data(params) {
1665
1738
  return Buffer.concat([
1666
1739
  IX_UPDATE_COVERAGE_PRODUCT_V2,
@@ -1749,17 +1822,6 @@ function encodeMigratePoolV1ToV2Data(params) {
1749
1822
  encodeString(params.metadataUri),
1750
1823
  ]);
1751
1824
  }
1752
- function deriveCoverageProductPaymentOptionPda(params) {
1753
- const program = asPubkey(params.programId);
1754
- const pool = asPubkey(params.poolAddress);
1755
- const paymentMint = asPubkey(params.paymentMint);
1756
- return PublicKey.findProgramAddressSync([
1757
- Buffer.from('coverage_product_payment_option'),
1758
- pool.toBuffer(),
1759
- Buffer.from(fromHex(params.productIdHashHex, 32)),
1760
- paymentMint.toBuffer(),
1761
- ], program);
1762
- }
1763
1825
  function buildActivateCycleWithQuoteSolTransaction(params) {
1764
1826
  const programId = asPubkey(params.programId);
1765
1827
  const payer = asPubkey(params.payer);
@@ -1788,7 +1850,7 @@ function buildActivateCycleWithQuoteSolTransaction(params) {
1788
1850
  const [coverageProductPaymentOption] = deriveCoverageProductPaymentOptionPda({
1789
1851
  programId,
1790
1852
  poolAddress,
1791
- productIdHashHex: params.productIdHashHex,
1853
+ productIdHash: fromHex(params.productIdHashHex, 32),
1792
1854
  paymentMint: zeroPubkey,
1793
1855
  });
1794
1856
  const [coveragePolicy] = deriveCoveragePolicyPda({ programId, poolAddress, member });
@@ -1823,7 +1885,7 @@ function buildActivateCycleWithQuoteSolTransaction(params) {
1823
1885
  });
1824
1886
  const ed25519Instruction = Ed25519Program.createInstructionWithPrivateKey({
1825
1887
  privateKey: params.oracleSecretKey,
1826
- message: params.quoteMessage,
1888
+ message: buildCycleQuoteSignatureMessage(params.quoteMessage),
1827
1889
  });
1828
1890
  const instruction = new TransactionInstruction({
1829
1891
  programId,
@@ -1855,6 +1917,7 @@ function buildActivateCycleWithQuoteSolTransaction(params) {
1855
1917
  IX_ACTIVATE_CYCLE_WITH_QUOTE_SOL,
1856
1918
  Buffer.from(fromHex(params.productIdHashHex, 32)),
1857
1919
  encodeU64Le(params.periodIndex),
1920
+ Buffer.from(fromHex(params.nonceHashHex, 32)),
1858
1921
  encodeU64Le(params.premiumAmountRaw),
1859
1922
  encodeU64Le(params.canonicalPremiumAmount),
1860
1923
  Buffer.from([params.commitmentEnabled ? 1 : 0]),
@@ -1867,14 +1930,19 @@ function buildActivateCycleWithQuoteSolTransaction(params) {
1867
1930
  Buffer.from([params.includedShieldCount]),
1868
1931
  encodeU16Le(params.thresholdBps),
1869
1932
  encodeI64Le(params.expiresAtTs),
1870
- Buffer.from(fromHex(params.nonceHashHex, 32)),
1871
1933
  Buffer.from(fromHex(params.quoteMetaHashHex, 32)),
1872
1934
  ]),
1873
1935
  });
1874
- return new Transaction({
1936
+ const transaction = new Transaction({
1875
1937
  feePayer: payer,
1876
1938
  recentBlockhash: params.recentBlockhash,
1877
- }).add(ed25519Instruction, instruction);
1939
+ });
1940
+ if (typeof params.computeUnitLimit === 'number') {
1941
+ transaction.add(ComputeBudgetProgram.setComputeUnitLimit({
1942
+ units: params.computeUnitLimit,
1943
+ }));
1944
+ }
1945
+ return transaction.add(ed25519Instruction, instruction);
1878
1946
  }
1879
1947
  function buildActivateCycleWithQuoteSplTransaction(params) {
1880
1948
  const programId = asPubkey(params.programId);
@@ -1904,7 +1972,7 @@ function buildActivateCycleWithQuoteSplTransaction(params) {
1904
1972
  const [coverageProductPaymentOption] = deriveCoverageProductPaymentOptionPda({
1905
1973
  programId,
1906
1974
  poolAddress,
1907
- productIdHashHex: params.productIdHashHex,
1975
+ productIdHash: fromHex(params.productIdHashHex, 32),
1908
1976
  paymentMint,
1909
1977
  });
1910
1978
  const [coveragePolicy] = deriveCoveragePolicyPda({ programId, poolAddress, member });
@@ -1962,7 +2030,7 @@ function buildActivateCycleWithQuoteSplTransaction(params) {
1962
2030
  });
1963
2031
  const ed25519Instruction = Ed25519Program.createInstructionWithPrivateKey({
1964
2032
  privateKey: params.oracleSecretKey,
1965
- message: params.quoteMessage,
2033
+ message: buildCycleQuoteSignatureMessage(params.quoteMessage),
1966
2034
  });
1967
2035
  const instruction = new TransactionInstruction({
1968
2036
  programId,
@@ -2002,6 +2070,7 @@ function buildActivateCycleWithQuoteSplTransaction(params) {
2002
2070
  IX_ACTIVATE_CYCLE_WITH_QUOTE_SPL,
2003
2071
  Buffer.from(fromHex(params.productIdHashHex, 32)),
2004
2072
  encodeU64Le(params.periodIndex),
2073
+ Buffer.from(fromHex(params.nonceHashHex, 32)),
2005
2074
  encodeU64Le(params.premiumAmountRaw),
2006
2075
  encodeU64Le(params.canonicalPremiumAmount),
2007
2076
  Buffer.from([params.commitmentEnabled ? 1 : 0]),
@@ -2014,14 +2083,15 @@ function buildActivateCycleWithQuoteSplTransaction(params) {
2014
2083
  Buffer.from([params.includedShieldCount]),
2015
2084
  encodeU16Le(params.thresholdBps),
2016
2085
  encodeI64Le(params.expiresAtTs),
2017
- Buffer.from(fromHex(params.nonceHashHex, 32)),
2018
2086
  Buffer.from(fromHex(params.quoteMetaHashHex, 32)),
2019
2087
  ]),
2020
2088
  });
2021
2089
  return new Transaction({
2022
2090
  feePayer: payer,
2023
2091
  recentBlockhash: params.recentBlockhash,
2024
- }).add(ed25519Instruction, instruction);
2092
+ }).add(ComputeBudgetProgram.setComputeUnitLimit({
2093
+ units: params.computeUnitLimit ?? 400_000,
2094
+ }), ed25519Instruction, instruction);
2025
2095
  }
2026
2096
  function buildSettleCycleCommitmentTransaction(params) {
2027
2097
  const programId = asPubkey(params.programId);
@@ -3128,6 +3198,42 @@ export function createProtocolClient(connection, programIdInput) {
3128
3198
  recentBlockhash: params.recentBlockhash,
3129
3199
  }).add(instruction);
3130
3200
  },
3201
+ buildSetPoolOraclePermissionsTx(params) {
3202
+ const authority = new PublicKey(params.authority);
3203
+ const poolAddress = new PublicKey(params.poolAddress);
3204
+ const oracle = new PublicKey(params.oracle);
3205
+ const [oracleEntryPda] = deriveOraclePda({
3206
+ programId,
3207
+ oracle,
3208
+ });
3209
+ const [poolOraclePda] = derivePoolOraclePda({
3210
+ programId,
3211
+ poolAddress,
3212
+ oracle,
3213
+ });
3214
+ const [poolOraclePermissionsPda] = derivePoolOraclePermissionSetPda({
3215
+ programId,
3216
+ poolAddress,
3217
+ oracle,
3218
+ });
3219
+ const instruction = new TransactionInstruction({
3220
+ programId,
3221
+ keys: [
3222
+ { pubkey: authority, isSigner: true, isWritable: true },
3223
+ { pubkey: poolAddress, isSigner: false, isWritable: false },
3224
+ { pubkey: oracle, isSigner: false, isWritable: false },
3225
+ { pubkey: oracleEntryPda, isSigner: false, isWritable: false },
3226
+ { pubkey: poolOraclePda, isSigner: false, isWritable: false },
3227
+ { pubkey: poolOraclePermissionsPda, isSigner: false, isWritable: true },
3228
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
3229
+ ],
3230
+ data: encodeSetPoolOraclePermissionsData(params),
3231
+ });
3232
+ return new Transaction({
3233
+ feePayer: authority,
3234
+ recentBlockhash: params.recentBlockhash,
3235
+ }).add(instruction);
3236
+ },
3131
3237
  buildSetPoolCoverageReserveFloorTx(params) {
3132
3238
  const authority = new PublicKey(params.authority);
3133
3239
  const poolAddress = new PublicKey(params.poolAddress);
@@ -3542,6 +3648,41 @@ export function createProtocolClient(connection, programIdInput) {
3542
3648
  recentBlockhash: params.recentBlockhash,
3543
3649
  }).add(instruction);
3544
3650
  },
3651
+ buildUpsertCoverageProductPaymentOptionTx(params) {
3652
+ const authority = new PublicKey(params.authority);
3653
+ const poolAddress = new PublicKey(params.poolAddress);
3654
+ const paymentMint = new PublicKey(params.paymentMint);
3655
+ const productIdHash = fromHex(params.productIdHashHex, 32);
3656
+ const [configV2Pda] = deriveConfigV2Pda(programId);
3657
+ const [coverageProductPda] = deriveCoverageProductPda({
3658
+ programId,
3659
+ poolAddress,
3660
+ productIdHash,
3661
+ });
3662
+ const [coverageProductPaymentOptionPda] = deriveCoverageProductPaymentOptionPda({
3663
+ programId,
3664
+ poolAddress,
3665
+ productIdHash,
3666
+ paymentMint,
3667
+ });
3668
+ const instruction = new TransactionInstruction({
3669
+ programId,
3670
+ keys: [
3671
+ { pubkey: authority, isSigner: true, isWritable: true },
3672
+ { pubkey: configV2Pda, isSigner: false, isWritable: false },
3673
+ { pubkey: poolAddress, isSigner: false, isWritable: false },
3674
+ { pubkey: coverageProductPda, isSigner: false, isWritable: true },
3675
+ { pubkey: paymentMint, isSigner: false, isWritable: false },
3676
+ { pubkey: coverageProductPaymentOptionPda, isSigner: false, isWritable: true },
3677
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
3678
+ ],
3679
+ data: encodeUpsertCoverageProductPaymentOptionData(params),
3680
+ });
3681
+ return new Transaction({
3682
+ feePayer: authority,
3683
+ recentBlockhash: params.recentBlockhash,
3684
+ }).add(instruction);
3685
+ },
3545
3686
  buildUpdateCoverageProductV2Tx(params) {
3546
3687
  const authority = new PublicKey(params.authority);
3547
3688
  const poolAddress = new PublicKey(params.poolAddress);
@@ -4275,6 +4416,18 @@ export function createProtocolClient(connection, programIdInput) {
4275
4416
  return null;
4276
4417
  return decodeCoverageProductAccount(pda.toBase58(), account.data);
4277
4418
  },
4419
+ async fetchCoverageProductPaymentOption(params) {
4420
+ const [pda] = deriveCoverageProductPaymentOptionPda({
4421
+ programId,
4422
+ poolAddress: params.poolAddress,
4423
+ productIdHash: fromHex(params.productIdHashHex, 32),
4424
+ paymentMint: params.paymentMint,
4425
+ });
4426
+ const account = await connection.getAccountInfo(pda, 'confirmed');
4427
+ if (!account)
4428
+ return null;
4429
+ return decodeCoverageProductPaymentOptionAccount(pda.toBase58(), account.data);
4430
+ },
4278
4431
  async fetchCoveragePolicy(params) {
4279
4432
  const [pda] = deriveCoveragePolicyPda({
4280
4433
  programId,
@@ -31,6 +31,7 @@ export declare const SEED_CLAIM_V2 = "claim_v2";
31
31
  export declare const SEED_COVERAGE_POLICY = "coverage_policy";
32
32
  export declare const SEED_COVERAGE_NFT = "coverage_nft";
33
33
  export declare const SEED_COVERAGE_PRODUCT = "coverage_product";
34
+ export declare const SEED_COVERAGE_PRODUCT_PAYMENT_OPTION = "coverage_product_payment_option";
34
35
  export declare const SEED_PREMIUM_LEDGER = "premium_ledger";
35
36
  export declare const SEED_PREMIUM_REPLAY = "premium_replay";
36
37
  export declare const SEED_COVERAGE_CLAIM = "coverage_claim";
@@ -101,6 +102,12 @@ export declare function derivePoolAssetVaultPda(params: {
101
102
  poolAddress: string | PublicKey;
102
103
  payoutMint: string | PublicKey;
103
104
  }): [PublicKey, number];
105
+ export declare function deriveCoverageProductPaymentOptionPda(params: {
106
+ programId: string | PublicKey;
107
+ poolAddress: string | PublicKey;
108
+ productIdHash: Uint8Array;
109
+ paymentMint: string | PublicKey;
110
+ }): [PublicKey, number];
104
111
  export declare function derivePoolOraclePermissionSetPda(params: {
105
112
  programId: string | PublicKey;
106
113
  poolAddress: string | PublicKey;
@@ -31,6 +31,7 @@ export const SEED_CLAIM_V2 = 'claim_v2';
31
31
  export const SEED_COVERAGE_POLICY = 'coverage_policy';
32
32
  export const SEED_COVERAGE_NFT = 'coverage_nft';
33
33
  export const SEED_COVERAGE_PRODUCT = 'coverage_product';
34
+ export const SEED_COVERAGE_PRODUCT_PAYMENT_OPTION = 'coverage_product_payment_option';
34
35
  export const SEED_PREMIUM_LEDGER = 'premium_ledger';
35
36
  export const SEED_PREMIUM_REPLAY = 'premium_replay';
36
37
  export const SEED_COVERAGE_CLAIM = 'coverage_claim';
@@ -136,6 +137,17 @@ export function derivePoolAssetVaultPda(params) {
136
137
  const mint = asPubkey(params.payoutMint);
137
138
  return PublicKey.findProgramAddressSync([Buffer.from(SEED_POOL_ASSET_VAULT), pool.toBuffer(), mint.toBuffer()], program);
138
139
  }
140
+ export function deriveCoverageProductPaymentOptionPda(params) {
141
+ const program = asPubkey(params.programId);
142
+ const pool = asPubkey(params.poolAddress);
143
+ const mint = asPubkey(params.paymentMint);
144
+ return PublicKey.findProgramAddressSync([
145
+ Buffer.from(SEED_COVERAGE_PRODUCT_PAYMENT_OPTION),
146
+ pool.toBuffer(),
147
+ Buffer.from(params.productIdHash),
148
+ mint.toBuffer(),
149
+ ], program);
150
+ }
139
151
  function encodeU64Seed(value) {
140
152
  const out = Buffer.alloc(8);
141
153
  out.writeBigUInt64LE(typeof value === 'bigint' ? value : BigInt(value));
package/dist/rpc.js CHANGED
@@ -1,5 +1,6 @@
1
- import { Connection, Transaction, } from '@solana/web3.js';
1
+ import { Connection, } from '@solana/web3.js';
2
2
  import { normalizeClaimSimulationFailure } from './claims.js';
3
+ import { decodeSolanaTransaction, } from './transactions.js';
3
4
  export const OMEGAX_NETWORKS = {
4
5
  devnet: {
5
6
  network: 'devnet',
@@ -73,7 +74,7 @@ export function createRpcClient(connection) {
73
74
  async simulateSignedTx(params) {
74
75
  let tx;
75
76
  try {
76
- tx = Transaction.from(Buffer.from(params.signedTxBase64, 'base64'));
77
+ tx = decodeSolanaTransaction(params.signedTxBase64);
77
78
  }
78
79
  catch (error) {
79
80
  return {
@@ -0,0 +1,10 @@
1
+ import { Transaction, VersionedTransaction } from '@solana/web3.js';
2
+ export type SolanaTransaction = Transaction | VersionedTransaction;
3
+ export declare function decodeSolanaTransaction(input: string | Uint8Array | Buffer): SolanaTransaction;
4
+ export declare function serializeSolanaTransaction(transaction: SolanaTransaction): Buffer;
5
+ export declare function serializeSolanaTransactionBase64(transaction: SolanaTransaction): string;
6
+ export declare function solanaTransactionMessageBytes(transaction: SolanaTransaction): Uint8Array;
7
+ export declare function solanaTransactionMessageBase64(input: SolanaTransaction | string | Uint8Array | Buffer): string;
8
+ export declare function solanaTransactionRequiredSigner(transaction: SolanaTransaction): string | null;
9
+ export declare function solanaTransactionFirstSignature(transaction: SolanaTransaction): string | null;
10
+ export declare function solanaTransactionSignerSignature(transaction: SolanaTransaction, signer: string): Uint8Array | null;
@@ -0,0 +1,104 @@
1
+ import bs58 from 'bs58';
2
+ import { Transaction, VersionedTransaction, } from '@solana/web3.js';
3
+ function decodeShortVecLength(bytes, offset = 0) {
4
+ let length = 0;
5
+ let size = 0;
6
+ let cursor = offset;
7
+ while (cursor < bytes.length) {
8
+ const value = bytes[cursor] ?? 0;
9
+ length |= (value & 0x7f) << (size * 7);
10
+ size += 1;
11
+ cursor += 1;
12
+ if ((value & 0x80) === 0) {
13
+ return { length, bytesRead: size };
14
+ }
15
+ }
16
+ throw new Error('invalid shortvec length');
17
+ }
18
+ function versionedStaticAccountKeys(transaction) {
19
+ const message = transaction.message;
20
+ return (message?.staticAccountKeys ??
21
+ message?.getAccountKeys?.().staticAccountKeys ??
22
+ []);
23
+ }
24
+ function signatureIsPresent(signature) {
25
+ if (!signature || signature.length === 0)
26
+ return false;
27
+ return signature.some((value) => value !== 0);
28
+ }
29
+ export function decodeSolanaTransaction(input) {
30
+ const bytes = typeof input === 'string' ? Buffer.from(input, 'base64') : Buffer.from(input);
31
+ const { length: signatureCount, bytesRead } = decodeShortVecLength(bytes);
32
+ const messageOffset = bytesRead + signatureCount * 64;
33
+ if (messageOffset >= bytes.length) {
34
+ throw new Error('invalid serialized transaction');
35
+ }
36
+ const messagePrefix = bytes[messageOffset] ?? 0;
37
+ if ((messagePrefix & 0x80) !== 0) {
38
+ return VersionedTransaction.deserialize(bytes);
39
+ }
40
+ return Transaction.from(bytes);
41
+ }
42
+ export function serializeSolanaTransaction(transaction) {
43
+ if (transaction instanceof Transaction) {
44
+ return transaction.serialize({
45
+ requireAllSignatures: false,
46
+ verifySignatures: false,
47
+ });
48
+ }
49
+ return Buffer.from(transaction.serialize());
50
+ }
51
+ export function serializeSolanaTransactionBase64(transaction) {
52
+ return serializeSolanaTransaction(transaction).toString('base64');
53
+ }
54
+ export function solanaTransactionMessageBytes(transaction) {
55
+ if (transaction instanceof Transaction) {
56
+ return transaction.serializeMessage();
57
+ }
58
+ return transaction.message.serialize();
59
+ }
60
+ export function solanaTransactionMessageBase64(input) {
61
+ const transaction = typeof input === 'string' || input instanceof Uint8Array || Buffer.isBuffer(input)
62
+ ? decodeSolanaTransaction(input)
63
+ : input;
64
+ return Buffer.from(solanaTransactionMessageBytes(transaction)).toString('base64');
65
+ }
66
+ export function solanaTransactionRequiredSigner(transaction) {
67
+ if (transaction instanceof Transaction) {
68
+ return transaction.feePayer?.toBase58() ?? null;
69
+ }
70
+ const accountKeys = versionedStaticAccountKeys(transaction);
71
+ return accountKeys[0]?.toBase58() ?? null;
72
+ }
73
+ export function solanaTransactionFirstSignature(transaction) {
74
+ if (transaction instanceof Transaction) {
75
+ if (transaction.signatures.length === 0)
76
+ return null;
77
+ const first = transaction.signatures[0];
78
+ if (!signatureIsPresent(first?.signature))
79
+ return null;
80
+ return bs58.encode(first.signature);
81
+ }
82
+ const first = transaction.signatures[0];
83
+ if (!signatureIsPresent(first))
84
+ return null;
85
+ return bs58.encode(first);
86
+ }
87
+ export function solanaTransactionSignerSignature(transaction, signer) {
88
+ if (transaction instanceof Transaction) {
89
+ const entry = transaction.signatures.find((candidate) => candidate.publicKey.toBase58() === signer);
90
+ return signatureIsPresent(entry?.signature) ? entry?.signature : null;
91
+ }
92
+ const accountKeys = versionedStaticAccountKeys(transaction);
93
+ const signerIndex = accountKeys.findIndex((candidate) => candidate.toBase58() === signer);
94
+ if (signerIndex < 0)
95
+ return null;
96
+ const header = transaction.message
97
+ .header;
98
+ const requiredSignerCount = header?.numRequiredSignatures ?? 0;
99
+ if (signerIndex >= requiredSignerCount) {
100
+ return null;
101
+ }
102
+ const signature = transaction.signatures[signerIndex];
103
+ return signatureIsPresent(signature) ? signature : null;
104
+ }
package/dist/types.d.ts CHANGED
@@ -394,6 +394,7 @@ export interface BuildActivateCycleWithQuoteSolTxParams {
394
394
  quoteMetaHashHex: string;
395
395
  quoteMessage: Uint8Array;
396
396
  oracleSecretKey: Uint8Array;
397
+ computeUnitLimit?: number;
397
398
  recentBlockhash: string;
398
399
  programId: string;
399
400
  }
@@ -421,6 +422,7 @@ export interface BuildActivateCycleWithQuoteSplTxParams {
421
422
  quoteMetaHashHex: string;
422
423
  quoteMessage: Uint8Array;
423
424
  oracleSecretKey: Uint8Array;
425
+ computeUnitLimit?: number;
424
426
  recentBlockhash: string;
425
427
  programId: string;
426
428
  }
@@ -572,6 +574,7 @@ export interface ProtocolClient {
572
574
  buildSlashOracleTx?: (params: BuildSlashOracleTxParams) => Transaction;
573
575
  buildCreatePoolV2Tx?: (params: BuildCreatePoolV2TxParams) => Transaction;
574
576
  buildSetPoolOraclePolicyTx?: (params: BuildSetPoolOraclePolicyTxParams) => Transaction;
577
+ buildSetPoolOraclePermissionsTx?: (params: BuildSetPoolOraclePermissionsTxParams) => Transaction;
575
578
  buildSetPoolTermsHashTx?: (params: BuildSetPoolTermsHashTxParams) => Transaction;
576
579
  buildRegisterOutcomeSchemaTx?: (params: BuildRegisterOutcomeSchemaTxParams) => Transaction;
577
580
  buildVerifyOutcomeSchemaTx?: (params: BuildVerifyOutcomeSchemaTxParams) => Transaction;
@@ -588,6 +591,7 @@ export interface ProtocolClient {
588
591
  buildSubmitRewardClaimTx?: (params: BuildSubmitRewardClaimTxParams) => Transaction;
589
592
  buildRegisterCoverageProductV2Tx?: (params: BuildRegisterCoverageProductV2TxParams) => Transaction;
590
593
  buildUpdateCoverageProductV2Tx?: (params: BuildUpdateCoverageProductV2TxParams) => Transaction;
594
+ buildUpsertCoverageProductPaymentOptionTx?: (params: BuildUpsertCoverageProductPaymentOptionTxParams) => Transaction;
591
595
  buildSubscribeCoverageProductV2Tx?: (params: BuildSubscribeCoverageProductV2TxParams) => Transaction;
592
596
  buildIssueCoveragePolicyFromProductV2Tx?: (params: BuildIssueCoveragePolicyFromProductV2TxParams) => Transaction;
593
597
  buildCreateCoveragePolicyTx?: (params: BuildCreateCoveragePolicyTxParams) => Transaction;
@@ -658,6 +662,11 @@ export interface ProtocolClient {
658
662
  poolAddress: string;
659
663
  productIdHashHex: string;
660
664
  }) => Promise<ProtocolCoverageProductAccount | null>;
665
+ fetchCoverageProductPaymentOption?: (params: {
666
+ poolAddress: string;
667
+ productIdHashHex: string;
668
+ paymentMint: string;
669
+ }) => Promise<ProtocolCoverageProductPaymentOptionAccount | null>;
661
670
  fetchCoveragePolicy?: (params: {
662
671
  poolAddress: string;
663
672
  member: string;
@@ -951,6 +960,15 @@ export interface ProtocolCoverageProductAccount {
951
960
  updatedAtTs: number;
952
961
  bump: number;
953
962
  }
963
+ export interface ProtocolCoverageProductPaymentOptionAccount {
964
+ address: string;
965
+ pool: string;
966
+ productIdHashHex: string;
967
+ paymentMint: string;
968
+ paymentAmount: bigint;
969
+ active: boolean;
970
+ bump: number;
971
+ }
954
972
  export interface ProtocolCoveragePolicyPositionNftAccount {
955
973
  address: string;
956
974
  pool: string;
@@ -1111,6 +1129,14 @@ export interface BuildSetPoolOraclePolicyTxParams {
1111
1129
  recentBlockhash: string;
1112
1130
  programId: string;
1113
1131
  }
1132
+ export interface BuildSetPoolOraclePermissionsTxParams {
1133
+ authority: string;
1134
+ poolAddress: string;
1135
+ oracle: string;
1136
+ permissions: number;
1137
+ recentBlockhash: string;
1138
+ programId: string;
1139
+ }
1114
1140
  export interface BuildSetPoolTermsHashTxParams {
1115
1141
  authority: string;
1116
1142
  poolAddress: string;
@@ -1336,6 +1362,16 @@ export interface BuildRegisterCoverageProductV2TxParams {
1336
1362
  recentBlockhash: string;
1337
1363
  programId: string;
1338
1364
  }
1365
+ export interface BuildUpsertCoverageProductPaymentOptionTxParams {
1366
+ authority: string;
1367
+ poolAddress: string;
1368
+ productIdHashHex: string;
1369
+ paymentMint: string;
1370
+ paymentAmount: bigint;
1371
+ active: boolean;
1372
+ recentBlockhash: string;
1373
+ programId: string;
1374
+ }
1339
1375
  export interface BuildUpdateCoverageProductV2TxParams {
1340
1376
  authority: string;
1341
1377
  poolAddress: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omegax/protocol-sdk",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "TypeScript SDK for OmegaX protocol integrations on Solana devnet beta (mainnet coming soon).",
5
5
  "keywords": [
6
6
  "omegax",
@@ -79,6 +79,7 @@
79
79
  "dev": "tsx watch src/index.ts"
80
80
  },
81
81
  "dependencies": {
82
+ "@noble/hashes": "^1.8.0",
82
83
  "@solana/web3.js": "^1.98.4",
83
84
  "bs58": "^6.0.0",
84
85
  "tweetnacl": "^1.0.3"