@drift-labs/sdk 2.85.0-beta.9 → 2.86.0-beta.1

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 (51) hide show
  1. package/VERSION +1 -1
  2. package/bun.lockb +0 -0
  3. package/lib/addresses/pda.d.ts +1 -0
  4. package/lib/addresses/pda.js +8 -1
  5. package/lib/adminClient.d.ts +2 -0
  6. package/lib/adminClient.js +22 -0
  7. package/lib/config.d.ts +3 -0
  8. package/lib/config.js +4 -1
  9. package/lib/constants/perpMarkets.d.ts +1 -0
  10. package/lib/constants/perpMarkets.js +57 -0
  11. package/lib/constants/spotMarkets.d.ts +1 -0
  12. package/lib/constants/spotMarkets.js +20 -0
  13. package/lib/driftClient.d.ts +26 -1
  14. package/lib/driftClient.js +157 -31
  15. package/lib/driftClientConfig.d.ts +2 -1
  16. package/lib/idl/drift.json +161 -2
  17. package/lib/math/oracles.d.ts +2 -0
  18. package/lib/math/oracles.js +14 -1
  19. package/lib/oracles/pythPullClient.js +1 -1
  20. package/lib/tx/baseTxSender.js +1 -0
  21. package/lib/tx/blockhashFetcher/baseBlockhashFetcher.d.ts +8 -0
  22. package/lib/tx/blockhashFetcher/baseBlockhashFetcher.js +13 -0
  23. package/lib/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts +28 -0
  24. package/lib/tx/blockhashFetcher/cachedBlockhashFetcher.js +73 -0
  25. package/lib/tx/blockhashFetcher/types.d.ts +4 -0
  26. package/lib/tx/blockhashFetcher/types.js +2 -0
  27. package/lib/tx/txHandler.d.ts +10 -0
  28. package/lib/tx/txHandler.js +16 -7
  29. package/lib/tx/utils.d.ts +2 -0
  30. package/lib/tx/utils.js +10 -0
  31. package/lib/util/pythPullOracleUtils.d.ts +2 -0
  32. package/lib/util/pythPullOracleUtils.js +15 -0
  33. package/package.json +6 -1
  34. package/src/addresses/pda.ts +13 -0
  35. package/src/adminClient.ts +39 -0
  36. package/src/config.ts +6 -0
  37. package/src/constants/perpMarkets.ts +115 -0
  38. package/src/constants/spotMarkets.ts +41 -0
  39. package/src/driftClient.ts +347 -41
  40. package/src/driftClientConfig.ts +2 -1
  41. package/src/idl/drift.json +161 -2
  42. package/src/math/oracles.ts +17 -0
  43. package/src/oracles/pythPullClient.ts +2 -3
  44. package/src/tx/baseTxSender.ts +1 -0
  45. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +19 -0
  46. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +90 -0
  47. package/src/tx/blockhashFetcher/types.ts +5 -0
  48. package/src/tx/txHandler.ts +38 -4
  49. package/src/tx/utils.ts +11 -0
  50. package/src/util/pythPullOracleUtils.ts +11 -0
  51. package/tests/tx/cachedBlockhashFetcher.test.ts +96 -0
