Skip to content

Commit f723b1d

Browse files
committed
Add instruction builder
1 parent 6f5d6be commit f723b1d

1 file changed

Lines changed: 76 additions & 0 deletions

File tree

interface/src/instruction.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,24 @@ pub enum TokenInstruction<'a> {
731731
ScaledUiAmountExtension,
732732
/// Instruction prefix for instructions to the pausable extension
733733
PausableExtension,
734+
/// 45
735+
/// Transfer lamports from a native SOL account to a destination account.
736+
///
737+
/// This is useful to unwrap lamports from a wrapped SOL account.
738+
///
739+
/// Accounts expected by this instruction:
740+
///
741+
/// 0. `[writable]` The source account.
742+
/// 1. `[writable]` The destination account.
743+
/// 2. `[signer]` The source account's owner/delegate.
744+
///
745+
UnwrapLamports {
746+
/// The amount of lamports to transfer. When an amount is
747+
/// not specified, the entire balance of the source account will be
748+
/// transferred.
749+
#[cfg_attr(feature = "serde", serde(with = "coption_fromstr"))]
750+
amount: COption<u64>,
751+
},
734752
}
735753
impl<'a> TokenInstruction<'a> {
736754
/// Unpacks a byte buffer into a
@@ -873,6 +891,10 @@ impl<'a> TokenInstruction<'a> {
873891
42 => Self::ConfidentialMintBurnExtension,
874892
43 => Self::ScaledUiAmountExtension,
875893
44 => Self::PausableExtension,
894+
45 => {
895+
let (amount, _rest) = Self::unpack_u64_option(rest)?;
896+
Self::UnwrapLamports { amount }
897+
}
876898
_ => return Err(TokenError::InvalidInstruction.into()),
877899
})
878900
}
@@ -1053,6 +1075,10 @@ impl<'a> TokenInstruction<'a> {
10531075
&Self::PausableExtension => {
10541076
buf.push(44);
10551077
}
1078+
&Self::UnwrapLamports { amount } => {
1079+
buf.push(45);
1080+
Self::pack_u64_option(&amount, &mut buf);
1081+
}
10561082
};
10571083
buf
10581084
}
@@ -2084,6 +2110,37 @@ pub fn withdraw_excess_lamports(
20842110
})
20852111
}
20862112

2113+
/// Creates an `UnwrapLamports` instruction
2114+
pub fn unwrap_lamports(
2115+
token_program_id: &Pubkey,
2116+
source_pubkey: &Pubkey,
2117+
destination_pubkey: &Pubkey,
2118+
authority_pubkey: &Pubkey,
2119+
signer_pubkeys: &[&Pubkey],
2120+
amount: Option<u64>,
2121+
) -> Result<Instruction, ProgramError> {
2122+
check_program_account(token_program_id)?;
2123+
let amount = amount.into();
2124+
let data = TokenInstruction::UnwrapLamports { amount }.pack();
2125+
2126+
let mut accounts = Vec::with_capacity(3 + signer_pubkeys.len());
2127+
accounts.push(AccountMeta::new(*source_pubkey, false));
2128+
accounts.push(AccountMeta::new(*destination_pubkey, false));
2129+
accounts.push(AccountMeta::new_readonly(
2130+
*authority_pubkey,
2131+
signer_pubkeys.is_empty(),
2132+
));
2133+
for signer_pubkey in signer_pubkeys.iter() {
2134+
accounts.push(AccountMeta::new_readonly(**signer_pubkey, true));
2135+
}
2136+
2137+
Ok(Instruction {
2138+
program_id: *token_program_id,
2139+
accounts,
2140+
data,
2141+
})
2142+
}
2143+
20872144
#[cfg(test)]
20882145
mod test {
20892146
use {super::*, proptest::prelude::*};
@@ -2458,6 +2515,25 @@ mod test {
24582515
assert_eq!(unpacked, check);
24592516
}
24602517

2518+
#[test]
2519+
fn test_unwrap_lamports_packing() {
2520+
let amount = COption::None;
2521+
let check = TokenInstruction::UnwrapLamports { amount };
2522+
let packed = check.pack();
2523+
let expect = Vec::from([45u8, 0]);
2524+
assert_eq!(packed, expect);
2525+
let unpacked = TokenInstruction::unpack(&expect).unwrap();
2526+
assert_eq!(unpacked, check);
2527+
2528+
let amount = COption::Some(1);
2529+
let check = TokenInstruction::UnwrapLamports { amount };
2530+
let packed = check.pack();
2531+
let expect = Vec::from([45u8, 1, 1, 0, 0, 0, 0, 0, 0, 0]);
2532+
assert_eq!(packed, expect);
2533+
let unpacked = TokenInstruction::unpack(&expect).unwrap();
2534+
assert_eq!(unpacked, check);
2535+
}
2536+
24612537
macro_rules! test_instruction {
24622538
($a:ident($($b:tt)*)) => {
24632539
let instruction_v3 = spl_token_interface::instruction::$a($($b)*).unwrap();

0 commit comments

Comments
 (0)