bvs-library 2.0.1

SatLayer Bitcoin Validated Service
Documentation
# BVS Library

A standalone library for the BVS project that provides shared functionality for BVS Contracts.

### `bvs_library::*`

Used in other CosmWasm contracts to share common functionality.

- `bvs_library::ownership`: Similar to `Ownable.sol` to assert that the caller is the owner of the contract.
- `bvs_library::addr`: Additional utilities for working with addresses.

### `bvs_library::testing`

Test utilities for BVS contracts for unit and integration tests.
Only compile in non wasm32 targets `#![cfg(not(target_arch = "wasm32"))]`, purely for testing.
Won't be included in the `*.wasm` artifact.

`TestingContract` is a trait that provides a common testing interface for setting up testing contracts.
It provides utils for common functions or traits for easy testing—allowing for testing code to be **colocated at
the cosmwasm** crates, as they should—for integration testing productivity sake.

```rust filename="testing.rs"
pub trait TestingContract<IM, EM, QM> {
    fn wrapper() -> Box<dyn Contract<Empty>>;
    fn default_init(app: &mut App, env: &Env) -> IM;
    fn new(app: &mut App, env: &Env, msg: Option<IM>) -> Self;
}
```

```txt
crates/
├── bvs-library/              <-- You are here
├── bvs-pauser/
│   └── src/
│       └── testing.rs        <-- put here with `#![cfg(not(target_arch = "wasm32"))]`
├── bvs-vault-router/
│   └── src/
│       └── testing.rs        <-- put here with `#![cfg(not(target_arch = "wasm32"))]`
```

For integration tests, downstream crates can implement `TestingContract` for execute/query/init/defaults functionality.

```rust filename="bvs-pauser/src/testing.rs"
pub struct PauserContract {
    pub addr: Addr,
    pub init: InstantiateMsg,
}

impl TestingContract<InstantiateMsg, ExecuteMsg, QueryMsg> for PauserContract {
    fn wrapper() -> Box<dyn Contract<Empty>> {
        Box::new(ContractWrapper::new(
            crate::contract::execute,
            crate::contract::instantiate,
            crate::contract::query,
        ))
    }

    fn default_init(app: &mut App, _env: &Env) -> InstantiateMsg {
        // You can get a contract address by their label, allowing you to orchestrate "instinctively" — however, we still need to remove circular dependency.
        // Self::get_contract_addr(app, "contract-label")
        InstantiateMsg {
            owner: app.api().addr_make("owner").to_string(),
            initial_paused: false,
        }
    }

    fn new(app: &mut App, env: &Env, msg: Option<InstantiateMsg>) -> Self {
        let init = msg.unwrap_or(Self::default_init(app, env));
        let code_id = Self::store_code(app);
        let addr = Self::instantiate(app, code_id, "contract-label", &init);
        Self { addr, init }
    }

    fn addr(&self) -> &Addr {
        &self.addr
    }
}
```