clients/js - initial injective commit (#1447)
* clients/js - initial injective commit * clients/js - upgrading the ethers package * clients/js: fix packages
This commit is contained in:
parent
066a2a56aa
commit
66700359f7
|
@ -0,0 +1,191 @@
|
|||
import { getNetworkInfo, Network } from "@injectivelabs/networks";
|
||||
import {
|
||||
MsgExecuteContract,
|
||||
DEFAULT_STD_FEE,
|
||||
privateKeyToPublicKeyBase64,
|
||||
ChainRestAuthApi,
|
||||
} from "@injectivelabs/sdk-ts";
|
||||
import { PrivateKey } from "@injectivelabs/sdk-ts/dist/local";
|
||||
import { createTransaction, MsgArg, TxGrpcClient } from "@injectivelabs/tx-ts";
|
||||
import { fromUint8Array } from "js-base64";
|
||||
import { impossible, Payload } from "./vaa";
|
||||
import { NETWORKS } from "./networks";
|
||||
import { CONTRACTS } from "@certusone/wormhole-sdk";
|
||||
|
||||
export async function execute_injective(
|
||||
payload: Payload,
|
||||
vaa: Buffer,
|
||||
environment: "MAINNET" | "TESTNET" | "DEVNET"
|
||||
) {
|
||||
if (environment === "DEVNET") {
|
||||
throw new Error("Injective is not supported in DEVNET");
|
||||
}
|
||||
const chainName = "injective";
|
||||
let n = NETWORKS[environment][chainName];
|
||||
if (!n.key) {
|
||||
throw Error(`No ${environment} key defined for Injective`);
|
||||
}
|
||||
let contracts = CONTRACTS[environment][chainName];
|
||||
const endPoint =
|
||||
environment === "MAINNET" ? Network.MainnetK8s : Network.TestnetK8s;
|
||||
|
||||
const network = getNetworkInfo(endPoint);
|
||||
const walletPKHash = n.key;
|
||||
const walletPK = PrivateKey.fromPrivateKey(walletPKHash);
|
||||
const walletInjAddr = walletPK.toBech32();
|
||||
const walletPublicKey = privateKeyToPublicKeyBase64(
|
||||
Buffer.from(walletPKHash, "hex")
|
||||
);
|
||||
|
||||
let target_contract: string;
|
||||
let execute_msg: object;
|
||||
|
||||
switch (payload.module) {
|
||||
case "Core":
|
||||
target_contract = contracts.core;
|
||||
execute_msg = {
|
||||
submit_v_a_a: {
|
||||
vaa: fromUint8Array(vaa),
|
||||
},
|
||||
};
|
||||
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) {
|
||||
// NOTE: this code can safely be removed once the injective NFT bridge is
|
||||
// released, but it's fine for it to stay, as the condition will just be
|
||||
// skipped once 'contracts.nft_bridge' is defined
|
||||
throw new Error("NFT bridge not supported yet for injective");
|
||||
}
|
||||
target_contract = contracts.nft_bridge;
|
||||
execute_msg = {
|
||||
submit_vaa: {
|
||||
data: fromUint8Array(vaa),
|
||||
},
|
||||
};
|
||||
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":
|
||||
console.log("contracts:", contracts);
|
||||
if (contracts.token_bridge === undefined) {
|
||||
throw new Error("contracts.token_bridge is undefined");
|
||||
}
|
||||
target_contract = contracts.token_bridge;
|
||||
execute_msg = {
|
||||
submit_vaa: {
|
||||
data: fromUint8Array(vaa),
|
||||
},
|
||||
};
|
||||
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:
|
||||
target_contract = impossible(payload);
|
||||
execute_msg = impossible(payload);
|
||||
}
|
||||
|
||||
console.log("execute_msg", execute_msg);
|
||||
const transaction = MsgExecuteContract.fromJSON({
|
||||
sender: walletInjAddr,
|
||||
contractAddress: target_contract,
|
||||
msg: {
|
||||
data: fromUint8Array(vaa),
|
||||
},
|
||||
action: "submit_vaa",
|
||||
});
|
||||
console.log("transaction:", transaction);
|
||||
|
||||
const accountDetails = await new ChainRestAuthApi(
|
||||
network.sentryHttpApi
|
||||
).fetchAccount(walletInjAddr);
|
||||
const { signBytes, txRaw } = createTransaction({
|
||||
message: transaction.toDirectSign(),
|
||||
memo: "",
|
||||
fee: DEFAULT_STD_FEE,
|
||||
pubKey: walletPublicKey,
|
||||
sequence: parseInt(accountDetails.account.base_account.sequence, 10),
|
||||
accountNumber: parseInt(
|
||||
accountDetails.account.base_account.account_number,
|
||||
10
|
||||
),
|
||||
chainId: network.chainId,
|
||||
});
|
||||
console.log("txRaw", txRaw);
|
||||
|
||||
console.log("sign transaction...");
|
||||
/** Sign transaction */
|
||||
const sig = await walletPK.sign(Buffer.from(signBytes));
|
||||
|
||||
/** Append Signatures */
|
||||
txRaw.setSignaturesList([sig]);
|
||||
|
||||
const txService = new TxGrpcClient({
|
||||
txRaw,
|
||||
endpoint: network.sentryGrpcApi,
|
||||
});
|
||||
|
||||
console.log("simulate transaction...");
|
||||
/** Simulate transaction */
|
||||
try {
|
||||
const simulationResponse = await txService.simulate();
|
||||
console.log(
|
||||
`Transaction simulation response: ${JSON.stringify(
|
||||
simulationResponse.gasInfo
|
||||
)}`
|
||||
);
|
||||
} catch (e) {
|
||||
console.log("Failed to simulate:", e);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("broadcast transaction...");
|
||||
/** Broadcast transaction */
|
||||
const txResponse = await txService.broadcast();
|
||||
console.log("txResponse", txResponse);
|
||||
|
||||
if (txResponse.code !== 0) {
|
||||
console.log(`Transaction failed: ${txResponse.rawLog}`);
|
||||
} else {
|
||||
console.log(
|
||||
`Broadcasted transaction hash: ${JSON.stringify(txResponse.txhash)}`
|
||||
);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import yargs from "yargs";
|
|||
|
||||
import { hideBin } from "yargs/helpers";
|
||||
|
||||
import { Bech32, fromBech32, toHex } from "@cosmjs/encoding";
|
||||
import { fromBech32, toHex } from "@cosmjs/encoding";
|
||||
import {
|
||||
isTerraChain,
|
||||
assertEVMChain,
|
||||
|
@ -14,6 +14,7 @@ import {
|
|||
getEmitterAddressTerra,
|
||||
getEmitterAddressEth,
|
||||
getEmitterAddressAlgorand,
|
||||
isCosmWasmChain,
|
||||
} from "@certusone/wormhole-sdk";
|
||||
import { execute_solana } from "./solana";
|
||||
import {
|
||||
|
@ -40,6 +41,7 @@ import { ethers } from "ethers";
|
|||
import { NETWORKS } from "./networks";
|
||||
import base58 from "bs58";
|
||||
import { execute_algorand } from "./algorand";
|
||||
import { execute_injective } from "./injective";
|
||||
|
||||
setDefaultWasm("node");
|
||||
|
||||
|
@ -278,9 +280,9 @@ yargs(hideBin(process.argv))
|
|||
) {
|
||||
throw Error(`Unknown network: ${network}`);
|
||||
}
|
||||
let chain = argv["chain"]
|
||||
let chain = argv["chain"];
|
||||
let module = argv["module"] as "Core" | "NFTBridge" | "TokenBridge";
|
||||
let addr = ""
|
||||
let addr = "";
|
||||
switch (module) {
|
||||
case "Core":
|
||||
addr = CONTRACTS[network][chain]["core"];
|
||||
|
@ -295,7 +297,8 @@ yargs(hideBin(process.argv))
|
|||
impossible(module);
|
||||
}
|
||||
if (argv["emitter"]) {
|
||||
if (chain === "solana" || chain === "pythnet") { // TODO: Create an isSolanaChain()
|
||||
if (chain === "solana" || chain === "pythnet") {
|
||||
// TODO: Create an isSolanaChain()
|
||||
addr = await getEmitterAddressSolana(addr);
|
||||
} else if (isTerraChain(chain)) {
|
||||
addr = await getEmitterAddressTerra(addr);
|
||||
|
@ -303,9 +306,12 @@ yargs(hideBin(process.argv))
|
|||
addr = getEmitterAddressAlgorand(BigInt(addr));
|
||||
} else if (chain === "near") {
|
||||
if (network !== "MAINNET") {
|
||||
throw Error(`unable to look up near emitter address for ${network}`);
|
||||
throw Error(
|
||||
`unable to look up near emitter address for ${network}`
|
||||
);
|
||||
}
|
||||
addr = "148410499d3fcda4dcfd68a1ebfcdddda16ab28326448d4aae4d2f0465cdfcb7";
|
||||
addr =
|
||||
"148410499d3fcda4dcfd68a1ebfcdddda16ab28326448d4aae4d2f0465cdfcb7";
|
||||
} else {
|
||||
addr = getEmitterAddressEth(addr);
|
||||
}
|
||||
|
@ -317,15 +323,14 @@ yargs(hideBin(process.argv))
|
|||
"chain-id <chain>",
|
||||
"Print the wormhole chain ID integer associated with the specified chain name",
|
||||
(yargs) => {
|
||||
return yargs
|
||||
.positional("chain", {
|
||||
describe: "Chain to query",
|
||||
type: "string",
|
||||
choices: Object.keys(CHAINS),
|
||||
});
|
||||
return yargs.positional("chain", {
|
||||
describe: "Chain to query",
|
||||
type: "string",
|
||||
choices: Object.keys(CHAINS),
|
||||
});
|
||||
},
|
||||
async (argv) => {
|
||||
assertChain(argv["chain"]);
|
||||
assertChain(argv["chain"]);
|
||||
console.log(toChainId(argv["chain"]));
|
||||
}
|
||||
)
|
||||
|
@ -664,7 +669,7 @@ yargs(hideBin(process.argv))
|
|||
} else if (chain === "near") {
|
||||
await execute_near(parsed_vaa.payload, vaa_hex, network);
|
||||
} else if (chain === "injective") {
|
||||
throw Error("INJECTIVE is not supported yet");
|
||||
await execute_injective(parsed_vaa.payload, buf, network);
|
||||
} else if (chain === "osmosis") {
|
||||
throw Error("OSMOSIS is not supported yet");
|
||||
} else if (chain === "sui") {
|
||||
|
@ -694,7 +699,7 @@ function parseAddress(chain: ChainName, address: string): string {
|
|||
throw Error("Chain unset");
|
||||
} else if (isEVMChain(chain)) {
|
||||
return "0x" + evm_address(address);
|
||||
} else if (isTerraChain(chain)) {
|
||||
} else if (isCosmWasmChain(chain)) {
|
||||
return "0x" + toHex(fromBech32(address).data).padStart(64, "0");
|
||||
} else if (chain === "solana" || chain === "pythnet") {
|
||||
return "0x" + toHex(base58.decode(address)).padStart(64, "0");
|
||||
|
@ -702,9 +707,7 @@ function parseAddress(chain: ChainName, address: string): string {
|
|||
// TODO: is there a better native format for algorand?
|
||||
return "0x" + evm_address(address);
|
||||
} else if (chain === "near") {
|
||||
return "0x" + hex(address).substring(2).padStart(64, "0")
|
||||
} else if (chain === "injective") {
|
||||
throw Error("INJECTIVE is not supported yet");
|
||||
return "0x" + hex(address).substring(2).padStart(64, "0");
|
||||
} else if (chain === "osmosis") {
|
||||
throw Error("OSMOSIS is not supported yet");
|
||||
} else if (chain === "sui") {
|
||||
|
|
|
@ -82,7 +82,8 @@ const MAINNET = {
|
|||
rpc: "https://rpc.mainnet.near.org",
|
||||
key: get_env_var("NEAR_KEY"),
|
||||
networkId: "mainnet",
|
||||
deployerAccount: "85957f38de1768d6db9eab29bee9dd2a01462aff9c8d83daefb9bcd2506c32d2",
|
||||
deployerAccount:
|
||||
"85957f38de1768d6db9eab29bee9dd2a01462aff9c8d83daefb9bcd2506c32d2",
|
||||
},
|
||||
injective: {
|
||||
rpc: undefined,
|
||||
|
@ -210,12 +211,12 @@ const TESTNET = {
|
|||
injective: {
|
||||
rpc: "https://k8s.testnet.tm.injective.network:443",
|
||||
chain_id: "injective-888",
|
||||
key: get_env_var("ETH_KEY_TESTNET"),
|
||||
key: get_env_var("INJECTIVE_KEY_TESTNET"),
|
||||
},
|
||||
osmosis: {
|
||||
rpc: undefined,
|
||||
chain_id: "osmo-test-4",
|
||||
key: get_env_var("ETH_KEY_TESTNET"),
|
||||
key: get_env_var("OSMOSIS_KEY_TESTNET"),
|
||||
},
|
||||
aptos: {
|
||||
rpc: undefined,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,6 +5,9 @@
|
|||
"@celo-tools/celo-ethers-wrapper": "^0.1.0",
|
||||
"@certusone/wormhole-sdk": "^0.7.0",
|
||||
"@cosmjs/encoding": "^0.26.2",
|
||||
"@injectivelabs/networks": "^1.0.12",
|
||||
"@injectivelabs/sdk-ts": "^1.0.75",
|
||||
"@injectivelabs/tx-ts": "^1.0.22",
|
||||
"@solana/web3.js": "^1.22.0",
|
||||
"@terra-money/terra.js": "^3.1.3",
|
||||
"algosdk": "^1.15.0",
|
||||
|
@ -14,7 +17,7 @@
|
|||
"bs58": "^4.0.1",
|
||||
"buffer-layout": "^1.2.2",
|
||||
"dotenv": "^10.0.0",
|
||||
"ethers": "^5.4.1",
|
||||
"ethers": "^5.6.8",
|
||||
"js-base64": "^3.6.1",
|
||||
"near-api-js": "^0.45.1",
|
||||
"npm": "^7.20.0",
|
||||
|
|
Loading…
Reference in New Issue