@@ -76,6 +76,7 @@ import {
76
76
  getInsuranceFundStakeAccountPublicKey,
77
77
  getPerpMarketPublicKey,
78
78
  getPhoenixFulfillmentConfigPublicKey,
79
+ getPythPullOraclePublicKey,
79
80
  getReferrerNamePublicKeySync,
80
81
  getSerumFulfillmentConfigPublicKey,
81
82
  getSerumSignerPublicKey,
@@ -127,8 +128,23 @@ import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
127
128
  import { getOrderParams } from './orderParams';
128
129
  import { numberToSafeBN } from './math/utils';
129
130
  import { TransactionParamProcessor } from './tx/txParamProcessor';
130
- import { isOracleValid } from './math/oracles';
131
+ import { isOracleValid, trimVaaSignatures } from './math/oracles';
131
132
  import { TxHandler } from './tx/txHandler';
133
+ import {
134
+ wormholeCoreBridgeIdl,
135
+ pythSolanaReceiverIdl,
136
+ DEFAULT_RECEIVER_PROGRAM_ID,
137
+ } from '@pythnetwork/pyth-solana-receiver';
138
+ import { parseAccumulatorUpdateData } from '@pythnetwork/price-service-sdk';
139
+ import {
140
+ DEFAULT_WORMHOLE_PROGRAM_ID,
141
+ getGuardianSetPda,
142
+ } from '@pythnetwork/pyth-solana-receiver/lib/address';
143
+ import { DRIFT_ORACLE_RECEIVER_ID } from './config';
144
+ import { WormholeCoreBridgeSolana } from '@pythnetwork/pyth-solana-receiver/lib/idl/wormhole_core_bridge_solana';
145
+ import { PythSolanaReceiver } from '@pythnetwork/pyth-solana-receiver/lib/idl/pyth_solana_receiver';
146
+ import { getFeedIdUint8Array, trimFeedId } from './util/pythPullOracleUtils';
147
+ import { isVersionedTransaction } from './tx/utils';
132
148
 
133
149
  type RemainingAccountParams = {
134
150
  userAccounts: UserAccount[];
@@ -178,6 +194,9 @@ export class DriftClient {
178
194
 
179
195
  txHandler: TxHandler;
180
196
 
197
+ receiverProgram?: Program<PythSolanaReceiver>;
198
+ wormholeProgram?: Program<WormholeCoreBridgeSolana>;
199
+
181
200
  public get isSubscribed() {
182
201
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
183
202
  }
@@ -227,6 +246,7 @@ export class DriftClient {
227
246
  onSignedCb: this.handleSignedTransaction.bind(this),
228
247
  preSignedCb: this.handlePreSignedTransaction.bind(this),
229
248
  },
249
+ config: config.txHandlerConfig,
230
250
  });
231
251
 
232
252
  if (config.includeDelegates && config.subAccountIds) {
@@ -1800,25 +1820,14 @@ export class DriftClient {
1800
1820
  });
1801
1821
  }
1802
1822
 
