From e699ceee72dfe859956e9f7cbd2d206bd810a8b9 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Thu, 31 Oct 2024 15:01:33 +0100 Subject: [PATCH 01/11] docs: update base pop-api README --- pop-api/README.md | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/pop-api/README.md b/pop-api/README.md index 91effa08..b6525631 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -1,8 +1,11 @@ # Pop API +_A stable runtime interface for ink! smart contracts that elevates the experience of building Web3 applications._ + ## Examples ink! smart contract examples using the Pop API - [balance-transfer](./examples/balance-transfer/) +- [fungibles](./examples/fungibles/) - [NFTs](./examples/nfts/) - [place-spot-order](./examples/place-spot-order/) - [read-runtime-state](./examples/read-runtime-state/) @@ -31,7 +34,7 @@ Everything in [`pop-api`](./src/) **is the** Pop API ink! library. So when the ink! smart contract wants to use the Pop API library, it can simply have a line like: ```rust -use pop_api::nfts::*; +use pop_api::fungibles::{self as api}; ``` ## The Glue @@ -42,27 +45,37 @@ Certain types are shared between the ink! library portion of the Pop API and the When we use the Pop API in our smart contract like so: ```rust -use pop_api::nfts::*; -mint(collection_id, item_id, receiver)?; +use pop_api::fungibles::{self as api}; +api::transfer(token, to, value) ``` -This will call the Pop API `mint` function in the [./src/v0/nfts.rs](./src/v0/nfts.rs) file, which is a wrapper to `dispatch` a `Runtime::Call` to the NFTs pallet's mint function. This is how most of the Pop API is built. This abstraction allows for creating a developer-friendly API over runtime level features such as calling pallets, reading state, and cross-chain interactions. All Pop API functionality can be found in [./src/v0/](./src/v0/) which is the current version of the Pop API. +This will call the Pop API `transfer` function in the [./src/v0/fungibles/mod.rs](./src/v0/fungibles/mod.rs) file, which is a wrapper to `dispatch` a `Runtime::Call` to the assets pallet's transfer function. This is how most of the Pop API is built. This abstraction allows for creating a developer-friendly API over runtime level features such as calling pallets, reading state, and cross-chain interactions. All Pop API versions can be found in [pop-api/src/](./src/). ## Dispatching to the runtime ([./src/lib.rs](./src/lib.rs)) -### `PopApi` -The `PopApi` trait is an ink! chain extension trait with three functions: -- `dispatch()` -- `read_state()` -- `send_xcm()` +### `PopApi` +The `PopApi` is an ink! [`ChainExtensionMethod`](https://docs.rs/ink_env/5.0.0/ink_env/chain_extension/struct.ChainExtensionMethod.html) instance used to derive the execution of the different calls a smart contract can do into the runtime. + +Its purpose its two fold, constructing the runtime calls that are going to be executed by the chain extension and handling the information returned. + +The calls are built out of the following information: +- The `function` Id: Identifies the specific function within the chain extension. +- The API `version`: This byte allows the runtime to distinguish between different API versions, ensuring that older contracts call the correct, version-specific implementation.. +- A `module` index: Identifies the pallet responsible for handling the call. +- A `dispatchable` index: Indicates the specific dispatchable or state read function within the pallet. + +Multiple **functions** can be implemented for the chain extension, so whenever something needs to be added or changed, a new function will have to be implemented. +`DISPATCH` and `READ_STATE` functions are the workhorse functions of the Pop API. +Through these functions all the interactions between the ink! smart contract and the runtime are carried out. + +By embedding the **version** directly into the encoding scheme, the runtime can manage different versions of dispatch calls and queries, ensuring that both legacy and new contracts function as intended, even as the underlying system evolves. This structure provides the flexibility needed to support ongoing improvements and changes in the runtime without disrupting existing smart contracts. -These are the workhorse functions of the Pop API. Through these functions all the interactions between the ink! smart contract and the runtime are carried out. So in our example above, the `mint` function in [nfts.rs](./src/v0/nfts.rs) calls a `dispatch`, this `dispatch` is defined here in the [lib.rs](./src/lib.rs) file. It is what calls into the runtime chain extension. +So in our example above, when the `trasnfer` function in [./src/v0/fungibles/mod.rs](./src/v0/fungibles/mod.rs) is called, the following is constructed `u32::from_le_bytes([DISPATCH, 0, FUNGIBLES, TRANSFER])` to be executed by the runtime chain extension. -> Notice how each function is assigned a function ID e.g. `#[ink(function = 1)]`. This will play a role later when we cover the runtime portion of the chain extension. -### `PopApiError` -When Pop API calls the runtime, it will either receive a successful result or an encoded error. `PopApiError` translates the encoded error into the appropriate module error according to the index that the pallet has been configured to. +### `StatusCode` +When Pop API calls the runtime, it will either receive a successful result or an encoded error. `StatusCode` translates the encoded error into the appropriate module error according to the index that the pallet has been configured to. ## The Pop API Chain Extension @@ -70,4 +83,4 @@ So we have covered how the ink! Pop API library calls the chain extension. But w Chain extensions "extend" a runtime. We can find the `PopApiExtension` chain extension in [extension.rs](../runtime/devnet/src/extensions.rs). The `PopApiExtension` chain extension is matching based on the function IDs that we defined on the ink! side of the Pop API. The chain extension here will execute the appropriate functions e.g. `dispatch` or `read_state`. These functions are defined in this file as well and interact directly with the Pop Network runtime. -If you would like to see the whole flow, checkout the end-to-end tests in [extensions.rs](../runtime/devnet/src/extensions.rs) file e.g. `dispatch_nfts_mint_from_contract_works()` \ No newline at end of file +If you would like to see the whole flow, checkout the integration tests in [pop-api/integration-tests](./integration-tests/) e.g. [`instantiate_and_create_fungible_works()`](./integration-tests/src/fungibles/mod.rs). From f9853cdaa4b1b82218960e41d62764176aeef23b Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Thu, 31 Oct 2024 16:53:58 +0100 Subject: [PATCH 02/11] docs: pop-api v0 READMEs --- pop-api/README.md | 33 ++++-- pop-api/src/v0/README.md | 18 ++++ pop-api/src/v0/fungibles/README.md | 162 +++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 6 deletions(-) create mode 100644 pop-api/src/v0/README.md create mode 100644 pop-api/src/v0/fungibles/README.md diff --git a/pop-api/README.md b/pop-api/README.md index b6525631..702f69bd 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -2,17 +2,25 @@ _A stable runtime interface for ink! smart contracts that elevates the experience of building Web3 applications._ +--- + +## What is the Pop API? + +One of the core value propositions of Pop Network is to enable smart contracts to easily access the power of Polkadot. As such, the Pop API was built to enable smart contracts to easily utilize the functionality provided by the Pop Network parachain runtime. + +## Versions + +- [V0](./src/v0/README.md) + ## Examples ink! smart contract examples using the Pop API -- [balance-transfer](./examples/balance-transfer/) + - [fungibles](./examples/fungibles/) -- [NFTs](./examples/nfts/) -- [place-spot-order](./examples/place-spot-order/) - [read-runtime-state](./examples/read-runtime-state/) -## What is the Pop API? +--- -One of the core value propositions of Pop Network is to enable smart contracts to easily access the power of Polkadot. As such, the Pop API was built to enable smart contracts to easily utilize the functionality provided by the Pop Network parachain runtime. +## Design Substrate already exposes a Runtime API which is typically associated with the “outer node” calling into the runtime via RPC. Pop Network extends this concept in a direction that makes it usable by smart contracts, allowing untrusted contracts to make use of carefully exposed trusted functionality available within the runtime - this is the Pop API. @@ -46,7 +54,12 @@ Certain types are shared between the ink! library portion of the Pop API and the When we use the Pop API in our smart contract like so: ```rust use pop_api::fungibles::{self as api}; -api::transfer(token, to, value) +// -- snip -- +#[ink(message)] +pub fn transfer(&mut self, token: TokenId, to: AccountId, value: Balance) -> Result<()> { + // Use of Pop API to call into the runtime to transfer some fungible assets. + api::transfer(token, to, value) +} ``` This will call the Pop API `transfer` function in the [./src/v0/fungibles/mod.rs](./src/v0/fungibles/mod.rs) file, which is a wrapper to `dispatch` a `Runtime::Call` to the assets pallet's transfer function. This is how most of the Pop API is built. This abstraction allows for creating a developer-friendly API over runtime level features such as calling pallets, reading state, and cross-chain interactions. All Pop API versions can be found in [pop-api/src/](./src/). @@ -83,4 +96,12 @@ So we have covered how the ink! Pop API library calls the chain extension. But w Chain extensions "extend" a runtime. We can find the `PopApiExtension` chain extension in [extension.rs](../runtime/devnet/src/extensions.rs). The `PopApiExtension` chain extension is matching based on the function IDs that we defined on the ink! side of the Pop API. The chain extension here will execute the appropriate functions e.g. `dispatch` or `read_state`. These functions are defined in this file as well and interact directly with the Pop Network runtime. +`PopApiExtension` implements the different **functions** that can be called by the API. Two functions are provided: + +- `DISPATCH`: +The Dispatch function decodes the received bytes into a `RuntimeCall`, optionally processing them as needed (versioning). It filters out any calls that are not explicitly permitted, then charges the appropriate weight, dispatches the call, and adjusts the weight accordingly before returning the result of the dispatch call. + +- `READ_STATE`: +The ReadState function decodes the received bytes into a `Readable` type, with optional processing (versioning). It filters out any unauthorised state reads, charges the appropriate weight, executes the state read, optionally converts the result (versioning), and finally returns the result. + If you would like to see the whole flow, checkout the integration tests in [pop-api/integration-tests](./integration-tests/) e.g. [`instantiate_and_create_fungible_works()`](./integration-tests/src/fungibles/mod.rs). diff --git a/pop-api/src/v0/README.md b/pop-api/src/v0/README.md new file mode 100644 index 00000000..f8f608c3 --- /dev/null +++ b/pop-api/src/v0/README.md @@ -0,0 +1,18 @@ +# Pop API V0 + +The version `0` of Pop API features integrations with the following pallets: +- [Fungibles](#fungibles) + + +--- +### FUNGIBLES +```rust +#[runtime::pallet_index(150)] +pub type Fungibles = fungibles::Pallet; +``` +The fungibles pallet offers a streamlined interface for interacting with fungible tokens. The +goal is to provide a simplified, consistent API that adheres to standards in the smart contract +space. + +For more details please refer to: +[Fungibles API](./fungibles/README.md) diff --git a/pop-api/src/v0/fungibles/README.md b/pop-api/src/v0/fungibles/README.md new file mode 100644 index 00000000..456b8541 --- /dev/null +++ b/pop-api/src/v0/fungibles/README.md @@ -0,0 +1,162 @@ +# Fungibles API + +The `fungibles` module provides an API for interacting and managing fungible tokens. + +The API includes the following interfaces: + 1. PSP-22 + 2. PSP-22 Metadata + 3. Management + 4. PSP-22 Mintable & Burnable +--- + +## Interface + +#### PSP-22, PSP-22 Mintable & PSP-22 Burnable +The interface for transferring, delegating, minting and burning tokens. +```rust +/// Returns the total token supply for a specified token. +/// +/// # Parameters +/// - `token` - The token. +pub fn total_supply(token: TokenId) -> Result {} + +/// Returns the account balance for a specified `token` and `owner`. Returns `0` if +/// the account is non-existent. +/// +/// # Parameters +/// - `token` - The token. +/// - `owner` - The account whose balance is being queried. +pub fn balance_of(token: TokenId, owner: AccountId) -> Result {} + +/// Returns the allowance for a `spender` approved by an `owner`, for a specified `token`. Returns +/// `0` if no allowance has been set. +/// +/// # Parameters +/// - `token` - The token. +/// - `owner` - The account that owns the tokens. +/// - `spender` - The account that is allowed to spend the tokens. +pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result {} + +/// Transfers `value` amount of tokens from the caller's account to account `to`. +/// +/// # Parameters +/// - `token` - The token to transfer. +/// - `to` - The recipient account. +/// - `value` - The number of tokens to transfer. +pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> {} + +/// Transfers `value` amount tokens on behalf of `from` to account `to`. +/// +/// # Parameters +/// - `token` - The token to transfer. +/// - `from` - The account from which the token balance will be withdrawn. +/// - `to` - The recipient account. +/// - `value` - The number of tokens to transfer. +pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> {} + +/// Approves `spender` to spend `value` amount of tokens on behalf of the caller. +/// +/// # Parameters +/// - `token` - The token to approve. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to approve. +pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> {} + +/// Increases the allowance of `spender` by `value` amount of tokens. +/// +/// # Parameters +/// - `token` - The token to have an allowance increased. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to increase the allowance by. +pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> {} + +/// Decreases the allowance of `spender` by `value` amount of tokens. +/// +/// # Parameters +/// - `token` - The token to have an allowance decreased. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to decrease the allowance by. +pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> {} + +/// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. +/// +/// # Parameters +/// - `token` - The token to mint. +/// - `account` - The account to be credited with the created tokens. +/// - `value` - The number of tokens to mint. +pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> {} + +/// Destroys `value` amount of tokens from `account`, reducing the total supply. +/// +/// # Parameters +/// - `token` - the token to burn. +/// - `account` - The account from which the tokens will be destroyed. +/// - `value` - The number of tokens to destroy. +pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> {} +``` + +#### PSP-22 Metadata +The PSP-22 compliant interface for querying metadata. +```rust +/// Returns the name of the specified token, if available. +/// +/// # Parameters +/// - `token` - The token. +pub fn token_name(token: TokenId) -> Result>> {} + +/// Returns the symbol for the specified token, if available. +/// +/// # Parameters +/// - `token` - The token. +pub fn token_symbol(token: TokenId) -> Result>> {} + +/// Returns the decimals for the specified token. +/// +/// # Parameters +/// - `token` - The token. +pub fn token_decimals(token: TokenId) -> Result {} +``` + +#### PSP-22 Management +The interface for creating, managing and destroying fungible tokens. +```rust +/// Create a new token with a given identifier. +/// +/// # Parameters +/// - `id` - The identifier of the token. +/// - `admin` - The account that will administer the token. +/// - `min_balance` - The minimum balance required for accounts holding this token. +pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> {} + +/// Start the process of destroying a token. +/// +/// # Parameters +/// - `token` - The token to be destroyed. +pub fn start_destroy(token: TokenId) -> Result<()> {} + +/// Set the metadata for a token. +/// +/// # Parameters +/// - `token`: The token to update. +/// - `name`: The user friendly name of this token. +/// - `symbol`: The exchange symbol for this token. +/// - `decimals`: The number of decimals this token uses to represent one unit. +pub fn set_metadata( + token: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, +) -> Result<()> {} + +/// Clear the metadata for a token. +/// +/// # Parameters +/// - `token` - The token to update +pub fn clear_metadata(token: TokenId) -> Result<()> {} + +/// Checks if a specified token exists. +/// +/// # Parameters +/// - `token` - The token. +pub fn token_exists(token: TokenId) -> Result {} +``` From 3742940e1f977877cea838eac48a3cdd8f82dd82 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:35:56 +0100 Subject: [PATCH 03/11] docs: link fungibles examples --- pop-api/src/v0/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pop-api/src/v0/README.md b/pop-api/src/v0/README.md index f8f608c3..aa8a6e2a 100644 --- a/pop-api/src/v0/README.md +++ b/pop-api/src/v0/README.md @@ -14,5 +14,6 @@ The fungibles pallet offers a streamlined interface for interacting with fungibl goal is to provide a simplified, consistent API that adheres to standards in the smart contract space. -For more details please refer to: -[Fungibles API](./fungibles/README.md) +For more details please refer to the [Fungibles API documentation](./fungibles/README.md). + +Find examples in: [`../../examples/fungibles/`](../../examples/fungibles/). From 084efd88b3e89b1e31d810a202d3a0ba78c58f48 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:38:58 +0100 Subject: [PATCH 04/11] docs: link pallet fungibles --- pop-api/src/v0/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pop-api/src/v0/README.md b/pop-api/src/v0/README.md index aa8a6e2a..02f46ca6 100644 --- a/pop-api/src/v0/README.md +++ b/pop-api/src/v0/README.md @@ -17,3 +17,5 @@ space. For more details please refer to the [Fungibles API documentation](./fungibles/README.md). Find examples in: [`../../examples/fungibles/`](../../examples/fungibles/). + +The fungibles pallet can be found in [`pallets/api/src/fungibles/`](../../../pallets/api/src/fungibles/) From 2ac8551e1abb55805d40e4ecda6a7c6be996280a Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:02:16 +0100 Subject: [PATCH 05/11] docs: include use pop-api --- pop-api/README.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pop-api/README.md b/pop-api/README.md index 702f69bd..fe63bfab 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -12,12 +12,34 @@ One of the core value propositions of Pop Network is to enable smart contracts t - [V0](./src/v0/README.md) + +## Use Pop API + +Including Pop API in your ink! smart contract is as easy as adding one dependency to `pop-api` crate in your project manifest: + +```toml +# Cargo.toml +pop-api = { git = "https://github.com/r0gue-io/pop-node", default-features = false } +``` + +and importing it within the contract source: + +```rust +// contract.rs +use pop_api::v0::*; +``` + ## Examples ink! smart contract examples using the Pop API - [fungibles](./examples/fungibles/) - [read-runtime-state](./examples/read-runtime-state/) +## Testing + +// cover pop-drink + + --- ## Design @@ -57,7 +79,7 @@ use pop_api::fungibles::{self as api}; // -- snip -- #[ink(message)] pub fn transfer(&mut self, token: TokenId, to: AccountId, value: Balance) -> Result<()> { - // Use of Pop API to call into the runtime to transfer some fungible assets. + // Usege of Pop API to call into the runtime to transfer some fungible assets. api::transfer(token, to, value) } ``` From 3f96f63f95bdc76e6ca045cc367db2e8bcee4174 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:18:27 +0100 Subject: [PATCH 06/11] docs: table of contents --- pop-api/README.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/pop-api/README.md b/pop-api/README.md index fe63bfab..5232ecfa 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -1,12 +1,23 @@ # Pop API -_A stable runtime interface for ink! smart contracts that elevates the experience of building Web3 applications._ + +- [What is Pop API](#what-is-pop-api) +- [Versions](#versions) +- [Use Pop API](#use-pop-api) +- [Examples](#examples) +- [Testing](#testing) +- [Design of Pop API](#design-of-pop-api-) +- - [The Pop API ink! Library](#the-pop-api-ink-library) +- - [The Glue](#the-glue) +- - [The Entry into the Pop API](#the-entry-into-the-pop-api) +- - [Dispatching to the runtime](#dispatching-to-the-runtime-srclibrs) +- - [The Pop API Chain Extension](#the-pop-api-chain-extension) --- -## What is the Pop API? +## What is Pop API -One of the core value propositions of Pop Network is to enable smart contracts to easily access the power of Polkadot. As such, the Pop API was built to enable smart contracts to easily utilize the functionality provided by the Pop Network parachain runtime. +The Pop API ink! library provides APIs for tailored use cases. The apis are versioned ensuring compatibility across different runtime updates and preserves the functionality of existing contracts. ## Versions @@ -15,7 +26,7 @@ One of the core value propositions of Pop Network is to enable smart contracts t ## Use Pop API -Including Pop API in your ink! smart contract is as easy as adding one dependency to `pop-api` crate in your project manifest: +Using Pop API in your ink! smart contract is as easy as adding one dependency to `pop-api` crate in your project manifest: ```toml # Cargo.toml @@ -42,7 +53,9 @@ ink! smart contract examples using the Pop API --- -## Design +# Design of Pop API + +One of the core value propositions of Pop Network is to enable smart contracts to easily access the power of Polkadot. As such, the Pop API was built to enable smart contracts to easily utilize the functionality provided by the Pop Network parachain runtime. Substrate already exposes a Runtime API which is typically associated with the “outer node” calling into the runtime via RPC. Pop Network extends this concept in a direction that makes it usable by smart contracts, allowing untrusted contracts to make use of carefully exposed trusted functionality available within the runtime - this is the Pop API. From 91017bced41ae37174cf0c424967e154932ada64 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:33:14 +0100 Subject: [PATCH 07/11] docs: mention features --- pop-api/README.md | 2 +- pop-api/src/v0/README.md | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pop-api/README.md b/pop-api/README.md index 5232ecfa..accaa779 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -26,7 +26,7 @@ The Pop API ink! library provides APIs for tailored use cases. The apis are vers ## Use Pop API -Using Pop API in your ink! smart contract is as easy as adding one dependency to `pop-api` crate in your project manifest: +Using the Pop API in your ink! smart contract is as easy as adding the `pop-api` crate in your project manifest: ```toml # Cargo.toml diff --git a/pop-api/src/v0/README.md b/pop-api/src/v0/README.md index 02f46ca6..3bbe2ad4 100644 --- a/pop-api/src/v0/README.md +++ b/pop-api/src/v0/README.md @@ -3,19 +3,26 @@ The version `0` of Pop API features integrations with the following pallets: - [Fungibles](#fungibles) +Each pallet integration can be included individually with its own feature, this way only the necessary dependencies will be compiled into the contract. --- ### FUNGIBLES -```rust -#[runtime::pallet_index(150)] -pub type Fungibles = fungibles::Pallet; -``` +| pop-api feature | pallet-index | +|:---------------:|:--------------:| +| `fungibles` | `150` | + The fungibles pallet offers a streamlined interface for interacting with fungible tokens. The goal is to provide a simplified, consistent API that adheres to standards in the smart contract space. +To use the `Fungibles` API the `fungibles` features needs to be included in the pop-api crate dependency. +```toml +# Cargo.toml +pop-api = { git = "https://github.com/r0gue-io/pop-node", default-features = false, features = [ "fungibles" ] } +``` + For more details please refer to the [Fungibles API documentation](./fungibles/README.md). Find examples in: [`../../examples/fungibles/`](../../examples/fungibles/). -The fungibles pallet can be found in [`pallets/api/src/fungibles/`](../../../pallets/api/src/fungibles/) +The fungibles pallet can be found in [`pallets/api/src/fungibles/`](../../../pallets/api/src/fungibles/). From 1344170f1347169589b48324a234d857c6e1ce9c Mon Sep 17 00:00:00 2001 From: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:46:10 +0100 Subject: [PATCH 08/11] docs: api readme (#366) --- pop-api/README.md | 156 +++++++-------------------- pop-api/src/v0/README.md | 28 ----- pop-api/src/v0/fungibles/README.md | 167 +++-------------------------- 3 files changed, 51 insertions(+), 300 deletions(-) delete mode 100644 pop-api/src/v0/README.md diff --git a/pop-api/README.md b/pop-api/README.md index accaa779..f127e9c2 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -1,142 +1,64 @@ -# Pop API +## Pop API +The `pop-api` crate provides a high-level interface that allows smart contracts to seamlessly interact with Pop, a +blockchain built to power innovative and impactful solutions on Polkadot. Designed for stability, simplicity and +efficiency, the API abstracts away the complexities of the runtime, enabling developers to focus on building powerful +applications rather than managing intricate blockchain details. -- [What is Pop API](#what-is-pop-api) -- [Versions](#versions) -- [Use Pop API](#use-pop-api) -- [Examples](#examples) -- [Testing](#testing) -- [Design of Pop API](#design-of-pop-api-) -- - [The Pop API ink! Library](#the-pop-api-ink-library) -- - [The Glue](#the-glue) -- - [The Entry into the Pop API](#the-entry-into-the-pop-api) -- - [Dispatching to the runtime](#dispatching-to-the-runtime-srclibrs) -- - [The Pop API Chain Extension](#the-pop-api-chain-extension) +### Design Goals ---- +- **Simple**: enhance the developer experience by abstracting away the complexities of runtime functionality, making it + easy for developers to build advanced applications. +- **Versioned**: offer a stable, versioned interface that ensures smart contracts stay compatible as the runtime + evolves, enabling seamless integration of new features without disrupting existing contracts. +- **Efficient**: optimise for minimal contract size, having the lowest possible deployment and execution costs. -## What is Pop API +### Key Features -The Pop API ink! library provides APIs for tailored use cases. The apis are versioned ensuring compatibility across different runtime updates and preserves the functionality of existing contracts. +- **Versioned Interface**: Provides backward compatibility, ensuring that existing contract functionality remains stable + as new features are added to the runtime. +- **Error Handling**: Supports rich, versioned error types, enabling contracts to receive and interpret any runtime + error, making troubleshooting and development easier. +- **Use Cases**: + - [Fungibles](./src/v0/fungibles/README.md): Interacting and managing fungible tokens. + - In development: + - Non Fungibles: Interacting and managing non fungible tokens. + - Messaging: Cross chain rails for interaction with other chains using ISMP & XCM. + - Sponsorship: Allowing smart contracts to sponsor transactions. + - Incentives: Incentivise smart contracts by sharing chain revenue. -## Versions +### Getting Started -- [V0](./src/v0/README.md) - - -## Use Pop API - -Using the Pop API in your ink! smart contract is as easy as adding the `pop-api` crate in your project manifest: +Using the API in your ink! smart contract is as easy as adding the `pop-api` crate in your `Cargo.toml`: ```toml -# Cargo.toml pop-api = { git = "https://github.com/r0gue-io/pop-node", default-features = false } ``` and importing it within the contract source: ```rust -// contract.rs -use pop_api::v0::*; -``` - -## Examples -ink! smart contract examples using the Pop API - -- [fungibles](./examples/fungibles/) -- [read-runtime-state](./examples/read-runtime-state/) - -## Testing - -// cover pop-drink - - ---- - -# Design of Pop API - -One of the core value propositions of Pop Network is to enable smart contracts to easily access the power of Polkadot. As such, the Pop API was built to enable smart contracts to easily utilize the functionality provided by the Pop Network parachain runtime. - -Substrate already exposes a Runtime API which is typically associated with the “outer node” calling into the runtime via RPC. Pop Network extends this concept in a direction that makes it usable by smart contracts, allowing untrusted contracts to make use of carefully exposed trusted functionality available within the runtime - this is the Pop API. - -The Pop API is designed to be: -- **Stable**: contracts are generally immutable and therefore need a stable interface, especially as the runtime evolves over time. -- **Future Proof**: technologies improve, so the Pop API implementation is adaptable to new approaches without affecting the interface. The Pop API implementation also selects the optimal approach to realize a use case from a range of possible technical implementations. -- **Versioned**: not every future technology can be retro-fitted, so the API is versioned. -- **Simple**: providing an abstraction layer over runtime-level features. Hand-rolled with love, Pop API is easy to use for smart contract development. - -The Pop API consists of three main parts: -- the Pop API ink! library -- the Pop API runtime code (chain extension) -- shared primitive types between the Pop API ink! library and the Pop API runtime code - -Let's go over the flow. - -## The Pop API ink! Library -Everything in [`pop-api`](./src/) **is the** Pop API ink! library. - -So when the ink! smart contract wants to use the Pop API library, it can simply have a line like: -```rust -use pop_api::fungibles::{self as api}; +use pop_api::*; ``` -## The Glue - -Certain types are shared between the ink! library portion of the Pop API and the runtime portion of the Pop API. These types can be found in [`pop_primitives`](../primitives/src/), outside the [`pop-api`](./src/) folder. - -## The Entry into the Pop API - -When we use the Pop API in our smart contract like so: -```rust -use pop_api::fungibles::{self as api}; -// -- snip -- -#[ink(message)] -pub fn transfer(&mut self, token: TokenId, to: AccountId, value: Balance) -> Result<()> { - // Usege of Pop API to call into the runtime to transfer some fungible assets. - api::transfer(token, to, value) -} -``` - -This will call the Pop API `transfer` function in the [./src/v0/fungibles/mod.rs](./src/v0/fungibles/mod.rs) file, which is a wrapper to `dispatch` a `Runtime::Call` to the assets pallet's transfer function. This is how most of the Pop API is built. This abstraction allows for creating a developer-friendly API over runtime level features such as calling pallets, reading state, and cross-chain interactions. All Pop API versions can be found in [pop-api/src/](./src/). - - -## Dispatching to the runtime ([./src/lib.rs](./src/lib.rs)) - -### `PopApi` -The `PopApi` is an ink! [`ChainExtensionMethod`](https://docs.rs/ink_env/5.0.0/ink_env/chain_extension/struct.ChainExtensionMethod.html) instance used to derive the execution of the different calls a smart contract can do into the runtime. - -Its purpose its two fold, constructing the runtime calls that are going to be executed by the chain extension and handling the information returned. - -The calls are built out of the following information: -- The `function` Id: Identifies the specific function within the chain extension. -- The API `version`: This byte allows the runtime to distinguish between different API versions, ensuring that older contracts call the correct, version-specific implementation.. -- A `module` index: Identifies the pallet responsible for handling the call. -- A `dispatchable` index: Indicates the specific dispatchable or state read function within the pallet. - -Multiple **functions** can be implemented for the chain extension, so whenever something needs to be added or changed, a new function will have to be implemented. -`DISPATCH` and `READ_STATE` functions are the workhorse functions of the Pop API. -Through these functions all the interactions between the ink! smart contract and the runtime are carried out. - -By embedding the **version** directly into the encoding scheme, the runtime can manage different versions of dispatch calls and queries, ensuring that both legacy and new contracts function as intended, even as the underlying system evolves. This structure provides the flexibility needed to support ongoing improvements and changes in the runtime without disrupting existing smart contracts. - -So in our example above, when the `trasnfer` function in [./src/v0/fungibles/mod.rs](./src/v0/fungibles/mod.rs) is called, the following is constructed `u32::from_le_bytes([DISPATCH, 0, FUNGIBLES, TRANSFER])` to be executed by the runtime chain extension. - +Check out the ink! smart contract [examples](./example) using the API. -### `StatusCode` -When Pop API calls the runtime, it will either receive a successful result or an encoded error. `StatusCode` translates the encoded error into the appropriate module error according to the index that the pallet has been configured to. +### Learn more -## The Pop API Chain Extension +The true strength of the API lies in the Pop runtime, where a single, unified chain extension provides flexible and +efficient access to all runtime features, while specialized API modules deliver stable, intuitive interfaces for +developers. Together, these elements make the API a powerful tool for creating decentralized applications on Polkadot. -So we have covered how the ink! Pop API library calls the chain extension. But where is the chain extension actually defined? In the Pop Network runtime. +Want to explore how it all works? Check out: -Chain extensions "extend" a runtime. We can find the `PopApiExtension` chain extension in [extension.rs](../runtime/devnet/src/extensions.rs). The `PopApiExtension` chain extension is matching based on the function IDs that we defined on the ink! side of the Pop API. The chain extension here will execute the appropriate functions e.g. `dispatch` or `read_state`. These functions are defined in this file as well and interact directly with the Pop Network runtime. +- [Chain Extension Implementation](../extension) +- [API Modules](../pallets/api) -`PopApiExtension` implements the different **functions** that can be called by the API. Two functions are provided: +### Support -- `DISPATCH`: -The Dispatch function decodes the received bytes into a `RuntimeCall`, optionally processing them as needed (versioning). It filters out any calls that are not explicitly permitted, then charges the appropriate weight, dispatches the call, and adjusts the weight accordingly before returning the result of the dispatch call. +Be part of our passionate community of Web3 builders. [Join our Telegram](https://t.me/onpopio)! -- `READ_STATE`: -The ReadState function decodes the received bytes into a `Readable` type, with optional processing (versioning). It filters out any unauthorised state reads, charges the appropriate weight, executes the state read, optionally converts the result (versioning), and finally returns the result. +Feel free to raise issues if anything is unclear, have ideas or want to contribute to Pop! -If you would like to see the whole flow, checkout the integration tests in [pop-api/integration-tests](./integration-tests/) e.g. [`instantiate_and_create_fungible_works()`](./integration-tests/src/fungibles/mod.rs). +For any questions related to ink! you can also go to [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) or +ask the [ink! community](https://t.me/inkathon/1). \ No newline at end of file diff --git a/pop-api/src/v0/README.md b/pop-api/src/v0/README.md deleted file mode 100644 index 3bbe2ad4..00000000 --- a/pop-api/src/v0/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Pop API V0 - -The version `0` of Pop API features integrations with the following pallets: -- [Fungibles](#fungibles) - -Each pallet integration can be included individually with its own feature, this way only the necessary dependencies will be compiled into the contract. - ---- -### FUNGIBLES -| pop-api feature | pallet-index | -|:---------------:|:--------------:| -| `fungibles` | `150` | - -The fungibles pallet offers a streamlined interface for interacting with fungible tokens. The -goal is to provide a simplified, consistent API that adheres to standards in the smart contract -space. - -To use the `Fungibles` API the `fungibles` features needs to be included in the pop-api crate dependency. -```toml -# Cargo.toml -pop-api = { git = "https://github.com/r0gue-io/pop-node", default-features = false, features = [ "fungibles" ] } -``` - -For more details please refer to the [Fungibles API documentation](./fungibles/README.md). - -Find examples in: [`../../examples/fungibles/`](../../examples/fungibles/). - -The fungibles pallet can be found in [`pallets/api/src/fungibles/`](../../../pallets/api/src/fungibles/). diff --git a/pop-api/src/v0/fungibles/README.md b/pop-api/src/v0/fungibles/README.md index 456b8541..484a422f 100644 --- a/pop-api/src/v0/fungibles/README.md +++ b/pop-api/src/v0/fungibles/README.md @@ -1,162 +1,19 @@ -# Fungibles API +## Fungibles API -The `fungibles` module provides an API for interacting and managing fungible tokens. +The `fungibles` module provides an api for interacting and managing fungible tokens. -The API includes the following interfaces: - 1. PSP-22 - 2. PSP-22 Metadata - 3. Management - 4. PSP-22 Mintable & Burnable ---- +It includes the following interfaces: -## Interface +1. PSP-22 +2. PSP-22 Metadata +3. Management +4. PSP-22 Mintable & Burnable -#### PSP-22, PSP-22 Mintable & PSP-22 Burnable -The interface for transferring, delegating, minting and burning tokens. -```rust -/// Returns the total token supply for a specified token. -/// -/// # Parameters -/// - `token` - The token. -pub fn total_supply(token: TokenId) -> Result {} +To use it in your contract add the `fungibles` feature to the `pop-api` dependency. -/// Returns the account balance for a specified `token` and `owner`. Returns `0` if -/// the account is non-existent. -/// -/// # Parameters -/// - `token` - The token. -/// - `owner` - The account whose balance is being queried. -pub fn balance_of(token: TokenId, owner: AccountId) -> Result {} - -/// Returns the allowance for a `spender` approved by an `owner`, for a specified `token`. Returns -/// `0` if no allowance has been set. -/// -/// # Parameters -/// - `token` - The token. -/// - `owner` - The account that owns the tokens. -/// - `spender` - The account that is allowed to spend the tokens. -pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result {} - -/// Transfers `value` amount of tokens from the caller's account to account `to`. -/// -/// # Parameters -/// - `token` - The token to transfer. -/// - `to` - The recipient account. -/// - `value` - The number of tokens to transfer. -pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> {} - -/// Transfers `value` amount tokens on behalf of `from` to account `to`. -/// -/// # Parameters -/// - `token` - The token to transfer. -/// - `from` - The account from which the token balance will be withdrawn. -/// - `to` - The recipient account. -/// - `value` - The number of tokens to transfer. -pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> {} - -/// Approves `spender` to spend `value` amount of tokens on behalf of the caller. -/// -/// # Parameters -/// - `token` - The token to approve. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to approve. -pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> {} - -/// Increases the allowance of `spender` by `value` amount of tokens. -/// -/// # Parameters -/// - `token` - The token to have an allowance increased. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to increase the allowance by. -pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> {} - -/// Decreases the allowance of `spender` by `value` amount of tokens. -/// -/// # Parameters -/// - `token` - The token to have an allowance decreased. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to decrease the allowance by. -pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> {} - -/// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. -/// -/// # Parameters -/// - `token` - The token to mint. -/// - `account` - The account to be credited with the created tokens. -/// - `value` - The number of tokens to mint. -pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> {} - -/// Destroys `value` amount of tokens from `account`, reducing the total supply. -/// -/// # Parameters -/// - `token` - the token to burn. -/// - `account` - The account from which the tokens will be destroyed. -/// - `value` - The number of tokens to destroy. -pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> {} +```toml +# Cargo.toml +pop-api = { git = "https://github.com/r0gue-io/pop-node", default-features = false, features = [ "fungibles" ] } ``` -#### PSP-22 Metadata -The PSP-22 compliant interface for querying metadata. -```rust -/// Returns the name of the specified token, if available. -/// -/// # Parameters -/// - `token` - The token. -pub fn token_name(token: TokenId) -> Result>> {} - -/// Returns the symbol for the specified token, if available. -/// -/// # Parameters -/// - `token` - The token. -pub fn token_symbol(token: TokenId) -> Result>> {} - -/// Returns the decimals for the specified token. -/// -/// # Parameters -/// - `token` - The token. -pub fn token_decimals(token: TokenId) -> Result {} -``` - -#### PSP-22 Management -The interface for creating, managing and destroying fungible tokens. -```rust -/// Create a new token with a given identifier. -/// -/// # Parameters -/// - `id` - The identifier of the token. -/// - `admin` - The account that will administer the token. -/// - `min_balance` - The minimum balance required for accounts holding this token. -pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> {} - -/// Start the process of destroying a token. -/// -/// # Parameters -/// - `token` - The token to be destroyed. -pub fn start_destroy(token: TokenId) -> Result<()> {} - -/// Set the metadata for a token. -/// -/// # Parameters -/// - `token`: The token to update. -/// - `name`: The user friendly name of this token. -/// - `symbol`: The exchange symbol for this token. -/// - `decimals`: The number of decimals this token uses to represent one unit. -pub fn set_metadata( - token: TokenId, - name: Vec, - symbol: Vec, - decimals: u8, -) -> Result<()> {} - -/// Clear the metadata for a token. -/// -/// # Parameters -/// - `token` - The token to update -pub fn clear_metadata(token: TokenId) -> Result<()> {} - -/// Checks if a specified token exists. -/// -/// # Parameters -/// - `token` - The token. -pub fn token_exists(token: TokenId) -> Result {} -``` +Check out the [examples](../../examples/fungibles/) to learn how you can use the fungibles api. \ No newline at end of file From c3349831fac7a72ff199bdc824166683ba0659e8 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:45:47 +0100 Subject: [PATCH 09/11] docs: clean link --- pop-api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pop-api/README.md b/pop-api/README.md index f127e9c2..60144ae9 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -61,4 +61,4 @@ Be part of our passionate community of Web3 builders. [Join our Telegram](https: Feel free to raise issues if anything is unclear, have ideas or want to contribute to Pop! For any questions related to ink! you can also go to [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) or -ask the [ink! community](https://t.me/inkathon/1). \ No newline at end of file +ask the [ink! community](https://t.me/inkathon/). From e9f7c517c6ff035289e0b99790f553a87c4ea0d5 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:39:45 +0100 Subject: [PATCH 10/11] Update pop-api/README.md Co-authored-by: Peter White --- pop-api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pop-api/README.md b/pop-api/README.md index 60144ae9..b0010af1 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -58,7 +58,7 @@ Want to explore how it all works? Check out: Be part of our passionate community of Web3 builders. [Join our Telegram](https://t.me/onpopio)! -Feel free to raise issues if anything is unclear, have ideas or want to contribute to Pop! +Feel free to raise issues if anything is unclear, if you have ideas or want to contribute to Pop! For any questions related to ink! you can also go to [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) or ask the [ink! community](https://t.me/inkathon/). From b4bfd68186f622f2556f3db049956a285cc80fa3 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:39:56 +0100 Subject: [PATCH 11/11] Update pop-api/README.md Co-authored-by: Peter White --- pop-api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pop-api/README.md b/pop-api/README.md index b0010af1..2fe56428 100644 --- a/pop-api/README.md +++ b/pop-api/README.md @@ -1,7 +1,7 @@ ## Pop API The `pop-api` crate provides a high-level interface that allows smart contracts to seamlessly interact with Pop, a -blockchain built to power innovative and impactful solutions on Polkadot. Designed for stability, simplicity and +blockchain built to power innovative and impactful solutions on Polkadot. Designed for stability, simplicity, and efficiency, the API abstracts away the complexities of the runtime, enabling developers to focus on building powerful applications rather than managing intricate blockchain details.