wormhole/terra/tools/deploy.js

268 lines
7.6 KiB
JavaScript
Raw Normal View History

import { Wallet, LCDClient, MnemonicKey } from "@terra-money/terra.js";
import {
StdFee,
MsgInstantiateContract,
MsgExecuteContract,
MsgStoreCode,
} from "@terra-money/terra.js";
import { readFileSync, readdirSync } from "fs";
// TODO: Workaround /tx/estimate_fee errors.
const gas_prices = {
uluna: "0.15",
usdr: "0.1018",
uusd: "0.15",
ukrw: "178.05",
umnt: "431.6259",
ueur: "0.125",
ucny: "0.97",
ujpy: "16",
ugbp: "0.11",
uinr: "11",
ucad: "0.19",
uchf: "0.13",
uaud: "0.19",
usgd: "0.2",
};
async function main() {
const terra = new LCDClient({
URL: "http://localhost:1317",
chainID: "localterra",
});
const wallet = terra.wallet(
new MnemonicKey({
mnemonic:
"notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius",
})
);
await wallet.sequence();
// Deploy WASM blobs.
// Read a list of files from directory containing compiled contracts.
const artifacts = readdirSync("../artifacts/");
// Sort them to get a determinstic list for consecutive code ids.
artifacts.sort();
artifacts.reverse();
const hardcodedGas = {
"cw20_base.wasm": 4000000,
"cw20_wrapped.wasm": 4000000,
"wormhole.wasm": 5000000,
"token_bridge.wasm": 6000000,
"pyth_bridge.wasm": 5000000,
};
// Deploy all found WASM files and assign Code IDs.
const codeIds = {};
for (const artifact in artifacts) {
if (
artifacts.hasOwnProperty(artifact) &&
artifacts[artifact].includes(".wasm")
) {
const file = artifacts[artifact];
const contract_bytes = readFileSync(`../artifacts/${file}`);
console.log(`Storing WASM: ${file} (${contract_bytes.length} bytes)`);
const store_code = new MsgStoreCode(
wallet.key.accAddress,
contract_bytes.toString("base64")
);
try {
const tx = await wallet.createAndSignTx({
msgs: [store_code],
memo: "",
fee: new StdFee(hardcodedGas[artifacts[artifact]], {
uluna: "100000",
}),
});
const rs = await terra.tx.broadcast(tx);
const ci = /"code_id","value":"([^"]+)/gm.exec(rs.raw_log)[1];
codeIds[file] = parseInt(ci);
} catch (e) {
console.log("Failed to Execute");
}
}
}
console.log(codeIds);
// Governance constants defined by the Wormhole spec.
const govChain = 1;
const govAddress =
"0000000000000000000000000000000000000000000000000000000000000004";
const addresses = {};
// Instantiate Wormhole
console.log("Instantiating Wormhole");
await wallet
.createAndSignTx({
msgs: [
new MsgInstantiateContract(
wallet.key.accAddress,
wallet.key.accAddress,
codeIds["wormhole.wasm"],
{
gov_chain: govChain,
gov_address: Buffer.from(govAddress, "hex").toString("base64"),
guardian_set_expirity: 86400,
initial_guardian_set: {
addresses: [
{
bytes: Buffer.from(
"beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe",
"hex"
).toString("base64"),
},
],
expiration_time: 0,
},
}
),
],
memo: "",
})
.then((tx) => terra.tx.broadcast(tx))
.then((rs) => {
const address = /"contract_address","value":"([^"]+)/gm.exec(
rs.raw_log
)[1];
addresses["wormhole.wasm"] = address;
});
console.log("Instantiating Token Bridge");
await wallet
.createAndSignTx({
msgs: [
new MsgInstantiateContract(
wallet.key.accAddress,
wallet.key.accAddress,
codeIds["token_bridge.wasm"],
{
owner: wallet.key.accAddress,
gov_chain: govChain,
gov_address: Buffer.from(govAddress, "hex").toString("base64"),
wormhole_contract: addresses["wormhole.wasm"],
wrapped_asset_code_id: codeIds["cw20_wrapped.wasm"],
}
),
],
memo: "",
})
.then((tx) => terra.tx.broadcast(tx))
.then((rs) => {
const address = /"contract_address","value":"([^"]+)/gm.exec(
rs.raw_log
)[1];
addresses["token_bridge.wasm"] = address;
});
await wallet
.createAndSignTx({
msgs: [
new MsgInstantiateContract(
wallet.key.accAddress,
undefined,
codeIds["cw20_base.wasm"],
{
name: "MOCK",
symbol: "MCK",
decimals: 6,
initial_balances: [
{
address: wallet.key.accAddress,
amount: "100000000",
},
],
mint: null,
}
),
],
memo: "",
})
.then((tx) => terra.tx.broadcast(tx))
.then((rs) => {
const address = /"contract_address","value":"([^"]+)/gm.exec(
rs.raw_log
)[1];
addresses["mock.wasm"] = address;
});
const pythEmitterAddress =
"71f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b";
const pythChain = 1;
// Instantiate Pyth over Wormhole
console.log("Instantiating Pyth over Wormhole");
await wallet
.createAndSignTx({
msgs: [
new MsgInstantiateContract(
wallet.key.accAddress,
wallet.key.accAddress,
codeIds["pyth_bridge.wasm"],
{
gov_chain: govChain,
gov_address: Buffer.from(govAddress, "hex").toString("base64"),
wormhole_contract: addresses["wormhole.wasm"],
pyth_emitter: Buffer.from(pythEmitterAddress, "hex").toString(
"base64"
),
pyth_emitter_chain: pythChain,
}
),
],
memo: "",
})
.then((tx) => terra.tx.broadcast(tx))
.then((rs) => {
const address = /"contract_address","value":"([^"]+)/gm.exec(
rs.raw_log
)[1];
addresses["pyth_bridge.wasm"] = address;
});
console.log(addresses);
const registrations = [
"01000000000100c9f4230109e378f7efc0605fb40f0e1869f2d82fda5b1dfad8a5a2dafee85e033d155c18641165a77a2db6a7afbf2745b458616cb59347e89ae0c7aa3e7cc2d400000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e4272696467650100000001c69a1b1a65dd336bf1df6a77afb501fc25db7fc0938cb08595a9ef473265cb4f",
"01000000000100e2e1975d14734206e7a23d90db48a6b5b6696df72675443293c6057dcb936bf224b5df67d32967adeb220d4fe3cb28be515be5608c74aab6adb31099a478db5c01000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e42726964676501000000020000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16",
];
for (const registration in registrations) {
if (registrations.hasOwnProperty(registration)) {
console.log('Registering');
await wallet
.createAndSignTx({
msgs: [
new MsgExecuteContract(
wallet.key.accAddress,
addresses["token_bridge.wasm"],
{
submit_vaa: {
data: Buffer.from(registrations[registration], "hex").toString('base64'),
},
},
{ uluna: 1000 }
),
],
memo: "",
fee: new StdFee(2000000, {
uluna: "100000",
}),
})
.then((tx) => terra.tx.broadcast(tx))
.then((rs) => console.log(rs));
}
}
}
main();