Skip to content

Commit

Permalink
marketplace_native: adding initializeand starting publish
Browse files Browse the repository at this point in the history
  • Loading branch information
kox committed Nov 20, 2024
1 parent 52c3f09 commit cdbe551
Show file tree
Hide file tree
Showing 14 changed files with 498 additions and 12 deletions.
14 changes: 13 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 25 additions & 1 deletion marketplace-native/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
[package]
name = "marketplace-native"
name = "marketplace_native"
version = "0.1.0"
edition = "2021"
authors.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true

[package.metadata.solana]
program-id = "22222222222222222222222222222222222222222222"
program-dependencies = []
account-dependencies = []

[lib]
crate-type = ["cdylib", "lib"]

[dependencies]
pinocchio = { workspace = true }
pinocchio-system = { workspace = true}
pinocchio-token = { workspace = true}
bytemuck = { workspace = true }
five8_const = { workspace = true }
solana-nostd-sha256 = { workspace = true }

[dev-dependencies]
mollusk-svm = { workspace = true }
mollusk-token = { workspace = true }
solana-sdk = { workspace = true }
spl-token = { workspace = true }

[features]
test-sbf = []
no-entrypoint = []
7 changes: 7 additions & 0 deletions marketplace-native/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Flow

- Maker creates a Marketplace
- Producer wants to sell something and publish it
- Consumer wants to buy something in the marketplace
- Consumer sends money to vault and recieves the NFT
- Producer claims sell recieving money but fee
20 changes: 20 additions & 0 deletions marketplace-native/src/instructions/initialize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use pinocchio::{
account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult,
};

pub fn initialize(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {
let [marketplace] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};

unsafe {
let marketplace_account = marketplace.borrow_mut_data_unchecked().as_mut_ptr();

*(marketplace_account.add(0) as *mut Pubkey) = *((data.as_ptr() as * const Pubkey)); // maker
*(marketplace_account.add(32) as *mut u64) = *((data.as_ptr() as * const u64)); // fee
*(marketplace_account.add(32) as *mut u8) = *((data.as_ptr() as * const u8)); // bump
*(marketplace_account.add(32) as *mut u8) = *((data.as_ptr() as * const u8)); // treasury_bump
}

Ok(())
}
35 changes: 35 additions & 0 deletions marketplace-native/src/instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
pub mod initialize;
pub use initialize::*;

pub mod publish;
pub use publish::*;

pub mod unpublish;
pub use unpublish::*;

pub mod purchase;
pub use purchase::*;

use pinocchio::program_error::ProgramError;

#[derive(Clone, Copy, Debug)]
pub enum MarketplaceInstruction {
Initialize,
Publish,
Unpublish,
Purchase,
}

impl TryFrom<&u8> for MarketplaceInstruction {
type Error = ProgramError;

fn try_from(value: &u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(MarketplaceInstruction::Initialize),
1 => Ok(MarketplaceInstruction::Publish),
2 => Ok(MarketplaceInstruction::Unpublish),
3 => Ok(MarketplaceInstruction::Purchase),
_ => Err(ProgramError::InvalidInstructionData),
}
}
}
20 changes: 20 additions & 0 deletions marketplace-native/src/instructions/publish.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use pinocchio::{
account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult,
};