1803
- /**
1804
- * Deposit funds into the given spot market
1805
- *
1806
- * @param amount to deposit
1807
- * @param marketIndex spot market index to deposit into
1808
- * @param associatedTokenAccount can be the wallet public key if using native sol
1809
- * @param subAccountId subaccountId to deposit
1810
- * @param reduceOnly if true, deposit must not increase account risk
1811
- */
1812
- public async deposit(
1823
+ public async createDepositTxn(
1813
1824
  amount: BN,
1814
1825
  marketIndex: number,
1815
1826
  associatedTokenAccount: PublicKey,
1816
1827
  subAccountId?: number,
1817
1828
  reduceOnly = false,
1818
1829
  txParams?: TxParams
1819
- ): Promise<TransactionSignature> {
1820
- const additionalSigners: Array<Signer> = [];
1821
-
1830
+ ): Promise<ReturnType<typeof this.buildTransaction>> {
1822
1831
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
1823
1832
 
1824
1833
  const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
@@ -1868,11 +1877,36 @@ export class DriftClient {
1868
1877
 
1869
1878
  const tx = await this.buildTransaction(instructions, txParams);
1870
1879
 
1871
- const { txSig, slot } = await this.sendTransaction(
1872
- tx,
1873
- additionalSigners,
1874
- this.opts
1880
+ return tx;
1881
+ }
1882
+
1883
+ /**
1884
+ * Deposit funds into the given spot market
1885
+ *
1886
+ * @param amount to deposit
1887
+ * @param marketIndex spot market index to deposit into
1888
+ * @param associatedTokenAccount can be the wallet public key if using native sol
1889
+ * @param subAccountId subaccountId to deposit
1890
+ * @param reduceOnly if true, deposit must not increase account risk
1891
+ */
1892
+ public async deposit(
1893
+ amount: BN,
1894
+ marketIndex: number,
1895
+ associatedTokenAccount: PublicKey,
1896
+ subAccountId?: number,
1897
+ reduceOnly = false,
1898
+ txParams?: TxParams
1899
+ ): Promise<TransactionSignature> {
1900
+ const tx = await this.createDepositTxn(
1901
+ amount,
1902
+ marketIndex,
1903
+ associatedTokenAccount,
1904
+ subAccountId,
1905
+ reduceOnly,
1906
+ txParams
1875
1907
  );
1908
+
1909
+ const { txSig, slot } = await this.sendTransaction(tx, [], this.opts);
1876
1910
  this.spotMarketLastSlotCache.set(marketIndex, slot);
1877
1911
  return txSig;
1878
1912
  }
@@ -2005,20 +2039,7 @@ export class DriftClient {
2005
2039
  );
2006
2040
  }
2007
2041
 
2008
- /**
2009
- * Creates the User account for a user, and deposits some initial collateral
2010
- * @param amount
2011
- * @param userTokenAccount
2012
- * @param marketIndex
2013
- * @param subAccountId
2014
- * @param name
2015
- * @param fromSubAccountId
2016
- * @param referrerInfo
2017
- * @param donateAmount
2018
- * @param txParams
2019
- * @returns
2020
- */
2021
- public async initializeUserAccountAndDepositCollateral(
2042
+ public async createInitializeUserAccountAndDepositCollateral(
2022
2043
  amount: BN,
2023
2044
  userTokenAccount: PublicKey,
2024
2045
  marketIndex = 0,
@@ -2029,7 +2050,7 @@ export class DriftClient {
2029
2050
  donateAmount?: BN,
2030
2051
  txParams?: TxParams,
2031
2052
  customMaxMarginRatio?: number
2032
- ): Promise<[TransactionSignature, PublicKey]> {
2053
+ ): Promise<[Transaction | VersionedTransaction, PublicKey]> {
2033
2054
  const ixs = [];
2034
2055
 
2035
2056
  const [userAccountPublicKey, initializeUserAccountIx] =
@@ -2039,8 +2060,6 @@ export class DriftClient {
2039
2060
  referrerInfo
2040
2061
  );
2041
2062
 
2042
- const additionalSigners: Array<Signer> = [];
2043
-
2044
2063
  const spotMarket = this.getSpotMarketAccount(marketIndex);
2045
2064
 
2046
2065
  const isSolMarket = spotMarket.mint.equals(WRAPPED_SOL_MINT);
@@ -2134,6 +2153,49 @@ export class DriftClient {
2134
2153
 
2135
2154
  const tx = await this.buildTransaction(ixs, txParams);
2136
2155
 
2156
+ return [tx, userAccountPublicKey];
2157
+ }
2158
+
2159
+ /**
2160
+ * Creates the User account for a user, and deposits some initial collateral
2161
+ * @param amount
2162
+ * @param userTokenAccount
2163
+ * @param marketIndex
2164
+ * @param subAccountId
2165
+ * @param name
2166
+ * @param fromSubAccountId
2167
+ * @param referrerInfo
2168
+ * @param donateAmount
2169
+ * @param txParams
2170
+ * @returns
2171
+ */
2172
+ public async initializeUserAccountAndDepositCollateral(
2173
+ amount: BN,
2174
+ userTokenAccount: PublicKey,
2175
+ marketIndex = 0,
2176
+ subAccountId = 0,
2177
+ name?: string,
2178
+ fromSubAccountId?: number,
2179
+ referrerInfo?: ReferrerInfo,
2180
+ donateAmount?: BN,
2181
+ txParams?: TxParams,
2182
+ customMaxMarginRatio?: number
2183
+ ): Promise<[TransactionSignature, PublicKey]> {
2184
+ const [tx, userAccountPublicKey] =
2185
+ await this.createInitializeUserAccountAndDepositCollateral(
2186
+ amount,
2187
+ userTokenAccount,
2188
+ marketIndex,
2189
+ subAccountId,
2190
+ name,
2191
+ fromSubAccountId,
2192
+ referrerInfo,
2193
+ donateAmount,
2194
+ txParams,
2195
+ customMaxMarginRatio
2196
+ );
2197
+ const additionalSigners: Array<Signer> = [];
2198
+
2137
2199
  const { txSig, slot } = await this.sendTransaction(
2138
2200
  tx,
2139
2201
  additionalSigners,
@@ -4118,6 +4180,10 @@ export class DriftClient {
4118
4180
  const outMarket = this.getSpotMarketAccount(outMarketIndex);
4119
4181
  const inMarket = this.getSpotMarketAccount(inMarketIndex);
4120
4182
 
4183
+ const isExactOut = swapMode === 'ExactOut' || quote.swapMode === 'ExactOut';
4184
+ const amountIn = new BN(quote.inAmount);
4185
+ const exactOutBufferedAmountIn = amountIn.muln(1001).divn(1000); // Add 10bp buffer
4186
+
4121
4187
  if (!quote) {
4122
4188
  const fetchedQuote = await jupiterClient.getQuote({
4123
4189
  inputMint: inMarket.mint,
@@ -4198,7 +4264,7 @@ export class DriftClient {
4198
4264
  const { beginSwapIx, endSwapIx } = await this.getSwapIx({
4199
4265
  outMarketIndex,
4200
4266
  inMarketIndex,
4201
- amountIn: new BN(quote.inAmount),
4267
+ amountIn: isExactOut ? exactOutBufferedAmountIn : amountIn,
4202
4268
  inTokenAccount: inAssociatedTokenAccount,
4203
4269
  outTokenAccount: outAssociatedTokenAccount,
4204
4270
  reduceOnly,
@@ -6844,6 +6910,250 @@ export class DriftClient {
6844
6910
  return undefined;
6845
6911
  }
6846
6912
 
6913
+ public getReceiverProgram(): Program<PythSolanaReceiver> {
6914
+ if (this.receiverProgram === undefined) {
6915
+ this.receiverProgram = new Program(
6916
+ pythSolanaReceiverIdl,
6917
+ DEFAULT_RECEIVER_PROGRAM_ID,
6918
+ this.provider
6919
+ );
6920
+ }
6921
+ return this.receiverProgram;
6922
+ }
6923
+
6924
+ public async postPythPullOracleUpdateAtomic(
6925
+ vaaString: string,
6926
+ feedId: string
6927
+ ): Promise<TransactionSignature> {
6928
+ const postIxs = await this.getPostPythPullOracleUpdateAtomicIxs(
6929
+ vaaString,
6930
+ feedId
6931
+ );
6932
+ const tx = await this.buildTransaction(postIxs);
6933
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
6934
+
6935
+ return txSig;
6936
+ }
6937
+
6938
+ public async getPostPythPullOracleUpdateAtomicIxs(
6939
+ vaaString: string,
6940
+ feedId: string,
6941
+ numSignatures = 2
6942
+ ): Promise<TransactionInstruction[]> {
6943
+ feedId = trimFeedId(feedId);
6944
+ const accumulatorUpdateData = parseAccumulatorUpdateData(
6945
+ Buffer.from(vaaString, 'base64')
6946
+ );
6947
+ const guardianSetIndex = accumulatorUpdateData.vaa.readUInt32BE(1);
6948
+ const guardianSet = getGuardianSetPda(
6949
+ guardianSetIndex,
6950
+ DEFAULT_WORMHOLE_PROGRAM_ID
6951
+ );
6952
+ const trimmedVaa = trimVaaSignatures(
6953
+ accumulatorUpdateData.vaa,
6954
+ numSignatures
6955
+ );
6956
+
6957
+ const postIxs: TransactionInstruction[] = [];
6958
+ for (const update of accumulatorUpdateData.updates) {
6959
+ postIxs.push(
6960
+ await this.getSinglePostPythPullOracleAtomicIx(
6961
+ {
6962
+ vaa: trimmedVaa,
6963
+ merklePriceUpdate: update,
6964
+ },
6965
+ feedId,
6966
+ guardianSet
6967
+ )
6968
+ );
6969
+ }
6970
+
6971
+ return postIxs;
6972
+ }
6973
+
6974
+ public async getSinglePostPythPullOracleAtomicIx(
6975
+ params: {
6976
+ vaa: Buffer;
6977
+ merklePriceUpdate: {
6978
+ message: Buffer;
6979
+ proof: number[][];
6980
+ };
6981
+ },
6982
+ feedId: string,
6983
+ guardianSet: PublicKey
6984
+ ): Promise<TransactionInstruction> {
6985
+ const feedIdBuffer = getFeedIdUint8Array(feedId);
6986
+ const receiverProgram = this.getReceiverProgram();
6987
+
6988
+ const encodedParams = receiverProgram.coder.types.encode(
6989
+ 'PostUpdateAtomicParams',
6990
+ params
6991
+ );
6992
+
6993
+ return this.program.instruction.postPythPullOracleUpdateAtomic(
6994
+ feedIdBuffer,
6995
+ encodedParams,
6996
+ {
6997
+ accounts: {
6998
+ keeper: this.wallet.publicKey,
6999
+ pythSolanaReceiver: DRIFT_ORACLE_RECEIVER_ID,
7000
+ guardianSet,
7001
+ priceFeed: getPythPullOraclePublicKey(
7002
+ this.program.programId,
7003
+ feedIdBuffer
7004
+ ),
7005
+ },
7006
+ }
7007
+ );
7008
+ }
7009
+
7010
+ public async updatePythPullOracle(
7011
+ vaaString: string,
7012
+ feedId: string
7013
+ ): Promise<TransactionSignature> {
7014
+ feedId = trimFeedId(feedId);
7015
+ const accumulatorUpdateData = parseAccumulatorUpdateData(
7016
+ Buffer.from(vaaString, 'base64')
7017
+ );
7018
+ const guardianSetIndex = accumulatorUpdateData.vaa.readUInt32BE(1);
7019
+ const guardianSet = getGuardianSetPda(
7020
+ guardianSetIndex,
7021
+ DEFAULT_WORMHOLE_PROGRAM_ID
7022
+ );
7023
+
7024
+ const [postIxs, encodedVaaAddress] = await this.getBuildEncodedVaaIxs(
7025
+ accumulatorUpdateData.vaa,
7026
+ guardianSet
7027
+ );
7028
+
7029
+ for (const update of accumulatorUpdateData.updates) {
7030
+ postIxs.push(
7031
+ await this.getUpdatePythPullOracleIxs(
7032
+ {
7033
+ merklePriceUpdate: update,
7034
+ },
7035
+ feedId,
7036
+ encodedVaaAddress.publicKey
7037
+ )
7038
+ );
7039
+ }
7040
+
7041
+ const tx = await this.buildTransaction(postIxs);
7042
+ const { txSig } = await this.sendTransaction(
7043
+ tx,
7044
+ [encodedVaaAddress],
7045
+ this.opts
7046
+ );
7047
+
7048
+ return txSig;
7049
+ }
7050
+
7051
+ public async getUpdatePythPullOracleIxs(
7052
+ params: {
7053
+ merklePriceUpdate: {
7054
+ message: Buffer;
7055
+ proof: number[][];
7056
+ };
7057
+ },
7058
+ feedId: string,
7059
+ encodedVaaAddress: PublicKey
7060
+ ): Promise<TransactionInstruction> {
7061
+ const feedIdBuffer = getFeedIdUint8Array(feedId);
7062
+ const receiverProgram = this.getReceiverProgram();
7063
+
7064
+ const encodedParams = receiverProgram.coder.types.encode(
7065
+ 'PostUpdateParams',
7066
+ params
7067
+ );
7068
+
7069
+ return this.program.instruction.updatePythPullOracle(
7070
+ feedIdBuffer,
7071
+ encodedParams,
7072
+ {
7073
+ accounts: {
7074
+ keeper: this.wallet.publicKey,
7075
+ pythSolanaReceiver: DRIFT_ORACLE_RECEIVER_ID,
7076
+ encodedVaa: encodedVaaAddress,
7077
+ priceFeed: getPythPullOraclePublicKey(
7078
+ this.program.programId,
7079
+ feedIdBuffer
7080
+ ),
7081
+ },
7082
+ }
7083
+ );
7084
+ }
7085
+
7086
+ public async getBuildEncodedVaaIxs(
7087
+ vaa: Buffer,
7088
+ guardianSet: PublicKey
7089
+ ): Promise<[TransactionInstruction[], Keypair]> {
7090
+ const postIxs: TransactionInstruction[] = [];
7091
+
7092
+ if (this.wormholeProgram === undefined) {
7093
+ this.wormholeProgram = new Program(
7094
+ wormholeCoreBridgeIdl,
7095
+ DEFAULT_WORMHOLE_PROGRAM_ID,
7096
+ this.provider
7097
+ );
7098
+ }
7099
+
7100
+ const encodedVaaKeypair = new Keypair();
7101
+ postIxs.push(
7102
+ await this.wormholeProgram.account.encodedVaa.createInstruction(
7103
+ encodedVaaKeypair,
7104
+ vaa.length + 46
7105
+ )
7106
+ );
7107
+
7108
+ // Why do we need this too?
7109
+ postIxs.push(
7110
+ await this.wormholeProgram.methods
7111
+ .initEncodedVaa()
7112
+ .accounts({
7113
+ encodedVaa: encodedVaaKeypair.publicKey,
7114
+ })
7115
+ .instruction()
7116
+ );
7117
+
7118
+ // Split the write into two ixs
7119
+ postIxs.push(
7120
+ await this.wormholeProgram.methods
7121
+ .writeEncodedVaa({
7122
+ index: 0,
7123
+ data: vaa.subarray(0, 755),
7124
+ })
7125
+ .accounts({
7126
+ draftVaa: encodedVaaKeypair.publicKey,
7127
+ })
7128
+ .instruction()
7129
+ );
7130
+
7131
+ postIxs.push(
7132
+ await this.wormholeProgram.methods
7133
+ .writeEncodedVaa({
7134
+ index: 755,
7135
+ data: vaa.subarray(755),
7136
+ })
7137
+ .accounts({
7138
+ draftVaa: encodedVaaKeypair.publicKey,
7139
+ })
7140
+ .instruction()
7141
+ );
7142
+
7143
+ // Verify
7144
+ postIxs.push(
7145
+ await this.wormholeProgram.methods
7146
+ .verifyEncodedVaaV1()
7147
+ .accounts({
7148
+ guardianSet,
7149
+ draftVaa: encodedVaaKeypair.publicKey,
7150
+ })
7151
+ .instruction()
7152
+ );
7153
+
7154
+ return [postIxs, encodedVaaKeypair];
7155
+ }
7156
+
6847
7157
  private handleSignedTransaction(signedTxs: SignedTxData[]) {
6848
7158
  if (this.enableMetricsEvents && this.metricsEventEmitter) {
6849
7159
  this.metricsEventEmitter.emit('txSigned', signedTxs);
@@ -6859,11 +7169,7 @@ export class DriftClient {
6859
7169
  private isVersionedTransaction(
6860
7170
  tx: Transaction | VersionedTransaction
6861
7171
  ): boolean {
6862
- const version = (tx as VersionedTransaction)?.version;
6863
- const isVersionedTx =
6864
- tx instanceof VersionedTransaction || version !== undefined;
6865
-
6866
- return isVersionedTx;
7172
+ return isVersionedTransaction(tx);
6867
7173
  }
6868
7174
 
6869
7175
  sendTransaction(
@@ -10,7 +10,7 @@ import { OracleInfo } from './oracles/types';
10
10
  import { BulkAccountLoader } from './accounts/bulkAccountLoader';
11
11
  import { DriftEnv } from './config';
12
12
  import { TxSender } from './tx/types';
13
- import { TxHandler } from './tx/txHandler';
13
+ import { TxHandler, TxHandlerConfig } from './tx/txHandler';
14
14
 
15
15
  export type DriftClientConfig = {
16
16
  connection: Connection;
@@ -35,6 +35,7 @@ export type DriftClientConfig = {
35
35
  txVersion?: TransactionVersion; // which tx version to use
36
36
  txParams?: TxParams; // default tx params to use
37
37
  enableMetricsEvents?: boolean;
38
+ txHandlerConfig?: TxHandlerConfig;
38
39
  };
39
40
 
40
41
  export type DriftClientSubscriptionConfig =
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.84.0",
2
+ "version": "2.85.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -2547,6 +2547,86 @@
2547
2547
  }
2548
2548
  ]
2549
2549
  },
2550
+ {
2551
+ "name": "updatePythPullOracle",
2552
+ "accounts": [
2553
+ {
2554
+ "name": "keeper",
2555
+ "isMut": true,
2556
+ "isSigner": true
2557
+ },
2558
+ {
2559
+ "name": "pythSolanaReceiver",
2560
+ "isMut": false,
2561
+ "isSigner": false
2562
+ },
2563
+ {
2564
+ "name": "encodedVaa",
2565
+ "isMut": false,
2566
+ "isSigner": false
2567
+ },
2568
+ {
2569
+ "name": "priceFeed",
2570
+ "isMut": true,
2571
+ "isSigner": false
2572
+ }
2573
+ ],
2574
+ "args": [
2575
+ {
2576
+ "name": "feedId",
2577
+ "type": {
2578
+ "array": [
2579
+ "u8",
2580
+ 32
2581
+ ]
2582
+ }
2583
+ },
2584
+ {
2585
+ "name": "params",
2586
+ "type": "bytes"
2587
+ }
2588
+ ]
2589
+ },
2590
+ {
2591
+ "name": "postPythPullOracleUpdateAtomic",
2592
+ "accounts": [
2593
+ {
2594
+ "name": "keeper",
2595
+ "isMut": true,
2596
+ "isSigner": true
2597
+ },
2598
+ {
2599
+ "name": "pythSolanaReceiver",
2600
+ "isMut": false,
2601
+ "isSigner": false
2602
+ },
2603
+ {
2604
+ "name": "guardianSet",
2605
+ "isMut": false,
2606
+ "isSigner": false
2607
+ },
2608
+ {
2609
+ "name": "priceFeed",
2610
+ "isMut": true,
2611
+ "isSigner": false
2612
+ }
2613
+ ],
2614
+ "args": [
2615
+ {
2616
+ "name": "feedId",
2617
+ "type": {
2618
+ "array": [
2619
+ "u8",
2620
+ 32
2621
+ ]
2622
+ }
2623
+ },
2624
+ {
2625
+ "name": "params",
2626
+ "type": "bytes"
2627
+ }
2628
+ ]
2629
+ },
2550
2630
  {
2551
2631
  "name": "initialize",
2552
2632
  "accounts": [
@@ -5296,6 +5376,47 @@
5296
5376
  "type": "u16"
5297
5377
  }
5298
5378
  ]
5379
+ },
5380
+ {
5381
+ "name": "initializePythPullOracle",
5382
+ "accounts": [
5383
+ {
5384
+ "name": "admin",
5385
+ "isMut": true,
5386
+ "isSigner": true
5387
+ },
5388
+ {
5389
+ "name": "pythSolanaReceiver",
5390
+ "isMut": false,
5391
+ "isSigner": false
5392
+ },
5393
+ {
5394
+ "name": "priceFeed",
5395
+ "isMut": true,
5396
+ "isSigner": false
5397
+ },
5398
+ {
5399
+ "name": "systemProgram",
5400
+ "isMut": false,
5401
+ "isSigner": false
5402
+ },
5403
+ {
5404
+ "name": "state",
5405
+ "isMut": false,
5406
+ "isSigner": false
5407
+ }
5408
+ ],
5409
+ "args": [
5410
+ {
5411
+ "name": "feedId",
5412
+ "type": {
5413
+ "array": [
5414
+ "u8",
5415
+ 32
5416
+ ]
5417
+ }
5418
+ }
5419
+ ]
5299
5420
  }
5300
5421
  ],
5301
5422
  "accounts": [
@@ -12029,6 +12150,44 @@
12029
12150
  "code": 6268,
12030
12151
  "name": "MaxBorrows",
12031
12152
  "msg": "Can not borow more than max borrows"
12153
+ },
12154
+ {
12155
+ "code": 6269,
12156
+ "name": "OracleUpdatesNotMonotonic",
12157
+ "msg": "Updates must be monotonically increasing"
12158
+ },
12159
+ {
12160
+ "code": 6270,
12161
+ "name": "OraclePriceFeedMessageMismatch",
12162
+ "msg": "Trying to update price feed with the wrong feed id"
12163
+ },
12164
+ {
12165
+ "code": 6271,
12166
+ "name": "OracleUnsupportedMessageType",
12167
+ "msg": "The message in the update must be a PriceFeedMessage"
12168
+ },
12169
+ {
12170
+ "code": 6272,
12171
+ "name": "OracleDeserializeMessageFailed",
12172
+ "msg": "Could not deserialize the message in the update"
12173
+ },
12174
+ {
12175
+ "code": 6273,
12176
+ "name": "OracleWrongGuardianSetOwner",
12177
+ "msg": "Wrong guardian set owner in update price atomic"
12178
+ },
12179
+ {
12180
+ "code": 6274,
12181
+ "name": "OracleWrongWriteAuthority",
12182
+ "msg": "Oracle post update atomic price feed account must be drift program"
12183
+ },
12184
+ {
12185
+ "code": 6275,
12186
+ "name": "OracleWrongVaaOwner",
12187
+ "msg": "Oracle vaa owner must be wormhole program"
12032
12188
  }
12033
- ]
12189
+ ],
12190
+ "metadata": {
12191
+ "address": "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
12192
+ }
12034
12193
  }
@@ -209,3 +209,20 @@ export function getNewOracleConfPct(
209
209
 
210
210
  return confIntervalPctResult;
211
211
  }
212
+
213
+ export function trimVaaSignatures(vaa: Buffer, n = 3): Buffer {
214
+ const currentNumSignatures = vaa[5];
215
+ if (n > currentNumSignatures) {
216
+ throw new Error(
217
+ "Resulting VAA can't have more signatures than the original VAA"
218
+ );
219
+ }
220
+
221
+ const trimmedVaa = Buffer.concat([
222
+ vaa.subarray(0, 6 + n * 66),
223
+ vaa.subarray(6 + currentNumSignatures * 66),
224
+ ]);
225
+
226
+ trimmedVaa[5] = n;
227
+ return trimmedVaa;
228
+ }