diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/initialize.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/initialize.rs index f73831546..540270f2e 100644 --- a/cross-chain/solana/programs/wormhole-gateway/src/processor/initialize.rs +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/initialize.rs @@ -3,7 +3,7 @@ use anchor_lang::prelude::*; use anchor_spl::token; use wormhole_anchor_sdk::token_bridge; -const TBTC_FOREIGN_TOKEN_CHAIN: u8 = 2; +const TBTC_FOREIGN_TOKEN_CHAIN: u16 = 2; #[cfg(feature = "mainnet")] const TBTC_FOREIGN_TOKEN_ADDRESS: [u8; 32] = [ @@ -48,7 +48,8 @@ pub struct Initialize<'info> { &TBTC_FOREIGN_TOKEN_CHAIN.to_be_bytes(), TBTC_FOREIGN_TOKEN_ADDRESS.as_ref() ], - bump + bump, + seeds::program = token_bridge::program::ID )] wrapped_tbtc_mint: Account<'info, token::Mint>, @@ -84,7 +85,7 @@ pub struct Initialize<'info> { pub fn initialize(ctx: Context, minting_limit: u64) -> Result<()> { ctx.accounts.custodian.set_inner(Custodian { - bump: ctx.bumps["config"], + bump: ctx.bumps["custodian"], authority: ctx.accounts.authority.key(), tbtc_mint: ctx.accounts.tbtc_mint.key(), wrapped_tbtc_mint: ctx.accounts.wrapped_tbtc_mint.key(), diff --git a/cross-chain/solana/tests/02__wormholeGateway.ts b/cross-chain/solana/tests/02__wormholeGateway.ts index 69eb14fe3..47390f8ae 100644 --- a/cross-chain/solana/tests/02__wormholeGateway.ts +++ b/cross-chain/solana/tests/02__wormholeGateway.ts @@ -9,7 +9,10 @@ import * as spl from "@solana/spl-token"; import { expect } from 'chai'; import { WormholeGateway } from "../target/types/wormhole_gateway"; import { generatePayer, getOrCreateTokenAccount } from "./helpers/utils"; +import { getCustodianPDA, getTokenBridgeRedeemerPDA, getTokenBridgeSenderPDA, getWrappedTbtcTokenPDA } from "./helpers/wormholeGatewayHelpers"; +import { getConfigPDA, getTokenPDA, getMinterPDA, getGuardianPDA } from "./helpers/tbtcHelpers"; import { web3 } from "@coral-xyz/anchor"; +import { Tbtc } from "../target/types/tbtc"; const SOLANA_CORE_BRIDGE_ADDRESS = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"; const SOLANA_TOKEN_BRIDGE_ADDRESS = "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb"; @@ -18,17 +21,49 @@ const ETHEREUM_TBTC_ADDRESS = "0x18084fbA666a33d37592fA2633fD49a74DD93a88"; const GUARDIAN_SET_INDEX = 3; -function getCustodianPDA( + +async function setup( program: Program, -): [anchor.web3.PublicKey, number] { - return web3.PublicKey.findProgramAddressSync( - [ - Buffer.from('custodian'), - ], - program.programId - ); + tbtc: Program, + authority, + mintingLimit: number +) { + const [custodian,] = getCustodianPDA(program); + const [tbtcMint,] = getTokenPDA(tbtc); + const [gatewayWrappedTbtcToken,] = getWrappedTbtcTokenPDA(program); + const [tokenBridgeSender,] = getTokenBridgeSenderPDA(program); + const [tokenBridgeRedeemer,] = getTokenBridgeRedeemerPDA(program); + + const connection = program.provider.connection; + + const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS); + + await program.methods + .initialize(new anchor.BN(mintingLimit)) + .accounts({ + authority: authority.publicKey, + custodian, + tbtcMint, + wrappedTbtcMint, + wrappedTbtcToken: gatewayWrappedTbtcToken, + tokenBridgeSender, + tokenBridgeRedeemer, + }) + .rpc(); } +async function checkState( + program: Program, + expectedAuthority, + expectedMintingLimit, + // expectedMintedAmount, +) { + const [custodian,] = getCustodianPDA(program); + let custodianState = await program.account.custodian.fetch(custodian); + + expect(custodianState.mintingLimit.eq(new anchor.BN(expectedMintingLimit))).to.be.true; + expect(custodianState.authority).to.eql(expectedAuthority.publicKey); +} describe("wormhole-gateway", () => { // Configure the client to use the local cluster. @@ -37,6 +72,8 @@ describe("wormhole-gateway", () => { const program = anchor.workspace.WormholeGateway as Program; const connection = program.provider.connection; + const tbtcProgram = anchor.workspace.Tbtc as Program; + const authority = (program.provider as anchor.AnchorProvider).wallet as anchor.Wallet; const newAuthority = anchor.web3.Keypair.generate(); const minterKeys = anchor.web3.Keypair.generate(); @@ -90,8 +127,8 @@ describe("wormhole-gateway", () => { }); it('setup', async () => { - // await setup(program, authority); - // await checkState(program, authority, 0, 0, 0); + await setup(program, tbtcProgram, authority, 1000); + await checkState(program, authority, 1000); }); }); diff --git a/cross-chain/solana/tests/helpers/wormholeGatewayHelpers.ts b/cross-chain/solana/tests/helpers/wormholeGatewayHelpers.ts new file mode 100644 index 000000000..90d2ee31d --- /dev/null +++ b/cross-chain/solana/tests/helpers/wormholeGatewayHelpers.ts @@ -0,0 +1,67 @@ +import * as anchor from "@coral-xyz/anchor"; +import { Program } from "@coral-xyz/anchor"; +import * as web3 from '@solana/web3.js'; +import { WormholeGateway } from "../../target/types/wormhole_gateway"; + +export function getCustodianPDA( + program: Program, +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('custodian'), + ], + program.programId + ); +} + +export function getGatewayInfoPDA( + program: Program, + targetChain +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('gateway-info'), + toBytesLE(targetChain), + ], + program.programId + ); +} + +export function getWrappedTbtcTokenPDA( + program: Program, +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('wrapped-token'), + ], + program.programId + ); +} + +export function getTokenBridgeSenderPDA( + program: Program, +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('sender'), + ], + program.programId + ); +} + +export function getTokenBridgeRedeemerPDA( + program: Program, +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('redeemer'), + ], + program.programId + ); +} + +function toBytesLE(x): Buffer { + const buf = Buffer.alloc(2); + buf.writeUint16LE(x); + return buf; +} \ No newline at end of file