Tejas Badadare 11 月之前
父節點
當前提交
b2e493367d

+ 54 - 77
pnpm-lock.yaml

@@ -988,7 +988,7 @@ importers:
         version: 5.0.0(ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))
       openapi-client-axios:
         specifier: ^7.5.5
-        version: 7.5.5(axios@1.7.7)(js-yaml@4.1.0)
+        version: 7.5.5(axios@1.7.8)(js-yaml@4.1.0)
       openapi-fetch:
         specifier: ^0.8.2
         version: 0.8.2
@@ -2437,14 +2437,20 @@ importers:
         specifier: ^1.4.0
         version: 1.4.0
       '@pythnetwork/price-service-sdk':
-        specifier: '>=1.6.0'
-        version: 1.7.1
+        specifier: workspace:*
+        version: link:../../../../../price_service/sdk/js
+      '@pythnetwork/pyth-solana-receiver':
+        specifier: 'link:'
+        version: 'link:'
       '@pythnetwork/solana-utils':
         specifier: workspace:*
         version: link:../solana_utils
       '@solana/web3.js':
         specifier: 1.92.3
         version: 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)
+      axios:
+        specifier: ^1.7.8
+        version: 1.7.8(debug@4.3.6)
     devDependencies:
       '@pythnetwork/hermes-client':
         specifier: workspace:*
@@ -11770,17 +11776,14 @@ packages:
   axios@1.6.8:
     resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==}
 
-  axios@1.7.2:
-    resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==}
-
   axios@1.7.3:
     resolution: {integrity: sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==}
 
   axios@1.7.4:
     resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==}
 
-  axios@1.7.7:
-    resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==}
+  axios@1.7.8:
+    resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==}
 
   axobject-query@3.2.1:
     resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==}
@@ -14961,10 +14964,6 @@ packages:
     resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==}
     engines: {node: '>= 0.12'}
 
-  form-data@3.0.1:
-    resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
-    engines: {node: '>= 6'}
-
   form-data@3.0.2:
     resolution: {integrity: sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==}
     engines: {node: '>= 6'}
@@ -28290,7 +28289,7 @@ snapshots:
       '@cosmjs/socket': 0.30.1(bufferutil@4.0.7)(utf-8-validate@5.0.10)
       '@cosmjs/stream': 0.30.1
       '@cosmjs/utils': 0.30.1
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       readonly-date: 1.0.0
       xstream: 11.14.0
     transitivePeerDependencies:
@@ -28308,7 +28307,7 @@ snapshots:
       '@cosmjs/socket': 0.30.1(bufferutil@4.0.7)(utf-8-validate@6.0.3)
       '@cosmjs/stream': 0.30.1
       '@cosmjs/utils': 0.30.1
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       readonly-date: 1.0.0
       xstream: 11.14.0
     transitivePeerDependencies:
@@ -28326,7 +28325,7 @@ snapshots:
       '@cosmjs/socket': 0.30.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)
       '@cosmjs/stream': 0.30.1
       '@cosmjs/utils': 0.30.1
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       readonly-date: 1.0.0
       xstream: 11.14.0
     transitivePeerDependencies:
@@ -28343,7 +28342,7 @@ snapshots:
       '@cosmjs/socket': 0.30.1(bufferutil@4.0.8)(utf-8-validate@6.0.4)
       '@cosmjs/stream': 0.30.1
       '@cosmjs/utils': 0.30.1
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       readonly-date: 1.0.0
       xstream: 11.14.0
     transitivePeerDependencies:
@@ -28361,7 +28360,7 @@ snapshots:
       '@cosmjs/socket': 0.32.3(bufferutil@4.0.7)(utf-8-validate@5.0.10)
       '@cosmjs/stream': 0.32.3
       '@cosmjs/utils': 0.32.3
-      axios: 1.7.4
+      axios: 1.7.8(debug@4.3.6)
       readonly-date: 1.0.0
       xstream: 11.14.0
     transitivePeerDependencies:
