const nearAPI = require("near-api-js"); const BN = require("bn.js"); const fs = require("fs").promises; const assert = require("assert").strict; const fetch = require('node-fetch'); const elliptic = require("elliptic"); const web3Utils = require("web3-utils"); function getConfig(env: any) { switch (env) { case "sandbox": case "local": return { networkId: "sandbox", nodeUrl: "http://localhost:3030", masterAccount: "test.near", contractAccount: Math.floor(Math.random() * 10000).toString() + "wormhole2.test.near", }; } } const contractMethods = { viewMethods: [], changeMethods: ["recover_key"], }; let config :any; let masterAccount : any; let masterKey : any; let pubKey : any; let keyStore : any; let near : any; async function initNear() { config = getConfig(process.env.NEAR_ENV || "sandbox"); // Retrieve the validator key directly in the Tilt environment const response = await fetch('http://localhost:3031/validator_key.json'); const keyFile = await response.json(); masterKey = nearAPI.utils.KeyPair.fromString( keyFile.secret_key || keyFile.private_key ); pubKey = masterKey.getPublicKey(); keyStore = new nearAPI.keyStores.InMemoryKeyStore(); keyStore.setKey(config.networkId, config.masterAccount, masterKey); near = await nearAPI.connect({ deps: { keyStore, }, networkId: config.networkId, nodeUrl: config.nodeUrl, }); masterAccount = new nearAPI.Account(near.connection, config.masterAccount); console.log("Finish init NEAR: " + JSON.stringify(await masterAccount.getAccountBalance())); } async function createContractUser( accountPrefix : any, contractAccountId : any, contractMethod : any ) { let accountId = Math.floor(Math.random() * 10000).toString() + accountPrefix + "." + config.masterAccount; console.log(accountId); let resp = await masterAccount.createAccount( accountId, pubKey, new BN(10).pow(new BN(25)) ); console.log("accountId: " + JSON.stringify(resp)) keyStore.setKey(config.networkId, accountId, masterKey); const account = new nearAPI.Account(near.connection, accountId); const accountUseContract = new nearAPI.Contract( account, contractAccountId, contractMethods ); return accountUseContract; } async function initTest() { const contract = await fs.readFile("./target/wasm32-unknown-unknown/release/near_wormhole.wasm"); const _contractAccount = await masterAccount.createAndDeployContract( config.contractAccount, pubKey, contract, new BN(10).pow(new BN(26)) ); const wormholeUseContract = await createContractUser( "wormhole", config.contractAccount, contractMethods ); console.log("Finish deploy contracts and create test accounts"); return { wormholeUseContract }; } async function test() { const guardianKey = "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe"; const guardianPrivKeys = "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"; const message = Buffer.from("Hello there").toString("hex"); // The actual hash function here doesn't matter that much but this happens to be the hash function used by wormhole const hash = web3Utils.keccak256(web3Utils.keccak256("0x" + message)).substr(2); const ec = new elliptic.ec("secp256k1"); const key = ec.keyFromPrivate(guardianPrivKeys); const signature = key.sign(hash, { canonical: true }); // const key.recoverPubKey(hash, signature, signature.recoveryParam, "hex") const sig = signature.r.toString(16) + signature.s.toString(16); console.log("hash: " + hash); console.log("sig: " + sig); console.log("originalKey: " + guardianKey); await initNear(); const { wormholeUseContract } = await initTest(); let ret = await wormholeUseContract.recover_key({ args: { digest: hash, sig: sig, recovery: signature.recoveryParam } }); console.log(ret); console.log(guardianKey); } test();