[Xc admin] proposer server (#816)

* Proposer server

* Add package-lock.json

* Add rpc as enviornment variables
This commit is contained in:
guibescos 2023-05-16 13:15:08 -05:00 committed by GitHub
parent c23fc8dbad
commit e243e6734b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 323 additions and 57 deletions

View File

@ -0,0 +1,30 @@
{
"name": "proposer_server",
"version": "0.0.0",
"description": "A server that proposes the instructions that it receives to the multisig",
"private": "true",
"author": "",
"homepage": "https://github.com/pyth-network/pyth-crosschain",
"license": "ISC",
"main": "src/index.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/pyth-network/pyth-crosschain.git"
},
"bugs": {
"url": "https://github.com/pyth-network/pyth-crosschain/issues"
},
"scripts": {
"build": "tsc",
"format": "prettier --write \"src/**/*.ts\""
},
"dependencies": {
"@coral-xyz/anchor": "^0.27.0",
"@pythnetwork/client": "^2.17.0",
"@solana/web3.js": "^1.76.0",
"@sqds/mesh": "^1.0.6",
"cors": "^2.8.5",
"ts-node": "^10.9.1",
"xc_admin_common": "*"
}
}

View File

@ -0,0 +1,89 @@
import express, { Request, Response } from "express";
import cors from "cors";
import {
Cluster,
Connection,
Keypair,
PublicKey,
TransactionInstruction,
} from "@solana/web3.js";
import {
envOrErr,
getMultisigCluster,
isRemoteCluster,
PRICE_FEED_MULTISIG,
proposeInstructions,
WORMHOLE_ADDRESS,
} from "xc_admin_common";
import * as fs from "fs";
import { getPythClusterApiUrl, PythCluster } from "@pythnetwork/client";
import SquadsMesh from "@sqds/mesh";
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
const PORT: number = Number(process.env.PORT ?? "3000");
const KEYPAIR: Keypair = Keypair.fromSecretKey(
Uint8Array.from(JSON.parse(fs.readFileSync(envOrErr("WALLET"), "ascii")))
);
const MAINNET_RPC: string =
process.env.MAINNET_RPC ?? getPythClusterApiUrl("mainnet-beta");
const DEVNET_RPC: string =
process.env.DEVNET_RPC ?? getPythClusterApiUrl("devnet");
const TESTNET_RPC: string =
process.env.TESTNET_RPC ?? getPythClusterApiUrl("testnet");
const LOCALNET_RPC: string =
process.env.LOCALNET_RPC ?? getPythClusterApiUrl("localnet");
const RPC_URLS: Record<Cluster | "localnet", string> = {
"mainnet-beta": MAINNET_RPC,
devnet: DEVNET_RPC,
testnet: TESTNET_RPC,
localnet: LOCALNET_RPC,
};
const app = express();
app.use(cors());
app.use(express.json());
app.post("/api/propose", async (req: Request, res: Response) => {
try {
const instructions: TransactionInstruction[] = req.body.instructions.map(
(ix: any) =>
new TransactionInstruction({
data: Buffer.from(ix.data),
programId: new PublicKey(ix.programId),
keys: ix.keys.map((key: any) => {
return {
isSigner: key.isSigner,
isWritable: key.isWritable,
pubkey: new PublicKey(key.pubkey),
};
}),
})
);
const cluster: PythCluster = req.body.cluster;
const proposeSquads: SquadsMesh = new SquadsMesh({
connection: new Connection(RPC_URLS[getMultisigCluster(cluster)]),
wallet: new NodeWallet(KEYPAIR),
});
const proposalPubkey = await proposeInstructions(
proposeSquads,
PRICE_FEED_MULTISIG[getMultisigCluster(cluster)],
instructions,
isRemoteCluster(cluster),
WORMHOLE_ADDRESS[getMultisigCluster(cluster)]
);
res.status(200).json({ proposalPubkey });
} catch (error) {
if (error instanceof Error) {
res.status(500).json(error.message);
} else {
res.status(500).json("An unknown error occurred");
}
}
});
app.listen(PORT);

View File

@ -0,0 +1,10 @@
{
"extends": "../../../../tsconfig.base.json",
"include": ["src"],
"exclude": ["node_modules", "**/__tests__/*"],
"compilerOptions": {
"rootDir": "src/",
"outDir": "./lib",
"skipLibCheck": true
}
}

251
package-lock.json generated
View File