@@ -30929,7 +30928,7 @@ snapshots:
 
   '@injectivelabs/test-utils@1.14.4':
     dependencies:
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       bignumber.js: 9.1.2
       link-module-alias: 1.2.0
       shx: 0.3.4
@@ -30998,7 +30997,7 @@ snapshots:
     dependencies:
       '@injectivelabs/exceptions': 1.14.6(google-protobuf@3.21.2)
       '@injectivelabs/ts-types': 1.14.6
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       bignumber.js: 9.1.2
       http-status-codes: 2.2.0
       link-module-alias: 1.2.0
@@ -31014,7 +31013,7 @@ snapshots:
     dependencies:
       '@injectivelabs/exceptions': 1.14.6(google-protobuf@3.21.4)
       '@injectivelabs/ts-types': 1.14.6
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       bignumber.js: 9.1.2
       http-status-codes: 2.2.0
       link-module-alias: 1.2.0
@@ -31030,7 +31029,7 @@ snapshots:
     dependencies:
       '@injectivelabs/exceptions': 1.14.6(google-protobuf@3.21.2)
       '@injectivelabs/ts-types': 1.14.6
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       bignumber.js: 9.1.2
       http-status-codes: 2.2.0
       link-module-alias: 1.2.0
@@ -31045,7 +31044,7 @@ snapshots:
     dependencies:
       '@injectivelabs/exceptions': 1.14.6(google-protobuf@3.21.4)
       '@injectivelabs/ts-types': 1.14.6
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       bignumber.js: 9.1.2
       http-status-codes: 2.2.0
       link-module-alias: 1.2.0
@@ -31989,7 +31988,7 @@ snapshots:
   '@json-rpc-tools/provider@1.7.6(bufferutil@4.0.8)(utf-8-validate@5.0.10)':
     dependencies:
       '@json-rpc-tools/utils': 1.7.6
-      axios: 0.21.4
+      axios: 0.21.4(debug@4.3.6)
       safe-json-utils: 1.1.1
       ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)
     transitivePeerDependencies:
@@ -32340,7 +32339,7 @@ snapshots:
   '@matterlabs/hardhat-zksync-node@1.1.1(encoding@0.1.13)(hardhat@2.22.8(bufferutil@4.0.7)(ts-node@10.9.2(@types/node@22.8.2)(typescript@4.9.5))(typescript@4.9.5)(utf-8-validate@6.0.3))':
     dependencies:
       '@matterlabs/hardhat-zksync-solc': 1.2.5(encoding@0.1.13)(hardhat@2.22.8(bufferutil@4.0.7)(ts-node@10.9.2(@types/node@22.8.2)(typescript@4.9.5))(typescript@4.9.5)(utf-8-validate@6.0.3))
-      axios: 1.7.7(debug@4.3.7)
+      axios: 1.7.8(debug@4.3.6)
       chai: 4.5.0
       chalk: 4.1.2
       fs-extra: 11.2.0
@@ -32444,7 +32443,7 @@ snapshots:
       '@ethersproject/address': 5.7.0
       '@matterlabs/hardhat-zksync-solc': 1.2.5(encoding@0.1.13)(hardhat@2.22.8(bufferutil@4.0.7)(ts-node@10.9.2(@types/node@22.8.2)(typescript@4.9.5))(typescript@4.9.5)(utf-8-validate@6.0.3))
       '@nomicfoundation/hardhat-verify': 2.0.9(hardhat@2.22.8(bufferutil@4.0.7)(ts-node@10.9.2(@types/node@22.8.2)(typescript@4.9.5))(typescript@4.9.5)(utf-8-validate@6.0.3))
-      axios: 1.7.7(debug@4.3.7)
+      axios: 1.7.8(debug@4.3.7)
       cbor: 9.0.2
       chai: 4.5.0
       chalk: 4.1.2
@@ -33567,7 +33566,7 @@ snapshots:
     dependencies:
       amazon-cognito-identity-js: 6.3.12(encoding@0.1.13)
       async-retry: 1.3.3
