Skip to content

Commit

Permalink
feat: pop api crate (#16)
Browse files Browse the repository at this point in the history
* ci: add build workflow

* chore: improve zombienet config

* ci: grant write permission to actions

* feat: initialize pop-api directory

* feat: add codec indexes, and wrap NFT interface

* feat: add example contract utilizing pop-api crate -- not working

* feat: minting NFT from contract through runtime works

* feat pop api crate refactoring and test (#15)

* refactor: simplify api usage from contract

* test: add NFT mint unit test to pop api extension

---------

Co-authored-by: Frank Bell <[email protected]>

---------

Co-authored-by: Frank Bell <[email protected]>
  • Loading branch information
peterwht and evilrobot-01 committed Mar 6, 2024
1 parent 39662f2 commit 8066adb
Show file tree
Hide file tree
Showing 17 changed files with 2,190 additions and 813 deletions.
2,432 changes: 1,628 additions & 804 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ repository = "https://github.com/r0gue-io/pop-node/"
members = [
"node",
"runtime",
"pop-api",
]
exclude = [
"demo-contracts"
"contracts"
]

resolver = "2"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions contracts/pop-api-examples/nfts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Ignore build artifacts from the local tests sub-crate.
/target/

# Ignore backup files creates by cargo fmt.
**/*.rs.bk

# Remove Cargo.lock when creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock
32 changes: 32 additions & 0 deletions contracts/pop-api-examples/nfts/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "pop_api_nft_example"
version = "0.1.0"
authors = ["[your_name] <[your_email]>"]
edition = "2021"

[dependencies]
ink = { version = "4.3.0", default-features = false }
pop-api = { path = "../../../pop-api", default-features = false }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true }
sp-io = { version = "23.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] }
sp-runtime = { version = "24.0.0", default-features = false }

[dev-dependencies]
ink_e2e = "4.3.0"

[lib]
path = "lib.rs"

[features]
default = ["std"]
std = [
"ink/std",
"scale/std",
"scale-info/std",
"sp-io/std",
"sp-runtime/std",
"pop-api/std",
]
ink-as-dependency = []
e2e-tests = []
58 changes: 58 additions & 0 deletions contracts/pop-api-examples/nfts/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

use pop_api::PopApiError;

#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum ContractError {
SomeError,
}

impl From<PopApiError> for ContractError {
fn from(_value: PopApiError) -> Self {
ContractError::SomeError
}
}

#[ink::contract(env = pop_api::PopEnv)]
mod pop_api_extension_demo {
use super::ContractError;

#[ink(storage)]
#[derive(Default)]
pub struct PopApiExtensionDemo;

impl PopApiExtensionDemo {
#[ink(constructor, payable)]
pub fn new() -> Self {
ink::env::debug_println!("PopApiExtensionDemo::new");
Default::default()
}

#[ink(message)]
pub fn mint_through_runtime(
&mut self,
collection_id: u32,
item_id: u32,
receiver: AccountId,
) -> Result<(), ContractError> {
ink::env::debug_println!("PopApiExtensionDemo::mint_through_runtime: collection_id: {:?} \nitem_id {:?} \nreceiver: {:?}, ", collection_id, item_id, receiver);

// simplified API call
pop_api::nfts::mint(collection_id, item_id, receiver)?;

ink::env::debug_println!("PopApiExtensionDemo::mint_through_runtime end");
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;

#[ink::test]
fn default_works() {
PopApiExtensionDemo::new();
}
}
}
15 changes: 15 additions & 0 deletions pop-api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.idea/
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
29 changes: 29 additions & 0 deletions pop-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "pop-api"
description = "Reserved crate for pop-api."
license = "GPL-3.0-only"
version = "0.0.0"
edition = "2021"

[dependencies]
ink = { version = "4.3.0", default-features = false }
ink_env = { version = "4.3.0", default-features = false }
sp-runtime = { version = "24.0.0", default-features = false }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true }

[lib]
name = "pop_api"
path = "src/lib.rs"
crate-type = [
"rlib",
]

[features]
default = ["std"]
std = [
"ink/std",
"sp-runtime/std",
"scale/std",
"scale-info/std",
]
1 change: 1 addition & 0 deletions pop-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reserved crate for pop-api.
77 changes: 77 additions & 0 deletions pop-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

pub mod v0;

use ink::{env::Environment, prelude::vec::Vec, ChainExtensionInstance};
use scale;
use sp_runtime::MultiSignature;
pub use v0::nfts;
use v0::RuntimeCall;

// Id used for identifying non-fungible collections.
pub type CollectionId = u32;

// Id used for identifying non-fungible items.
pub type ItemId = u32;

type AccountId = <ink::env::DefaultEnvironment as Environment>::AccountId;
type Balance = <ink::env::DefaultEnvironment as Environment>::Balance;
type BlockNumber = <ink::env::DefaultEnvironment as Environment>::BlockNumber;
type Signature = MultiSignature;
type StringLimit = u32;
type KeyLimit = u32;
type MaxTips = u32;

pub type Result<T> = core::result::Result<T, PopApiError>;

#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum PopApiError {
PlaceholderError,
}

impl ink::env::chain_extension::FromStatusCode for PopApiError {
fn from_status_code(status_code: u32) -> core::result::Result<(), Self> {
match status_code {
0 => Ok(()),
1 => Err(Self::PlaceholderError),
_ => panic!("encountered unknown status code"),
}
}
}

impl From<scale::Error> for PopApiError {
fn from(_: scale::Error) -> Self {
panic!("encountered unexpected invalid SCALE encoding")
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum PopEnv {}

impl Environment for PopEnv {
const MAX_EVENT_TOPICS: usize = <ink::env::DefaultEnvironment as Environment>::MAX_EVENT_TOPICS;

type AccountId = <ink::env::DefaultEnvironment as Environment>::AccountId;
type Balance = <ink::env::DefaultEnvironment as Environment>::Balance;
type Hash = <ink::env::DefaultEnvironment as Environment>::Hash;
type BlockNumber = <ink::env::DefaultEnvironment as Environment>::BlockNumber;
type Timestamp = <ink::env::DefaultEnvironment as Environment>::Timestamp;

type ChainExtension = PopApi;
}

#[ink::chain_extension]
pub trait PopApi {
type ErrorCode = PopApiError;

#[ink(extension = 0xfecb)]
#[allow(private_interfaces)]
fn dispatch(call: RuntimeCall) -> crate::Result<Vec<u8>>;
}

fn call_runtime(call: RuntimeCall) -> Result<Vec<u8>> {
<<PopEnv as Environment>::ChainExtension as ChainExtensionInstance>::instantiate()
.dispatch(call)
}
1 change: 1 addition & 0 deletions pop-api/src/v0/balances.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

8 changes: 8 additions & 0 deletions pop-api/src/v0/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pub mod balances;
pub mod nfts;

#[derive(scale::Encode)]
pub(crate) enum RuntimeCall {
#[codec(index = 50)]
Nfts(nfts::NftCalls),
}
Loading

0 comments on commit 8066adb

Please sign in to comment.