wormhole/clients/js/near.ts

234 lines
6.3 KiB
TypeScript

import { impossible, Payload } from "./vaa";
import { NETWORKS } from "./networks";
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts";
const { parseSeedPhrase, generateSeedPhrase } = require("near-seed-phrase");
const fs = require("fs");
const BN = require("bn.js");
const nearAPI = require("near-api-js");
function default_near_args(argv) {
let network = argv["n"].toUpperCase();
let contracts = CONTRACTS[network]["near"];
let n = NETWORKS[network]["near"];
if (!("rpc" in argv)) {
argv["rpc"] = n["rpc"];
}
if (!("target" in argv) && "module" in argv) {
if (argv["module"] == "Core") {
argv["target"] = contracts["core"];
console.log("Setting target to core");
}
if (argv["module"] == "TokenBridge") {
argv["target"] = contracts["token_bridge"];
console.log("Setting target to token_bridge");
}
}
if (!("key" in argv)) {
if (n["key"]) {
argv["key"] = n["key"];
}
}
if (!("key" in argv)) {
if ("mnemonic" in argv) {
let k = parseSeedPhrase(argv["mnemonic"]);
argv["key"] = k["secretKey"];
}
}
}
export async function deploy_near(argv) {
default_near_args(argv);
let masterKey = nearAPI.utils.KeyPair.fromString(argv["key"]);
let keyStore = new nearAPI.keyStores.InMemoryKeyStore();
keyStore.setKey(argv["networkId"], argv["account"], masterKey);
keyStore.setKey(argv["networkId"], argv["target"], masterKey);
let near = await nearAPI.connect({
deps: {
keyStore,
},
networkId: argv["networkId"],
nodeUrl: argv["rpc"],
});
let masterAccount = new nearAPI.Account(near.connection, argv["account"]);
let targetAccount = new nearAPI.Account(near.connection, argv["target"]);
console.log(argv);
if ("attach" in argv) {
console.log(
"Sending money: " +
argv["target"] +
" from " +
argv["account"] +
" being sent " +
argv["attach"]
);
console.log(await masterAccount.sendMoney(argv["target"], argv["attach"]));
}
console.log("deploying contract");
console.log(
await targetAccount.deployContract(await fs.readFileSync(argv["file"]))
);
}
export async function upgrade_near(argv) {
default_near_args(argv);
let masterKey = nearAPI.utils.KeyPair.fromString(argv["key"]);
let keyStore = new nearAPI.keyStores.InMemoryKeyStore();
keyStore.setKey(argv["networkId"], argv["account"], masterKey);
let near = await nearAPI.connect({
deps: {
keyStore,
},
networkId: argv["networkId"],
nodeUrl: argv["rpc"],
});
let masterAccount = new nearAPI.Account(near.connection, argv["account"]);
let result = await masterAccount.functionCall({
contractId: argv["target"],
methodName: "update_contract",
args: await fs.readFileSync(argv["file"]),
attachedDeposit: "22797900000000000000000000",
gas: 300000000000000,
});
console.log(result);
}
export async function execute_near(
payload: Payload,
vaa: string,
network: "MAINNET" | "TESTNET" | "DEVNET"
) {
let n = NETWORKS[network]["near"];
let contracts = CONTRACTS[network]["near"];
let target_contract = "";
let numSubmits = 1;
switch (payload.module) {
case "Core":
if (contracts.core === undefined) {
throw new Error("Core bridge not supported yet for near");
}
target_contract = contracts.core;
switch (payload.type) {
case "GuardianSetUpgrade":
console.log("Submitting new guardian set");
break;
case "ContractUpgrade":
console.log("Upgrading core contract");
break;
default:
impossible(payload);
}
break;
case "NFTBridge":
if (contracts.nft_bridge === undefined) {
throw new Error("NFT bridge not supported yet for near");
}
numSubmits = 2;
target_contract = contracts.nft_bridge;
switch (payload.type) {
case "ContractUpgrade":
console.log("Upgrading contract");
break;
case "RegisterChain":
console.log("Registering chain");
break;
case "Transfer":
console.log("Completing transfer");
break;
default:
impossible(payload);
}
break;
case "TokenBridge":
if (contracts.token_bridge === undefined) {
throw new Error("Token bridge not supported yet for near");
}
numSubmits = 2;
target_contract = contracts.token_bridge;
switch (payload.type) {
case "ContractUpgrade":
console.log("Upgrading contract");
break;
case "RegisterChain":
console.log("Registering chain");
break;
case "Transfer":
console.log("Completing transfer");
break;
case "AttestMeta":
console.log("Creating wrapped token");
break;
case "TransferWithPayload":
throw Error("Can't complete payload 3 transfer from CLI");
default:
impossible(payload);
break;
}
break;
default:
impossible(payload);
}
let key = nearAPI.utils.KeyPair.fromString(n.key);
let keyStore = new nearAPI.keyStores.InMemoryKeyStore();
keyStore.setKey(n.networkId, n.deployerAccount, key);
let near = await nearAPI.connect({
keyStore,
networkId: n.networkId,
nodeUrl: n.rpc,
});
let nearAccount = new nearAPI.Account(near.connection, n.deployerAccount);
console.log("submitting vaa the first time");
let result1 = await nearAccount.functionCall({
contractId: target_contract,
methodName: "submit_vaa",
args: {
vaa: vaa,
},
attachedDeposit: new BN("100000000000000000000000"),
gas: new BN("300000000000000"),
});
if (numSubmits <= 1) {
console.log("Hash: " + result1.transaction.hash);
return;
}
// You have to feed a vaa twice into the contract (two submits),
// The first time, it checks if it has been seen at all.
// The second time, it executes.
console.log("submitting vaa the second time");
let result2 = await nearAccount.functionCall({
contractId: target_contract,
methodName: "submit_vaa",
args: {
vaa: vaa,
},
attachedDeposit: new BN("100000000000000000000000"),
gas: new BN("300000000000000"),
});
let txHash = result1.transaction.hash + ":" + result2.transaction.hash;
console.log("Hash: " + txHash);
}