-      axios: 1.7.4(debug@4.3.6)
+      axios: 1.7.8(debug@4.3.6)
       lodash: 4.17.21
       node-fetch: 2.7.0(encoding@0.1.13)
     transitivePeerDependencies:
@@ -33981,7 +33980,7 @@ snapshots:
     dependencies:
       '@pythnetwork/price-service-sdk': 1.7.1
       '@types/ws': 8.5.13
-      axios: 1.7.2
+      axios: 1.7.8(debug@4.3.6)
       axios-retry: 3.9.1
       isomorphic-ws: 4.0.1(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4))
       ts-log: 2.2.5
@@ -42805,40 +42804,34 @@ snapshots:
       axios: 1.6.8
       is-retry-allowed: 2.2.0
 
-  axios@0.21.4:
-    dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
-    transitivePeerDependencies:
-      - debug
-
   axios@0.21.4(debug@4.3.6):
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.6)
+      follow-redirects: 1.15.9(debug@4.3.6)
     transitivePeerDependencies:
       - debug
 
   axios@0.24.0:
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
+      follow-redirects: 1.15.6
     transitivePeerDependencies:
       - debug
 
   axios@0.25.0:
     dependencies:
-      follow-redirects: 1.15.9(debug@4.3.7)
+      follow-redirects: 1.15.9(debug@4.3.6)
     transitivePeerDependencies:
       - debug
 
   axios@0.26.1:
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
+      follow-redirects: 1.15.9(debug@4.3.6)
     transitivePeerDependencies:
       - debug
 
   axios@0.27.2:
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
-      form-data: 4.0.0
+      follow-redirects: 1.15.9(debug@4.3.6)
+      form-data: 4.0.1
     transitivePeerDependencies:
       - debug
 
@@ -42852,23 +42845,15 @@ snapshots:
 
   axios@1.6.0:
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
-      form-data: 4.0.0
+      follow-redirects: 1.15.9(debug@4.3.6)
+      form-data: 4.0.1
       proxy-from-env: 1.1.0
     transitivePeerDependencies:
       - debug
 
   axios@1.6.8:
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
-      form-data: 4.0.0
-      proxy-from-env: 1.1.0
-    transitivePeerDependencies:
-      - debug
-
-  axios@1.7.2:
-    dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
+      follow-redirects: 1.15.6
       form-data: 4.0.0
       proxy-from-env: 1.1.0
     transitivePeerDependencies:
@@ -42876,29 +42861,29 @@ snapshots:
 
   axios@1.7.3:
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
-      form-data: 4.0.0
+      follow-redirects: 1.15.9(debug@4.3.6)
+      form-data: 4.0.1
       proxy-from-env: 1.1.0
     transitivePeerDependencies:
       - debug
 
   axios@1.7.4:
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.7)
-      form-data: 4.0.0
+      follow-redirects: 1.15.9(debug@4.3.6)
+      form-data: 4.0.1
       proxy-from-env: 1.1.0
     transitivePeerDependencies:
       - debug
 
-  axios@1.7.4(debug@4.3.6):
+  axios@1.7.8(debug@4.3.6):
     dependencies:
-      follow-redirects: 1.15.6(debug@4.3.6)
-      form-data: 4.0.0
+      follow-redirects: 1.15.9(debug@4.3.6)
+      form-data: 4.0.1
       proxy-from-env: 1.1.0
     transitivePeerDependencies:
       - debug
 
-  axios@1.7.7(debug@4.3.7):
+  axios@1.7.8(debug@4.3.7):
     dependencies:
       follow-redirects: 1.15.9(debug@4.3.7)
       form-data: 4.0.1
@@ -47787,13 +47772,11 @@ snapshots:
 
   flow-parser@0.250.0: {}
 
-  follow-redirects@1.15.6(debug@4.3.6):
-    optionalDependencies:
-      debug: 4.3.6
+  follow-redirects@1.15.6: {}
 
