diff --git a/Cargo.lock b/Cargo.lock
index 4b5fb1e..bfc9981 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3473,6 +3473,7 @@ dependencies = [
"frame-system",
"log",
"pallet-assets",
+ "pallet-nfts 31.0.0",
"parity-scale-codec",
"pop-chain-extension",
"scale-info",
@@ -3917,7 +3918,7 @@ dependencies = [
"frame-system",
"log",
"pallet-assets",
- "pallet-nfts",
+ "pallet-nfts 30.0.0",
"parity-scale-codec",
"scale-info",
"sp-runtime",
@@ -3943,13 +3944,29 @@ 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",
+ "pallet-nfts 30.0.0",
"parity-scale-codec",
"sp-api",
"sp-std",
@@ -4737,7 +4754,7 @@ dependencies = [
"pallet-message-queue",
"pallet-multisig",
"pallet-nft-fractionalization",
- "pallet-nfts",
+ "pallet-nfts 31.0.0",
"pallet-nfts-runtime-api",
"pallet-preimage",
"pallet-proxy",
diff --git a/README.md b/README.md
index 2e17b48..807895b 100644
--- a/README.md
+++ b/README.md
@@ -1,68 +1,151 @@
-
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 smart contract using [Pop API](https://github.com/r0gue-io/pop-node/tree/main/pop-api) with [Pop Network runtimes](https://github.com/r0gue-io/pop-node/tree/main/runtime).
-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): Provides utility methods for testing contract methods with DRink! and Pop Network runtimes.
+- [examples](/crates/drink/examples): A collection of example contracts tested with DRink!
+- [drink](/crates/drink/drink): DRink! is a toolbox for ink! developers that allows for a fully functional ink! contract development without any running node.
+- [ink-sandbox](/crates/ink-sandbox): Sandbox refers to an isolated runtime environment that simulates the behavior of a full node, without requiring an actual node.
+- [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
+### Setup a testing environment
-- For `devnet` runtime
+Please see ["Quick start with DRink!"](/crates/drink/examples/quick-start-with-drink/README.md) for a detailed explanation.
-Implementation of the sandbox runtime environment for `devnet` runtime located in `pop-node/runtime/devnet`
+Add the below code at the top of your contract test file to setup [Sandbox](TODO) for the [**Pop Network Devnet**](https://github.com/r0gue-io/pop-node/tree/main/runtime/devnet) runtime.
```rs
-use pop_sandbox::DevnetSandbox;
+#[derive(Default)]
+struct Sandbox;
+
+// Implement `Sandbox` environment for the Pop Network Devnet runtime.
+drink::impl_sandbox!(Sandbox, drink::devnet::Runtime, ALICE);
```
-- For `testnet` runtime
+## Writing tests
-Implementation of the sandbox runtime environment for `testnet` runtime located in `pop-node/runtime/testnet`
+### Writing tests
-```rs
-use pop_sandbox::TestnetSandbox;
+Your typical test module will look like (See ["Quick start with DRink!"](/crates/drink/examples/quick-start-with-drink/README.md) example tests):
+
+```rust
+#[cfg(test)]
+mod tests {
+ use drink::session::{Session, NO_ARGS, None, NO_SALT};
+
+ #[drink::contract_bundle_provider]
+ enum BundleProvider {}
+
+ #[drink::test]
+ fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> {
+ let result: bool = session
+ .deploy_bundle_and(BundleProvider::local(), "new", &["true"], NO_SALT, None)?
+ .call_and("flip", NO_ARGS, None)?
+ .call_and("flip", NO_ARGS, None)?
+ .call_and("flip", NO_ARGS, None)?
+ .call("get", NO_ARGS, None)??;
+ assert_eq!(result, false);
+ }
+}
```
-- For `mainnet` runtime
+So, firstly, you declare a bundle provider like:
-Implementation of the sandbox runtime environment for `mainnet` runtime located in `pop-node/runtime/mainnet`
+```rust
+#[drink::contract_bundle_provider]
+enum BundleProvider {}
+```
-```rs
-use pop_sandbox::MainnetSandbox;
+It will take care of building all contract dependencies in the compilation phase and gather all contract bundles into a single registry.
+Then, you will be able to get a contract bundle by calling:
+
+```rust
+let bundle = BundleProvider::local()?; // for the contract from the current crate
+let bundle = BundleProvider::Flipper.bundle()?; // for the contract from the `flipper` crate
+```
+
+We mark each testcase with `#[drink::test]` attribute and declare return type as `Result` so that we can use the `?` operator:
+
+```rust
+#[drink::test]
+fn testcase() -> Result<(), Box> {
+ // ...
+}
```
-### Setup test environment for your contract
+Then, we can use the `Session` API to interact with both contracts and the whole runtime.
+For details, check out testcases in [lib.rs](lib.rs).
-Below is an example for the contract testing with `pop_drink` and `pop_sandbox` for `devnet` environment using `DevnetSandbox`.
+### Writing tests for methods using [Pop API](https://github.com/r0gue-io/pop-node/tree/main/pop-api)
+
+Pop DRink! also provides [utilitiy methods](/crates/pop-drink/src/lib.rs) that you can use to test your contracts. This example interacts with a [PSP22 example contract](https://github.com/r0gue-io/pop-node/blob/main/pop-api/examples/fungibles/lib.rs) that uses [Pop API](https://github.com/r0gue-io/pop-node/tree/main/pop-api). The contract method returns [`PSP22Error`](https://github.com/r0gue-io/pop-node/blob/main/pop-api/src/v0/fungibles/errors.rs#L73C1-L73C22) custom error which is provided by Pop API library.
```rs
-use pop_drink::session::Session;
-use pop_sandbox::DevnetSandbox as Sandbox;
+// Import required methods and types.
+use drink::{call, session::Session};
+use pop_api::v0::fungibles::PSP22Error;
-#[drink::contract_bundle_provider]
-enum BundleProvider {}
+// Interact with `transfer` method of the `Psp22` contract.
+fn transfer(session: &mut Session, to: AccountId, amount: Balance) -> Result<(), PSP22Error> {
+ let empty_array = serde_json::to_string::<[u8; 0]>(&[]).unwrap();
+ let input = vec![to.to_string(), amount.to_string(), empty_array];
-#[drink::test(sandbox = Sandbox)]
-fn test(mut session: Session) {
- // Your test case
+ call::(session, "Psp22::transfer", input, None)
}
```
-## Examples
+Asserts the returned error to an [`Error`](TODO) type using [`assert_err!`](TODO) to test errors of a runtime call.
+
+```rs
+use drink::{assert_err, v0::Error, Assets, AssetsError::NoAccount};
+
+#[drink::test(sandbox = Pop)]
+fn test_transfer_to_no_account() {
+ // Test the contract call if a custom error is the runtime module error.
+ assert_err!(
+ transfer(&mut session, ALICE, AMOUNT),
+ Error::Module(Assets(NoAccount))
+ );
+}
+```
+
+We need to specify the sandbox of Pop Network runtime for a testcase if the contract is using Pop API.
+
+```rs
+#[drink::test(sandbox = Pop)]
+```
+
+## Development Guide
+
+To run the `examples` contracts for DRink!
+
+```
+cargo test --release
+```
+
+### Support
-Please find more examples of `pop_drink` tests in the [`pop_drink/examples`](https://github.com/r0gue-io/pop-drink/tree/main/examples).
+- Be part of our passionate community of Web3 pioneers. [Join our Telegram](https://t.me/onpopio)!
+- Additionally, there are [GitHub issues](https://github.com/r0gue-io/pop-drink/issues) and
+ [Polkadot Stack Exchange](https://polkadot.stackexchange.com/).