|
@@ -1,10 +1,28 @@
|
|
|
-import * as web3s from '@solana/web3.js'
|
|
|
|
|
|
|
+import * as web3s from "@solana/web3.js";
|
|
|
import { NETWORKS } from "./networks";
|
|
import { NETWORKS } from "./networks";
|
|
|
import { impossible, Payload, VAA } from "./vaa";
|
|
import { impossible, Payload, VAA } from "./vaa";
|
|
|
import base58 from "bs58";
|
|
import base58 from "bs58";
|
|
|
-import { CHAINS, CONTRACTS, SolanaChainName } from '@certusone/wormhole-sdk/lib/cjs/utils/consts';
|
|
|
|
|
-import { importCoreWasm, importNftWasm, importTokenWasm } from '@certusone/wormhole-sdk/lib/cjs/solana/wasm';
|
|
|
|
|
-import { ixFromRust, postVaaSolanaWithRetry } from '@certusone/wormhole-sdk/lib/cjs/solana';
|
|
|
|
|
|
|
+import { postVaaSolanaWithRetry } from "@certusone/wormhole-sdk/lib/cjs/solana";
|
|
|
|
|
+import {
|
|
|
|
|
+ CHAINS,
|
|
|
|
|
+ CONTRACTS,
|
|
|
|
|
+ SolanaChainName,
|
|
|
|
|
+} from "@certusone/wormhole-sdk/lib/cjs/utils/consts";
|
|
|
|
|
+import {
|
|
|
|
|
+ createUpgradeContractInstruction as createWormholeUpgradeContractInstruction,
|
|
|
|
|
+ createUpgradeGuardianSetInstruction,
|
|
|
|
|
+} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
|
|
|
|
|
+import {
|
|
|
|
|
+ createCompleteTransferNativeInstruction,
|
|
|
|
|
+ createCompleteTransferWrappedInstruction,
|
|
|
|
|
+ createCreateWrappedInstruction,
|
|
|
|
|
+ createRegisterChainInstruction as createTokenBridgeRegisterChainInstruction,
|
|
|
|
|
+ createUpgradeContractInstruction as createTokenBridgeUpgradeContractInstruction,
|
|
|
|
|
+} from "@certusone/wormhole-sdk/lib/cjs/solana/tokenBridge";
|
|
|
|
|
+import {
|
|
|
|
|
+ createRegisterChainInstruction as createNFTBridgeRegisterChainInstruction,
|
|
|
|
|
+ createUpgradeContractInstruction as createNFTBridgeUpgradeContractInstruction,
|
|
|
|
|
+} from "@certusone/wormhole-sdk/lib/cjs/solana/nftBridge";
|
|
|
|
|
|
|
|
export async function execute_solana(
|
|
export async function execute_solana(
|
|
|
v: VAA<Payload>,
|
|
v: VAA<Payload>,
|
|
@@ -12,118 +30,165 @@ export async function execute_solana(
|
|
|
network: "MAINNET" | "TESTNET" | "DEVNET",
|
|
network: "MAINNET" | "TESTNET" | "DEVNET",
|
|
|
chain: SolanaChainName
|
|
chain: SolanaChainName
|
|
|
) {
|
|
) {
|
|
|
- let ix: web3s.TransactionInstruction
|
|
|
|
|
- let connection = setupConnection(NETWORKS[network][chain].rpc)
|
|
|
|
|
- let bridge_id = new web3s.PublicKey(CONTRACTS[network][chain].core)
|
|
|
|
|
- let token_bridge_id = CONTRACTS[network][chain].token_bridge && new web3s.PublicKey(CONTRACTS[network][chain].token_bridge)
|
|
|
|
|
- let nft_bridge_id = CONTRACTS[network][chain].nft_bridge && new web3s.PublicKey(CONTRACTS[network][chain].nft_bridge)
|
|
|
|
|
|
|
+ let ix: web3s.TransactionInstruction;
|
|
|
|
|
+ const connection = setupConnection(NETWORKS[network][chain].rpc);
|
|
|
|
|
+ const bridgeId = new web3s.PublicKey(CONTRACTS[network][chain].core);
|
|
|
|
|
+ const tokenBridgeId =
|
|
|
|
|
+ CONTRACTS[network][chain].token_bridge &&
|
|
|
|
|
+ new web3s.PublicKey(CONTRACTS[network][chain].token_bridge);
|
|
|
|
|
+ const nftBridgeId =
|
|
|
|
|
+ CONTRACTS[network][chain].nft_bridge &&
|
|
|
|
|
+ new web3s.PublicKey(CONTRACTS[network][chain].nft_bridge);
|
|
|
|
|
|
|
|
- let from = web3s.Keypair.fromSecretKey(base58.decode(NETWORKS[network][chain].key))
|
|
|
|
|
|
|
+ const from = web3s.Keypair.fromSecretKey(
|
|
|
|
|
+ base58.decode(NETWORKS[network][chain].key)
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
switch (v.payload.module) {
|
|
switch (v.payload.module) {
|
|
|
case "Core":
|
|
case "Core":
|
|
|
- if (bridge_id === undefined) {
|
|
|
|
|
- throw Error("core bridge contract is undefined")
|
|
|
|
|
|
|
+ if (bridgeId === undefined) {
|
|
|
|
|
+ throw Error("core bridge contract is undefined");
|
|
|
}
|
|
}
|
|
|
- const bridge = await importCoreWasm()
|
|
|
|
|
switch (v.payload.type) {
|
|
switch (v.payload.type) {
|
|
|
case "GuardianSetUpgrade":
|
|
case "GuardianSetUpgrade":
|
|
|
- console.log("Submitting new guardian set")
|
|
|
|
|
- ix = bridge.update_guardian_set_ix(bridge_id.toString(), from.publicKey.toString(), vaa);
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ console.log("Submitting new guardian set");
|
|
|
|
|
+ ix = createUpgradeGuardianSetInstruction(
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
|
|
+ break;
|
|
|
case "ContractUpgrade":
|
|
case "ContractUpgrade":
|
|
|
- console.log("Upgrading core contract")
|
|
|
|
|
- ix = bridge.upgrade_contract_ix(bridge_id.toString(), from.publicKey.toString(), from.publicKey.toString(), vaa);
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ console.log("Upgrading core contract");
|
|
|
|
|
+ ix = createWormholeUpgradeContractInstruction(
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
|
|
+ break;
|
|
|
default:
|
|
default:
|
|
|
- ix = impossible(v.payload)
|
|
|
|
|
|
|
+ ix = impossible(v.payload);
|
|
|
}
|
|
}
|
|
|
- break
|
|
|
|
|
|
|
+ break;
|
|
|
case "NFTBridge":
|
|
case "NFTBridge":
|
|
|
- if (nft_bridge_id === undefined) {
|
|
|
|
|
- throw Error("nft bridge contract is undefined")
|
|
|
|
|
|
|
+ if (nftBridgeId === undefined) {
|
|
|
|
|
+ throw Error("nft bridge contract is undefined");
|
|
|
}
|
|
}
|
|
|
- const nft_bridge = await importNftWasm()
|
|
|
|
|
switch (v.payload.type) {
|
|
switch (v.payload.type) {
|
|
|
case "ContractUpgrade":
|
|
case "ContractUpgrade":
|
|
|
- console.log("Upgrading contract")
|
|
|
|
|
- ix = nft_bridge.upgrade_contract_ix(nft_bridge_id.toString(), bridge_id.toString(), from.publicKey.toString(), from.publicKey.toString(), vaa);
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ console.log("Upgrading contract");
|
|
|
|
|
+ ix = createNFTBridgeUpgradeContractInstruction(
|
|
|
|
|
+ nftBridgeId,
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
|
|
+ break;
|
|
|
case "RegisterChain":
|
|
case "RegisterChain":
|
|
|
- console.log("Registering chain")
|
|
|
|
|
- ix = nft_bridge.register_chain_ix(nft_bridge_id.toString(), bridge_id.toString(), from.publicKey.toString(), vaa);
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ console.log("Registering chain");
|
|
|
|
|
+ ix = createNFTBridgeRegisterChainInstruction(
|
|
|
|
|
+ nftBridgeId,
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
|
|
+ break;
|
|
|
case "Transfer":
|
|
case "Transfer":
|
|
|
- throw Error("Can't redeem NFTs from CLI")
|
|
|
|
|
|
|
+ throw Error("Can't redeem NFTs from CLI");
|
|
|
// TODO: what's the authority account? just bail for now
|
|
// TODO: what's the authority account? just bail for now
|
|
|
default:
|
|
default:
|
|
|
- ix = impossible(v.payload)
|
|
|
|
|
|
|
+ ix = impossible(v.payload);
|
|
|
}
|
|
}
|
|
|
- break
|
|
|
|
|
|
|
+ break;
|
|
|
case "TokenBridge":
|
|
case "TokenBridge":
|
|
|
- if (token_bridge_id === undefined) {
|
|
|
|
|
- throw Error("token bridge contract is undefined")
|
|
|
|
|
|
|
+ if (tokenBridgeId === undefined) {
|
|
|
|
|
+ throw Error("token bridge contract is undefined");
|
|
|
}
|
|
}
|
|
|
- const token_bridge = await importTokenWasm()
|
|
|
|
|
const payload = v.payload;
|
|
const payload = v.payload;
|
|
|
switch (payload.type) {
|
|
switch (payload.type) {
|
|
|
case "ContractUpgrade":
|
|
case "ContractUpgrade":
|
|
|
- console.log("Upgrading contract")
|
|
|
|
|
- ix = token_bridge.upgrade_contract_ix(token_bridge_id.toString(), bridge_id.toString(), from.publicKey.toString(), from.publicKey.toString(), vaa)
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ console.log("Upgrading contract");
|
|
|
|
|
+ ix = createTokenBridgeUpgradeContractInstruction(
|
|
|
|
|
+ tokenBridgeId,
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
|
|
+ break;
|
|
|
case "RegisterChain":
|
|
case "RegisterChain":
|
|
|
- console.log("Registering chain")
|
|
|
|
|
- ix = token_bridge.register_chain_ix(token_bridge_id.toString(), bridge_id.toString(), from.publicKey.toString(), vaa)
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ console.log("Registering chain");
|
|
|
|
|
+ ix = createTokenBridgeRegisterChainInstruction(
|
|
|
|
|
+ tokenBridgeId,
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
|
|
+ break;
|
|
|
case "Transfer":
|
|
case "Transfer":
|
|
|
- console.log("Completing transfer")
|
|
|
|
|
|
|
+ console.log("Completing transfer");
|
|
|
if (payload.tokenChain === CHAINS[chain]) {
|
|
if (payload.tokenChain === CHAINS[chain]) {
|
|
|
- ix = token_bridge.complete_transfer_native_ix(token_bridge_id.toString(), bridge_id.toString(), from.publicKey.toString(), vaa)
|
|
|
|
|
|
|
+ ix = createCompleteTransferNativeInstruction(
|
|
|
|
|
+ tokenBridgeId,
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
} else {
|
|
} else {
|
|
|
- ix = token_bridge.complete_transfer_wrapped_ix(token_bridge_id.toString(), bridge_id.toString(), from.publicKey.toString(), vaa)
|
|
|
|
|
|
|
+ ix = createCompleteTransferWrappedInstruction(
|
|
|
|
|
+ tokenBridgeId,
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
- break
|
|
|
|
|
|
|
+ break;
|
|
|
case "AttestMeta":
|
|
case "AttestMeta":
|
|
|
- console.log("Creating wrapped token")
|
|
|
|
|
- ix = token_bridge.create_wrapped_ix(token_bridge_id.toString(), bridge_id.toString(), from.publicKey.toString(), vaa)
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ console.log("Creating wrapped token");
|
|
|
|
|
+ ix = createCreateWrappedInstruction(
|
|
|
|
|
+ tokenBridgeId,
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa
|
|
|
|
|
+ );
|
|
|
|
|
+ break;
|
|
|
case "TransferWithPayload":
|
|
case "TransferWithPayload":
|
|
|
- throw Error("Can't complete payload 3 transfer from CLI")
|
|
|
|
|
|
|
+ throw Error("Can't complete payload 3 transfer from CLI");
|
|
|
default:
|
|
default:
|
|
|
- impossible(payload)
|
|
|
|
|
- break
|
|
|
|
|
-
|
|
|
|
|
|
|
+ impossible(payload);
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
- break
|
|
|
|
|
|
|
+ break;
|
|
|
default:
|
|
default:
|
|
|
- ix = impossible(v.payload)
|
|
|
|
|
|
|
+ ix = impossible(v.payload);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// First upload the VAA
|
|
// First upload the VAA
|
|
|
- await postVaaSolanaWithRetry(connection,
|
|
|
|
|
|
|
+ await postVaaSolanaWithRetry(
|
|
|
|
|
+ connection,
|
|
|
async (tx) => {
|
|
async (tx) => {
|
|
|
- tx.partialSign(from)
|
|
|
|
|
- return tx
|
|
|
|
|
|
|
+ tx.partialSign(from);
|
|
|
|
|
+ return tx;
|
|
|
},
|
|
},
|
|
|
- bridge_id.toString(), from.publicKey.toString(), vaa, 5)
|
|
|
|
|
|
|
+ bridgeId,
|
|
|
|
|
+ from.publicKey,
|
|
|
|
|
+ vaa,
|
|
|
|
|
+ 5
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
// Then do the actual thing
|
|
// Then do the actual thing
|
|
|
- let transaction = new web3s.Transaction().add(ixFromRust(ix))
|
|
|
|
|
|
|
+ const transaction = new web3s.Transaction().add(ix);
|
|
|
|
|
|
|
|
- let signature = await web3s.sendAndConfirmTransaction(
|
|
|
|
|
|
|
+ const signature = await web3s.sendAndConfirmTransaction(
|
|
|
connection,
|
|
connection,
|
|
|
transaction,
|
|
transaction,
|
|
|
[from],
|
|
[from],
|
|
|
{
|
|
{
|
|
|
- skipPreflight: true
|
|
|
|
|
|
|
+ skipPreflight: true,
|
|
|
}
|
|
}
|
|
|
- )
|
|
|
|
|
- console.log('SIGNATURE', signature)
|
|
|
|
|
|
|
+ );
|
|
|
|
|
+ console.log("SIGNATURE", signature);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function setupConnection(rpc: string): web3s.Connection {
|
|
function setupConnection(rpc: string): web3s.Connection {
|
|
|
- return new web3s.Connection(
|
|
|
|
|
- rpc,
|
|
|
|
|
- 'confirmed',
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ return new web3s.Connection(rpc, "confirmed");
|
|
|
}
|
|
}
|