Working transfer in
This commit is contained in:
parent
2f526ff136
commit
e040449197
|
@ -386,7 +386,7 @@ dependencies = [
|
||||||
"solana-cli-config",
|
"solana-cli-config",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
"solana-faucet",
|
"solana-faucet",
|
||||||
"solana-logger",
|
"solana-logger 1.3.3",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-transaction-status",
|
"solana-transaction-status",
|
||||||
"spl-token 1.0.8 (git+https://github.com/solana-labs/solana-program-library)",
|
"spl-token 1.0.8 (git+https://github.com/solana-labs/solana-program-library)",
|
||||||
|
@ -1937,9 +1937,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.18.0"
|
version = "0.18.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cac94b333ee2aac3284c5b8a1b7fb4dd11cba88c244e3fe33cdbd047af0eb693"
|
checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.12.3",
|
"base64 0.12.3",
|
||||||
"log",
|
"log",
|
||||||
|
@ -2276,9 +2276,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-crate-features"
|
name = "solana-crate-features"
|
||||||
version = "1.3.3"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/jackcmay/solana?branch=cpi-create-account#d84010e4afe5f79c812ff7da349460dc690a8392"
|
||||||
checksum = "41045abbf3dd7ecb01db9851590cb2951df54d06f5f13667cfbc178497a9683b"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes 0.4.12",
|
"bytes 0.4.12",
|
||||||
|
@ -2313,7 +2312,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"solana-clap-utils",
|
"solana-clap-utils",
|
||||||
"solana-logger",
|
"solana-logger 1.3.3",
|
||||||
"solana-metrics",
|
"solana-metrics",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
|
@ -2332,6 +2331,16 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "solana-logger"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "git+https://github.com/jackcmay/solana?branch=cpi-create-account#d84010e4afe5f79c812ff7da349460dc690a8392"
|
||||||
|
dependencies = [
|
||||||
|
"env_logger",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-metrics"
|
name = "solana-metrics"
|
||||||
version = "1.3.3"
|
version = "1.3.3"
|
||||||
|
@ -2362,7 +2371,7 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"socket2",
|
"socket2",
|
||||||
"solana-clap-utils",
|
"solana-clap-utils",
|
||||||
"solana-logger",
|
"solana-logger 1.3.3",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
"tokio 0.1.22",
|
"tokio 0.1.22",
|
||||||
"tokio-codec",
|
"tokio-codec",
|
||||||
|
@ -2391,9 +2400,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-sdk"
|
name = "solana-sdk"
|
||||||
version = "1.3.3"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/jackcmay/solana?branch=cpi-create-account#d84010e4afe5f79c812ff7da349460dc690a8392"
|
||||||
checksum = "d96fb797cf378f8c85ce4e37f45e2fdc75f3a27793e831b3cccd74b0c66e809d"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
@ -2422,17 +2430,16 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"solana-crate-features",
|
"solana-crate-features",
|
||||||
"solana-logger",
|
"solana-logger 1.4.0",
|
||||||
"solana-sdk-macro",
|
"solana-sdk-macro",
|
||||||
"solana-sdk-macro-frozen-abi",
|
"solana-sdk-macro-frozen-abi 1.4.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-sdk-macro"
|
name = "solana-sdk-macro"
|
||||||
version = "1.3.3"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/jackcmay/solana?branch=cpi-create-account#d84010e4afe5f79c812ff7da349460dc690a8392"
|
||||||
checksum = "0aad003e717fc4f1831494de7c5307d667a5c5d2fa22b3dfbedd34a6e61ed4ea"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58",
|
"bs58",
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
|
@ -2454,6 +2461,18 @@ dependencies = [
|
||||||
"syn 1.0.38",
|
"syn 1.0.38",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "solana-sdk-macro-frozen-abi"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "git+https://github.com/jackcmay/solana?branch=cpi-create-account#d84010e4afe5f79c812ff7da349460dc690a8392"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"proc-macro2 1.0.19",
|
||||||
|
"quote 1.0.7",
|
||||||
|
"rustc_version",
|
||||||
|
"syn 1.0.38",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-stake-program"
|
name = "solana-stake-program"
|
||||||
version = "1.3.3"
|
version = "1.3.3"
|
||||||
|
@ -2470,7 +2489,7 @@ dependencies = [
|
||||||
"solana-config-program",
|
"solana-config-program",
|
||||||
"solana-metrics",
|
"solana-metrics",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-sdk-macro-frozen-abi",
|
"solana-sdk-macro-frozen-abi 1.3.3",
|
||||||
"solana-vote-program",
|
"solana-vote-program",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -2507,9 +2526,9 @@ dependencies = [
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"solana-logger",
|
"solana-logger 1.3.3",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-sdk-macro-frozen-abi",
|
"solana-sdk-macro-frozen-abi 1.3.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2525,10 +2544,10 @@ dependencies = [
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"solana-logger",
|
"solana-logger 1.3.3",
|
||||||
"solana-metrics",
|
"solana-metrics",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-sdk-macro-frozen-abi",
|
"solana-sdk-macro-frozen-abi 1.3.3",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2560,6 +2579,19 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spl-token"
|
||||||
|
version = "1.0.8"
|
||||||
|
dependencies = [
|
||||||
|
"cbindgen",
|
||||||
|
"num-derive 0.3.1",
|
||||||
|
"num-traits",
|
||||||
|
"rand",
|
||||||
|
"remove_dir_all",
|
||||||
|
"solana-sdk",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spl-token"
|
name = "spl-token"
|
||||||
version = "1.0.8"
|
version = "1.0.8"
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["agent", "bridge", "cli"]
|
members = ["agent", "bridge", "cli", "token"]
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
solana-sdk = { git="https://github.com/jackcmay/solana", branch="cpi-create-account" }
|
||||||
|
|
|
@ -19,7 +19,7 @@ default = ["solana-sdk/default", "spl-token/default"]
|
||||||
num-derive = "0.2"
|
num-derive = "0.2"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
remove_dir_all = "=0.5.0"
|
remove_dir_all = "=0.5.0"
|
||||||
solana-sdk = { version = "=1.3.3", default-features = false, optional = true }
|
solana-sdk = { version = "1.3.3", default-features = false, optional = true }
|
||||||
spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library", default-features = false, optional = true }
|
spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library", default-features = false, optional = true }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
byteorder = "1.3.4"
|
byteorder = "1.3.4"
|
||||||
|
|
|
@ -97,6 +97,9 @@ pub enum Error {
|
||||||
/// VAA is longer than the maximum size
|
/// VAA is longer than the maximum size
|
||||||
#[error("VAATooLong")]
|
#[error("VAATooLong")]
|
||||||
VAATooLong,
|
VAATooLong,
|
||||||
|
/// Cannot wrap a solana native asset
|
||||||
|
#[error("CannotWrapNative")]
|
||||||
|
CannotWrapNative,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for ProgramError {
|
impl From<Error> for ProgramError {
|
||||||
|
|
|
@ -37,6 +37,7 @@ impl PrintProgramError for Error {
|
||||||
Error::VAAProposalMismatch => info!("Error: VAAProposalMismatch"),
|
Error::VAAProposalMismatch => info!("Error: VAAProposalMismatch"),
|
||||||
Error::SameChainTransfer => info!("Error: SameChainTransfer"),
|
Error::SameChainTransfer => info!("Error: SameChainTransfer"),
|
||||||
Error::VAATooLong => info!("Error: VAATooLong"),
|
Error::VAATooLong => info!("Error: VAATooLong"),
|
||||||
|
Error::CannotWrapNative => info!("Error: CannotWrapNative"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,6 +241,7 @@ pub fn create_wrapped(
|
||||||
Bridge::derive_wrapped_meta_id(program_id, &bridge_key, &wrapped_mint_key)?;
|
Bridge::derive_wrapped_meta_id(program_id, &bridge_key, &wrapped_mint_key)?;
|
||||||
|
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
|
AccountMeta::new_readonly(*program_id, false),
|
||||||
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
||||||
AccountMeta::new_readonly(spl_token::id(), false),
|
AccountMeta::new_readonly(spl_token::id(), false),
|
||||||
AccountMeta::new(bridge_key, false),
|
AccountMeta::new(bridge_key, false),
|
||||||
|
@ -279,6 +280,7 @@ pub fn transfer_out(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut accounts = vec![
|
let mut accounts = vec![
|
||||||
|
AccountMeta::new_readonly(*program_id, false),
|
||||||
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
||||||
AccountMeta::new_readonly(spl_token::id(), false),
|
AccountMeta::new_readonly(spl_token::id(), false),
|
||||||
AccountMeta::new(*token_account, false),
|
AccountMeta::new(*token_account, false),
|
||||||
|
@ -331,6 +333,7 @@ pub fn post_vaa(
|
||||||
let claim_key = Bridge::derive_claim_id(program_id, &bridge_key, &vaa.body_hash()?)?;
|
let claim_key = Bridge::derive_claim_id(program_id, &bridge_key, &vaa.body_hash()?)?;
|
||||||
|
|
||||||
let mut accounts = vec![
|
let mut accounts = vec![
|
||||||
|
AccountMeta::new_readonly(*program_id, false),
|
||||||
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
||||||
AccountMeta::new_readonly(solana_sdk::sysvar::clock::id(), false),
|
AccountMeta::new_readonly(solana_sdk::sysvar::clock::id(), false),
|
||||||
AccountMeta::new(bridge_key, false),
|
AccountMeta::new(bridge_key, false),
|
||||||
|
|
|
@ -8,8 +8,6 @@ use num_traits::AsPrimitive;
|
||||||
use primitive_types::U256;
|
use primitive_types::U256;
|
||||||
use solana_sdk::clock::Clock;
|
use solana_sdk::clock::Clock;
|
||||||
use solana_sdk::hash::Hasher;
|
use solana_sdk::hash::Hasher;
|
||||||
#[cfg(not(target_arch = "bpf"))]
|
|
||||||
use solana_sdk::instruction::Instruction;
|
|
||||||
#[cfg(target_arch = "bpf")]
|
#[cfg(target_arch = "bpf")]
|
||||||
use solana_sdk::program::invoke_signed;
|
use solana_sdk::program::invoke_signed;
|
||||||
use solana_sdk::rent::Rent;
|
use solana_sdk::rent::Rent;
|
||||||
|
@ -17,7 +15,7 @@ use solana_sdk::system_instruction::{create_account, SystemInstruction};
|
||||||
use solana_sdk::sysvar::Sysvar;
|
use solana_sdk::sysvar::Sysvar;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account_info::next_account_info, account_info::AccountInfo, entrypoint::ProgramResult, info,
|
account_info::next_account_info, account_info::AccountInfo, entrypoint::ProgramResult, info,
|
||||||
program_error::ProgramError, pubkey::Pubkey,
|
instruction::Instruction, program_error::ProgramError, pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
use spl_token::state::Mint;
|
use spl_token::state::Mint;
|
||||||
|
|
||||||
|
@ -87,11 +85,12 @@ impl Bridge {
|
||||||
|
|
||||||
// Create bridge account
|
// Create bridge account
|
||||||
let bridge_seed = Bridge::derive_bridge_seeds();
|
let bridge_seed = Bridge::derive_bridge_seeds();
|
||||||
Bridge::check_and_create_account::<BridgeConfig>(
|
Bridge::check_and_create_account::<Bridge>(
|
||||||
program_id,
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
new_bridge_info.key,
|
new_bridge_info.key,
|
||||||
payer_info.key,
|
payer_info.key,
|
||||||
|
program_id,
|
||||||
&bridge_seed,
|
&bridge_seed,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -108,6 +107,7 @@ impl Bridge {
|
||||||
accounts,
|
accounts,
|
||||||
new_guardian_info.key,
|
new_guardian_info.key,
|
||||||
payer_info.key,
|
payer_info.key,
|
||||||
|
program_id,
|
||||||
&guardian_seed,
|
&guardian_seed,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ impl Bridge {
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("wrapped transfer out");
|
info!("wrapped transfer out");
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
|
next_account_info(account_info_iter)?; // Bridge program
|
||||||
next_account_info(account_info_iter)?; // System program
|
next_account_info(account_info_iter)?; // System program
|
||||||
next_account_info(account_info_iter)?; // Token program
|
next_account_info(account_info_iter)?; // Token program
|
||||||
let sender_account_info = next_account_info(account_info_iter)?;
|
let sender_account_info = next_account_info(account_info_iter)?;
|
||||||
|
@ -182,6 +183,7 @@ impl Bridge {
|
||||||
accounts,
|
accounts,
|
||||||
transfer_info.key,
|
transfer_info.key,
|
||||||
payer_info.key,
|
payer_info.key,
|
||||||
|
program_id,
|
||||||
&transfer_seed,
|
&transfer_seed,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -192,8 +194,10 @@ impl Bridge {
|
||||||
return Err(Error::AlreadyExists.into());
|
return Err(Error::AlreadyExists.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info!("burning");
|
||||||
// Burn tokens
|
// Burn tokens
|
||||||
Bridge::wrapped_burn(
|
Bridge::wrapped_burn(
|
||||||
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
&bridge.config.token_program,
|
&bridge.config.token_program,
|
||||||
authority_info.key,
|
authority_info.key,
|
||||||
|
@ -221,6 +225,7 @@ impl Bridge {
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("create wrapped");
|
info!("create wrapped");
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
|
next_account_info(account_info_iter)?; // Bridge program
|
||||||
next_account_info(account_info_iter)?; // System program
|
next_account_info(account_info_iter)?; // System program
|
||||||
next_account_info(account_info_iter)?; // Token program
|
next_account_info(account_info_iter)?; // Token program
|
||||||
let bridge_info = next_account_info(account_info_iter)?;
|
let bridge_info = next_account_info(account_info_iter)?;
|
||||||
|
@ -230,6 +235,10 @@ impl Bridge {
|
||||||
|
|
||||||
let bridge = Bridge::bridge_deserialize(bridge_info)?;
|
let bridge = Bridge::bridge_deserialize(bridge_info)?;
|
||||||
|
|
||||||
|
if a.chain == CHAIN_ID_SOLANA {
|
||||||
|
return Err(Error::CannotWrapNative.into());
|
||||||
|
}
|
||||||
|
|
||||||
// Create wrapped mint
|
// Create wrapped mint
|
||||||
Self::create_wrapped_mint(
|
Self::create_wrapped_mint(
|
||||||
program_id,
|
program_id,
|
||||||
|
@ -248,6 +257,7 @@ impl Bridge {
|
||||||
accounts,
|
accounts,
|
||||||
wrapped_meta_info.key,
|
wrapped_meta_info.key,
|
||||||
payer_info.key,
|
payer_info.key,
|
||||||
|
program_id,
|
||||||
&wrapped_meta_seeds,
|
&wrapped_meta_seeds,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -269,6 +279,7 @@ impl Bridge {
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("native transfer out");
|
info!("native transfer out");
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
|
next_account_info(account_info_iter)?; // Bridge program
|
||||||
next_account_info(account_info_iter)?; // System program
|
next_account_info(account_info_iter)?; // System program
|
||||||
next_account_info(account_info_iter)?; // Token program
|
next_account_info(account_info_iter)?; // Token program
|
||||||
let sender_account_info = next_account_info(account_info_iter)?;
|
let sender_account_info = next_account_info(account_info_iter)?;
|
||||||
|
@ -301,6 +312,7 @@ impl Bridge {
|
||||||
accounts,
|
accounts,
|
||||||
transfer_info.key,
|
transfer_info.key,
|
||||||
payer_info.key,
|
payer_info.key,
|
||||||
|
program_id,
|
||||||
&transfer_seed,
|
&transfer_seed,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -320,6 +332,7 @@ impl Bridge {
|
||||||
|
|
||||||
// Create the account if it does not exist
|
// Create the account if it does not exist
|
||||||
if custody_info.data_is_empty() {
|
if custody_info.data_is_empty() {
|
||||||
|
info!("custody acc");
|
||||||
Bridge::create_custody_account(
|
Bridge::create_custody_account(
|
||||||
program_id,
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
|
@ -331,19 +344,23 @@ impl Bridge {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let bridge_authority = Self::derive_bridge_id(program_id)?;
|
||||||
|
|
||||||
// Check that the custody token account is owned by the derived key
|
// Check that the custody token account is owned by the derived key
|
||||||
let custody = Self::token_account_deserialize(custody_info)?;
|
let custody = Self::token_account_deserialize(custody_info)?;
|
||||||
if custody.owner != *bridge_info.key {
|
if custody.owner != bridge_authority {
|
||||||
return Err(Error::WrongTokenAccountOwner.into());
|
return Err(Error::WrongTokenAccountOwner.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info!("transferring");
|
||||||
// Transfer tokens to custody - This also checks that custody mint = mint
|
// Transfer tokens to custody - This also checks that custody mint = mint
|
||||||
Bridge::token_transfer_caller(
|
Bridge::token_transfer_caller(
|
||||||
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
&bridge.config.token_program,
|
&bridge.config.token_program,
|
||||||
sender_account_info.key,
|
sender_account_info.key,
|
||||||
custody_info.key,
|
custody_info.key,
|
||||||
bridge_info.key,
|
&bridge_authority,
|
||||||
t.amount,
|
t.amount,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -373,6 +390,7 @@ impl Bridge {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
|
|
||||||
// Load VAA processing default accounts
|
// Load VAA processing default accounts
|
||||||
|
next_account_info(account_info_iter)?; // Bridge program
|
||||||
next_account_info(account_info_iter)?; // System program
|
next_account_info(account_info_iter)?; // System program
|
||||||
let clock_info = next_account_info(account_info_iter)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
let bridge_info = next_account_info(account_info_iter)?;
|
let bridge_info = next_account_info(account_info_iter)?;
|
||||||
|
@ -398,6 +416,7 @@ impl Bridge {
|
||||||
accounts,
|
accounts,
|
||||||
claim_info.key,
|
claim_info.key,
|
||||||
payer_info.key,
|
payer_info.key,
|
||||||
|
program_id,
|
||||||
&claim_seeds,
|
&claim_seeds,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -507,6 +526,7 @@ impl Bridge {
|
||||||
accounts,
|
accounts,
|
||||||
new_guardian_info.key,
|
new_guardian_info.key,
|
||||||
payer_info.key,
|
payer_info.key,
|
||||||
|
program_id,
|
||||||
&guardian_seed,
|
&guardian_seed,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -562,6 +582,7 @@ impl Bridge {
|
||||||
|
|
||||||
// Native Solana asset, transfer from custody
|
// Native Solana asset, transfer from custody
|
||||||
Bridge::token_transfer_custody(
|
Bridge::token_transfer_custody(
|
||||||
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
&bridge.config.token_program,
|
&bridge.config.token_program,
|
||||||
bridge_info.key,
|
bridge_info.key,
|
||||||
|
@ -584,6 +605,7 @@ impl Bridge {
|
||||||
// This automatically asserts that the mint was created by this account by using
|
// This automatically asserts that the mint was created by this account by using
|
||||||
// derivated keys
|
// derivated keys
|
||||||
Bridge::wrapped_mint_to(
|
Bridge::wrapped_mint_to(
|
||||||
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
&bridge.config.token_program,
|
&bridge.config.token_program,
|
||||||
mint_info.key,
|
mint_info.key,
|
||||||
|
@ -681,6 +703,7 @@ pub fn invoke_signed<'a>(
|
||||||
impl Bridge {
|
impl Bridge {
|
||||||
/// Burn a wrapped asset from account
|
/// Burn a wrapped asset from account
|
||||||
pub fn wrapped_burn(
|
pub fn wrapped_burn(
|
||||||
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
authority: &Pubkey,
|
authority: &Pubkey,
|
||||||
|
@ -698,11 +721,12 @@ impl Bridge {
|
||||||
all_signers.as_slice(),
|
all_signers.as_slice(),
|
||||||
amount.as_u64(),
|
amount.as_u64(),
|
||||||
)?;
|
)?;
|
||||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
Self::invoke_as_bridge(program_id, &ix, accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mint a wrapped asset to account
|
/// Mint a wrapped asset to account
|
||||||
pub fn wrapped_mint_to(
|
pub fn wrapped_mint_to(
|
||||||
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
mint: &Pubkey,
|
mint: &Pubkey,
|
||||||
|
@ -718,11 +742,12 @@ impl Bridge {
|
||||||
&[],
|
&[],
|
||||||
amount.as_u64(),
|
amount.as_u64(),
|
||||||
)?;
|
)?;
|
||||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
Self::invoke_as_bridge(program_id, &ix, accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transfer tokens from a caller
|
/// Transfer tokens from a caller
|
||||||
pub fn token_transfer_caller(
|
pub fn token_transfer_caller(
|
||||||
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
source: &Pubkey,
|
source: &Pubkey,
|
||||||
|
@ -738,11 +763,12 @@ impl Bridge {
|
||||||
&[],
|
&[],
|
||||||
amount.as_u64(),
|
amount.as_u64(),
|
||||||
)?;
|
)?;
|
||||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
Self::invoke_as_bridge(program_id, &ix, accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transfer tokens from a custody account
|
/// Transfer tokens from a custody account
|
||||||
pub fn token_transfer_custody(
|
pub fn token_transfer_custody(
|
||||||
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
bridge: &Pubkey,
|
bridge: &Pubkey,
|
||||||
|
@ -758,7 +784,7 @@ impl Bridge {
|
||||||
&[],
|
&[],
|
||||||
amount.as_u64(),
|
amount.as_u64(),
|
||||||
)?;
|
)?;
|
||||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
Self::invoke_as_bridge(program_id, &ix, accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new account
|
/// Create a new account
|
||||||
|
@ -771,15 +797,23 @@ impl Bridge {
|
||||||
mint: &Pubkey,
|
mint: &Pubkey,
|
||||||
payer: &Pubkey,
|
payer: &Pubkey,
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<(), ProgramError> {
|
||||||
Self::create_account::<Mint>(
|
Self::check_and_create_account::<spl_token::state::Account>(
|
||||||
token_program,
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
mint,
|
account,
|
||||||
payer,
|
payer,
|
||||||
|
token_program,
|
||||||
&Self::derive_custody_seeds(bridge, mint),
|
&Self::derive_custody_seeds(bridge, mint),
|
||||||
)?;
|
)?;
|
||||||
let ix = spl_token::instruction::initialize_account(token_program, account, mint, bridge)?;
|
info!("bababu");
|
||||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
info!(token_program.to_string().as_str());
|
||||||
|
let ix = spl_token::instruction::initialize_account(
|
||||||
|
token_program,
|
||||||
|
account,
|
||||||
|
mint,
|
||||||
|
&Self::derive_bridge_id(program_id)?,
|
||||||
|
)?;
|
||||||
|
invoke_signed(&ix, accounts, &[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a mint for a wrapped asset
|
/// Create a mint for a wrapped asset
|
||||||
|
@ -792,16 +826,43 @@ impl Bridge {
|
||||||
payer: &Pubkey,
|
payer: &Pubkey,
|
||||||
asset: &AssetMeta,
|
asset: &AssetMeta,
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<(), ProgramError> {
|
||||||
Self::create_account::<Mint>(
|
Self::check_and_create_account::<Mint>(
|
||||||
token_program,
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
mint,
|
mint,
|
||||||
payer,
|
payer,
|
||||||
|
token_program,
|
||||||
&Self::derive_wrapped_asset_seeds(bridge, asset.chain, asset.address),
|
&Self::derive_wrapped_asset_seeds(bridge, asset.chain, asset.address),
|
||||||
)?;
|
)?;
|
||||||
let ix =
|
let ix = spl_token::instruction::initialize_mint(
|
||||||
spl_token::instruction::initialize_mint(token_program, mint, None, Some(bridge), 0, 8)?;
|
token_program,
|
||||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
mint,
|
||||||
|
None,
|
||||||
|
Some(&Self::derive_bridge_id(program_id)?),
|
||||||
|
0,
|
||||||
|
8,
|
||||||
|
)?;
|
||||||
|
invoke_signed(&ix, accounts, &[])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn invoke_as_bridge<'a>(
|
||||||
|
program_id: &Pubkey,
|
||||||
|
instruction: &Instruction,
|
||||||
|
account_infos: &[AccountInfo<'a>],
|
||||||
|
) -> ProgramResult {
|
||||||
|
let (_, seeds) =
|
||||||
|
Self::find_program_address(&vec!["bridge".as_bytes().to_vec()], program_id);
|
||||||
|
Self::invoke_vec_seed(program_id, instruction, account_infos, &seeds)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn invoke_vec_seed<'a>(
|
||||||
|
program_id: &Pubkey,
|
||||||
|
instruction: &Instruction,
|
||||||
|
account_infos: &[AccountInfo<'a>],
|
||||||
|
seeds: &Vec<Vec<u8>>,
|
||||||
|
) -> ProgramResult {
|
||||||
|
let s: Vec<_> = seeds.iter().map(|item| item.as_slice()).collect();
|
||||||
|
invoke_signed(instruction, account_infos, &[s.as_slice()])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that a key was derived correctly and create account
|
/// Check that a key was derived correctly and create account
|
||||||
|
@ -810,22 +871,35 @@ impl Bridge {
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
new_account: &Pubkey,
|
new_account: &Pubkey,
|
||||||
payer: &Pubkey,
|
payer: &Pubkey,
|
||||||
|
owner: &Pubkey,
|
||||||
seeds: &Vec<Vec<u8>>,
|
seeds: &Vec<Vec<u8>>,
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<Vec<Vec<u8>>, ProgramError> {
|
||||||
let expected_key = Bridge::derive_key(program_id, seeds)?;
|
info!("deriving key");
|
||||||
|
let (expected_key, full_seeds) = Bridge::derive_key(program_id, seeds)?;
|
||||||
if expected_key != *new_account {
|
if expected_key != *new_account {
|
||||||
return Err(Error::InvalidDerivedAccount.into());
|
return Err(Error::InvalidDerivedAccount.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::create_account::<T>(program_id, accounts, new_account, payer, seeds)
|
info!("deploying contract");
|
||||||
|
Self::create_account_raw::<T>(
|
||||||
|
program_id,
|
||||||
|
accounts,
|
||||||
|
new_account,
|
||||||
|
payer,
|
||||||
|
owner,
|
||||||
|
&full_seeds,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(full_seeds)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new account
|
/// Create a new account
|
||||||
pub fn create_account<T: Sized>(
|
fn create_account_raw<T: Sized>(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
new_account: &Pubkey,
|
new_account: &Pubkey,
|
||||||
payer: &Pubkey,
|
payer: &Pubkey,
|
||||||
|
owner: &Pubkey,
|
||||||
seeds: &Vec<Vec<u8>>,
|
seeds: &Vec<Vec<u8>>,
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<(), ProgramError> {
|
||||||
let size = size_of::<T>();
|
let size = size_of::<T>();
|
||||||
|
@ -834,7 +908,7 @@ impl Bridge {
|
||||||
new_account,
|
new_account,
|
||||||
Rent::default().minimum_balance(size as usize),
|
Rent::default().minimum_balance(size as usize),
|
||||||
size as u64,
|
size as u64,
|
||||||
program_id,
|
owner,
|
||||||
);
|
);
|
||||||
let s: Vec<_> = seeds.iter().map(|item| item.as_slice()).collect();
|
let s: Vec<_> = seeds.iter().map(|item| item.as_slice()).collect();
|
||||||
invoke_signed(&ix, accounts, &[s.as_slice()])
|
invoke_signed(&ix, accounts, &[s.as_slice()])
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
||||||
use primitive_types::U256;
|
use primitive_types::U256;
|
||||||
|
use solana_sdk::hash::Hasher;
|
||||||
|
use solana_sdk::pubkey::{PubkeyError, MAX_SEED_LEN};
|
||||||
use solana_sdk::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey};
|
use solana_sdk::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey};
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
|
@ -323,7 +325,7 @@ impl Bridge {
|
||||||
|
|
||||||
/// Calculates a derived address for this program
|
/// Calculates a derived address for this program
|
||||||
pub fn derive_bridge_id(program_id: &Pubkey) -> Result<Pubkey, Error> {
|
pub fn derive_bridge_id(program_id: &Pubkey) -> Result<Pubkey, Error> {
|
||||||
Self::derive_key(program_id, &Self::derive_bridge_seeds())
|
Ok(Self::derive_key(program_id, &Self::derive_bridge_seeds())?.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates a derived address for a custody account
|
/// Calculates a derived address for a custody account
|
||||||
|
@ -332,7 +334,7 @@ impl Bridge {
|
||||||
bridge: &Pubkey,
|
bridge: &Pubkey,
|
||||||
mint: &Pubkey,
|
mint: &Pubkey,
|
||||||
) -> Result<Pubkey, Error> {
|
) -> Result<Pubkey, Error> {
|
||||||
Self::derive_key(program_id, &Self::derive_custody_seeds(bridge, mint))
|
Ok(Self::derive_key(program_id, &Self::derive_custody_seeds(bridge, mint))?.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates a derived address for a claim account
|
/// Calculates a derived address for a claim account
|
||||||
|
@ -341,7 +343,7 @@ impl Bridge {
|
||||||
bridge: &Pubkey,
|
bridge: &Pubkey,
|
||||||
hash: &[u8; 32],
|
hash: &[u8; 32],
|
||||||
) -> Result<Pubkey, Error> {
|
) -> Result<Pubkey, Error> {
|
||||||
Self::derive_key(program_id, &Self::derive_claim_seeds(bridge, hash))
|
Ok(Self::derive_key(program_id, &Self::derive_claim_seeds(bridge, hash))?.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates a derived address for a wrapped asset meta entry
|
/// Calculates a derived address for a wrapped asset meta entry
|
||||||
|
@ -350,7 +352,7 @@ impl Bridge {
|
||||||
bridge: &Pubkey,
|
bridge: &Pubkey,
|
||||||
mint: &Pubkey,
|
mint: &Pubkey,
|
||||||
) -> Result<Pubkey, Error> {
|
) -> Result<Pubkey, Error> {
|
||||||
Self::derive_key(program_id, &Self::derive_wrapped_meta_seeds(bridge, mint))
|
Ok(Self::derive_key(program_id, &Self::derive_wrapped_meta_seeds(bridge, mint))?.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates a derived address for this program
|
/// Calculates a derived address for this program
|
||||||
|
@ -359,10 +361,11 @@ impl Bridge {
|
||||||
bridge_key: &Pubkey,
|
bridge_key: &Pubkey,
|
||||||
guardian_set_index: u32,
|
guardian_set_index: u32,
|
||||||
) -> Result<Pubkey, Error> {
|
) -> Result<Pubkey, Error> {
|
||||||
Self::derive_key(
|
Ok(Self::derive_key(
|
||||||
program_id,
|
program_id,
|
||||||
&Self::derive_guardian_set_seeds(bridge_key, guardian_set_index),
|
&Self::derive_guardian_set_seeds(bridge_key, guardian_set_index),
|
||||||
)
|
)?
|
||||||
|
.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates a derived seeds for a wrapped asset
|
/// Calculates a derived seeds for a wrapped asset
|
||||||
|
@ -372,10 +375,11 @@ impl Bridge {
|
||||||
asset_chain: u8,
|
asset_chain: u8,
|
||||||
asset: ForeignAddress,
|
asset: ForeignAddress,
|
||||||
) -> Result<Pubkey, Error> {
|
) -> Result<Pubkey, Error> {
|
||||||
Self::derive_key(
|
Ok(Self::derive_key(
|
||||||
program_id,
|
program_id,
|
||||||
&Self::derive_wrapped_asset_seeds(bridge_key, asset_chain, asset),
|
&Self::derive_wrapped_asset_seeds(bridge_key, asset_chain, asset),
|
||||||
)
|
)?
|
||||||
|
.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates a derived address for a transfer out
|
/// Calculates a derived address for a transfer out
|
||||||
|
@ -389,7 +393,7 @@ impl Bridge {
|
||||||
user: ForeignAddress,
|
user: ForeignAddress,
|
||||||
slot: u32,
|
slot: u32,
|
||||||
) -> Result<Pubkey, Error> {
|
) -> Result<Pubkey, Error> {
|
||||||
Self::derive_key(
|
Ok(Self::derive_key(
|
||||||
program_id,
|
program_id,
|
||||||
&Self::derive_transfer_id_seeds(
|
&Self::derive_transfer_id_seeds(
|
||||||
bridge_key,
|
bridge_key,
|
||||||
|
@ -400,22 +404,32 @@ impl Bridge {
|
||||||
user,
|
user,
|
||||||
slot,
|
slot,
|
||||||
),
|
),
|
||||||
)
|
)?
|
||||||
|
.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derive_key(program_id: &Pubkey, seeds: &Vec<Vec<u8>>) -> Result<Pubkey, Error> {
|
pub fn derive_key(
|
||||||
let s: Vec<_> = seeds.iter().map(|item| item.as_slice()).collect();
|
program_id: &Pubkey,
|
||||||
Ok(Self::find_program_address(s.as_slice(), program_id).0)
|
seeds: &Vec<Vec<u8>>,
|
||||||
|
) -> Result<(Pubkey, Vec<Vec<u8>>), Error> {
|
||||||
|
Ok(Self::find_program_address(seeds, program_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> (Pubkey, u8) {
|
pub fn find_program_address(
|
||||||
let mut nonce = [255];
|
seeds: &Vec<Vec<u8>>,
|
||||||
|
program_id: &Pubkey,
|
||||||
|
) -> (Pubkey, Vec<Vec<u8>>) {
|
||||||
|
let mut nonce = [255u8];
|
||||||
for _ in 0..std::u8::MAX {
|
for _ in 0..std::u8::MAX {
|
||||||
{
|
{
|
||||||
let mut seeds_with_nonce = seeds.to_vec();
|
let mut seeds_with_nonce = seeds.to_vec();
|
||||||
seeds_with_nonce.push(&nonce);
|
seeds_with_nonce.push(nonce.to_vec());
|
||||||
if let Ok(address) = Pubkey::create_program_address(&seeds_with_nonce, program_id) {
|
let s: Vec<_> = seeds_with_nonce
|
||||||
return (address, nonce[0]);
|
.iter()
|
||||||
|
.map(|item| item.as_slice())
|
||||||
|
.collect();
|
||||||
|
if let Ok(address) = Pubkey::create_program_address(&s, program_id) {
|
||||||
|
return (address, seeds_with_nonce);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nonce[0] -= 1;
|
nonce[0] -= 1;
|
||||||
|
|
|
@ -8,12 +8,14 @@ use clap::{
|
||||||
};
|
};
|
||||||
use hex;
|
use hex;
|
||||||
use primitive_types::U256;
|
use primitive_types::U256;
|
||||||
|
use solana_account_decoder::{parse_token::TokenAccountType, UiAccountData};
|
||||||
use solana_clap_utils::input_parsers::value_of;
|
use solana_clap_utils::input_parsers::value_of;
|
||||||
use solana_clap_utils::input_validators::is_derivation;
|
use solana_clap_utils::input_validators::is_derivation;
|
||||||
use solana_clap_utils::{
|
use solana_clap_utils::{
|
||||||
input_parsers::{keypair_of, pubkey_of},
|
input_parsers::{keypair_of, pubkey_of},
|
||||||
input_validators::{is_amount, is_keypair, is_pubkey_or_keypair, is_url},
|
input_validators::{is_amount, is_keypair, is_pubkey_or_keypair, is_url},
|
||||||
};
|
};
|
||||||
|
use solana_client::client_error::ClientError;
|
||||||
use solana_client::{rpc_client::RpcClient, rpc_request::TokenAccountsFilter};
|
use solana_client::{rpc_client::RpcClient, rpc_request::TokenAccountsFilter};
|
||||||
use solana_sdk::system_instruction::create_account;
|
use solana_sdk::system_instruction::create_account;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
|
@ -31,7 +33,6 @@ use spl_token::{
|
||||||
state::{Account, Mint},
|
state::{Account, Mint},
|
||||||
};
|
};
|
||||||
|
|
||||||
use solana_account_decoder::{parse_token::TokenAccountType, UiAccountData};
|
|
||||||
use spl_bridge::instruction::*;
|
use spl_bridge::instruction::*;
|
||||||
use spl_bridge::state::*;
|
use spl_bridge::state::*;
|
||||||
|
|
||||||
|
@ -94,9 +95,20 @@ fn command_lock_tokens(
|
||||||
|
|
||||||
// Check whether we can find wrapped asset meta for the given token
|
// Check whether we can find wrapped asset meta for the given token
|
||||||
let wrapped_key = Bridge::derive_wrapped_meta_id(bridge, &bridge_key, &token)?;
|
let wrapped_key = Bridge::derive_wrapped_meta_id(bridge, &bridge_key, &token)?;
|
||||||
let wrapped_info = config.rpc_client.get_account(&wrapped_key).or_else(Err)?;
|
let asset_meta = match config.rpc_client.get_account(&wrapped_key) {
|
||||||
|
Ok(v) => {
|
||||||
let wrapped_meta: &WrappedAssetMeta =
|
let wrapped_meta: &WrappedAssetMeta =
|
||||||
Bridge::unpack_unchecked_immutable(wrapped_info.data.as_slice())?;
|
Bridge::unpack_unchecked_immutable(v.data.as_slice())?;
|
||||||
|
AssetMeta {
|
||||||
|
address: wrapped_meta.address,
|
||||||
|
chain: wrapped_meta.chain,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => AssetMeta {
|
||||||
|
address: token.to_bytes(),
|
||||||
|
chain: CHAIN_ID_SOLANA,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let ix = transfer_out(
|
let ix = transfer_out(
|
||||||
bridge,
|
bridge,
|
||||||
|
@ -106,37 +118,30 @@ fn command_lock_tokens(
|
||||||
&TransferOutPayload {
|
&TransferOutPayload {
|
||||||
amount: U256::from(amount),
|
amount: U256::from(amount),
|
||||||
chain_id: to_chain,
|
chain_id: to_chain,
|
||||||
asset: {
|
asset: asset_meta,
|
||||||
if wrapped_meta.is_initialized() {
|
|
||||||
AssetMeta {
|
|
||||||
address: wrapped_meta.address,
|
|
||||||
chain: wrapped_meta.chain,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AssetMeta {
|
|
||||||
address: token.to_bytes(),
|
|
||||||
chain: CHAIN_ID_SOLANA,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
target,
|
target,
|
||||||
nonce,
|
nonce,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
println!("custody: {}, ", ix.accounts[7].pubkey.to_string());
|
println!("custody: {}, ", ix.accounts[7].pubkey.to_string());
|
||||||
|
|
||||||
|
let mut instructions = vec![];
|
||||||
// Approve tokens
|
// Approve tokens
|
||||||
|
if asset_meta.chain == CHAIN_ID_SOLANA {
|
||||||
let ix_a = approve(
|
let ix_a = approve(
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&account,
|
&account,
|
||||||
&ix.accounts[3].pubkey,
|
&ix.accounts[4].pubkey,
|
||||||
&config.owner.pubkey(),
|
&config.owner.pubkey(),
|
||||||
&[],
|
&[],
|
||||||
amount,
|
amount,
|
||||||
)?;
|
)?;
|
||||||
|
instructions.push(ix_a);
|
||||||
|
}
|
||||||
|
instructions.push(ix);
|
||||||
|
|
||||||
let mut transaction =
|
let mut transaction =
|
||||||
Transaction::new_with_payer(&[ix_a, ix], Some(&config.fee_payer.pubkey()));
|
Transaction::new_with_payer(&instructions.as_slice(), Some(&config.fee_payer.pubkey()));
|
||||||
|
|
||||||
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
|
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
|
||||||
check_fee_payer_balance(
|
check_fee_payer_balance(
|
||||||
|
|
Loading…
Reference in New Issue