//
// Publish instruction
//
// A publisher who owns a NFT, wants to sell it in a marketplace
// It will require to pass:
// > publisher
// > publisher_ta
// > the marketplace
// > the token account
// > price
//
pub fn publish(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {
let [publisher, marketplace, , _token_program] = accounts

Ok(())
}
8 changes: 8 additions & 0 deletions marketplace-native/src/instructions/purchase.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use pinocchio::{
account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult,
};

pub fn purchase(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {

Ok(())
}
8 changes: 8 additions & 0 deletions marketplace-native/src/instructions/unpublish.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use pinocchio::{
account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult,
};

pub fn unpublish(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {

Ok(())
}
38 changes: 28 additions & 10 deletions marketplace-native/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
#![feature(asm_experimental_arch)]
use pinocchio::{
account_info::AccountInfo, entrypoint, program_error::ProgramError, pubkey::Pubkey,
ProgramResult,
};

mod instructions;
use instructions::*;

mod state;
pub use state::*;

const ID: Pubkey = five8_const::decode_32_const("22222222222222222222222222222222222222222222");

entrypoint!(process_instruction);

#[cfg(test)]
mod tests {
use super::*;
pub fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let (discriminator, data) = instruction_data
.split_first()
.ok_or(ProgramError::InvalidInstructionData)?;

#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
match MarketplaceInstruction::try_from(discriminator)? {
MarketplaceInstruction::Initialize => initialize(accounts, data),
MarketplaceInstruction::Publish => publish(accounts, data),
MarketplaceInstruction::Unpublish => unpublish(accounts, data),
MarketplaceInstruction::Purchase => purchase(accounts, data),
}
}
62 changes: 62 additions & 0 deletions marketplace-native/src/state/marketplace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use pinocchio::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult};

/// # Marketplace State
///
/// -- Data --
/// > Maker: Pubkey
/// > fee: u64
/// > bump: u8
/// > treasury_bump: u8
///
/// -- Data Logic --
/// [...]
///
pub struct Marketplace(*const u8);

impl Marketplace {
pub const LEN: usize = 32 // maker
+ 8 // fee
+ 1 // bump
+ 1; // treasury_bump

#[inline(always)]
pub fn init(&self, data: &[u8; Self::LEN]) -> ProgramResult {
unsafe { *(self.0 as *mut [u8; Self::LEN]) = *data };
Ok(())
}

#[inline(always)]
pub fn from_account_info_unchecked(account_info: &AccountInfo) -> Self {
unsafe { Self(account_info.borrow_data_unchecked().as_ptr()) }
}

#[inline(always)]
pub fn from_account_info(account_info: &AccountInfo) -> Result<Self, ProgramError> {
assert_eq!(account_info.data_len(), Self::LEN);
assert_eq!(account_info.owner(), &crate::ID);
Ok(Self::from_account_info_unchecked(account_info))
}

// We store who owns the marketplace
#[inline(always)]
pub fn maker(&self) -> Pubkey {
unsafe { *(self.0 as *const Pubkey) }
}

// How much the marketplace will retain per purchase
#[inline(always)]
pub fn fee(&self) -> u64 {
unsafe { *(self.0.add(32) as *const u64) }
}

#[inline(always)]
pub fn bump(&self) -> u8 {
unsafe { *(self.0.add(40) as *const u8) }
}

// To store the SOL
#[inline(always)]
pub fn treasury_bump(&self) -> u8 {
unsafe { *(self.0.add(41) as *const u8) }
}
}
5 changes: 5 additions & 0 deletions marketplace-native/src/state/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod marketplace;
pub use marketplace::*;

pub mod publish;
pub use publish::*;
45 changes: 45 additions & 0 deletions marketplace-native/src/state/publish.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use pinocchio::{account_info::AccountInfo, pubkey::Pubkey};

/// # Publish State
///
/// -- Data --
/// > Maker: Pubkey
/// > fee: u64
/// > bump: u8
/// > treasury_bump: u8
///
/// -- Data Logic --
/// [...]
///
pub struct Publish(*const u8);

impl Publish {
pub const LEN: usize = 32 + 32 + 8 + 1;

#[inline(always)]
pub fn from_account_info_unchecked(account_info: &AccountInfo) -> Self {
unsafe { Self(account_info.borrow_data_unchecked().as_ptr()) }
}

pub fn from_account_info(account_info: &AccountInfo) -> Self {
assert_eq!(account_info.data_len(), Self::LEN);
assert_eq!(account_info.owner(), &crate::ID);
Self::from_account_info_unchecked(account_info)
}

pub fn publisher(&self) -> Pubkey {
unsafe { *(self.0 as *const Pubkey) }
}

pub fn mint(&self) -> Pubkey {
unsafe { *(self.0.add(32) as *const Pubkey) }
}

pub fn price(&self) -> u64 {
unsafe { *(self.0.add(64) as *const u64) }
}

pub fn bump(&self) -> u8 {
unsafe { *(self.0.add(72) as *const u8) }
}
}
Loading

0 comments on commit cdbe551

Please sign in to comment.