Add Price Feed to Price Service (#187)

* Update new PriceFeed in p2w-sdk based on sdk update
This commit is contained in:
Ali Behjati 2022-04-22 16:36:26 +01:00 committed by GitHub
parent 787ad7d190
commit e9807ade29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1989 additions and 1173 deletions

File diff suppressed because it is too large Load Diff

View File

@ -36,11 +36,12 @@
"typescript": "^4.3.5" "typescript": "^4.3.5"
}, },
"peerDependencies": { "peerDependencies": {
"@solana/web3.js": "^1.24.0" "@solana/web3.js": "^1.24.0"
}, },
"dependencies": { "dependencies": {
"@certusone/wormhole-sdk": "0.2.1", "@certusone/wormhole-sdk": "0.2.1",
"@improbable-eng/grpc-web-node-http-transport": "^0.14.1" "@improbable-eng/grpc-web-node-http-transport": "^0.14.1",
"@pythnetwork/pyth-sdk-js": "^0.1.0"
}, },
"bugs": { "bugs": {
"url": "https://github.com/certusone/wormhole/issues" "url": "https://github.com/certusone/wormhole/issues"

View File

@ -1,6 +1,7 @@
import { getSignedVAA, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk"; import { getSignedVAA, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
import { zeroPad } from "ethers/lib/utils"; import { zeroPad } from "ethers/lib/utils";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { PriceFeed, PriceStatus } from "@pythnetwork/pyth-sdk-js";
/* /*
@ -162,8 +163,8 @@ export function parsePriceAttestation(arr: Buffer): PriceAttestation {
denominator: arr.readBigInt64BE(124), denominator: arr.readBigInt64BE(124),
}, },
confidenceInterval: arr.readBigUInt64BE(132), confidenceInterval: arr.readBigUInt64BE(132),
status: arr.readUInt32BE(140), status: arr[140],
corpAct: arr.readUInt32BE(141), corpAct: arr[141],
timestamp: arr.readBigUInt64BE(142), timestamp: arr.readBigUInt64BE(142),
}; };
} }
@ -257,6 +258,39 @@ export async function getSignedAttestation(host: string, p2w_addr: string, seque
return await getSignedVAA(host, CHAIN_ID_SOLANA, emitterHex, "" + sequence, extraGrpcOpts); return await getSignedVAA(host, CHAIN_ID_SOLANA, emitterHex, "" + sequence, extraGrpcOpts);
} }
export function priceAttestationToPriceFeed(priceAttestation: PriceAttestation): PriceFeed {
let status;
if (priceAttestation.status === 0) {
status = PriceStatus.Unknown;
} else if (priceAttestation.status === 1) {
status = PriceStatus.Trading;
} else if (priceAttestation.status === 2) {
status = PriceStatus.Halted;
} else if (priceAttestation.status === 3) {
status = PriceStatus.Auction;
} else {
throw(new Error(`Invalid attestation status: ${priceAttestation.status}`));
}
// FIXME: populate 0 fields once they are in priceAttestation
return new PriceFeed({
conf: priceAttestation.confidenceInterval.toString(),
emaConf: priceAttestation.emaConfidence.value.toString(),
emaPrice: priceAttestation.emaPrice.value.toString(),
expo: priceAttestation.exponent,
id: priceAttestation.priceId,
maxNumPublishers: 0,
numPublishers: 0,
prevConf: "0",
prevPrice: "0",
prevPublishTime: 0,
price: priceAttestation.price.toString(),
productId: priceAttestation.productId,
publishTime: 0,
status
})
}
function computePrice(rawPrice: BigInt, expo: number): number { function computePrice(rawPrice: BigInt, expo: number): number {
return Number(rawPrice) * 10 ** expo; return Number(rawPrice) * 10 ** expo;
} }

View File

@ -12,12 +12,14 @@
"@certusone/p2w-sdk": "file:../p2w-sdk/js", "@certusone/p2w-sdk": "file:../p2w-sdk/js",
"@certusone/wormhole-sdk": "^0.1.4", "@certusone/wormhole-sdk": "^0.1.4",
"@certusone/wormhole-spydk": "^0.0.1", "@certusone/wormhole-spydk": "^0.0.1",
"@pythnetwork/pyth-sdk-js": "^0.1.0",
"@types/cors": "^2.8.12", "@types/cors": "^2.8.12",
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"ethers": "^5.4.4", "ethers": "^5.4.4",
"express": "^4.17.2", "express": "^4.17.2",
"http-status-codes": "^2.2.0",
"prom-client": "^14.0.1", "prom-client": "^14.0.1",
"winston": "^3.3.3" "winston": "^3.3.3"
}, },
@ -36,7 +38,8 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@certusone/wormhole-sdk": "0.2.1", "@certusone/wormhole-sdk": "0.2.1",
"@improbable-eng/grpc-web-node-http-transport": "^0.14.1" "@improbable-eng/grpc-web-node-http-transport": "^0.14.1",
"@pythnetwork/pyth-sdk-js": "^0.1.0"
}, },
"devDependencies": { "devDependencies": {
"@openzeppelin/contracts": "^4.2.0", "@openzeppelin/contracts": "^4.2.0",
@ -66,9 +69,9 @@
} }
}, },
"node_modules/@babel/generator": { "node_modules/@babel/generator": {
"version": "7.17.7", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.9.tgz",
"integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", "integrity": "sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==",
"dependencies": { "dependencies": {
"@babel/types": "^7.17.0", "@babel/types": "^7.17.0",
"jsesc": "^2.5.1", "jsesc": "^2.5.1",
@ -101,24 +104,12 @@
} }
}, },
"node_modules/@babel/helper-function-name": { "node_modules/@babel/helper-function-name": {
"version": "7.16.7", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz",
"integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==",
"dependencies": { "dependencies": {
"@babel/helper-get-function-arity": "^7.16.7",
"@babel/template": "^7.16.7", "@babel/template": "^7.16.7",
"@babel/types": "^7.16.7" "@babel/types": "^7.17.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-get-function-arity": {
"version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz",
"integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==",
"dependencies": {
"@babel/types": "^7.16.7"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -166,9 +157,9 @@
} }
}, },
"node_modules/@babel/highlight": { "node_modules/@babel/highlight": {
"version": "7.16.10", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz",
"integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==",
"dependencies": { "dependencies": {
"@babel/helper-validator-identifier": "^7.16.7", "@babel/helper-validator-identifier": "^7.16.7",
"chalk": "^2.0.0", "chalk": "^2.0.0",
@ -179,9 +170,9 @@
} }
}, },
"node_modules/@babel/parser": { "node_modules/@babel/parser": {
"version": "7.17.8", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz",
"integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==",
"bin": { "bin": {
"parser": "bin/babel-parser.js" "parser": "bin/babel-parser.js"
}, },
@ -190,9 +181,9 @@
} }
}, },
"node_modules/@babel/runtime": { "node_modules/@babel/runtime": {
"version": "7.17.8", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz",
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==", "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==",
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
}, },
@ -214,17 +205,17 @@
} }
}, },
"node_modules/@babel/traverse": { "node_modules/@babel/traverse": {
"version": "7.17.3", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.9.tgz",
"integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", "integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.16.7", "@babel/code-frame": "^7.16.7",
"@babel/generator": "^7.17.3", "@babel/generator": "^7.17.9",
"@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-environment-visitor": "^7.16.7",
"@babel/helper-function-name": "^7.16.7", "@babel/helper-function-name": "^7.17.9",
"@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-hoist-variables": "^7.16.7",
"@babel/helper-split-export-declaration": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7",
"@babel/parser": "^7.17.3", "@babel/parser": "^7.17.9",
"@babel/types": "^7.17.0", "@babel/types": "^7.17.0",
"debug": "^4.1.0", "debug": "^4.1.0",
"globals": "^11.1.0" "globals": "^11.1.0"
@ -338,9 +329,9 @@
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
}, },
"node_modules/@ethersproject/abi": { "node_modules/@ethersproject/abi": {
"version": "5.6.0", "version": "5.6.1",
"resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.0.tgz", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.1.tgz",
"integrity": "sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg==", "integrity": "sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w==",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@ -680,9 +671,9 @@
] ]
}, },
"node_modules/@ethersproject/networks": { "node_modules/@ethersproject/networks": {
"version": "5.6.1", "version": "5.6.2",
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.2.tgz",
"integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", "integrity": "sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA==",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@ -735,9 +726,9 @@
} }
}, },
"node_modules/@ethersproject/providers": { "node_modules/@ethersproject/providers": {
"version": "5.6.2", "version": "5.6.4",
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.2.tgz", "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.4.tgz",
"integrity": "sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg==", "integrity": "sha512-WAdknnaZ52hpHV3qPiJmKx401BLpup47h36Axxgre9zT+doa/4GC/Ne48ICPxTm0BqndpToHjpLP1ZnaxyE+vw==",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@ -1047,9 +1038,9 @@
} }
}, },
"node_modules/@grpc/grpc-js": { "node_modules/@grpc/grpc-js": {
"version": "1.6.0", "version": "1.6.7",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.0.tgz", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz",
"integrity": "sha512-KwNibKGx1qmAwsrYu75FhUo3+m6GMJoBfdnYZte9YQ2EM3hZ5Ez+8+Q+FAMONtfU0XJGUkGK5S+q4CXSjx5Ahw==", "integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==",
"dependencies": { "dependencies": {
"@grpc/proto-loader": "^0.6.4", "@grpc/proto-loader": "^0.6.4",
"@types/node": ">=12.12.47" "@types/node": ">=12.12.47"
@ -1141,6 +1132,11 @@
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
}, },
"node_modules/@pythnetwork/pyth-sdk-js": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@pythnetwork/pyth-sdk-js/-/pyth-sdk-js-0.1.0.tgz",
"integrity": "sha512-fsGx2vkXncoIpsrcjx6WY7JN0R74YG/lX2UA1Wz/m6MPgJrde1LHkmikOSdMZUU3KkpWGHT1ZdYoW+Ikv7Nv9g=="
},
"node_modules/@solana/buffer-layout": { "node_modules/@solana/buffer-layout": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz",
@ -1169,9 +1165,9 @@
} }
}, },
"node_modules/@solana/web3.js": { "node_modules/@solana/web3.js": {
"version": "1.37.0", "version": "1.39.1",
"resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.37.0.tgz", "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.39.1.tgz",
"integrity": "sha512-O2iCcgkGdi2FXwVLztPIZHcBuZXdhbVLavMsG+RdEyFGzFD0tQN1rOJ+Xb5eaexjqtgcqRN+Fyg3wAhLcHJbiA==", "integrity": "sha512-Q7XnWTAiU7n7GcoINDAAMLO7CJHpm5kPK46HKwJi2x0cusHQ3WFa7QEp6aPzH7tuf7yl/Kw1lYitcwTVOvqARA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"@ethersproject/sha2": "^5.5.0", "@ethersproject/sha2": "^5.5.0",
@ -1489,9 +1485,9 @@
} }
}, },
"node_modules/@types/lodash": { "node_modules/@types/lodash": {
"version": "4.14.181", "version": "4.14.182",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz",
"integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==" "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q=="
}, },
"node_modules/@types/long": { "node_modules/@types/long": {
"version": "4.0.1", "version": "4.0.1",
@ -1504,9 +1500,9 @@
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "16.11.26", "version": "16.11.27",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.26.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.27.tgz",
"integrity": "sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==" "integrity": "sha512-C1pD3kgLoZ56Uuy5lhfOxie4aZlA3UMGLX9rXteq4WitEZH6Rl80mwactt9QG0w0gLFlN/kLBTFnGXtDVWvWQw=="
}, },
"node_modules/@types/qs": { "node_modules/@types/qs": {
"version": "6.9.7", "version": "6.9.7",
@ -1756,9 +1752,9 @@
} }
}, },
"node_modules/babel-plugin-styled-components": { "node_modules/babel-plugin-styled-components": {
"version": "2.0.6", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.6.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz",
"integrity": "sha512-Sk+7o/oa2HfHv3Eh8sxoz75/fFvEdHsXV4grdeHufX0nauCmymlnN0rGhIvfpMQSJMvGutJ85gvCGea4iqmDpg==", "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==",
"dependencies": { "dependencies": {
"@babel/helper-annotate-as-pure": "^7.16.0", "@babel/helper-annotate-as-pure": "^7.16.0",
"@babel/helper-module-imports": "^7.16.0", "@babel/helper-module-imports": "^7.16.0",
@ -2353,9 +2349,9 @@
} }
}, },
"node_modules/ethers": { "node_modules/ethers": {
"version": "5.6.2", "version": "5.6.4",
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.2.tgz", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.4.tgz",
"integrity": "sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ==", "integrity": "sha512-62UIfxAQXdf67TeeOaoOoPctm5hUlYgfd0iW3wxfj7qRYKDcvvy0f+sJ3W2/Pyx77R8dblvejA8jokj+lS+ATQ==",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@ -2367,7 +2363,7 @@
} }
], ],
"dependencies": { "dependencies": {
"@ethersproject/abi": "5.6.0", "@ethersproject/abi": "5.6.1",
"@ethersproject/abstract-provider": "5.6.0", "@ethersproject/abstract-provider": "5.6.0",
"@ethersproject/abstract-signer": "5.6.0", "@ethersproject/abstract-signer": "5.6.0",
"@ethersproject/address": "5.6.0", "@ethersproject/address": "5.6.0",
@ -2382,10 +2378,10 @@
"@ethersproject/json-wallets": "5.6.0", "@ethersproject/json-wallets": "5.6.0",
"@ethersproject/keccak256": "5.6.0", "@ethersproject/keccak256": "5.6.0",
"@ethersproject/logger": "5.6.0", "@ethersproject/logger": "5.6.0",
"@ethersproject/networks": "5.6.1", "@ethersproject/networks": "5.6.2",
"@ethersproject/pbkdf2": "5.6.0", "@ethersproject/pbkdf2": "5.6.0",
"@ethersproject/properties": "5.6.0", "@ethersproject/properties": "5.6.0",
"@ethersproject/providers": "5.6.2", "@ethersproject/providers": "5.6.4",
"@ethersproject/random": "5.6.0", "@ethersproject/random": "5.6.0",
"@ethersproject/rlp": "5.6.0", "@ethersproject/rlp": "5.6.0",
"@ethersproject/sha2": "5.6.0", "@ethersproject/sha2": "5.6.0",
@ -2458,9 +2454,9 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
}, },
"node_modules/fecha": { "node_modules/fecha": {
"version": "4.2.1", "version": "4.2.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
"integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
}, },
"node_modules/file-uri-to-path": { "node_modules/file-uri-to-path": {
"version": "1.0.0", "version": "1.0.0",
@ -2582,9 +2578,9 @@
} }
}, },
"node_modules/google-protobuf": { "node_modules/google-protobuf": {
"version": "3.19.4", "version": "3.20.1",
"resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.4.tgz", "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.20.1.tgz",
"integrity": "sha512-OIPNCxsG2lkIvf+P5FNfJ/Km95CsXOBecS9ZcAU6m2Rq3svc0Apl9nB3GMDNKfQ9asNv4KjyAqGwPQFrVle3Yg==" "integrity": "sha512-XMf1+O32FjYIV3CYu6Tuh5PNbfNEU5Xu22X+Xkdb/DUexFlCzhvv7d5Iirm4AOwn8lv4al1YvIhzGrg2j9Zfzw=="
}, },
"node_modules/has": { "node_modules/has": {
"version": "1.0.3", "version": "1.0.3",
@ -2666,6 +2662,11 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/http-status-codes": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz",
"integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng=="
},
"node_modules/iconv-lite": { "node_modules/iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -2724,9 +2725,9 @@
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
}, },
"node_modules/is-core-module": { "node_modules/is-core-module": {
"version": "2.8.1", "version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
"integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"has": "^1.0.3" "has": "^1.0.3"
@ -2796,9 +2797,9 @@
} }
}, },
"node_modules/jayson/node_modules/@types/node": { "node_modules/jayson/node_modules/@types/node": {
"version": "12.20.47", "version": "12.20.48",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.48.tgz",
"integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==" "integrity": "sha512-4kxzqkrpwYtn6okJUcb2lfUu9ilnb3yhUOH6qX3nug8D2DupZ2drIkff2yJzYcNJVl3begnlcaBJ7tqiTTzjnQ=="
}, },
"node_modules/js-base64": { "node_modules/js-base64": {
"version": "3.7.2", "version": "3.7.2",
@ -3179,9 +3180,9 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "2.6.1", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==", "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true, "dev": true,
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
@ -3817,9 +3818,9 @@
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
}, },
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.3.1", "version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}, },
"node_modules/tslint": { "node_modules/tslint": {
"version": "6.1.3", "version": "6.1.3",
@ -4003,9 +4004,9 @@
} }
}, },
"node_modules/winston": { "node_modules/winston": {
"version": "3.6.0", "version": "3.7.2",
"resolved": "https://registry.npmjs.org/winston/-/winston-3.6.0.tgz", "resolved": "https://registry.npmjs.org/winston/-/winston-3.7.2.tgz",
"integrity": "sha512-9j8T75p+bcN6D00sF/zjFVmPp+t8KMPB1MzbbzYjeN9VWxdsYnTB40TkbNUEXAmILEfChMvAMgidlX64OG3p6w==", "integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==",
"dependencies": { "dependencies": {
"@dabh/diagnostics": "^2.0.2", "@dabh/diagnostics": "^2.0.2",
"async": "^3.2.3", "async": "^3.2.3",
@ -4150,9 +4151,9 @@
} }
}, },
"@babel/generator": { "@babel/generator": {
"version": "7.17.7", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.9.tgz",
"integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", "integrity": "sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==",
"requires": { "requires": {
"@babel/types": "^7.17.0", "@babel/types": "^7.17.0",
"jsesc": "^2.5.1", "jsesc": "^2.5.1",
@ -4176,21 +4177,12 @@
} }
}, },
"@babel/helper-function-name": { "@babel/helper-function-name": {
"version": "7.16.7", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz",
"integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==",
"requires": { "requires": {
"@babel/helper-get-function-arity": "^7.16.7",
"@babel/template": "^7.16.7", "@babel/template": "^7.16.7",
"@babel/types": "^7.16.7" "@babel/types": "^7.17.0"
}
},
"@babel/helper-get-function-arity": {
"version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz",
"integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==",
"requires": {
"@babel/types": "^7.16.7"
} }
}, },
"@babel/helper-hoist-variables": { "@babel/helper-hoist-variables": {
@ -4223,9 +4215,9 @@
"integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw=="
}, },
"@babel/highlight": { "@babel/highlight": {
"version": "7.16.10", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz",
"integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==",
"requires": { "requires": {
"@babel/helper-validator-identifier": "^7.16.7", "@babel/helper-validator-identifier": "^7.16.7",
"chalk": "^2.0.0", "chalk": "^2.0.0",
@ -4233,14 +4225,14 @@
} }
}, },
"@babel/parser": { "@babel/parser": {
"version": "7.17.8", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz",
"integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==" "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg=="
}, },
"@babel/runtime": { "@babel/runtime": {
"version": "7.17.8", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz",
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==", "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==",
"requires": { "requires": {
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
} }
@ -4256,17 +4248,17 @@
} }
}, },
"@babel/traverse": { "@babel/traverse": {
"version": "7.17.3", "version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.9.tgz",
"integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", "integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==",
"requires": { "requires": {
"@babel/code-frame": "^7.16.7", "@babel/code-frame": "^7.16.7",
"@babel/generator": "^7.17.3", "@babel/generator": "^7.17.9",
"@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-environment-visitor": "^7.16.7",
"@babel/helper-function-name": "^7.16.7", "@babel/helper-function-name": "^7.17.9",
"@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-hoist-variables": "^7.16.7",
"@babel/helper-split-export-declaration": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7",
"@babel/parser": "^7.17.3", "@babel/parser": "^7.17.9",
"@babel/types": "^7.17.0", "@babel/types": "^7.17.0",
"debug": "^4.1.0", "debug": "^4.1.0",
"globals": "^11.1.0" "globals": "^11.1.0"
@ -4302,6 +4294,7 @@
"@certusone/wormhole-sdk": "0.2.1", "@certusone/wormhole-sdk": "0.2.1",
"@improbable-eng/grpc-web-node-http-transport": "^0.14.1", "@improbable-eng/grpc-web-node-http-transport": "^0.14.1",
"@openzeppelin/contracts": "^4.2.0", "@openzeppelin/contracts": "^4.2.0",
"@pythnetwork/pyth-sdk-js": "^0.1.0",
"@typechain/ethers-v5": "^7.1.2", "@typechain/ethers-v5": "^7.1.2",
"@types/long": "^4.0.1", "@types/long": "^4.0.1",
"@types/node": "^16.6.1", "@types/node": "^16.6.1",
@ -4378,9 +4371,9 @@
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
}, },
"@ethersproject/abi": { "@ethersproject/abi": {
"version": "5.6.0", "version": "5.6.1",
"resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.0.tgz", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.1.tgz",
"integrity": "sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg==", "integrity": "sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w==",
"requires": { "requires": {
"@ethersproject/address": "^5.6.0", "@ethersproject/address": "^5.6.0",
"@ethersproject/bignumber": "^5.6.0", "@ethersproject/bignumber": "^5.6.0",
@ -4574,9 +4567,9 @@
"integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg=="
}, },
"@ethersproject/networks": { "@ethersproject/networks": {
"version": "5.6.1", "version": "5.6.2",
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.2.tgz",
"integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", "integrity": "sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA==",
"requires": { "requires": {
"@ethersproject/logger": "^5.6.0" "@ethersproject/logger": "^5.6.0"
} }
@ -4599,9 +4592,9 @@
} }
}, },
"@ethersproject/providers": { "@ethersproject/providers": {
"version": "5.6.2", "version": "5.6.4",
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.2.tgz", "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.4.tgz",
"integrity": "sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg==", "integrity": "sha512-WAdknnaZ52hpHV3qPiJmKx401BLpup47h36Axxgre9zT+doa/4GC/Ne48ICPxTm0BqndpToHjpLP1ZnaxyE+vw==",
"requires": { "requires": {
"@ethersproject/abstract-provider": "^5.6.0", "@ethersproject/abstract-provider": "^5.6.0",
"@ethersproject/abstract-signer": "^5.6.0", "@ethersproject/abstract-signer": "^5.6.0",
@ -4781,9 +4774,9 @@
} }
}, },
"@grpc/grpc-js": { "@grpc/grpc-js": {
"version": "1.6.0", "version": "1.6.7",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.0.tgz", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz",
"integrity": "sha512-KwNibKGx1qmAwsrYu75FhUo3+m6GMJoBfdnYZte9YQ2EM3hZ5Ez+8+Q+FAMONtfU0XJGUkGK5S+q4CXSjx5Ahw==", "integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==",
"requires": { "requires": {
"@grpc/proto-loader": "^0.6.4", "@grpc/proto-loader": "^0.6.4",
"@types/node": ">=12.12.47" "@types/node": ">=12.12.47"
@ -4863,6 +4856,11 @@
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
}, },
"@pythnetwork/pyth-sdk-js": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@pythnetwork/pyth-sdk-js/-/pyth-sdk-js-0.1.0.tgz",
"integrity": "sha512-fsGx2vkXncoIpsrcjx6WY7JN0R74YG/lX2UA1Wz/m6MPgJrde1LHkmikOSdMZUU3KkpWGHT1ZdYoW+Ikv7Nv9g=="
},
"@solana/buffer-layout": { "@solana/buffer-layout": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz",
@ -4885,9 +4883,9 @@
} }
}, },
"@solana/web3.js": { "@solana/web3.js": {
"version": "1.37.0", "version": "1.39.1",
"resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.37.0.tgz", "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.39.1.tgz",
"integrity": "sha512-O2iCcgkGdi2FXwVLztPIZHcBuZXdhbVLavMsG+RdEyFGzFD0tQN1rOJ+Xb5eaexjqtgcqRN+Fyg3wAhLcHJbiA==", "integrity": "sha512-Q7XnWTAiU7n7GcoINDAAMLO7CJHpm5kPK46HKwJi2x0cusHQ3WFa7QEp6aPzH7tuf7yl/Kw1lYitcwTVOvqARA==",
"requires": { "requires": {
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"@ethersproject/sha2": "^5.5.0", "@ethersproject/sha2": "^5.5.0",
@ -5115,9 +5113,9 @@
} }
}, },
"@types/lodash": { "@types/lodash": {
"version": "4.14.181", "version": "4.14.182",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz",
"integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==" "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q=="
}, },
"@types/long": { "@types/long": {
"version": "4.0.1", "version": "4.0.1",
@ -5130,9 +5128,9 @@
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
}, },
"@types/node": { "@types/node": {
"version": "16.11.26", "version": "16.11.27",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.26.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.27.tgz",
"integrity": "sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==" "integrity": "sha512-C1pD3kgLoZ56Uuy5lhfOxie4aZlA3UMGLX9rXteq4WitEZH6Rl80mwactt9QG0w0gLFlN/kLBTFnGXtDVWvWQw=="
}, },
"@types/qs": { "@types/qs": {
"version": "6.9.7", "version": "6.9.7",
@ -5363,9 +5361,9 @@
} }
}, },
"babel-plugin-styled-components": { "babel-plugin-styled-components": {
"version": "2.0.6", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.6.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz",
"integrity": "sha512-Sk+7o/oa2HfHv3Eh8sxoz75/fFvEdHsXV4grdeHufX0nauCmymlnN0rGhIvfpMQSJMvGutJ85gvCGea4iqmDpg==", "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==",
"requires": { "requires": {
"@babel/helper-annotate-as-pure": "^7.16.0", "@babel/helper-annotate-as-pure": "^7.16.0",
"@babel/helper-module-imports": "^7.16.0", "@babel/helper-module-imports": "^7.16.0",
@ -5860,11 +5858,11 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
}, },
"ethers": { "ethers": {
"version": "5.6.2", "version": "5.6.4",
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.2.tgz", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.4.tgz",
"integrity": "sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ==", "integrity": "sha512-62UIfxAQXdf67TeeOaoOoPctm5hUlYgfd0iW3wxfj7qRYKDcvvy0f+sJ3W2/Pyx77R8dblvejA8jokj+lS+ATQ==",
"requires": { "requires": {
"@ethersproject/abi": "5.6.0", "@ethersproject/abi": "5.6.1",
"@ethersproject/abstract-provider": "5.6.0", "@ethersproject/abstract-provider": "5.6.0",
"@ethersproject/abstract-signer": "5.6.0", "@ethersproject/abstract-signer": "5.6.0",
"@ethersproject/address": "5.6.0", "@ethersproject/address": "5.6.0",
@ -5879,10 +5877,10 @@
"@ethersproject/json-wallets": "5.6.0", "@ethersproject/json-wallets": "5.6.0",
"@ethersproject/keccak256": "5.6.0", "@ethersproject/keccak256": "5.6.0",
"@ethersproject/logger": "5.6.0", "@ethersproject/logger": "5.6.0",
"@ethersproject/networks": "5.6.1", "@ethersproject/networks": "5.6.2",
"@ethersproject/pbkdf2": "5.6.0", "@ethersproject/pbkdf2": "5.6.0",
"@ethersproject/properties": "5.6.0", "@ethersproject/properties": "5.6.0",
"@ethersproject/providers": "5.6.2", "@ethersproject/providers": "5.6.4",
"@ethersproject/random": "5.6.0", "@ethersproject/random": "5.6.0",
"@ethersproject/rlp": "5.6.0", "@ethersproject/rlp": "5.6.0",
"@ethersproject/sha2": "5.6.0", "@ethersproject/sha2": "5.6.0",
@ -5949,9 +5947,9 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
}, },
"fecha": { "fecha": {
"version": "4.2.1", "version": "4.2.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
"integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
}, },
"file-uri-to-path": { "file-uri-to-path": {
"version": "1.0.0", "version": "1.0.0",
@ -6035,9 +6033,9 @@
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
}, },
"google-protobuf": { "google-protobuf": {
"version": "3.19.4", "version": "3.20.1",
"resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.4.tgz", "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.20.1.tgz",
"integrity": "sha512-OIPNCxsG2lkIvf+P5FNfJ/Km95CsXOBecS9ZcAU6m2Rq3svc0Apl9nB3GMDNKfQ9asNv4KjyAqGwPQFrVle3Yg==" "integrity": "sha512-XMf1+O32FjYIV3CYu6Tuh5PNbfNEU5Xu22X+Xkdb/DUexFlCzhvv7d5Iirm4AOwn8lv4al1YvIhzGrg2j9Zfzw=="
}, },
"has": { "has": {
"version": "1.0.3", "version": "1.0.3",
@ -6109,6 +6107,11 @@
"toidentifier": "1.0.1" "toidentifier": "1.0.1"
} }
}, },
"http-status-codes": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz",
"integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng=="
},
"iconv-lite": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -6147,9 +6150,9 @@
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
}, },
"is-core-module": { "is-core-module": {
"version": "2.8.1", "version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
"integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
"dev": true, "dev": true,
"requires": { "requires": {
"has": "^1.0.3" "has": "^1.0.3"
@ -6199,9 +6202,9 @@
}, },
"dependencies": { "dependencies": {
"@types/node": { "@types/node": {
"version": "12.20.47", "version": "12.20.48",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.48.tgz",
"integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==" "integrity": "sha512-4kxzqkrpwYtn6okJUcb2lfUu9ilnb3yhUOH6qX3nug8D2DupZ2drIkff2yJzYcNJVl3begnlcaBJ7tqiTTzjnQ=="
} }
} }
}, },
@ -6498,9 +6501,9 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
}, },
"prettier": { "prettier": {
"version": "2.6.1", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==", "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true "dev": true
}, },
"prom-client": { "prom-client": {
@ -6982,9 +6985,9 @@
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
}, },
"tslib": { "tslib": {
"version": "2.3.1", "version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}, },
"tslint": { "tslint": {
"version": "6.1.3", "version": "6.1.3",
@ -7127,9 +7130,9 @@
} }
}, },
"winston": { "winston": {
"version": "3.6.0", "version": "3.7.2",
"resolved": "https://registry.npmjs.org/winston/-/winston-3.6.0.tgz", "resolved": "https://registry.npmjs.org/winston/-/winston-3.7.2.tgz",
"integrity": "sha512-9j8T75p+bcN6D00sF/zjFVmPp+t8KMPB1MzbbzYjeN9VWxdsYnTB40TkbNUEXAmILEfChMvAMgidlX64OG3p6w==", "integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==",
"requires": { "requires": {
"@dabh/diagnostics": "^2.0.2", "@dabh/diagnostics": "^2.0.2",
"async": "^3.2.3", "async": "^3.2.3",

View File

@ -21,12 +21,14 @@
"@certusone/p2w-sdk": "file:../p2w-sdk/js", "@certusone/p2w-sdk": "file:../p2w-sdk/js",
"@certusone/wormhole-sdk": "^0.1.4", "@certusone/wormhole-sdk": "^0.1.4",
"@certusone/wormhole-spydk": "^0.0.1", "@certusone/wormhole-spydk": "^0.0.1",
"@pythnetwork/pyth-sdk-js": "^0.1.0",
"@types/cors": "^2.8.12", "@types/cors": "^2.8.12",
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"ethers": "^5.4.4", "ethers": "^5.4.4",
"express": "^4.17.2", "express": "^4.17.2",
"http-status-codes": "^2.2.0",
"prom-client": "^14.0.1", "prom-client": "^14.0.1",
"winston": "^3.3.3" "winston": "^3.3.3"
}, },

View File

@ -13,19 +13,21 @@ import { importCoreWasm } from "@certusone/wormhole-sdk/lib/cjs/solana/wasm";
import { envOrErr, sleep, TimestampInSec } from "./helpers"; import { envOrErr, sleep, TimestampInSec } from "./helpers";
import { PromClient } from "./promClient"; import { PromClient } from "./promClient";
import { getBatchSummary, parseBatchPriceAttestation } from "@certusone/p2w-sdk"; import { getBatchSummary, parseBatchPriceAttestation, priceAttestationToPriceFeed } from "@certusone/p2w-sdk";
import { ClientReadableStream } from "@grpc/grpc-js"; import { ClientReadableStream } from "@grpc/grpc-js";
import { FilterEntry, SubscribeSignedVAAResponse } from "@certusone/wormhole-spydk/lib/cjs/proto/spy/v1/spy"; import { FilterEntry, SubscribeSignedVAAResponse } from "@certusone/wormhole-spydk/lib/cjs/proto/spy/v1/spy";
import { logger } from "./logging"; import { logger } from "./logging";
import { PriceFeed } from "@pythnetwork/pyth-sdk-js";
export type VaaInfo = { export type PriceInfo = {
vaaBytes: string, vaaBytes: string,
seqNum: number, seqNum: number,
receiveTime: TimestampInSec, receiveTime: TimestampInSec,
priceFeed: PriceFeed
}; };
export interface PriceFeedVaaInfo { export interface PriceFeedPriceInfo {
getLatestVaaForPriceFeed(priceFeedId: string): VaaInfo | undefined; getLatestPriceInfo(priceFeedId: string): PriceInfo | undefined;
} }
type ListenerReadinessConfig = { type ListenerReadinessConfig = {
@ -39,9 +41,9 @@ type ListenerConfig = {
readiness: ListenerReadinessConfig, readiness: ListenerReadinessConfig,
}; };
export class Listener implements PriceFeedVaaInfo { export class Listener implements PriceFeedPriceInfo {
// Mapping of Price Feed Id to Vaa // Mapping of Price Feed Id to Vaa
private priceFeedVaaMap = new Map<string, VaaInfo>(); private priceFeedVaaMap = new Map<string, PriceInfo>();
private promClient: PromClient | undefined; private promClient: PromClient | undefined;
private spyServiceHost: string; private spyServiceHost: string;
private filters: FilterEntry[] = []; private filters: FilterEntry[] = [];
@ -178,6 +180,7 @@ export class Listener implements PriceFeedVaaInfo {
seqNum: parsedVAA.sequence, seqNum: parsedVAA.sequence,
vaaBytes: vaaBytes, vaaBytes: vaaBytes,
receiveTime: (new Date()).getTime() / 1000, receiveTime: (new Date()).getTime() / 1000,
priceFeed: priceAttestationToPriceFeed(priceAttestation)
}); });
} }
} }
@ -196,7 +199,7 @@ export class Listener implements PriceFeedVaaInfo {
this.promClient?.incReceivedVaa(); this.promClient?.incReceivedVaa();
} }
getLatestVaaForPriceFeed(priceFeedId: string): VaaInfo | undefined { getLatestPriceInfo(priceFeedId: string): PriceInfo | undefined {
return this.priceFeedVaaMap.get(priceFeedId); return this.priceFeedVaaMap.get(priceFeedId);
} }

View File

@ -36,6 +36,24 @@ export class PromClient {
help: "Freshness time of Vaa (time difference of Vaa and request time)", help: "Freshness time of Vaa (time difference of Vaa and request time)",
buckets: [1, 5, 10, 15, 30, 60, 120, 180] buckets: [1, 5, 10, 15, 30, 60, 120, 180]
}); });
private apiLatestPriceFeedRequestsCounter = new client.Counter({
name: `${SERVICE_PREFIX}api_latest_price_feed_requests_received`,
help: "Number of requests for latest Price Feed of a price feed id"
});
private apiLatestPriceFeedNotFoundResponseCounter = new client.Counter({
name: `${SERVICE_PREFIX}api_latest_price_feed_not_found_response`,
help: "Number of not found responses for latest Price Feed of a price feed id"
});
private apiLatestPriceFeedSuccessResponseCounter = new client.Counter({
name: `${SERVICE_PREFIX}api_latest_price_feed_success_response`,
help: "Number of successful responses for latest vaa of a price feed id"
});
private apiLatestPriceFeedFreshnessHistogram = new client.Histogram({
name: `${SERVICE_PREFIX}api_latest_price_feed_freshness`,
help: "Freshness time of Vaa (time difference of retrieval time and request time)",
buckets: [1, 5, 10, 15, 30, 60, 120, 180]
});
// End metrics // End metrics
private server = http.createServer(async (req, res) => { private server = http.createServer(async (req, res) => {
@ -54,10 +72,16 @@ export class PromClient {
this.collectDefaultMetrics({ register: this.register, prefix: SERVICE_PREFIX }); this.collectDefaultMetrics({ register: this.register, prefix: SERVICE_PREFIX });
// Register each metric // Register each metric
this.register.registerMetric(this.receivedVaaCounter); this.register.registerMetric(this.receivedVaaCounter);
this.register.registerMetric(this.apiLatestVaaRequestsCounter); this.register.registerMetric(this.apiLatestVaaRequestsCounter);
this.register.registerMetric(this.apiLatestVaaNotFoundResponseCounter); this.register.registerMetric(this.apiLatestVaaNotFoundResponseCounter);
this.register.registerMetric(this.apiLatestVaaSuccessResponseCounter); this.register.registerMetric(this.apiLatestVaaSuccessResponseCounter);
this.register.registerMetric(this.apiLatestVaaFreshnessHistogram); this.register.registerMetric(this.apiLatestVaaFreshnessHistogram);
this.register.registerMetric(this.apiLatestPriceFeedRequestsCounter);
this.register.registerMetric(this.apiLatestPriceFeedNotFoundResponseCounter);
this.register.registerMetric(this.apiLatestPriceFeedSuccessResponseCounter);
this.register.registerMetric(this.apiLatestPriceFeedFreshnessHistogram);
// End registering metric // End registering metric
logger.info("prometheus client listening on port " + config.port); logger.info("prometheus client listening on port " + config.port);
@ -83,4 +107,20 @@ export class PromClient {
addApiLatestVaaFreshness(duration: DurationInSec) { addApiLatestVaaFreshness(duration: DurationInSec) {
this.apiLatestVaaFreshnessHistogram.observe(duration); this.apiLatestVaaFreshnessHistogram.observe(duration);
} }
incApiLatestPriceFeedRequests() {
this.apiLatestPriceFeedRequestsCounter.inc();
}
incApiLatestPriceFeedNotFoundResponse() {
this.apiLatestPriceFeedNotFoundResponseCounter.inc();
}
incApiLatestPriceFeedSuccessResponse() {
this.apiLatestPriceFeedSuccessResponseCounter.inc();
}
addApiLatestPriceFeedFreshness(duration: DurationInSec) {
this.apiLatestPriceFeedFreshnessHistogram.observe(duration);
}
} }

View File

@ -1,20 +1,20 @@
import express from "express"; import express from "express";
import cors from "cors"; import cors from "cors";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { PriceFeedVaaInfo } from "./listen"; import { PriceFeedPriceInfo } from "./listen";
import { logger } from "./logging"; import { logger } from "./logging";
import { PromClient } from "./promClient"; import { PromClient } from "./promClient";
import { DurationInSec } from "./helpers"; import { DurationInSec } from "./helpers";
import { StatusCodes } from "http-status-codes";
export class RestAPI { export class RestAPI {
private port: number; private port: number;
private priceFeedVaaInfo: PriceFeedVaaInfo; private priceFeedVaaInfo: PriceFeedPriceInfo;
private isReady: (() => boolean) | undefined; private isReady: (() => boolean) | undefined;
private promClient: PromClient | undefined; private promClient: PromClient | undefined;
constructor(config: { port: number; }, constructor(config: { port: number; },
priceFeedVaaInfo: PriceFeedVaaInfo, priceFeedVaaInfo: PriceFeedPriceInfo,
isReady?: () => boolean, isReady?: () => boolean,
promClient?: PromClient) { promClient?: PromClient) {
this.port = config.port; this.port = config.port;
@ -38,36 +38,85 @@ export class RestAPI {
this.promClient?.incApiLatestVaaRequests(); this.promClient?.incApiLatestVaaRequests();
logger.info(`Received latest_vaa_bytes request for ${req.params.price_feed_id}`) logger.info(`Received latest_vaa_bytes request for ${req.params.price_feed_id}`)
let latestVaa = this.priceFeedVaaInfo.getLatestVaaForPriceFeed(req.params.price_feed_id); let latestPriceInfo = this.priceFeedVaaInfo.getLatestPriceInfo(req.params.price_feed_id);
if (latestVaa === undefined) { if (latestPriceInfo === undefined) {
this.promClient?.incApiLatestVaaNotFoundResponse(); this.promClient?.incApiLatestVaaNotFoundResponse();
res.sendStatus(404); res.sendStatus(StatusCodes.NOT_FOUND);
return; return;
} }
this.promClient?.incApiLatestVaaSuccessResponse(); this.promClient?.incApiLatestVaaSuccessResponse();
const freshness: DurationInSec = (new Date).getTime()/1000 - latestVaa.receiveTime; const freshness: DurationInSec = (new Date).getTime()/1000 - latestPriceInfo.receiveTime;
this.promClient?.addApiLatestVaaFreshness(freshness); this.promClient?.addApiLatestVaaFreshness(freshness);
res.status(200); res.send(latestPriceInfo.vaaBytes);
res.write(latestVaa.vaaBytes);
res.end();
}); });
endpoints.push("latest_vaa_bytes/<price_feed_id>"); endpoints.push("latest_vaa_bytes/<price_feed_id>");
// It will be called with query param `id` such as: `/latest_price_feed?id=xyz&id=abc
app.get("/latest_price_feed", (req: Request, res: Response) => {
this.promClient?.incApiLatestPriceFeedRequests();
logger.info(`Received latest_price_feed request for query: ${req.query}`);
if (req.query.id === undefined) {
res.status(StatusCodes.BAD_REQUEST).send("No id is provided");
return;
}
let priceIds: string[] = [];
if (typeof(req.query.id) === "string") {
priceIds.push(req.query.id);
} else if (Array.isArray(req.query.id)) {
for (let entry of req.query.id) {
if (typeof(entry) === "string") {
priceIds.push(entry);
} else {
res.status(StatusCodes.BAD_REQUEST).send("id is expected to be a hex string or an array of hex strings");
return;
}
}
} else {
res.status(StatusCodes.BAD_REQUEST).send("id is expected to be a hex string or an array of hex strings");
return;
}
let responseJson = []
for (let id of priceIds) {
let latestPriceInfo = this.priceFeedVaaInfo.getLatestPriceInfo(id);
if (latestPriceInfo === undefined) {
this.promClient?.incApiLatestPriceFeedNotFoundResponse();
res.status(StatusCodes.NOT_FOUND).send(`Price Feed with id ${id} not found`);
return;
}
const freshness: DurationInSec = (new Date).getTime()/1000 - latestPriceInfo.receiveTime;
this.promClient?.addApiLatestPriceFeedFreshness(freshness);
responseJson.push(latestPriceInfo.priceFeed.toJson());
}
this.promClient?.incApiLatestPriceFeedSuccessResponse();
res.json(responseJson);
});
endpoints.push("latest_price_feed/<price_feed_id>");
app.get("/ready", (_, res: Response) => { app.get("/ready", (_, res: Response) => {
if (this.isReady!()) { if (this.isReady!()) {
res.sendStatus(200); res.sendStatus(StatusCodes.OK);
} else { } else {
res.sendStatus(503); res.sendStatus(StatusCodes.SERVICE_UNAVAILABLE);
} }
}); });
endpoints.push('ready'); endpoints.push('ready');
app.get("/live", (_, res: Response) => { app.get("/live", (_, res: Response) => {
res.sendStatus(200); res.sendStatus(StatusCodes.OK);
}); });
endpoints.push("live"); endpoints.push("live");