diff --git a/Cargo.lock b/Cargo.lock
index bfc9981..4b5fb1e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3473,7 +3473,6 @@ dependencies = [
"frame-system",
"log",
"pallet-assets",
- "pallet-nfts 31.0.0",
"parity-scale-codec",
"pop-chain-extension",
"scale-info",
@@ -3918,7 +3917,7 @@ dependencies = [
"frame-system",
"log",
"pallet-assets",
- "pallet-nfts 30.0.0",
+ "pallet-nfts",
"parity-scale-codec",
"scale-info",
"sp-runtime",
@@ -3944,29 +3943,13 @@ dependencies = [
"sp-std",
]
-[[package]]
-name = "pallet-nfts"
-version = "31.0.0"
-dependencies = [
- "enumflags2",
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "log",
- "parity-scale-codec",
- "scale-info",
- "sp-core",
- "sp-io",
- "sp-runtime",
-]
-
[[package]]
name = "pallet-nfts-runtime-api"
version = "22.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0ca7a0446d2d3c27f726a016c6366218df2e0bfef9ed35886b252cfa9757f6c"
dependencies = [
- "pallet-nfts 30.0.0",
+ "pallet-nfts",
"parity-scale-codec",
"sp-api",
"sp-std",
@@ -4754,7 +4737,7 @@ dependencies = [
"pallet-message-queue",
"pallet-multisig",
"pallet-nft-fractionalization",
- "pallet-nfts 31.0.0",
+ "pallet-nfts",
"pallet-nfts-runtime-api",
"pallet-preimage",
"pallet-proxy",
diff --git a/README.md b/README.md
index 2e17b48..4116a1a 100644
--- a/README.md
+++ b/README.md
@@ -1,68 +1,85 @@
-
Pop DRink! (forked from DRink!)
- Dechained Ready-to-play ink! playground
+
+
Pop DRink!
-> [!IMPORTANT]
-> This repository is customized and maintained for Pop API contract end-to-end testing.
->
-> Quasi tests must be run with `cargo test --release`.
+
-# Pop Sandbox
+[![Twitter URL](https://img.shields.io/twitter/follow/Pop?style=social)](https://x.com/onpopio/)
+[![Twitter URL](https://img.shields.io/twitter/follow/R0GUE?style=social)](https://twitter.com/gor0gue)
+[![Telegram](https://img.shields.io/badge/Telegram-gray?logo=telegram)](https://t.me/onpopio)
-Implementation of the [`pop_drink::Sandbox`](https://github.com/r0gue-io/pop-drink) struct for the Pop Network runtimes (located in `pop-node/runtime`) required for the quasi testing with `drink`.
+Forked version of [inkdevhub/drink](https://github.com/inkdevhub/drink) for E2E testing of smart contract using the [Pop API](https://github.com/r0gue-io/pop-node/tree/main/pop-api) on Pop Network.
-In the context of quasi-testing with pop-drink, a sandbox refers to an isolated runtime environment that simulates the behavior of a full node, without requiring an actual node. It can emulate key processes (where runtime `pallets` are involved) such as block initialization, execution, and block finalization.
+
+
+## Overview
+
+About the repository folder structure:
+
+- [pop-drink](/crates/pop-drink): Library for testing contracts deployed on Pop Network using drink.
+- [drink](/crates/drink/drink): drink is a toolbox for ink! developers to test contracts in a sandbox environment.
+- [ink-sandbox](/crates/ink-sandbox): Creates a sandbox environment for a given runtime, without having to run a node.
+- [examples](/crates/drink/examples): A collection of example contracts tested with drink.
+- [drink-cli](/crates/drink/drink-cli): Simple command line tool to help you play with your local contracts in a convenient way.
## Getting Started
-### Installation
+Add `pop-drink` crate to your contract `Cargo.toml`:
```toml
-pop_drink = { version = "1.0.0", package = "pop-drink" }
+drink = { version = "1.0.0", package = "pop-drink" }
```
-### Import Sandbox for the specific runtime
-
-- For `devnet` runtime
-
-Implementation of the sandbox runtime environment for `devnet` runtime located in `pop-node/runtime/devnet`
+Set up your pop-drink test environment and write your first test.
```rs
-use pop_sandbox::DevnetSandbox;
-```
+use drink::{
+ devnet::{AccountId, Balance, Runtime},
+ TestExternalities,
+ deploy, call,
+};
-- For `testnet` runtime
-Implementation of the sandbox runtime environment for `testnet` runtime located in `pop-node/runtime/testnet`
+// Builds your contract(s).
+#[drink::contract_bundle_provider]
+enum BundleProvider {}
-```rs
-use pop_sandbox::TestnetSandbox;
-```
+/// Sandbox environment for Pop Devnet Runtime.
+pub struct Pop {
+ ext: TestExternalities,
+}
-- For `mainnet` runtime
+// Initialising genesis state.
+impl Default for Pop {
+ fn default() -> Self {
+ let balances: Vec<(AccountId, Balance)> = vec![(ALICE, 100u128)];
+ let ext = BlockBuilder::::new_ext(balances);
+ Self { ext }
+ }
+}
-Implementation of the sandbox runtime environment for `mainnet` runtime located in `pop-node/runtime/mainnet`
+// Implement core functionalities for the `Pop` sandbox.
+drink::impl_sandbox!(Pop, Runtime, ALICE);
-```rs
-use pop_sandbox::MainnetSandbox;
+// Write your first pop-drink test!
+#[drink::test(sandbox = Pop)]
+fn test(mut session: Session) { ... }
```
-### Setup test environment for your contract
+Important: run your tests with `--release`
+```
+cargo test --release
+```
-Below is an example for the contract testing with `pop_drink` and `pop_sandbox` for `devnet` environment using `DevnetSandbox`.
+## Learn more
-```rs
-use pop_drink::session::Session;
-use pop_sandbox::DevnetSandbox as Sandbox;
+Dive into the ["quick start with drink!"](/crates/drink/examples/quick-start-with-drink/README.md) to learn more about drink. Also check out the other examples provided by drink.
-#[drink::contract_bundle_provider]
-enum BundleProvider {}
+If you are interested in learning more about testing contracts using the Pop API, check out the [example contracts](https://github.com/r0gue-io/pop-node/tree/main/pop-api/examples) tested with pop-drink!
-#[drink::test(sandbox = Sandbox)]
-fn test(mut session: Session) {
- // Your test case
-}
-```
+## Support
+
+Be part of our passionate community of Web3 builders. [Join our Telegram](https://t.me/onpopio)!
-## Examples
+Feel free to contribute to `drink` or `pop-drink` to help improve testing ink! smart contracts!
-Please find more examples of `pop_drink` tests in the [`pop_drink/examples`](https://github.com/r0gue-io/pop-drink/tree/main/examples).
+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/crates/pop-drink/Cargo.toml b/crates/pop-drink/Cargo.toml
index cd95815..e82fa10 100644
--- a/crates/pop-drink/Cargo.toml
+++ b/crates/pop-drink/Cargo.toml
@@ -4,10 +4,6 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-scale-info = { workspace = true, default-features = false, features = [
- "derive",
-] }
-
drink.workspace = true
ink_sandbox.workspace = true
pallet-contracts.workspace = true
@@ -19,6 +15,7 @@ scale.workspace = true
pop-api.workspace = true
[dev-dependencies]
+scale-info = { workspace = true, features = ["derive"] }
pallet-api.workspace = true
pallet-assets.workspace = true
pallet-balances.workspace = true
diff --git a/crates/pop-drink/src/error.rs b/crates/pop-drink/src/error.rs
index dd43094..8d2c528 100644
--- a/crates/pop-drink/src/error.rs
+++ b/crates/pop-drink/src/error.rs
@@ -1,4 +1,4 @@
-//! A set of errors used for testing smart contracts.
+//! The error type and utilities for testing smart contracts using the Pop API.
use std::fmt::Debug;
@@ -8,33 +8,166 @@ pub use drink::{
};
use scale::{Decode, Encode};
-fn decode(data: &[u8]) -> T {
- T::decode(&mut &data[..]).expect("Decoding failed")
+/// A simplified error type representing errors from the runtime and its modules.
+///
+/// This type can be used to assert to an error that holds a [status code](https://github.com/r0gue-io/pop-node/blob/main/pop-api/src/lib.rs#L33).
+/// The status code is returned by the Pop API and represents a runtime error.
+///
+/// # Generic Parameters:
+/// - `ApiError`: The pop api error type.
+/// - `ModuleError`: The error type for specific runtime modules.
+/// - `MODULE_INDEX`: Index of the variant `Error::Module`.
+#[derive(Encode, Decode, Debug)]
+pub enum Error
+where
+ ApiError: Decode + Encode + Debug + From + Into,
+ ModuleError: Decode + Encode + Debug,
+{
+ /// An error not related to any specific module.
+ Raw(ApiError),
+ /// An error originating from a runtime module.
+ Module(ModuleError),
+}
+
+impl From>
+ for u32
+where
+ ApiError: Decode + Encode + Debug + From + Into,
+ ModuleError: Decode + Encode + Debug,
+{
+ /// Converts an `Error` to a `u32` status code.
+ fn from(error: Error) -> Self {
+ match error {
+ Error::Raw(error) => decode::(&error.encode()),
+ Error::Module(error) => {
+ let mut encoded = error.encode();
+ encoded.insert(0, MODULE_INDEX);
+ encoded.resize(4, 0);
+ decode::(&encoded)
+ },
+ }
+ .into()
+ }
+}
+
+impl From
+ for Error
+where
+ ApiError: Decode + Encode + Debug + From + Into,
+ ModuleError: Decode + Encode + Debug,
+{
+ /// Converts a `u32` into an `Error`.
+ ///
+ /// If the status code represents a module error it converts it into `Error::Module` in stead
+ /// of `Error::Raw`.
+ fn from(value: u32) -> Self {
+ let error = ApiError::from(value);
+ let encoded = error.encode();
+ if encoded[0] == MODULE_INDEX {
+ let (index, module_error) = (encoded[1], &encoded[2..]);
+ let data = vec![vec![index], module_error.to_vec()].concat();
+ return Error::Module(decode(&data));
+ }
+ Error::Raw(error)
+ }
}
-/// Asserts a custom error type against the `Error`. This is useful when you want to check if a contract's custom error (e.g., [`PSP22Error`](https://github.com/r0gue-io/pop-node/blob/main/pop-api/src/v0/fungibles/errors.rs#L73C1-L73C22)) matches the error code returned by the runtime, which is represented by a [`StatusCode`](https://github.com/r0gue-io/pop-node/blob/main/pop-api/src/lib.rs#L33). The error type must be convertible to a `u32`.
+/// Asserts that a result matches an expected `Error`.
+///
+/// This can be used to assert that a contract execution resulted in a specific runtime error
+/// `Error`. The contract error must be convertible to a `u32` (i.e. the status code received from
+/// the api).
+///
+/// # Example
+///
+/// ## Errors
+///
+/// ```rs
+/// use drink::devnet::{
+/// Assets,
+/// AssetsError::BalanceLow,
+/// v0::{
+/// Arithmetic,
+/// ArithmeticError::Overflow,
+/// BadOrigin
+/// },
+/// };
+/// ```
///
-/// # Parameters
+/// [`BadOrigin`](https://github.com/r0gue-io/pop-node/blob/main/primitives/src/lib.rs#L36C4-L36C18):
+/// ```rs
+/// Error::Raw(BadOrigin)
+/// ```
+///
+/// [`Arithmetic(Overflow)`](https://github.com/r0gue-io/pop-node/blob/main/primitives/src/lib.rs#L55):
+/// ```rs
+/// Error::Raw(Arithmetic(Overflow))
+/// ```
///
-/// - `result` - Contract method's result returns the custom error type which is convertible to
-/// `u32`.
-/// - `error` - `Error` to assert against the custom error type.
+/// [`Assets(BalanceLow)`](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/pallet/enum.Error.html#variant.BalanceLow):
+/// ```rs
+/// Error::Module(Assets(BalanceLow))
+/// ```
///
-/// # Examples
+/// ## How to use `assert_err` macro.
///
-/// To assert the `StatusCode` returned by a contract method that uses Pop API, you simply use the
-/// provided `assert_err!` macro.
+/// - Create a custom error type that holds the status code.
///
/// ```rs
-/// // Required imports to test the custom error.
-/// use drink::{ assert_err, devnet::error::{ v0::Error, Arithmetic, ArithmeticError::Overflow }};
+/// use pop_api::StatusCode;
+///
+/// /// Custom error in contract.
+/// pub enum CustomError {
+/// ...,
+/// /// Error with status code.
+/// StatusCode(u32),
+/// }
+///
+/// impl From for CustomError {
+/// /// Converts a `StatusCode` (returned by the api) to a `CustomError`.
+/// fn from(value: StatusCode) -> Self {
+/// match value {
+/// ...,
+/// _ => CustomError::StatusCode(value.0),
+/// }
+/// }
+/// }
+///
+/// impl From for u32 {
+/// /// Converts a `CustomError to a `u32`.
+/// //
+/// // Required for the `assert_err` macro to assert to `Error`.
+/// fn from(value: CustomError) -> Self {
+/// match value {
+/// ...,
+/// CustomError::StatusCode(status_code) => status_code,
+/// }
+/// }
+/// }
///
-/// // Call a contract method named "hello_world" that throws `StatusCode`.
-/// let result = call::(session, "hello_world", vec![], None);
+/// - Use `assert_err` in a test.
///
-/// // Asserts that the call fails because of an arithmetic operation error.
-/// assert_err!(result, Error::Raw(Arithmetic(Overflow)));
+/// #[drink::test(sandbox = Pop)]
+/// fn test_custom_error(mut session: Session) {
+/// ...
+///
+/// // Call a contract method that returns a `Result<(), CustomError>`.
+/// let result = call::(session, "hello_world", vec![], None);
+///
+/// // Assert the result to the expected error.
+/// assert_err!(result, Error::Raw(BadOrigin)));
+///
+/// // Other assertions:
+/// ...
+/// assert_err!(result, Error::Raw(Arithmetic(Overflow)));
+/// ...
+/// assert_err!(result, Error::Module(Assets(BalanceLow)));
+/// }
/// ```
+///
+/// # Parameters:
+/// - `result`: The result which contains the custom error type.
+/// - `error`: The expected error.
#[macro_export]
macro_rules! assert_err {
($result:expr, $error:expr $(,)?) => {
@@ -42,22 +175,9 @@ macro_rules! assert_err {
};
}
-/// Asserts an error type to Error. This can be used for custom error types used by a contract which
-/// uses the [`StatusCode`](https://github.com/r0gue-io/pop-node/blob/main/pop-api/src/lib.rs#L33) returned by the pop runtime. The error type must be convertible to a `u32`.
-///
-/// # Generic parameters
-///
-/// - `R` - Type returned if `result` is `Ok()`.
-/// - `E` - Type returned if `result` is `Err()`. Must be convertible to `u32`.
-/// - `Error` - `Error` to assert against the custom error type.
-///
-/// # Parameters
-///
-/// - `result` - Contract method's result returns the custom error type which is convertible to
-/// `u32`.
-/// - `expected_error` - `Error` to assert against the custom error type.
#[track_caller]
-pub fn assert_err_inner(result: Result, expected_error: Error)
+#[allow(unused)]
+fn assert_err_inner(result: Result, expected_error: Error)
where
E: Into,
Error: From + Into + Debug,
@@ -85,177 +205,40 @@ where
}
}
-/// Error type for testing why a runtime call fails.
-///
-/// # Generic Parameters
-///
-/// - [`RuntimeCallError`](https://github.com/r0gue-io/pop-node/blob/main/primitives/src/lib.rs#L30)
-/// - Reason why a runtime call fails. (.e.g, arithmetic operation errors)
-/// - [`ModuleError`](https://paritytech.github.io/polkadot-sdk/master/solochain_template_runtime/enum.Error.html)
-/// - Refers to specific reasons a runtime call fails, originating from the runtime modules.
-/// - [`MODULE_INDEX`](https://github.com/r0gue-io/pop-node/blob/main/primitives/src/lib.rs#L38)
-/// - Index of the variant `Error::Module`.
-///
-/// # Examples
-///
-/// ### Runtime call errors
-///
-/// - Import types to construct runtime call errors:
-///
-/// ```rs
-/// use drink::devnet::v0::{
-/// Arithmetic,
-/// ArithmeticError::Overflow,
-/// BadOrigin
-/// };
-/// ```
-///
-/// - Runtime call error [`Arithmetic(Overflow)`](https://github.com/r0gue-io/pop-node/blob/main/primitives/src/lib.rs#L55):
-///
-/// ```rs
-/// Error::Raw(Arithmetic(Overflow))
-/// ```
-///
-/// - Runtime call error [`BadOrigin`](https://github.com/r0gue-io/pop-node/blob/main/primitives/src/lib.rs#L36C4-L36C18):
-///
-/// ```rs
-/// Error::Raw(BadOrigin)
-/// ```
-///
-/// ### Runtime module errors
-///
-/// - Import types to construct runtime module errors:
-///
-/// ```rs
-/// use drink::devnet::{
-/// Assets,
-/// AssetsError::AssetNotLive,
-/// Balances::BelowMinimum,
-/// BalancesError::BelowMinimum
-/// };
-/// ```
-///
-/// - Construct a runtime module error [`Assets(AssetNotLive)`](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/pallet/enum.Error.html#variant.AssetNotLive):
-///
-/// ```rs
-/// Error::Module(Assets(AssetNotLive))
-/// ```
-///
-/// - Construct a runtime module error [`Balances(InsufficientBalance)`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/enum.Error.html#variant.InsufficientBalance):
-///
-/// ```rs
-/// Error::Module(Balances(InsufficientBalance))
-/// ```
-
-#[derive(Encode, Decode, Debug)]
-pub enum Error
-where
- RuntimeCallError: Decode + Encode + Debug + From + Into,
- ModuleError: Decode + Encode + Debug,
-{
- /// Reason why a runtime call fails. [Reference](https://github.com/r0gue-io/pop-node/blob/52fb7f06a89955d462900e33d2b9c9170c4534a0/primitives/src/lib.rs#L30).
- Raw(RuntimeCallError),
- /// [Module error](https://paritytech.github.io/polkadot-sdk/master/solochain_template_runtime/enum.Error.html) refers to specific reasons a runtime call fails, originating from the runtime modules.
- Module(ModuleError),
-}
-
-impl
- From> for u32
-where
- RuntimeCallError: Decode + Encode + Debug + From + Into,
- ModuleError: Decode + Encode + Debug,
-{
- /// Converts an `Error` to a `u32` number.
- ///
- /// This conversion is necessary for comparing `Error` instances with other types.
- // Compared types must implement `Into`, as `Error` does not implement `Eq`.
- // Use this function to obtain a numerical representation of the error for comparison or
- // further processing.
- fn from(error: Error) -> Self {
- match error {
- Error::Raw(error) => decode::(&error.encode()),
- Error::Module(error) => {
- let mut encoded = error.encode();
- encoded.insert(0, MODULE_INDEX);
- encoded.resize(4, 0);
- decode::(&encoded)
- },
- }
- .into()
- }
-}
-
-impl From
- for Error
-where
- RuntimeCallError: Decode + Encode + Debug + From + Into,
- ModuleError: Decode + Encode + Debug,
-{
- /// Converts a numerical value `u32` into an `Error`.
- ///
- /// This is used to reconstruct and display an `Error` from its numerical representation
- /// when an error is thrown.
- fn from(value: u32) -> Self {
- let error = RuntimeCallError::from(value);
- let encoded = error.encode();
- if encoded[0] == MODULE_INDEX {
- let (index, module_error) = (encoded[1], &encoded[2..]);
- let data = vec![vec![index], module_error.to_vec()].concat();
- return Error::Module(decode(&data));
- }
- Error::Raw(error)
- }
+fn decode(data: &[u8]) -> T {
+ T::decode(&mut &data[..]).expect("Decoding failed")
}
#[cfg(test)]
mod test {
- use pop_api::primitives::v0::Error as RuntimeCallError;
+ use pop_api::primitives::v0::Error as ApiError;
use crate::error::{AssetsError::*, BalancesError::*, *};
- fn test_cases() -> Vec<(Error, RuntimeCallError)>
- {
+ fn test_cases() -> Vec<(Error, ApiError)> {
use frame_support::traits::PalletInfoAccess;
use pop_api::primitives::{ArithmeticError::*, TokenError::*};
use crate::mock::RuntimeError::*;
vec![
- (Error::Raw(RuntimeCallError::BadOrigin), RuntimeCallError::BadOrigin),
- (
- Error::Raw(RuntimeCallError::Token(BelowMinimum)),
- RuntimeCallError::Token(BelowMinimum),
- ),
- (
- Error::Raw(RuntimeCallError::Arithmetic(Overflow)),
- RuntimeCallError::Arithmetic(Overflow),
- ),
+ (Error::Raw(ApiError::BadOrigin), ApiError::BadOrigin),
+ (Error::Raw(ApiError::Token(BelowMinimum)), ApiError::Token(BelowMinimum)),
+ (Error::Raw(ApiError::Arithmetic(Overflow)), ApiError::Arithmetic(Overflow)),
(
Error::Module(Assets(BalanceLow)),
- RuntimeCallError::Module {
- index: crate::mock::Assets::index() as u8,
- error: [0, 0],
- },
+ ApiError::Module { index: crate::mock::Assets::index() as u8, error: [0, 0] },
),
(
Error::Module(Assets(NoAccount)),
- RuntimeCallError::Module {
- index: crate::mock::Assets::index() as u8,
- error: [1, 0],
- },
+ ApiError::Module { index: crate::mock::Assets::index() as u8, error: [1, 0] },
),
(
Error::Module(Balances(VestingBalance)),
- RuntimeCallError::Module {
- index: crate::mock::Balances::index() as u8,
- error: [0, 0],
- },
+ ApiError::Module { index: crate::mock::Balances::index() as u8, error: [0, 0] },
),
(
Error::Module(Balances(LiquidityRestrictions)),
- RuntimeCallError::Module {
- index: crate::mock::Balances::index() as u8,
- error: [1, 0],
- },
+ ApiError::Module { index: crate::mock::Balances::index() as u8, error: [1, 0] },
),
]
}
diff --git a/crates/pop-drink/src/lib.rs b/crates/pop-drink/src/lib.rs
index ab24098..5c20ee4 100644
--- a/crates/pop-drink/src/lib.rs
+++ b/crates/pop-drink/src/lib.rs
@@ -1,3 +1,5 @@
+//! A library for testing smart contracts on Pop Network.
+
pub use drink::*;
pub use frame_support::{self, assert_ok};
pub use ink_sandbox::api::assets_api::AssetsAPI;
@@ -6,29 +8,30 @@ use scale::Decode;
pub use session::{error::SessionError, ContractBundle, Session, NO_SALT};
pub use sp_io::TestExternalities;
+/// Error type and utilities for testing contracts using the Pop API.
pub mod error;
#[cfg(test)]
mod mock;
+/// Types and utilities for testing smart contracts interacting with Pop Network Devnet via the pop
+/// api.
pub mod devnet {
pub use pop_runtime_devnet::Runtime;
use super::*;
+ pub use crate::error::*;
- /// A set of primitive runtime errors and versioned runtime errors used for testing.
+ /// Error related utilities for smart contracts using pop api.
pub mod error {
pub use pop_runtime_devnet::RuntimeError::*;
pub use crate::error::*;
- /// A collection of error types from the `v0` module used for smart contract testing in the
- /// `devnet` environment.
pub mod v0 {
- pub use pop_api::primitives::v0::{Error as RuntimeCallError, *};
+ pub use pop_api::primitives::v0::{self, *};
- /// Error type for testing contracts using the API V0.
- pub type Error =
- crate::error::Error;
+ /// Error type for writing tests (see `error` module).
+ pub type Error = crate::error::Error;
}
}
@@ -36,61 +39,39 @@ pub mod devnet {
pub type Balance = BalanceFor;
pub type AccountId = AccountIdFor;
- /// This is used to resolve type mismatches between the `AccountId` in the quasi testing
- /// environment and the contract environment.
+ /// Converts an AccountId from Pop's runtime to the account ID used in the contract environment.
pub fn account_id_from_slice(s: &AccountId) -> pop_api::primitives::AccountId {
let account: [u8; 32] = s.clone().into();
super::account_id_from_slice(&account)
}
}
-/// Deploys a contract with a given constructor method, arguments, salt and an initial value. In
+/// Deploy a contract with a given constructor, arguments, salt and an initial value. In
/// case of success, returns the address of the deployed contract.
///
-/// # Generic Parameters
-///
-/// - `S` - [`Sandbox`](https://github.com/r0gue-io/pop-drink/blob/main/crates/ink-sandbox/src/lib.rs)
-/// environment for the Pop Network runtime.
-/// - `E` - Decodable error type returned if the contract deployment fails.
-///
-/// # Parameters
-///
-/// - `session` - Wrapper around Sandbox that provides methods to interact with multiple contracts. [Reference](https://github.com/r0gue-io/pop-drink/blob/main/crates/drink/drink/src/session.rs).
-/// - `bundle` - A struct representing the result of parsing a `.contract` bundle file. [Reference](https://github.com/r0gue-io/pop-drink/blob/main/crates/drink/drink/src/session/bundle.rs).
-/// - `method` - The name of the contract constructor method. For trait methods, use
-/// `trait_name::method_name` (e.g., `Psp22::transfer`).
-/// - `input` - Arguments passed to the constructor method.
-/// - `salt` - Additional data used to influence the contract deployment address.
-/// - `init_value` - Initial funds allocated for the contract. Requires the contract method to be
-/// `payable`.
+/// # Generic Parameters:
+/// - `S` - Sandbox environment.
+/// - `E` - `Err()` type returned by the contract.
///
-/// # Examples
+/// # Parameters:
+/// - `session` - The session for interacting with contracts.
+/// - `bundle` - The contract bundle.
+/// - `method` - The name of the constructor method.
+/// - `input` - The input arguments.
+/// - `salt` - Optional deployment salt.
+/// - `init_value` - Initial balance to transfer during the contract creation. Requires the contract
+/// method to be `payable`.
///
+/// # Example:
/// ```rs
-/// /// The contract bundle provider.
-/// #[drink::contract_bundle_provider]
-/// enum BundleProvider {}
-///
-/// /// Sandbox environment for Pop Devnet Runtime.
-/// pub struct Pop {
-/// ext: TestExternalities,
-/// }
-///
-/// // Implement core functionalities for the `Pop` sandbox.
-/// drink::impl_sandbox!(Pop, Runtime, ALICE);
-///
/// #[drink::test(sandbox = Pop)]
-/// fn test_constructor_works() {
-/// let local_contract = BundleProvider::local().unwrap();
-/// // Contract address is returned if a deployment succeeds.
-/// let contract = deploy(
-/// &mut session,
-/// local_contract,
-/// "new",
-/// vec![TOKEN.to_string(), MIN_BALANCE.to_string()],
-/// vec![],
-/// None
-/// ).unwrap();
+/// fn test_constructor_works(mut session: Session) {
+/// let bundle = BundleProvider::local().unwrap();
+///
+/// // Deploy contract.
+/// //
+/// // `ContractError` is the error type used by the contract.
+/// assert_ok!(deploy(&mut session, bundle, "new", input, salt, init_value));
/// }
/// ```
pub fn deploy(
@@ -115,48 +96,36 @@ where
Ok(result.unwrap())
}
-/// Call a contract method and decode the returned data.
-///
-/// # Generic Parameters
-///
-/// - `S` - [`Sandbox`](https://github.com/r0gue-io/pop-drink/blob/main/crates/ink-sandbox/src/lib.rs)
-/// environment for the Pop Network runtime.
-/// - `O` - Decodable output type returned if the contract execution succeeds.
-/// - `E` - Decodable error type returned if the contract execution fails.
-///
-/// # Parameters
-///
-/// - `session` - Wrapper around Sandbox that provides methods to interact with multiple contracts. [Reference](https://github.com/r0gue-io/pop-drink/blob/main/crates/drink/drink/src/session.rs).
-/// - `func_name`: The name of the contract method. For trait methods, use `trait_name::method_name`
-/// (e.g., `Psp22::transfer`).
-/// - `input` - Arguments passed to the contract method.
-/// - `endowment` - Funds allocated for the contract execution. Requires the contract method to be
+/// Call a method and decode the returned data.
+///
+/// # Generic Parameters:
+/// - `S` - Sandbox environment.
+/// - `O` - `Ok()` type returned by the contract.
+/// - `E` - `Err()` type returned by the contract.
+///
+/// # Parameters:
+/// - `session` - The session for interacting with contracts.
+/// - `func_name`: The name of the contract method.
+/// - `input` - The input arguments.
+/// - `init_value` - Balance to transfer during the call. Requires the contract method to be
/// `payable`.
///
-/// # Examples
-///
+/// # Example:
/// ```rs
-/// /// The contract bundle provider.
-/// #[drink::contract_bundle_provider]
-/// enum BundleProvider {}
-///
-/// /// Sandbox environment for Pop Devnet Runtime.
-/// pub struct Pop {
-/// ext: TestExternalities,
-/// }
-///
-/// // Implement core functionalities for the `Pop` sandbox.
-/// drink::impl_sandbox!(Pop, Runtime, ALICE);
-///
-/// /// Call to a contract method `Psp22::transfer` and return error `PSP22Error` if fails.
-/// fn transfer(session: &mut Session, to: AccountId, amount: Balance) -> Result<(), PSP22Error> {
-/// // Convert empty array into string.
-/// let empty_array = serde_json::to_string::<[u8; 0]>(&[]).unwrap();
-/// call::(
+/// #[drink::test(sandbox = Pop)]
+/// fn call_works(mut session: Session) {
+/// let bundle = BundleProvider::local().unwrap();
+/// assert_ok!(deploy(&mut session, bundle, "new", input, salt, init_value));
+///
+/// // Call contract.
+/// //
+/// // `()` is the successful result type used by the contract.
+/// // `ContractError` is the error type used by the contract.
+/// call::(
/// session,
-/// "Psp22::transfer",
-/// vec![to.to_string(), amount.to_string(), empty_array],
-/// None,
+/// "transfer",
+/// input,
+/// init_value,
/// )
/// }
/// ```
@@ -187,32 +156,22 @@ where
}
}
-fn account_id_from_slice(s: &[u8; 32]) -> pop_api::primitives::AccountId {
- pop_api::primitives::AccountId::decode(&mut &s[..]).expect("Should be decoded to AccountId")
-}
-
-/// Get the last event from pallet contracts.
+/// Get the last contract event.
///
-/// # Generic Parameters
+/// # Generic Parameters:
+/// - `S` - Sandbox environment.
///
-/// - `S` - [`Sandbox`](https://github.com/r0gue-io/pop-drink/blob/main/crates/ink-sandbox/src/lib.rs)
-/// environment for the Pop Network runtime.
-///
-/// # Parameters
-///
-/// - `session` - Wrapper around Sandbox that provides methods to interact with multiple contracts. [Reference](https://github.com/r0gue-io/pop-drink/blob/main/crates/drink/drink/src/session.rs).
-///
-/// # Examples
+/// # Parameters:
+/// - `session` - The session for interacting with contracts.
///
+/// # Example:
/// ```rs
-/// use drink::{assert_ok, devnet::account_id_from_slice, last_contract_event};
+/// use drink::last_contract_event;
///
/// assert_eq!(
-/// last_contract_event(&session).unwrap(),
-/// Transfer {
-/// from: Some(account_id_from_slice(&ALICE)),
-/// to: Some(account_id_from_slice(&BOB)),
-/// value,
+/// last_contract_event::(&session).unwrap(),
+/// ContractEvent {
+/// value: 42,
/// }
/// .encode()
/// .as_slice()
@@ -227,3 +186,7 @@ where
{
session.record().last_event_batch().contract_events().last().cloned()
}
+
+fn account_id_from_slice(s: &[u8; 32]) -> pop_api::primitives::AccountId {
+ pop_api::primitives::AccountId::decode(&mut &s[..]).expect("Should be decoded to AccountId")
+}