@ -1240,6 +1240,70 @@
"follow-redirects": "^1.14.4"
}
},
"governance/xc_admin/packages/proposer_server": {
"version": "0.0.0",
"license": "ISC",
"dependencies": {
"@coral-xyz/anchor": "^0.27.0",
"@pythnetwork/client": "^2.17.0",
"@solana/web3.js": "^1.76.0",
"@sqds/mesh": "^1.0.6",
"cors": "^2.8.5",
"ts-node": "^10.9.1",
"xc_admin_common": "*"
}
},
"governance/xc_admin/packages/proposer_server/node_modules/@coral-xyz/anchor": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.27.0.tgz",
"integrity": "sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==",
"dependencies": {
"@coral-xyz/borsh": "^0.27.0",
"@solana/web3.js": "^1.68.0",
"base64-js": "^1.5.1",
"bn.js": "^5.1.2",
"bs58": "^4.0.1",
"buffer-layout": "^1.2.2",
"camelcase": "^6.3.0",
"cross-fetch": "^3.1.5",
"crypto-hash": "^1.3.0",
"eventemitter3": "^4.0.7",
"js-sha256": "^0.9.0",
"pako": "^2.0.3",
"snake-case": "^3.0.4",
"superstruct": "^0.15.4",
"toml": "^3.0.0"
},
"engines": {
"node": ">=11"
}
},
"governance/xc_admin/packages/proposer_server/node_modules/@coral-xyz/borsh": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.27.0.tgz",
"integrity": "sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==",
"dependencies": {
"bn.js": "^5.1.2",
"buffer-layout": "^1.2.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@solana/web3.js": "^1.68.0"
}
},
"governance/xc_admin/packages/proposer_server/node_modules/camelcase": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"governance/xc_admin/packages/xc_admin_cli": {
"version": "0.0.0",
"license": "ISC",
@ -9775,10 +9839,24 @@
"node": ">=4.0"
}
},
"node_modules/@noble/ed25519": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.1.tgz",
"integrity": "sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw==",
"node_modules/@noble/curves": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz",
"integrity": "sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==",
"funding": [
{
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
],
"dependencies": {
"@noble/hashes": "1.3.0"
}
},
"node_modules/@noble/curves/node_modules/@noble/hashes": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz",
"integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==",
"funding": [
{
"type": "individual",
@ -9797,17 +9875,6 @@
}
]
},
"node_modules/@noble/secp256k1": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz",
"integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==",
"funding": [
{
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
]
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -14742,35 +14809,42 @@
}
},
"node_modules/@solana/web3.js": {
"version": "1.73.0",
"resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.73.0.tgz",
"integrity": "sha512-YrgX3Py7ylh8NYkbanoINUPCj//bWUjYZ5/WPy9nQ9SK3Cl7QWCR+NmbDjmC/fTspZGR+VO9LTQslM++jr5PRw==",
"version": "1.76.0",
"resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.76.0.tgz",
"integrity": "sha512-aJtF/nTs+9St+KtTK/wgVJ+SinfjYzn+3w1ygYIPw8ST6LH+qHBn8XkodgDTwlv/xzNkaVz1kkUDOZ8BPXyZWA==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@noble/ed25519": "^1.7.0",
"@noble/hashes": "^1.1.2",
"@noble/secp256k1": "^1.6.3",
"@noble/curves": "^1.0.0",
"@noble/hashes": "^1.3.0",
"@solana/buffer-layout": "^4.0.0",
"agentkeepalive": "^4.2.1",
"bigint-buffer": "^1.1.5",
"bn.js": "^5.0.0",
"borsh": "^0.7.0",
"bs58": "^4.0.1",
"buffer": "6.0.1",
"buffer": "6.0.3",
"fast-stable-stringify": "^1.0.0",
"jayson": "^3.4.4",
"node-fetch": "2",
"rpc-websockets": "^7.5.0",
"node-fetch": "^2.6.7",
"rpc-websockets": "^7.5.1",
"superstruct": "^0.14.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@solana/web3.js/node_modules/@noble/hashes": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz",
"integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==",
"funding": [
{
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
]
},
"node_modules/@solana/web3.js/node_modules/buffer": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz",
"integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==",
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
@ -43383,6 +43457,10 @@
"signal-exit": "^3.0.2"
}
},
"node_modules/proposer_server": {
"resolved": "governance/xc_admin/packages/proposer_server",
"link": true
},
"node_modules/proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@ -47448,9 +47526,9 @@
}
},
"node_modules/rpc-websockets": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.0.tgz",
"integrity": "sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ==",
"version": "7.5.1",
"resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.1.tgz",
"integrity": "sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==",
"dependencies": {
"@babel/runtime": "^7.17.2",
"eventemitter3": "^4.0.7",
@ -64961,21 +65039,26 @@
}
}
},
"@noble/ed25519": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.1.tgz",
"integrity": "sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw=="
"@noble/curves": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz",
"integrity": "sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==",
"requires": {
"@noble/hashes": "1.3.0"
},
"dependencies": {
"@noble/hashes": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz",
"integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg=="
}
}
},
"@noble/hashes": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.5.tgz",
"integrity": "sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ=="
},
"@noble/secp256k1": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz",
"integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw=="
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -72490,32 +72573,36 @@
}
},
"@solana/web3.js": {
"version": "1.73.0",
"resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.73.0.tgz",
"integrity": "sha512-YrgX3Py7ylh8NYkbanoINUPCj//bWUjYZ5/WPy9nQ9SK3Cl7QWCR+NmbDjmC/fTspZGR+VO9LTQslM++jr5PRw==",
"version": "1.76.0",
"resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.76.0.tgz",
"integrity": "sha512-aJtF/nTs+9St+KtTK/wgVJ+SinfjYzn+3w1ygYIPw8ST6LH+qHBn8XkodgDTwlv/xzNkaVz1kkUDOZ8BPXyZWA==",
"requires": {
"@babel/runtime": "^7.12.5",
"@noble/ed25519": "^1.7.0",
"@noble/hashes": "^1.1.2",
"@noble/secp256k1": "^1.6.3",
"@noble/curves": "^1.0.0",
"@noble/hashes": "^1.3.0",
"@solana/buffer-layout": "^4.0.0",
"agentkeepalive": "^4.2.1",
"bigint-buffer": "^1.1.5",
"bn.js": "^5.0.0",
"borsh": "^0.7.0",
"bs58": "^4.0.1",
"buffer": "6.0.1",
"buffer": "6.0.3",
"fast-stable-stringify": "^1.0.0",
"jayson": "^3.4.4",
"node-fetch": "2",
"rpc-websockets": "^7.5.0",
"node-fetch": "^2.6.7",
"rpc-websockets": "^7.5.1",
"superstruct": "^0.14.2"
},
"dependencies": {
"@noble/hashes": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz",
"integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg=="
},
"buffer": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz",
"integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==",
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
@ -95158,6 +95245,56 @@
"signal-exit": "^3.0.2"
}
},
"proposer_server": {
"version": "file:governance/xc_admin/packages/proposer_server",
"requires": {
"@coral-xyz/anchor": "^0.27.0",
"@pythnetwork/client": "^2.17.0",
"@solana/web3.js": "^1.76.0",
"@sqds/mesh": "^1.0.6",
"cors": "^2.8.5",
"ts-node": "^10.9.1",
"xc_admin_common": "*"
},
"dependencies": {
"@coral-xyz/anchor": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.27.0.tgz",
"integrity": "sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==",
"requires": {
"@coral-xyz/borsh": "^0.27.0",
"@solana/web3.js": "^1.68.0",
"base64-js": "^1.5.1",
"bn.js": "^5.1.2",
"bs58": "^4.0.1",
"buffer-layout": "^1.2.2",
"camelcase": "^6.3.0",
"cross-fetch": "^3.1.5",
"crypto-hash": "^1.3.0",
"eventemitter3": "^4.0.7",
"js-sha256": "^0.9.0",
"pako": "^2.0.3",
"snake-case": "^3.0.4",
"superstruct": "^0.15.4",
"toml": "^3.0.0"
}
},
"@coral-xyz/borsh": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.27.0.tgz",
"integrity": "sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==",
"requires": {
"bn.js": "^5.1.2",
"buffer-layout": "^1.2.0"
}
},
"camelcase": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
}
}
},
"proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@ -99248,9 +99385,9 @@
}
},
"rpc-websockets": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.0.tgz",
"integrity": "sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ==",
"version": "7.5.1",
"resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.1.tgz",
"integrity": "sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==",
"requires": {
"@babel/runtime": "^7.17.2",
"bufferutil": "^4.0.1",