-  follow-redirects@1.15.6(debug@4.3.7):
+  follow-redirects@1.15.9(debug@4.3.6):
     optionalDependencies:
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.6
 
   follow-redirects@1.15.9(debug@4.3.7):
     optionalDependencies:
@@ -47862,12 +47845,6 @@ snapshots:
       combined-stream: 1.0.8
       mime-types: 2.1.35
 
-  form-data@3.0.1:
-    dependencies:
-      asynckit: 0.4.0
-      combined-stream: 1.0.8
-      mime-types: 2.1.35
-
   form-data@3.0.2:
     dependencies:
       asynckit: 0.4.0
@@ -48491,7 +48468,7 @@ snapshots:
       '@graphql-typed-document-node/core': 3.2.0(graphql@16.9.0)
       cross-fetch: 3.1.8(encoding@0.1.13)
       extract-files: 9.0.0
-      form-data: 3.0.1
+      form-data: 3.0.2
       graphql: 16.9.0
     transitivePeerDependencies:
       - encoding
@@ -54049,7 +54026,7 @@ snapshots:
       '@yarnpkg/lockfile': 1.1.0
       '@yarnpkg/parsers': 3.0.0-rc.46
       '@zkochan/js-yaml': 0.0.7
-      axios: 1.7.7(debug@4.3.7)
+      axios: 1.7.8(debug@4.3.6)
       chalk: 4.1.2
       cli-cursor: 3.1.0
       cli-spinners: 2.6.1
@@ -54270,9 +54247,9 @@ snapshots:
       is-docker: 2.2.1
       is-wsl: 2.2.0
 
-  openapi-client-axios@7.5.5(axios@1.7.7)(js-yaml@4.1.0):
+  openapi-client-axios@7.5.5(axios@1.7.8)(js-yaml@4.1.0):
     dependencies:
-      axios: 1.7.7(debug@4.3.7)
+      axios: 1.7.8(debug@4.3.6)
       bath-es5: 3.0.3
       dereference-json-schema: 0.2.1
       js-yaml: 4.1.0
@@ -57301,7 +57278,7 @@ snapshots:
     dependencies:
       command-exists: 1.2.9
       commander: 8.3.0
-      follow-redirects: 1.15.6(debug@4.3.7)
+      follow-redirects: 1.15.6
       js-sha3: 0.8.0
       memorystream: 0.3.1
       semver: 5.7.2
@@ -57313,7 +57290,7 @@ snapshots:
     dependencies:
       command-exists: 1.2.9
       commander: 8.3.0
-      follow-redirects: 1.15.6(debug@4.3.6)
+      follow-redirects: 1.15.9(debug@4.3.6)
       js-sha3: 0.8.0
       memorystream: 0.3.1
       semver: 5.7.2
@@ -57325,7 +57302,7 @@ snapshots:
     dependencies:
       command-exists: 1.2.9
       commander: 8.3.0
-      follow-redirects: 1.15.6(debug@4.3.7)
+      follow-redirects: 1.15.9(debug@4.3.7)
       js-sha3: 0.8.0
       memorystream: 0.3.1
       semver: 5.7.2
@@ -57337,7 +57314,7 @@ snapshots:
     dependencies:
       command-exists: 1.2.9
       commander: 3.0.2
-      follow-redirects: 1.15.6(debug@4.3.7)
+      follow-redirects: 1.15.6
       fs-extra: 0.30.0
       js-sha3: 0.8.0
       memorystream: 0.3.1

+ 2 - 1
price_service/sdk/js/package.json

@@ -24,7 +24,8 @@
     "test:lint": "eslint src/",
     "prepublishOnly": "pnpm run build && pnpm test:unit && pnpm run test:lint",
     "preversion": "pnpm run test:lint",
