From 70eced347cf973d3e20965530d2cec7855284b2c Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Tue, 27 Aug 2024 11:36:25 +0200 Subject: [PATCH 1/9] feat: add InitPriceFeedIndex method IDL --- package-lock.json | 4 ++-- package.json | 2 +- src/anchor/idl.json | 36 ++++++++++++++++++++++++++++++++++++ src/anchor/program.ts | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index d9080fb..6211421 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@pythnetwork/client", - "version": "2.21.1", + "version": "2.22.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@pythnetwork/client", - "version": "2.21.1", + "version": "2.22.0", "license": "Apache-2.0", "dependencies": { "@coral-xyz/anchor": "^0.29.0", diff --git a/package.json b/package.json index e17962b..5af1a4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pythnetwork/client", - "version": "2.21.1", + "version": "2.22.0", "description": "Client for consuming Pyth price data", "homepage": "https://pyth.network", "main": "lib/index.js", diff --git a/src/anchor/idl.json b/src/anchor/idl.json index 927802f..5a2c611 100644 --- a/src/anchor/idl.json +++ b/src/anchor/idl.json @@ -640,6 +640,42 @@ } } ] + }, + { + "name": "initPriceFeedIndex", + "discriminant": { "value": [2, 0, 0, 0, 19, 0, 0, 0] }, + "accounts": [ + { + "name": "fundingAccount", + "isMut": true, + "isSigner": true + }, + { + "name": "priceAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "permissionsAccount", + "isMut": true, + "isSigner": false, + "pda": { + "seeds": [ + { + "kind": "const", + "type": "string", + "value": "permissions" + } + ] + } + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [] } ], "types": [ diff --git a/src/anchor/program.ts b/src/anchor/program.ts index a61705e..84c5566 100644 --- a/src/anchor/program.ts +++ b/src/anchor/program.ts @@ -19,7 +19,7 @@ export function pythOracleCoder(): PythOracleCoder { export { default as pythIdl } from './idl.json' export type PythOracle = { - version: '2.20.0' + version: '2.33.0' name: 'pyth_oracle' instructions: [ { @@ -661,6 +661,42 @@ export type PythOracle = { }, ] }, + { + name: 'initPriceFeedIndex' + discriminant: { value: [2, 0, 0, 0, 19, 0, 0, 0] } + accounts: [ + { + name: 'fundingAccount' + isMut: true + isSigner: true + }, + { + name: 'priceAccount' + isMut: true + isSigner: false + }, + { + name: 'permissionsAccount' + isMut: true + isSigner: false + pda: { + seeds: [ + { + kind: 'const' + type: 'string' + value: 'permissions' + }, + ] + } + }, + { + name: 'systemProgram' + isMut: false + isSigner: false + }, + ] + args: [] + }, ] types: [ { From 452568b0a61732018db5962e78027c330aeb08b1 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Tue, 27 Aug 2024 11:47:22 +0200 Subject: [PATCH 2/9] fix: update tests to use pythnet/pythtest --- src/__tests__/Anchor.test.ts | 5 +++-- src/__tests__/Example.test.ts | 6 +++--- src/__tests__/Mapping.test.ts | 6 +++--- src/__tests__/Price.test.ts | 5 +++-- src/__tests__/Product.ETH.test.ts | 6 +++--- src/__tests__/Product.test.ts | 5 +++-- src/__tests__/PythNetworkRestClient.test.ts | 15 ++++++++------- src/cluster.ts | 2 +- 8 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/__tests__/Anchor.test.ts b/src/__tests__/Anchor.test.ts index 1f988d0..d639aca 100644 --- a/src/__tests__/Anchor.test.ts +++ b/src/__tests__/Anchor.test.ts @@ -1,16 +1,17 @@ import { AnchorProvider, Wallet } from '@coral-xyz/anchor' import { Connection, Keypair, PublicKey } from '@solana/web3.js' import { BN } from 'bn.js' +import { getPythClusterApiUrl } from '../cluster' import { getPythProgramKeyForCluster, pythOracleProgram, pythOracleCoder } from '../index' test('Anchor', (done) => { jest.setTimeout(60000) const provider = new AnchorProvider( - new Connection('https://api.mainnet-beta.solana.com'), + new Connection(getPythClusterApiUrl('pythnet')), new Wallet(new Keypair()), AnchorProvider.defaultOptions(), ) - const pythOracle = pythOracleProgram(getPythProgramKeyForCluster('mainnet-beta'), provider) + const pythOracle = pythOracleProgram(getPythProgramKeyForCluster('pythnet'), provider) pythOracle.methods .initMapping() .accounts({ fundingAccount: PublicKey.unique(), freshMappingAccount: PublicKey.unique() }) diff --git a/src/__tests__/Example.test.ts b/src/__tests__/Example.test.ts index ca9803e..b9d1399 100644 --- a/src/__tests__/Example.test.ts +++ b/src/__tests__/Example.test.ts @@ -1,7 +1,7 @@ -import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' -import { parseMappingData, parsePriceData, parseProductData } from '../index' +import { Connection, PublicKey } from '@solana/web3.js' +import { getPythClusterApiUrl, parseMappingData, parsePriceData, parseProductData } from '../index' -const SOLANA_CLUSTER_URL = clusterApiUrl('devnet') +const SOLANA_CLUSTER_URL = getPythClusterApiUrl('pythtest-crosschain') const ORACLE_MAPPING_PUBLIC_KEY = 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2' test('Mapping', (done) => { diff --git a/src/__tests__/Mapping.test.ts b/src/__tests__/Mapping.test.ts index eaef299..c4bb3c6 100644 --- a/src/__tests__/Mapping.test.ts +++ b/src/__tests__/Mapping.test.ts @@ -1,9 +1,9 @@ -import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' -import { parseMappingData, Magic, Version } from '../index' +import { Connection, PublicKey } from '@solana/web3.js' +import { parseMappingData, Magic, Version, getPythClusterApiUrl } from '../index' test('Mapping', (done) => { jest.setTimeout(60000) - const url = clusterApiUrl('devnet') + const url = getPythClusterApiUrl('pythtest-crosschain') const oraclePublicKey = 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2' const connection = new Connection(url) const publicKey = new PublicKey(oraclePublicKey) diff --git a/src/__tests__/Price.test.ts b/src/__tests__/Price.test.ts index 94cbf16..af0326c 100644 --- a/src/__tests__/Price.test.ts +++ b/src/__tests__/Price.test.ts @@ -1,5 +1,6 @@ -import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' +import { Connection, PublicKey } from '@solana/web3.js' import { + getPythClusterApiUrl, Magic, MAX_SLOT_DIFFERENCE, parseMappingData, @@ -11,7 +12,7 @@ import { test('Price', (done) => { jest.setTimeout(60000) - const url = clusterApiUrl('devnet') + const url = getPythClusterApiUrl('pythtest-crosschain') const oraclePublicKey = 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2' const connection = new Connection(url) const publicKey = new PublicKey(oraclePublicKey) diff --git a/src/__tests__/Product.ETH.test.ts b/src/__tests__/Product.ETH.test.ts index a3af53f..7bc8629 100644 --- a/src/__tests__/Product.ETH.test.ts +++ b/src/__tests__/Product.ETH.test.ts @@ -1,9 +1,9 @@ -import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' -import { Magic, parseProductData, Version } from '../index' +import { Connection, PublicKey } from '@solana/web3.js' +import { getPythClusterApiUrl, Magic, parseProductData, Version } from '../index' test('Product', (done) => { jest.setTimeout(60000) - const url = clusterApiUrl('devnet') + const url = getPythClusterApiUrl('pythtest-crosschain') const ethProductKey = '2ciUuGZiee5macAMeQ7bHGTJtwcYTgnt6jdmQnnKZrfu' const connection = new Connection(url) const publicKey = new PublicKey(ethProductKey) diff --git a/src/__tests__/Product.test.ts b/src/__tests__/Product.test.ts index 0354055..9d27268 100644 --- a/src/__tests__/Product.test.ts +++ b/src/__tests__/Product.test.ts @@ -1,9 +1,10 @@ -import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' +import { Connection, PublicKey } from '@solana/web3.js' +import { getPythClusterApiUrl } from '../cluster' import { parseMappingData, parseProductData, Magic, Version } from '../index' test('Product', (done) => { jest.setTimeout(60000) - const url = clusterApiUrl('devnet') + const url = getPythClusterApiUrl('pythtest-crosschain') const oraclePublicKey = 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2' const connection = new Connection(url) const publicKey = new PublicKey(oraclePublicKey) diff --git a/src/__tests__/PythNetworkRestClient.test.ts b/src/__tests__/PythNetworkRestClient.test.ts index a524e79..abd1240 100644 --- a/src/__tests__/PythNetworkRestClient.test.ts +++ b/src/__tests__/PythNetworkRestClient.test.ts @@ -1,11 +1,12 @@ -import { clusterApiUrl, Connection, PublicKey, SystemProgram } from '@solana/web3.js' +import { Connection, PublicKey, SystemProgram } from '@solana/web3.js' import { getPythProgramKeyForCluster, parseProductData, PythHttpClient } from '..' +import { getPythClusterApiUrl } from '../cluster' test('PythHttpClientCall: getData', (done) => { - jest.setTimeout(20000) + jest.setTimeout(60000) try { - const programKey = getPythProgramKeyForCluster('testnet') - const currentConnection = new Connection(clusterApiUrl('testnet')) + const programKey = getPythProgramKeyForCluster('pythtest-conformance') + const currentConnection = new Connection(getPythClusterApiUrl('pythtest-conformance')) const pyth_client = new PythHttpClient(currentConnection, programKey) pyth_client.getData().then( (result) => { @@ -30,7 +31,7 @@ test('PythHttpClientCall: getAssetPricesFromAccounts for one account', (done) => const solUSDKey = new PublicKey('7VJsBtJzgTftYzEeooSDYyjKXvYRWJHdwvbwfBvTg9K') try { const programKey = getPythProgramKeyForCluster('testnet') - const currentConnection = new Connection(clusterApiUrl('testnet')) + const currentConnection = new Connection(getPythClusterApiUrl('pythtest-conformance')) const pyth_client = new PythHttpClient(currentConnection, programKey) pyth_client .getAssetPricesFromAccounts([solUSDKey]) @@ -66,7 +67,7 @@ test('PythHttpClientCall: getAssetPricesFromAccounts for multiple accounts', (do try { const programKey = getPythProgramKeyForCluster('testnet') - const currentConnection = new Connection(clusterApiUrl('testnet')) + const currentConnection = new Connection(getPythClusterApiUrl('pythtest-conformance')) const pyth_client = new PythHttpClient(currentConnection, programKey) pyth_client .getAssetPricesFromAccounts([solUSDKey, bonkUSDKey, usdcUSDKey]) @@ -106,7 +107,7 @@ test('PythHttpClientCall: getAssetPricesFromAccounts should throw for invalid ac try { const programKey = getPythProgramKeyForCluster('testnet') - const currentConnection = new Connection(clusterApiUrl('testnet')) + const currentConnection = new Connection(getPythClusterApiUrl('pythtest-conformance')) const pyth_client = new PythHttpClient(currentConnection, programKey) pyth_client .getAssetPricesFromAccounts([solUSDKey, systemProgram, usdcUSDKey]) diff --git a/src/cluster.ts b/src/cluster.ts index fd09c0d..cefdf19 100644 --- a/src/cluster.ts +++ b/src/cluster.ts @@ -32,7 +32,7 @@ export function getPythClusterApiUrl(cluster: PythCluster): string { if (cluster === 'pythtest-conformance' || cluster === 'pythtest-crosschain') { return 'https://api.pythtest.pyth.network' } else if (cluster === 'pythnet') { - return 'https://pythnet.rpcpool.com' + return 'https://api2.pythnet.pyth.network' } else if (cluster === 'localnet') { return 'http://localhost:8899' } else { From 337bc21dbf031097d75af7b80f61107320da503b Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Tue, 27 Aug 2024 12:47:27 +0200 Subject: [PATCH 3/9] fix: address review comments --- src/anchor/idl.json | 7 +------ src/anchor/program.ts | 9 ++------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/anchor/idl.json b/src/anchor/idl.json index 5a2c611..052b1d8 100644 --- a/src/anchor/idl.json +++ b/src/anchor/idl.json @@ -171,7 +171,7 @@ }, { "name": "permissionsAccount", - "isMut": false, + "isMut": true, "isSigner": false, "pda": { "seeds": [ @@ -668,11 +668,6 @@ } ] } - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false } ], "args": [] diff --git a/src/anchor/program.ts b/src/anchor/program.ts index 84c5566..7e7dd38 100644 --- a/src/anchor/program.ts +++ b/src/anchor/program.ts @@ -191,7 +191,7 @@ export type PythOracle = { }, { name: 'permissionsAccount' - isMut: false + isMut: true isSigner: false pda: { seeds: [ @@ -688,12 +688,7 @@ export type PythOracle = { }, ] } - }, - { - name: 'systemProgram' - isMut: false - isSigner: false - }, + } ] args: [] }, From a0389e6e512e2cb6e00ee32ba250762a9c40c411 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Tue, 27 Aug 2024 12:47:39 +0200 Subject: [PATCH 4/9] feat: add tests for this instruction and setMaxLatency --- src/__tests__/Anchor.test.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/__tests__/Anchor.test.ts b/src/__tests__/Anchor.test.ts index d639aca..2d5508c 100644 --- a/src/__tests__/Anchor.test.ts +++ b/src/__tests__/Anchor.test.ts @@ -203,5 +203,27 @@ test('Anchor', (done) => { expect(decoded?.data.securityAuthority.equals(new PublicKey(8))).toBeTruthy() }) + pythOracle.methods + .setMaxLatency(1, [0,0,0]) + .accounts({ fundingAccount: PublicKey.unique(), priceAccount: PublicKey.unique() }) + .instruction() + .then((instruction) => { + expect(instruction.data).toStrictEqual(Buffer.from([2, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0])) + const decoded = pythOracleCoder().instruction.decode(instruction.data) + expect(decoded?.name).toBe('setMaxLatency') + expect(decoded?.data.maxLatency === 1).toBeTruthy() + }) + + pythOracle.methods + .initPriceFeedIndex() + .accounts({ fundingAccount: PublicKey.unique(), priceAccount: PublicKey.unique(), permissionsAccount: PublicKey.unique() }) + .instruction() + .then((instruction) => { + expect(instruction.data).toStrictEqual(Buffer.from([2, 0, 0, 0, 19, 0, 0, 0])) + const decoded = pythOracleCoder().instruction.decode(instruction.data) + expect(decoded?.name).toBe('initPriceFeedIndex') + expect(decoded?.data).toStrictEqual({}) + }) + done() }) From 858caf633741c90738f7c5be947805aa085eb261 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Tue, 27 Aug 2024 12:48:25 +0200 Subject: [PATCH 5/9] refactor: format --- src/__tests__/Anchor.test.ts | 8 ++++++-- src/anchor/program.ts | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/__tests__/Anchor.test.ts b/src/__tests__/Anchor.test.ts index 2d5508c..2b66d91 100644 --- a/src/__tests__/Anchor.test.ts +++ b/src/__tests__/Anchor.test.ts @@ -204,7 +204,7 @@ test('Anchor', (done) => { }) pythOracle.methods - .setMaxLatency(1, [0,0,0]) + .setMaxLatency(1, [0, 0, 0]) .accounts({ fundingAccount: PublicKey.unique(), priceAccount: PublicKey.unique() }) .instruction() .then((instruction) => { @@ -216,7 +216,11 @@ test('Anchor', (done) => { pythOracle.methods .initPriceFeedIndex() - .accounts({ fundingAccount: PublicKey.unique(), priceAccount: PublicKey.unique(), permissionsAccount: PublicKey.unique() }) + .accounts({ + fundingAccount: PublicKey.unique(), + priceAccount: PublicKey.unique(), + permissionsAccount: PublicKey.unique(), + }) .instruction() .then((instruction) => { expect(instruction.data).toStrictEqual(Buffer.from([2, 0, 0, 0, 19, 0, 0, 0])) diff --git a/src/anchor/program.ts b/src/anchor/program.ts index 7e7dd38..d3c9a7c 100644 --- a/src/anchor/program.ts +++ b/src/anchor/program.ts @@ -688,7 +688,7 @@ export type PythOracle = { }, ] } - } + }, ] args: [] }, From aebbbd7f799246294fe9ca812d02209cea971651 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Tue, 27 Aug 2024 12:51:57 +0200 Subject: [PATCH 6/9] fix: remove permissions account from the test as its pda --- src/__tests__/Anchor.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/__tests__/Anchor.test.ts b/src/__tests__/Anchor.test.ts index 2b66d91..7ac83bd 100644 --- a/src/__tests__/Anchor.test.ts +++ b/src/__tests__/Anchor.test.ts @@ -219,7 +219,6 @@ test('Anchor', (done) => { .accounts({ fundingAccount: PublicKey.unique(), priceAccount: PublicKey.unique(), - permissionsAccount: PublicKey.unique(), }) .instruction() .then((instruction) => { From 02f751c8d5ad432437ef549f238c8c3729d2bde2 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Tue, 27 Aug 2024 13:30:50 +0200 Subject: [PATCH 7/9] feat: add account parsing --- src/__tests__/Price.test.ts | 33 +++++++++++++++++++++++++++++++++ src/index.ts | 25 +++++++++++++++++-------- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/__tests__/Price.test.ts b/src/__tests__/Price.test.ts index af0326c..de03b29 100644 --- a/src/__tests__/Price.test.ts +++ b/src/__tests__/Price.test.ts @@ -104,6 +104,9 @@ test('Handle price getting stale', (done) => { expect(price.magic).toBe(Magic) expect(price.version).toBe(Version) expect(price.status).toBe(PriceStatus.Trading) + expect(price.flags.accumulatorV2).toBe(false); + expect(price.flags.messageBufferCleared).toBe(false); + expect(price.feedIndex).toBe(0) expect(parsePriceData(data, price.aggregate.publishSlot + MAX_SLOT_DIFFERENCE).status).toBe(PriceStatus.Trading) @@ -129,3 +132,33 @@ test('Handle ignored quote', (done) => { done() }) + +test('Handle flags', (done) => { + jest.setTimeout(60000) + + // This data is the BTC price account on Pythnet at 27 Aug 2024 while some flags are set + const b64_data = + '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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa/TMEwuo74QSAAAAAAAAAOxOpnA8+9UCAAAAAAAAAADaZAAAAAAAAAAAAAAAAAAA' + + const data = Buffer.from(b64_data, 'base64') + const price = parsePriceData(data) + + expect(price.flags.accumulatorV2).toBe(true); + expect(price.flags.messageBufferCleared).toBe(true); + + done() +}) + +test('Handle priceFeedIndex', (done) => { + jest.setTimeout(60000) + + // This data is the same as above, except that the feed index is manually modified to be a5 + const b64_data = + '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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa/TMEwuo74QSAAAAAAAAAOxOpnA8+9UCAAAAAAAAAADaZAAAAAAAAAAAAAAAAAAA' + + const data = Buffer.from(b64_data, 'base64') + const price = parsePriceData(data) + + expect(price.feedIndex).toBe(165) + done() +}) diff --git a/src/index.ts b/src/index.ts index 5cef564..b79c5f5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -41,6 +41,11 @@ export enum AccountType { Permission, } +export type Flags = { + accumulatorV2: boolean, + messageBufferCleared: boolean, +} + const empty32Buffer = Buffer.alloc(32) const PKorNull = (data: Buffer) => (data.equals(empty32Buffer) ? null : new PublicKey(data)) @@ -105,8 +110,8 @@ export interface PriceData extends Base { minPublishers: number messageSent: number maxLatency: number - drv3: number - drv4: number + flags: Flags, + feedIndex: number productAccountKey: PublicKey nextPriceAccountKey: PublicKey | null previousSlot: bigint @@ -290,10 +295,14 @@ export const parsePriceData = (data: Buffer, currentSlot?: number): PriceData => const messageSent = data.readUInt8(105) // configurable max latency in slots between send and receive const maxLatency = data.readUInt8(106) - // space for future derived values - const drv3 = data.readInt8(107) - // space for future derived values - const drv4 = data.readInt32LE(108) + // Various flags (used for operations) + const flag_bits = data.readInt8(107) + const flags = { + accumulatorV2: (flag_bits & (1<<0)) !== 0, + messageBufferCleared: (flag_bits & (1<<1)) !== 0, + } + // Globally immutable unique price feed index used for publishing. + const feedIndex = data.readInt32LE(108) // product id / reference account const productAccountKey = new PublicKey(data.slice(112, 144)) // next price account in list @@ -355,8 +364,8 @@ export const parsePriceData = (data: Buffer, currentSlot?: number): PriceData => minPublishers, messageSent, maxLatency, - drv3, - drv4, + flags, + feedIndex, productAccountKey, nextPriceAccountKey, previousSlot, From f3a5352e17ba8414790860e55a0aee7c303e0da0 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Tue, 27 Aug 2024 13:46:16 +0200 Subject: [PATCH 8/9] fix: address lint issues --- src/index.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index b79c5f5..a57be35 100644 --- a/src/index.ts +++ b/src/index.ts @@ -296,11 +296,15 @@ export const parsePriceData = (data: Buffer, currentSlot?: number): PriceData => // configurable max latency in slots between send and receive const maxLatency = data.readUInt8(106) // Various flags (used for operations) - const flag_bits = data.readInt8(107) + const flagBits = data.readInt8(107) + + /* tslint:disable:no-bitwise */ const flags = { - accumulatorV2: (flag_bits & (1<<0)) !== 0, - messageBufferCleared: (flag_bits & (1<<1)) !== 0, + accumulatorV2: (flagBits & (1<<0)) !== 0, + messageBufferCleared: (flagBits & (1<<1)) !== 0, } + /* tslint:enable:no-bitwise */ + // Globally immutable unique price feed index used for publishing. const feedIndex = data.readInt32LE(108) // product id / reference account From ffdc0bdd25f68e24229355e1ddbcc596d8ef9b3f Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Wed, 28 Aug 2024 11:52:57 +0200 Subject: [PATCH 9/9] fix: update oracle version in idl.json --- src/anchor/idl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anchor/idl.json b/src/anchor/idl.json index 052b1d8..d4b158c 100644 --- a/src/anchor/idl.json +++ b/src/anchor/idl.json @@ -1,5 +1,5 @@ { - "version": "2.20.0", + "version": "2.33.0", "name": "pyth_oracle", "instructions": [ {