-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added Optimized Spl-token program #31
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
1937a7f
Added most of the SPL instruction and State, need to fix some errors …
L0STE 0443219
Merge branch 'main' of https://github.com/febo/pinocchio
L0STE b28d42d
Update token.rs
deanmlittle e76afc9
Update mint.rs
deanmlittle 2e58b93
Possible optimal solution to COption alignment
L0STE 12e8961
Fixed a Typo
L0STE 9945358
Optimized u8 handling
L0STE 46d980e
Cleaned up + fixed discriminator to u8 from u32
L0STE 48fa4c2
Fixed naming
L0STE c95cb04
fixed set authority
deanmlittle 55d47bb
Fixed spl id
deanmlittle 16b114c
Last fixes
L0STE 75c3480
Fixed mint naming
L0STE bc43e96
Added Pubkey dereferencing
L0STE 7578518
got rid of the tests folder
L0STE 205583c
Fixed and tested all the instruction using the new method
L0STE 3b33753
cargo fmt and clippy done
L0STE e46c96f
Fixed alignment issues using since didn't add any CUs
L0STE 7fa5c86
Added a new function for and added a for the rest
L0STE 292c914
missed one unaligned u64
L0STE fe54636
Addressed some of the final comments
L0STE 50341d6
final nits
L0STE File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
resolver = "2" | ||
members = [ | ||
"programs/system", | ||
"programs/token", | ||
"sdk/pinocchio", | ||
"sdk/pubkey", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "pinocchio-token" | ||
description = "Pinocchio helpers to invoke Token program instructions" | ||
version = "0.1.0" | ||
edition = "2021" | ||
license = "Apache-2.0" | ||
readme = "./README.md" | ||
repository = "https://github.com/febo/pinocchio" | ||
|
||
[dependencies] | ||
pinocchio = { version="0.6", path="../../sdk/pinocchio" } | ||
pinocchio-pubkey = { version="0.2.1", path="../../sdk/pubkey" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use core::slice::from_raw_parts; | ||
|
||
use pinocchio::{ | ||
account_info::AccountInfo, | ||
instruction::{AccountMeta, Instruction, Signer}, | ||
program::invoke_signed, | ||
ProgramResult, | ||
}; | ||
|
||
use crate::{write_bytes, UNINIT_BYTE}; | ||
|
||
/// Approves a delegate. | ||
/// | ||
/// ### Accounts: | ||
/// 0. `[WRITE]` The token account. | ||
/// 1. `[]` The delegate. | ||
/// 2. `[SIGNER]` The source account owner. | ||
pub struct Approve<'a> { | ||
/// Source Account. | ||
pub token: &'a AccountInfo, | ||
/// Delegate Account | ||
pub delegate: &'a AccountInfo, | ||
/// Source Owner Account | ||
pub authority: &'a AccountInfo, | ||
/// Amount | ||
pub amount: u64, | ||
} | ||
|
||
impl<'a> Approve<'a> { | ||
#[inline(always)] | ||
pub fn invoke(&self) -> ProgramResult { | ||
self.invoke_signed(&[]) | ||
} | ||
|
||
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { | ||
// Account metadata | ||
let account_metas: [AccountMeta; 3] = [ | ||
AccountMeta::writable(self.token.key()), | ||
AccountMeta::readonly(self.delegate.key()), | ||
AccountMeta::readonly_signer(self.authority.key()), | ||
]; | ||
|
||
// Instruction data | ||
// - [0]: instruction discriminator (1 byte, u8) | ||
// - [1..9]: amount (8 bytes, u64) | ||
let mut instruction_data = [UNINIT_BYTE; 9]; | ||
|
||
// Set discriminator as u8 at offset [0] | ||
write_bytes(&mut instruction_data, &[4]); | ||
// Set amount as u64 at offset [1..9] | ||
write_bytes(&mut instruction_data[1..], &self.amount.to_le_bytes()); | ||
|
||
let instruction = Instruction { | ||
program_id: &crate::ID, | ||
accounts: &account_metas, | ||
data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, | ||
}; | ||
|
||
invoke_signed( | ||
&instruction, | ||
&[self.token, self.delegate, self.authority], | ||
signers, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
use core::slice::from_raw_parts; | ||
|
||
use pinocchio::{ | ||
account_info::AccountInfo, | ||
instruction::{AccountMeta, Instruction, Signer}, | ||
program::invoke_signed, | ||
ProgramResult, | ||
}; | ||
|
||
use crate::{write_bytes, UNINIT_BYTE}; | ||
|
||
/// Approves a delegate. | ||
/// | ||
/// ### Accounts: | ||
/// 0. `[WRITE]` The source account. | ||
/// 1. `[]` The token mint. | ||
/// 2. `[]` The delegate. | ||
/// 3. `[SIGNER]` The source account owner. | ||
pub struct ApproveChecked<'a> { | ||
/// Source Account. | ||
pub token: &'a AccountInfo, | ||
/// Mint Account. | ||
pub mint: &'a AccountInfo, | ||
/// Delegate Account. | ||
pub delegate: &'a AccountInfo, | ||
/// Source Owner Account. | ||
pub authority: &'a AccountInfo, | ||
/// Amount. | ||
pub amount: u64, | ||
/// Decimals. | ||
pub decimals: u8, | ||
} | ||
|
||
impl<'a> ApproveChecked<'a> { | ||
#[inline(always)] | ||
pub fn invoke(&self) -> ProgramResult { | ||
self.invoke_signed(&[]) | ||
} | ||
|
||
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { | ||
// Account metadata | ||
let account_metas: [AccountMeta; 4] = [ | ||
AccountMeta::writable(self.token.key()), | ||
AccountMeta::readonly(self.mint.key()), | ||
AccountMeta::readonly(self.delegate.key()), | ||
AccountMeta::readonly_signer(self.authority.key()), | ||
]; | ||
|
||
// Instruction data | ||
// - [0] : instruction discriminator (1 byte, u8) | ||
// - [1..9]: amount (8 bytes, u64) | ||
// - [9] : decimals (1 byte, u8) | ||
let mut instruction_data = [UNINIT_BYTE; 10]; | ||
|
||
// Set discriminator as u8 at offset [0] | ||
write_bytes(&mut instruction_data, &[13]); | ||
// Set amount as u64 at offset [1..9] | ||
write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes()); | ||
// Set decimals as u8 at offset [9] | ||
write_bytes(&mut instruction_data[9..], &[self.decimals]); | ||
|
||
let instruction = Instruction { | ||
program_id: &crate::ID, | ||
accounts: &account_metas, | ||
data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, | ||
}; | ||
|
||
invoke_signed( | ||
&instruction, | ||
&[self.token, self.mint, self.delegate, self.authority], | ||
signers, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use core::slice::from_raw_parts; | ||
|
||
use pinocchio::{ | ||
account_info::AccountInfo, | ||
instruction::{AccountMeta, Instruction, Signer}, | ||
program::invoke_signed, | ||
ProgramResult, | ||
}; | ||
|
||
use crate::{write_bytes, UNINIT_BYTE}; | ||
|
||
/// Burns tokens by removing them from an account. | ||
/// | ||
/// ### Accounts: | ||
/// 0. `[WRITE]` The account to burn from. | ||
/// 1. `[WRITE]` The token mint. | ||
/// 2. `[SIGNER]` The account's owner/delegate. | ||
pub struct Burn<'a> { | ||
/// Source of the Burn Account | ||
pub token: &'a AccountInfo, | ||
/// Mint Account | ||
pub mint: &'a AccountInfo, | ||
/// Owner of the Token Account | ||
pub authority: &'a AccountInfo, | ||
/// Amount | ||
pub amount: u64, | ||
} | ||
|
||
impl<'a> Burn<'a> { | ||
#[inline(always)] | ||
pub fn invoke(&self) -> ProgramResult { | ||
self.invoke_signed(&[]) | ||
} | ||
|
||
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { | ||
// Account metadata | ||
let account_metas: [AccountMeta; 3] = [ | ||
AccountMeta::writable(self.token.key()), | ||
AccountMeta::writable(self.mint.key()), | ||
AccountMeta::readonly_signer(self.authority.key()), | ||
]; | ||
|
||
// Instruction data | ||
// - [0]: instruction discriminator (1 byte, u8) | ||
// - [1..9]: amount (8 bytes, u64) | ||
let mut instruction_data = [UNINIT_BYTE; 9]; | ||
|
||
// Set discriminator as u8 at offset [0] | ||
write_bytes(&mut instruction_data, &[8]); | ||
// Set amount as u64 at offset [1..9] | ||
write_bytes(&mut instruction_data[1..], &self.amount.to_le_bytes()); | ||
|
||
let instruction = Instruction { | ||
program_id: &crate::ID, | ||
accounts: &account_metas, | ||
data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 9) }, | ||
}; | ||
|
||
invoke_signed( | ||
&instruction, | ||
&[self.token, self.mint, self.authority], | ||
signers, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use core::slice::from_raw_parts; | ||
|
||
use crate::{write_bytes, UNINIT_BYTE}; | ||
use pinocchio::{ | ||
account_info::AccountInfo, | ||
instruction::{AccountMeta, Instruction, Signer}, | ||
program::invoke_signed, | ||
ProgramResult, | ||
}; | ||
|
||
/// Burns tokens by removing them from an account. | ||
/// | ||
/// ### Accounts: | ||
/// 0. `[WRITE]` The account to burn from. | ||
/// 1. `[WRITE]` The token mint. | ||
/// 2. `[SIGNER]` The account's owner/delegate. | ||
pub struct BurnChecked<'a> { | ||
/// Source of the Burn Account | ||
pub token: &'a AccountInfo, | ||
/// Mint Account | ||
pub mint: &'a AccountInfo, | ||
/// Owner of the Token Account | ||
pub authority: &'a AccountInfo, | ||
/// Amount | ||
pub amount: u64, | ||
/// Decimals | ||
pub decimals: u8, | ||
} | ||
|
||
impl<'a> BurnChecked<'a> { | ||
#[inline(always)] | ||
pub fn invoke(&self) -> ProgramResult { | ||
self.invoke_signed(&[]) | ||
} | ||
|
||
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { | ||
// Account metadata | ||
let account_metas: [AccountMeta; 3] = [ | ||
AccountMeta::writable(self.token.key()), | ||
AccountMeta::writable(self.mint.key()), | ||
AccountMeta::readonly_signer(self.authority.key()), | ||
]; | ||
|
||
// Instruction data | ||
// - [0]: instruction discriminator (1 byte, u8) | ||
// - [1..9]: amount (8 bytes, u64) | ||
// - [9]: decimals (1 byte, u8) | ||
let mut instruction_data = [UNINIT_BYTE; 10]; | ||
|
||
// Set discriminator as u8 at offset [0] | ||
write_bytes(&mut instruction_data, &[15]); | ||
// Set amount as u64 at offset [1..9] | ||
write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes()); | ||
// Set decimals as u8 at offset [9] | ||
write_bytes(&mut instruction_data[9..], &[self.decimals]); | ||
|
||
let instruction = Instruction { | ||
program_id: &crate::ID, | ||
accounts: &account_metas, | ||
data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) }, | ||
}; | ||
|
||
invoke_signed( | ||
&instruction, | ||
&[self.token, self.mint, self.authority], | ||
signers, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use pinocchio::{ | ||
account_info::AccountInfo, | ||
instruction::{AccountMeta, Instruction, Signer}, | ||
program::invoke_signed, | ||
ProgramResult, | ||
}; | ||
|
||
/// Close an account by transferring all its SOL to the destination account. | ||
/// | ||
/// ### Accounts: | ||
/// 0. `[WRITE]` The account to close. | ||
/// 1. `[WRITE]` The destination account. | ||
/// 2. `[SIGNER]` The account's owner. | ||
pub struct CloseAccount<'a> { | ||
/// Token Account. | ||
pub account: &'a AccountInfo, | ||
/// Destination Account | ||
pub destination: &'a AccountInfo, | ||
/// Owner Account | ||
pub authority: &'a AccountInfo, | ||
} | ||
|
||
impl<'a> CloseAccount<'a> { | ||
#[inline(always)] | ||
pub fn invoke(&self) -> ProgramResult { | ||
self.invoke_signed(&[]) | ||
} | ||
|
||
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult { | ||
// account metadata | ||
let account_metas: [AccountMeta; 3] = [ | ||
AccountMeta::writable(self.account.key()), | ||
AccountMeta::writable(self.destination.key()), | ||
AccountMeta::readonly_signer(self.authority.key()), | ||
]; | ||
|
||
let instruction = Instruction { | ||
program_id: &crate::ID, | ||
accounts: &account_metas, | ||
data: &[9], | ||
}; | ||
|
||
invoke_signed( | ||
&instruction, | ||
&[self.account, self.destination, self.authority], | ||
signers, | ||
) | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just slice here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is an array of
[MaybeUninit<u8>]
so we need to cast it to[u8]
.