-    "version": "pnpm run format && git add -A src"
+    "version": "pnpm run format && git add -A src",
+    "driver": "pnpm exec ts-node driver.ts"
   },
   "keywords": [
     "pyth",

文件差異過大導致無法顯示
+ 32 - 0
target_chains/solana/sdk/js/pyth_solana_receiver/examples/post_twap_update.ts


+ 6 - 3
target_chains/solana/sdk/js/pyth_solana_receiver/package.json

@@ -22,7 +22,8 @@
     "test:lint": "eslint src/",
     "prepublishOnly": "pnpm run build && pnpm test:lint",
     "preversion": "pnpm run test:lint",
-    "version": "pnpm run format && git add -A src"
+    "version": "pnpm run format && git add -A src",
+    "driver": "ts-node test_twap.ts"
   },
   "keywords": [
     "pyth",
@@ -45,8 +46,10 @@
   "dependencies": {
     "@coral-xyz/anchor": "^0.29.0",
     "@noble/hashes": "^1.4.0",
-    "@pythnetwork/price-service-sdk": ">=1.6.0",
+    "@pythnetwork/price-service-sdk": "workspace:*",
+    "@pythnetwork/pyth-solana-receiver": "link:",
     "@pythnetwork/solana-utils": "workspace:*",
-    "@solana/web3.js": "^1.90.0"
+    "@solana/web3.js": "^1.90.0",
+    "axios": "^1.7.8"
   }
 }

+ 113 - 0
target_chains/solana/sdk/js/pyth_solana_receiver/src/PythSolanaReceiver.ts

