2021-08-30 01:37:53 -07:00
|
|
|
#![allow(warnings)]
|
|
|
|
|
|
|
|
use borsh::BorshSerialize;
|
2022-04-20 22:15:07 -07:00
|
|
|
use bridge::{
|
|
|
|
accounts::{
|
|
|
|
Bridge,
|
|
|
|
FeeCollector,
|
|
|
|
GuardianSet,
|
|
|
|
GuardianSetDerivationData,
|
|
|
|
PostedVAA,
|
|
|
|
PostedVAADerivationData,
|
|
|
|
SignatureSet,
|
|
|
|
},
|
|
|
|
instruction,
|
|
|
|
types::{
|
|
|
|
GovernancePayloadGuardianSetChange,
|
|
|
|
GovernancePayloadSetMessageFee,
|
|
|
|
GovernancePayloadTransferFees,
|
|
|
|
},
|
|
|
|
BridgeConfig,
|
|
|
|
BridgeData,
|
|
|
|
GuardianSetData,
|
|
|
|
Initialize,
|
|
|
|
MessageData,
|
|
|
|
PostVAA,
|
|
|
|
PostVAAData,
|
|
|
|
PostedVAAData,
|
|
|
|
SequenceTracker,
|
|
|
|
SerializePayload,
|
|
|
|
Signature,
|
|
|
|
SignatureSet as SignatureSetData,
|
|
|
|
};
|
2021-08-30 01:37:53 -07:00
|
|
|
use byteorder::{
|
|
|
|
BigEndian,
|
|
|
|
WriteBytesExt,
|
|
|
|
};
|
|
|
|
use hex_literal::hex;
|
2022-04-20 22:15:07 -07:00
|
|
|
use libsecp256k1::{
|
2021-08-30 01:37:53 -07:00
|
|
|
Message as Secp256k1Message,
|
|
|
|
PublicKey,
|
|
|
|
SecretKey,
|
|
|
|
};
|
2022-04-20 22:15:07 -07:00
|
|
|
use nft_bridge::{
|
|
|
|
accounts::{
|
|
|
|
ConfigAccount,
|
|
|
|
EmitterAccount,
|
|
|
|
SplTokenMeta,
|
|
|
|
SplTokenMetaDerivationData,
|
|
|
|
WrappedDerivationData,
|
|
|
|
WrappedMint,
|
|
|
|
},
|
|
|
|
messages::{
|
|
|
|
PayloadGovernanceRegisterChain,
|
|
|
|
PayloadTransfer,
|
|
|
|
},
|
|
|
|
types::{
|
|
|
|
Address,
|
|
|
|
Config,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
use primitive_types::U256;
|
|
|
|
use rand::Rng;
|
2021-08-30 01:37:53 -07:00
|
|
|
use sha3::Digest;
|
|
|
|
use solana_program::{
|
|
|
|
borsh::try_from_slice_unchecked,
|
|
|
|
hash,
|
|
|
|
instruction::{
|
|
|
|
AccountMeta,
|
|
|
|
Instruction,
|
|
|
|
},
|
|
|
|
program_pack::Pack,
|
|
|
|
pubkey::Pubkey,
|
|
|
|
system_instruction::{
|
|
|
|
self,
|
|
|
|
create_account,
|
|
|
|
},
|
|
|
|
system_program,
|
|
|
|
sysvar,
|
|
|
|
};
|
2022-04-20 22:15:07 -07:00
|
|
|
use solana_program_test::{
|
|
|
|
tokio,
|
|
|
|
BanksClient,
|
|
|
|
};
|
2021-08-30 01:37:53 -07:00
|
|
|
use solana_sdk::{
|
2022-04-20 22:15:07 -07:00
|
|
|
commitment_config::CommitmentLevel,
|
2021-08-30 01:37:53 -07:00
|
|
|
signature::{
|
|
|
|
read_keypair_file,
|
|
|
|
Keypair,
|
|
|
|
Signer,
|
|
|
|
},
|
|
|
|
transaction::Transaction,
|
2022-04-20 22:15:07 -07:00
|
|
|
transport::TransportError,
|
2021-08-30 01:37:53 -07:00
|
|
|
};
|
|
|
|
use solitaire::{
|
|
|
|
processors::seeded::Seeded,
|
|
|
|
AccountState,
|
|
|
|
};
|
|
|
|
use spl_token::state::Mint;
|
|
|
|
use std::{
|
2022-04-20 22:15:07 -07:00
|
|
|
collections::HashMap,
|
2021-08-30 01:37:53 -07:00
|
|
|
convert::TryInto,
|
|
|
|
io::{
|
|
|
|
Cursor,
|
|
|
|
Write,
|
|
|
|
},
|
2022-04-20 22:15:07 -07:00
|
|
|
str::FromStr,
|
2021-08-30 01:37:53 -07:00
|
|
|
time::{
|
|
|
|
Duration,
|
|
|
|
SystemTime,
|
2022-04-20 22:15:07 -07:00
|
|
|
UNIX_EPOCH,
|
2021-08-30 01:37:53 -07:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
mod common;
|
|
|
|
|
|
|
|
const GOVERNANCE_KEY: [u8; 64] = [
|
|
|
|
240, 133, 120, 113, 30, 67, 38, 184, 197, 72, 234, 99, 241, 21, 58, 225, 41, 157, 171, 44, 196,
|
|
|
|
163, 134, 236, 92, 148, 110, 68, 127, 114, 177, 0, 173, 253, 199, 9, 242, 142, 201, 174, 108,
|
|
|
|
197, 18, 102, 115, 0, 31, 205, 127, 188, 191, 56, 171, 228, 20, 247, 149, 170, 141, 231, 147,
|
|
|
|
88, 97, 199,
|
|
|
|
];
|
|
|
|
|
|
|
|
struct Context {
|
2022-04-20 22:15:07 -07:00
|
|
|
/// Guardian public keys.
|
|
|
|
guardians: Vec<[u8; 20]>,
|
|
|
|
|
|
|
|
/// Guardian secret keys.
|
|
|
|
guardian_keys: Vec<SecretKey>,
|
|
|
|
|
2021-08-30 01:37:53 -07:00
|
|
|
/// Address of the core bridge contract.
|
|
|
|
bridge: Pubkey,
|
|
|
|
|
|
|
|
/// Shared RPC client for tests to make transactions with.
|
2022-04-20 22:15:07 -07:00
|
|
|
client: BanksClient,
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
/// Payer key with a ton of lamports to ease testing with.
|
|
|
|
payer: Keypair,
|
|
|
|
|
|
|
|
/// Address of the token bridge itself that we wish to test.
|
2022-04-20 22:15:07 -07:00
|
|
|
nft_bridge: Pubkey,
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
/// Keypairs for mint information, required in multiple tests.
|
|
|
|
mint_authority: Keypair,
|
|
|
|
mint: Keypair,
|
|
|
|
mint_meta: Pubkey,
|
|
|
|
|
|
|
|
/// Keypairs for test token accounts.
|
|
|
|
token_authority: Keypair,
|
|
|
|
token_account: Keypair,
|
|
|
|
metadata_account: Pubkey,
|
|
|
|
}
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
async fn set_up() -> Result<Context, TransportError> {
|
|
|
|
let (guardians, guardian_keys) = common::generate_keys(6);
|
2021-08-30 01:37:53 -07:00
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
let (mut client, payer, bridge, nft_bridge) = common::setup().await;
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
// Setup a Bridge to test against.
|
2022-04-20 22:15:07 -07:00
|
|
|
common::initialize_bridge(&mut client, bridge, &payer, &guardians).await?;
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
// Context for test environment.
|
|
|
|
let mint = Keypair::new();
|
|
|
|
let mint_pubkey = mint.pubkey();
|
|
|
|
let metadata_pubkey = Pubkey::from_str("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s").unwrap();
|
|
|
|
|
|
|
|
// SPL Token Meta
|
|
|
|
let metadata_seeds = &[
|
|
|
|
"metadata".as_bytes(),
|
|
|
|
metadata_pubkey.as_ref(),
|
|
|
|
mint_pubkey.as_ref(),
|
|
|
|
];
|
|
|
|
|
|
|
|
let (metadata_key, metadata_bump_seed) = Pubkey::find_program_address(
|
|
|
|
metadata_seeds,
|
|
|
|
&Pubkey::from_str("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s").unwrap(),
|
|
|
|
);
|
|
|
|
|
|
|
|
// Token Bridge Meta
|
2022-04-20 22:15:07 -07:00
|
|
|
use nft_bridge::accounts::WrappedTokenMeta;
|
2021-08-30 01:37:53 -07:00
|
|
|
let metadata_account = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
2022-04-20 22:15:07 -07:00
|
|
|
&nft_bridge::accounts::WrappedMetaDerivationData {
|
2021-08-30 01:37:53 -07:00
|
|
|
mint_key: mint_pubkey.clone(),
|
|
|
|
},
|
2022-04-20 22:15:07 -07:00
|
|
|
&nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
let mut context = Context {
|
2022-04-20 22:15:07 -07:00
|
|
|
guardians,
|
|
|
|
guardian_keys,
|
2021-08-30 01:37:53 -07:00
|
|
|
bridge,
|
|
|
|
client,
|
|
|
|
payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
mint_authority: Keypair::new(),
|
|
|
|
mint,
|
|
|
|
mint_meta: metadata_account,
|
|
|
|
token_account: Keypair::new(),
|
|
|
|
token_authority: Keypair::new(),
|
|
|
|
metadata_account: metadata_key,
|
|
|
|
};
|
|
|
|
|
|
|
|
// Create a mint for use within tests.
|
|
|
|
common::create_mint(
|
2022-04-20 22:15:07 -07:00
|
|
|
&mut context.client,
|
2021-08-30 01:37:53 -07:00
|
|
|
&context.payer,
|
|
|
|
&context.mint_authority.pubkey(),
|
|
|
|
&context.mint,
|
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await?;
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
// Create Token accounts for use within tests.
|
|
|
|
common::create_token_account(
|
2022-04-20 22:15:07 -07:00
|
|
|
&mut context.client,
|
2021-08-30 01:37:53 -07:00
|
|
|
&context.payer,
|
|
|
|
&context.token_account,
|
2022-04-20 22:15:07 -07:00
|
|
|
&context.token_authority.pubkey(),
|
|
|
|
&context.mint.pubkey(),
|
2021-08-30 01:37:53 -07:00
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await?;
|
2021-08-30 01:37:53 -07:00
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
// Create an SPL metadata account for native NFTs.
|
|
|
|
common::create_spl_metadata(
|
|
|
|
&mut context.client,
|
2021-08-30 01:37:53 -07:00
|
|
|
&context.payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
context.metadata_account,
|
2021-08-30 01:37:53 -07:00
|
|
|
&context.mint_authority,
|
2022-04-20 22:15:07 -07:00
|
|
|
context.mint.pubkey(),
|
|
|
|
context.payer.pubkey(),
|
|
|
|
"Non-Fungible Token".into(),
|
|
|
|
"NFT".into(),
|
|
|
|
"https://example.com".into(),
|
2021-08-30 01:37:53 -07:00
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await?;
|
2021-08-30 01:37:53 -07:00
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
// Mint an NFT.
|
|
|
|
common::mint_tokens(
|
|
|
|
&mut context.client,
|
2021-08-30 01:37:53 -07:00
|
|
|
&context.payer,
|
|
|
|
&context.mint_authority,
|
|
|
|
&context.mint,
|
2022-04-20 22:15:07 -07:00
|
|
|
&context.token_account.pubkey(),
|
|
|
|
1,
|
2021-08-30 01:37:53 -07:00
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await?;
|
2021-08-30 01:37:53 -07:00
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
// Initialize the nft bridge.
|
|
|
|
common::initialize(
|
|
|
|
&mut context.client,
|
|
|
|
context.nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
&context.payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
context.bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await
|
2021-08-30 01:37:53 -07:00
|
|
|
.unwrap();
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
// Verify NFT Bridge State
|
|
|
|
let config_key = ConfigAccount::<'_, { AccountState::Uninitialized }>::key(None, &nft_bridge);
|
|
|
|
let config: Config = common::get_account_data(&mut context.client, config_key)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(config.wormhole_bridge, bridge);
|
2021-08-30 01:37:53 -07:00
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
Ok(context)
|
2021-08-30 01:37:53 -07:00
|
|
|
}
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
#[tokio::test]
|
|
|
|
async fn transfer_native() {
|
2021-08-30 01:37:53 -07:00
|
|
|
let Context {
|
|
|
|
ref payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
ref mut client,
|
|
|
|
bridge,
|
|
|
|
nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
ref mint_authority,
|
|
|
|
ref mint,
|
|
|
|
ref mint_meta,
|
|
|
|
ref token_account,
|
|
|
|
ref token_authority,
|
|
|
|
..
|
2022-04-20 22:15:07 -07:00
|
|
|
} = set_up().await.unwrap();
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
let message = &Keypair::new();
|
|
|
|
|
|
|
|
common::transfer_native(
|
|
|
|
client,
|
2022-04-20 22:15:07 -07:00
|
|
|
nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
bridge,
|
|
|
|
payer,
|
|
|
|
message,
|
|
|
|
token_account,
|
|
|
|
token_authority,
|
|
|
|
mint.pubkey(),
|
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await
|
2021-08-30 01:37:53 -07:00
|
|
|
.unwrap();
|
|
|
|
}
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
async fn register_chain(context: &mut Context) {
|
2021-08-30 01:37:53 -07:00
|
|
|
let Context {
|
|
|
|
ref payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
ref mut client,
|
2021-08-30 01:37:53 -07:00
|
|
|
ref bridge,
|
2022-04-20 22:15:07 -07:00
|
|
|
ref nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
ref mint_authority,
|
|
|
|
ref mint,
|
|
|
|
ref mint_meta,
|
|
|
|
ref token_authority,
|
2022-04-20 22:15:07 -07:00
|
|
|
ref guardian_keys,
|
2021-08-30 01:37:53 -07:00
|
|
|
..
|
|
|
|
} = context;
|
|
|
|
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
|
|
let emitter = Keypair::from_bytes(&GOVERNANCE_KEY).unwrap();
|
|
|
|
let payload = PayloadGovernanceRegisterChain {
|
|
|
|
chain: 2,
|
|
|
|
endpoint_address: [0u8; 32],
|
|
|
|
};
|
|
|
|
let message = payload.try_to_vec().unwrap();
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
let (vaa, body, _) = common::generate_vaa(emitter.pubkey().to_bytes(), 1, message, nonce, 0);
|
|
|
|
let signature_set = common::verify_signatures(client, &bridge, payer, body, guardian_keys, 0)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
common::post_vaa(client, *bridge, payer, signature_set, vaa.clone())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
2022-04-20 22:15:07 -07:00
|
|
|
payload_hash: body.to_vec(),
|
2021-08-30 01:37:53 -07:00
|
|
|
};
|
|
|
|
let message_key =
|
2022-04-20 22:15:07 -07:00
|
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, bridge);
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
common::register_chain(
|
|
|
|
client,
|
2022-04-20 22:15:07 -07:00
|
|
|
*nft_bridge,
|
|
|
|
*bridge,
|
|
|
|
message_key,
|
2021-08-30 01:37:53 -07:00
|
|
|
vaa,
|
|
|
|
payload,
|
|
|
|
payer,
|
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await
|
2021-08-30 01:37:53 -07:00
|
|
|
.unwrap();
|
|
|
|
}
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
#[tokio::test]
|
|
|
|
async fn transfer_native_in() {
|
|
|
|
let mut context = set_up().await.unwrap();
|
|
|
|
register_chain(&mut context).await;
|
2021-08-30 01:37:53 -07:00
|
|
|
let Context {
|
|
|
|
ref payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
ref mut client,
|
|
|
|
bridge,
|
|
|
|
nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
ref mint_authority,
|
|
|
|
ref mint,
|
|
|
|
ref mint_meta,
|
|
|
|
ref token_account,
|
|
|
|
ref token_authority,
|
2022-04-20 22:15:07 -07:00
|
|
|
ref guardian_keys,
|
2021-08-30 01:37:53 -07:00
|
|
|
..
|
|
|
|
} = context;
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
// Do an initial transfer so that the bridge account owns the NFT.
|
|
|
|
let message = &Keypair::new();
|
|
|
|
common::transfer_native(
|
|
|
|
client,
|
|
|
|
nft_bridge,
|
|
|
|
bridge,
|
|
|
|
payer,
|
|
|
|
message,
|
|
|
|
token_account,
|
|
|
|
token_authority,
|
|
|
|
mint.pubkey(),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
2021-08-30 01:37:53 -07:00
|
|
|
let nonce = rand::thread_rng().gen();
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
let token_address = [1u8; 32];
|
|
|
|
let token_chain = 1;
|
|
|
|
let token_id = U256::from_big_endian(&mint.pubkey().to_bytes());
|
|
|
|
|
|
|
|
let associated_addr = spl_associated_token_account::get_associated_token_address(
|
|
|
|
&token_authority.pubkey(),
|
|
|
|
&mint.pubkey(),
|
|
|
|
);
|
|
|
|
|
2021-08-30 01:37:53 -07:00
|
|
|
let payload = PayloadTransfer {
|
2022-04-20 22:15:07 -07:00
|
|
|
token_address: [1u8; 32],
|
2021-08-30 01:37:53 -07:00
|
|
|
token_chain: 1,
|
2022-04-20 22:15:07 -07:00
|
|
|
symbol: "NFT".into(),
|
|
|
|
name: "Non-Fungible Token".into(),
|
|
|
|
token_id,
|
|
|
|
uri: "https://example.com".to_string(),
|
|
|
|
to: associated_addr.to_bytes(),
|
2021-08-30 01:37:53 -07:00
|
|
|
to_chain: 1,
|
|
|
|
};
|
|
|
|
let message = payload.try_to_vec().unwrap();
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
let (vaa, body, _) = common::generate_vaa([0u8; 32], 2, message, nonce, 1);
|
|
|
|
let signature_set = common::verify_signatures(client, &bridge, payer, body, guardian_keys, 0)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
common::post_vaa(client, bridge, payer, signature_set, vaa.clone())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let msg_derivation_data = &PostedVAADerivationData {
|
|
|
|
payload_hash: body.to_vec(),
|
2021-08-30 01:37:53 -07:00
|
|
|
};
|
|
|
|
let message_key =
|
|
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
|
|
|
|
common::complete_native(
|
|
|
|
client,
|
2022-04-20 22:15:07 -07:00
|
|
|
nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
bridge,
|
2022-04-20 22:15:07 -07:00
|
|
|
message_key,
|
2021-08-30 01:37:53 -07:00
|
|
|
vaa,
|
|
|
|
payload,
|
|
|
|
payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
token_authority.pubkey(),
|
|
|
|
mint.pubkey(),
|
2021-08-30 01:37:53 -07:00
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await
|
2021-08-30 01:37:53 -07:00
|
|
|
.unwrap();
|
|
|
|
}
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
#[tokio::test]
|
|
|
|
async fn transfer_wrapped() {
|
|
|
|
let mut context = set_up().await.unwrap();
|
|
|
|
register_chain(&mut context).await;
|
2021-08-30 01:37:53 -07:00
|
|
|
|
|
|
|
let Context {
|
|
|
|
ref payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
ref mut client,
|
|
|
|
bridge,
|
|
|
|
nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
ref mint_authority,
|
|
|
|
ref mint,
|
|
|
|
ref mint_meta,
|
|
|
|
ref token_account,
|
|
|
|
ref token_authority,
|
2022-04-20 22:15:07 -07:00
|
|
|
ref guardian_keys,
|
|
|
|
metadata_account,
|
2021-08-30 01:37:53 -07:00
|
|
|
..
|
|
|
|
} = context;
|
|
|
|
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
let token_chain = 2;
|
|
|
|
let token_address = [7u8; 32];
|
|
|
|
let token_id = U256::from_big_endian(&[0x2cu8; 32]);
|
|
|
|
|
|
|
|
let wrapped_mint_key = WrappedMint::<'_, { AccountState::Uninitialized }>::key(
|
|
|
|
&WrappedDerivationData {
|
|
|
|
token_chain,
|
|
|
|
token_address,
|
|
|
|
token_id,
|
|
|
|
},
|
|
|
|
&nft_bridge,
|
|
|
|
);
|
|
|
|
let associated_addr = spl_associated_token_account::get_associated_token_address(
|
|
|
|
&token_authority.pubkey(),
|
|
|
|
&wrapped_mint_key,
|
|
|
|
);
|
|
|
|
|
|
|
|
let symbol = "UUC";
|
|
|
|
let name = "External Token";
|
|
|
|
let uri = "https://example.com";
|
2021-08-30 01:37:53 -07:00
|
|
|
let payload = PayloadTransfer {
|
2022-04-20 22:15:07 -07:00
|
|
|
token_address,
|
|
|
|
token_chain,
|
|
|
|
symbol: symbol.into(),
|
|
|
|
name: name.into(),
|
|
|
|
token_id,
|
|
|
|
uri: uri.into(),
|
|
|
|
to: associated_addr.to_bytes(),
|
2021-08-30 01:37:53 -07:00
|
|
|
to_chain: 1,
|
|
|
|
};
|
|
|
|
let message = payload.try_to_vec().unwrap();
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
let (vaa, body, _) =
|
|
|
|
common::generate_vaa([0u8; 32], 2, message, nonce, rand::thread_rng().gen());
|
|
|
|
let signature_set = common::verify_signatures(client, &bridge, payer, body, guardian_keys, 0)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
common::post_vaa(client, bridge, payer, signature_set, vaa.clone())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2021-08-30 01:37:53 -07:00
|
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
2022-04-20 22:15:07 -07:00
|
|
|
payload_hash: body.to_vec(),
|
2021-08-30 01:37:53 -07:00
|
|
|
};
|
|
|
|
let message_key =
|
|
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
common::complete_wrapped(
|
2021-08-30 01:37:53 -07:00
|
|
|
client,
|
2022-04-20 22:15:07 -07:00
|
|
|
nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
bridge,
|
2022-04-20 22:15:07 -07:00
|
|
|
message_key,
|
|
|
|
vaa.clone(),
|
|
|
|
payload.clone(),
|
|
|
|
token_authority.pubkey(),
|
2021-08-30 01:37:53 -07:00
|
|
|
payer,
|
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await
|
2021-08-30 01:37:53 -07:00
|
|
|
.unwrap();
|
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
// What this actually does is initialize the spl token metadata so that we can then burn the NFT
|
|
|
|
// in the future but of course, we can't call it something useful like
|
|
|
|
// `initialize_wrapped_nft_metadata`.
|
|
|
|
common::complete_wrapped_meta(client, nft_bridge, bridge, message_key, vaa, payload, payer)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2021-08-30 01:37:53 -07:00
|
|
|
|
2022-04-20 22:15:07 -07:00
|
|
|
// Now transfer the wrapped nft back, which will burn it.
|
|
|
|
let message = &Keypair::new();
|
|
|
|
common::transfer_wrapped(
|
2021-08-30 01:37:53 -07:00
|
|
|
client,
|
2022-04-20 22:15:07 -07:00
|
|
|
nft_bridge,
|
2021-08-30 01:37:53 -07:00
|
|
|
bridge,
|
|
|
|
payer,
|
2022-04-20 22:15:07 -07:00
|
|
|
message,
|
|
|
|
associated_addr,
|
|
|
|
token_authority,
|
|
|
|
token_chain,
|
|
|
|
token_address,
|
|
|
|
token_id,
|
2021-08-30 01:37:53 -07:00
|
|
|
)
|
2022-04-20 22:15:07 -07:00
|
|
|
.await
|
2021-08-30 01:37:53 -07:00
|
|
|
.unwrap();
|
|
|
|
}
|