|
|
@@ -12,7 +12,7 @@ import {
|
|
|
DataSource,
|
|
|
EvmSetWormholeAddress,
|
|
|
} from "xc_admin_common";
|
|
|
-import { AptosClient } from "aptos";
|
|
|
+import { AptosClient, AptosAccount, CoinClient } from "aptos";
|
|
|
import Web3 from "web3";
|
|
|
import {
|
|
|
CosmwasmExecutor,
|
|
|
@@ -20,6 +20,12 @@ import {
|
|
|
InjectiveExecutor,
|
|
|
} from "@pythnetwork/cosmwasm-deploy-tools";
|
|
|
import { Network } from "@injectivelabs/networks";
|
|
|
+import {
|
|
|
+ Connection,
|
|
|
+ Ed25519Keypair,
|
|
|
+ JsonRpcProvider,
|
|
|
+ RawSigner,
|
|
|
+} from "@mysten/sui.js";
|
|
|
|
|
|
export type ChainConfig = Record<string, string> & {
|
|
|
mainnet: boolean;
|
|
|
@@ -96,19 +102,44 @@ export abstract class Chain extends Storable {
|
|
|
* @param upgradeInfo based on the contract type, this can be a contract address, codeId, package digest, etc.
|
|
|
*/
|
|
|
abstract generateGovernanceUpgradePayload(upgradeInfo: unknown): Buffer;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the account address associated with the given private key.
|
|
|
+ * @param privateKey the account private key
|
|
|
+ */
|
|
|
+ abstract getAccountAddress(privateKey: PrivateKey): Promise<string>;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the balance of the account associated with the given private key.
|
|
|
+ * @param privateKey the account private key
|
|
|
+ */
|
|
|
+ abstract getAccountBalance(privateKey: PrivateKey): Promise<number>;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * A Chain object that represents all chains. This is used for governance instructions that apply to all chains.
|
|
|
+ * For example, governance instructions to upgrade Pyth data sources.
|
|
|
+ */
|
|
|
export class GlobalChain extends Chain {
|
|
|
static type = "GlobalChain";
|
|
|
constructor() {
|
|
|
super("global", true, "unset");
|
|
|
}
|
|
|
+
|
|
|
generateGovernanceUpgradePayload(): Buffer {
|
|
|
throw new Error(
|
|
|
"Can not create a governance message for upgrading contracts on all chains!"
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ async getAccountAddress(_privateKey: PrivateKey): Promise<string> {
|
|
|
+ throw new Error("Can not get account for GlobalChain.");
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAccountBalance(_privateKey: PrivateKey): Promise<number> {
|
|
|
+ throw new Error("Can not get account balance for GlobalChain.");
|
|
|
+ }
|
|
|
+
|
|
|
getType(): string {
|
|
|
return GlobalChain.type;
|
|
|
}
|
|
|
@@ -177,7 +208,9 @@ export class CosmWasmChain extends Chain {
|
|
|
return new CosmosUpgradeContract(this.wormholeChainName, codeId).encode();
|
|
|
}
|
|
|
|
|
|
- async getExecutor(privateKey: PrivateKey) {
|
|
|
+ async getExecutor(
|
|
|
+ privateKey: PrivateKey
|
|
|
+ ): Promise<CosmwasmExecutor | InjectiveExecutor> {
|
|
|
if (this.getId().indexOf("injective") > -1) {
|
|
|
return InjectiveExecutor.fromPrivateKey(
|
|
|
this.isMainnet() ? Network.Mainnet : Network.Testnet,
|
|
|
@@ -190,6 +223,20 @@ export class CosmWasmChain extends Chain {
|
|
|
this.gasPrice + this.feeDenom
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ async getAccountAddress(privateKey: PrivateKey): Promise<string> {
|
|
|
+ const executor = await this.getExecutor(privateKey);
|
|
|
+ if (executor instanceof InjectiveExecutor) {
|
|
|
+ return executor.getAddress();
|
|
|
+ } else {
|
|
|
+ return await executor.getAddress();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAccountBalance(privateKey: PrivateKey): Promise<number> {
|
|
|
+ const executor = await this.getExecutor(privateKey);
|
|
|
+ return await executor.getBalance();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export class SuiChain extends Chain {
|
|
|
@@ -238,6 +285,27 @@ export class SuiChain extends Chain {
|
|
|
digest
|
|
|
).encode();
|
|
|
}
|
|
|
+
|
|
|
+ getProvider(): JsonRpcProvider {
|
|
|
+ return new JsonRpcProvider(new Connection({ fullnode: this.rpcUrl }));
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAccountAddress(privateKey: PrivateKey): Promise<string> {
|
|
|
+ const provider = this.getProvider();
|
|
|
+ const keypair = Ed25519Keypair.fromSecretKey(
|
|
|
+ Buffer.from(privateKey, "hex")
|
|
|
+ );
|
|
|
+ const wallet = new RawSigner(keypair, provider);
|
|
|
+ return await wallet.getAddress();
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAccountBalance(privateKey: PrivateKey): Promise<number> {
|
|
|
+ const provider = this.getProvider();
|
|
|
+ const balance = await provider.getBalance({
|
|
|
+ owner: await this.getAccountAddress(privateKey),
|
|
|
+ });
|
|
|
+ return Number(balance.totalBalance) / 10 ** 9;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export class EvmChain extends Chain {
|
|
|
@@ -361,6 +429,20 @@ export class EvmChain extends Chain {
|
|
|
});
|
|
|
return deployedContract.options.address;
|
|
|
}
|
|
|
+
|
|
|
+ async getAccountAddress(privateKey: PrivateKey): Promise<string> {
|
|
|
+ const web3 = new Web3(this.getRpcUrl());
|
|
|
+ const signer = web3.eth.accounts.privateKeyToAccount(privateKey);
|
|
|
+ return signer.address;
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAccountBalance(privateKey: PrivateKey): Promise<number> {
|
|
|
+ const web3 = new Web3(this.getRpcUrl());
|
|
|
+ const balance = await web3.eth.getBalance(
|
|
|
+ await this.getAccountAddress(privateKey)
|
|
|
+ );
|
|
|
+ return Number(balance) / 10 ** 18;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export class AptosChain extends Chain {
|
|
|
@@ -413,4 +495,20 @@ export class AptosChain extends Chain {
|
|
|
parsed.rpcUrl
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ async getAccountAddress(privateKey: PrivateKey): Promise<string> {
|
|
|
+ const account = new AptosAccount(
|
|
|
+ new Uint8Array(Buffer.from(privateKey, "hex"))
|
|
|
+ );
|
|
|
+ return account.address().toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAccountBalance(privateKey: PrivateKey): Promise<number> {
|
|
|
+ const client = this.getClient();
|
|
|
+ const account = new AptosAccount(
|
|
|
+ new Uint8Array(Buffer.from(privateKey, "hex"))
|
|
|
+ );
|
|
|
+ const coinClient = new CoinClient(client);
|
|
|
+ return Number(await coinClient.checkBalance(account)) / 10 ** 8;
|
|
|
+ }
|
|
|
}
|