@@ -98,6 +98,7 @@ export class PythTransactionBuilder extends TransactionBuilder {
   readonly pythSolanaReceiver: PythSolanaReceiver;
   readonly closeInstructions: InstructionWithEphemeralSigners[];
   readonly priceFeedIdToPriceUpdateAccount: Record<string, PublicKey>;
+  readonly priceFeedIdToTwapUpdateAccount: Record<string, PublicKey>;
   readonly closeUpdateAccounts: boolean;
 
   constructor(
@@ -113,6 +114,7 @@ export class PythTransactionBuilder extends TransactionBuilder {
     this.pythSolanaReceiver = pythSolanaReceiver;
     this.closeInstructions = [];
     this.priceFeedIdToPriceUpdateAccount = {};
+    this.priceFeedIdToTwapUpdateAccount = {};
     this.closeUpdateAccounts = config.closeUpdateAccounts ?? true;
   }
 
@@ -230,6 +232,22 @@ export class PythTransactionBuilder extends TransactionBuilder {
     this.addInstructions(postInstructions);
   }
 
+  async addPostTwapUpdates(twapUpdateDataArray: string[]) {
+    const {
+      postInstructions,
+      priceFeedIdToTwapUpdateAccount,
+      closeInstructions,
+    } = await this.pythSolanaReceiver.buildPostTwapUpdateInstructions(
+      priceUpdateDataArray
+    );
+    this.closeInstructions.push(...closeInstructions);
+    Object.assign(
+      this.priceFeedIdToTwapUpdateAccount,
+      priceFeedIdToTwapUpdateAccount
+    );
+    this.addInstructions(postInstructions);
+  }
+
   /**
    * Add instructions that consume price updates to the builder.
    *
@@ -320,6 +338,20 @@ export class PythTransactionBuilder extends TransactionBuilder {
     }
     return priceUpdateAccount;
   }
+
+  /**
+   * This method is used to retrieve the address of the TWAP update account where the TWAP update for a given price feed ID will be posted.
+   * If multiple TWAP updates for the same price feed ID will be posted with the same builder, the address of the account corresponding to the last update to get posted will be returned.
+   * */
+  getTwapUpdateAccount(priceFeedId: string): PublicKey {
+    const twapUpdateAccount = this.priceFeedIdToTwapUpdateAccount[priceFeedId];
+    if (!twapUpdateAccount) {
+      throw new Error(
+        `No TWAP update account found for the price feed ID ${priceFeedId}. Make sure to call addPostTwapUpdates before calling this function.`
+      );
+    }
+    return twapUpdateAccount;
+  }
 }
 
 /**
@@ -669,6 +701,87 @@ export class PythSolanaReceiver {
     };
   }
 
+  async buildPostTwapUpdateInstructions(
+    twapUpdateDataArray: string[]
+  ): Promise<{
+    postInstructions: InstructionWithEphemeralSigners[];
+    priceFeedIdToTwapUpdateAccount: Record<string, PublicKey>;
+    closeInstructions: InstructionWithEphemeralSigners[];
+  }> {
+    const postInstructions: InstructionWithEphemeralSigners[] = [];
+    const priceFeedIdToTwapUpdateAccount: Record<string, PublicKey> = {};
+    const closeInstructions: InstructionWithEphemeralSigners[] = [];
+    const treasuryId = getRandomTreasuryId();
+
+    const [startUpdate, endUpdate] = twapUpdateDataArray;
+    const startAccumulatorUpdateData = parseAccumulatorUpdateData(
+      Buffer.from(startUpdate, "base64")
+    );
+    const endAccumulatorUpdateData = parseAccumulatorUpdateData(
+      Buffer.from(endUpdate, "base64")
+    );
+
+    // Verify both start and end VAAs
+    const {
+      postInstructions: postStartEncodedVaaInstructions,
+      encodedVaaAddress: startEncodedVaa,
+      closeInstructions: postStartEncodedVaaCloseInstructions,
+    } = await this.buildPostEncodedVaaInstructions(
+      startAccumulatorUpdateData.vaa
+    );
+    const {
+      postInstructions: postEndEncodedVaaInstructions,
+      encodedVaaAddress: endEncodedVaa,
+      closeInstructions: postEndEncodedVaaCloseInstructions,
+    } = await this.buildPostEncodedVaaInstructions(
+      endAccumulatorUpdateData.vaa
+    );
+    postInstructions.push(...postStartEncodedVaaInstructions);
+    postInstructions.push(...postEndEncodedVaaInstructions);
+    closeInstructions.push(...postStartEncodedVaaCloseInstructions);
+    closeInstructions.push(...postEndEncodedVaaCloseInstructions);
+
+    // Post TWAP updates to receiver
+    for (let i = 0; i < startAccumulatorUpdateData.updates.length; i++) {
+      // Get start and end cumulative prices for price feed i
+      const startUpdate = startAccumulatorUpdateData.updates[i];
+      const endUpdate = endAccumulatorUpdateData.updates[i];
+
+      const twapUpdateKeypair = new Keypair();
+      postInstructions.push({
+        instruction: await this.receiver.methods
+          .postTwapUpdate({
+            startMerklePriceUpdate: startUpdate,
+            endMerklePriceUpdate: endUpdate,
+            treasuryId,
+          })
+          .accounts({
+            startEncodedVaa: startEncodedVaa,
+            endEncodedVaa: endEncodedVaa,
+            twapUpdateAccount: twapUpdateKeypair.publicKey,
+            treasury: getTreasuryPda(treasuryId, this.receiver.programId),
+            config: getConfigPda(this.receiver.programId),
+          })
+          .instruction(),
+        signers: [twapUpdateKeypair],
+        computeUnits: POST_UPDATE_COMPUTE_BUDGET,
+      });
+
+      priceFeedIdToTwapUpdateAccount[
+        "0x" + parsePriceFeedMessage(startUpdate.message).feedId.toString("hex")
+      ] = twapUpdateKeypair.publicKey;
+      closeInstructions.push(
+        await this.buildClosePriceUpdateInstruction(twapUpdateKeypair.publicKey)
+      );
+    }
+
+    return {
+      postInstructions,
+      priceFeedIdToTwapUpdateAccount,
+      closeInstructions,
+    };
+  }
+
   /**
    * Build an instruction to close an encoded VAA account, recovering the rent.
    */

文件差異過大導致無法顯示
+ 22 - 0
target_chains/solana/sdk/js/pyth_solana_receiver/test_sdk.ts


文件差異過大導致無法顯示
+ 33 - 0
target_chains/solana/sdk/js/pyth_solana_receiver/test_twap.ts


部分文件因文件數量過多而無法顯示