snap-coin 11.2.2

The core library for developing and using Snap Coin
Documentation
# Snap Coin Core
A rust crate for developing with and for Snap Coin

# Some General Tips
1. Default binary to string serialization is `base36` (letters + numbers only).
2. Most helper functions (like `build_block(...)`, `build_transaction(...)`) take a blockchain data provider (this is a trait!), which is a struct that can access basic blockchain data and perform certain fetches etc. These are most commonly `core::blockchain::Blockchain` and `api::client::Client`.

# Getting started
## Installation
To utilize this library in your project run
```bash
cargo add snap_coin
```

## Utilization
There are **two** main ways of connecting and interacting with a snap coin network

### As a standalone node (***DIFFICULT***)
Your program becomes the node, and you have direct access over its blockchain, peers, connected nodes, status. This is best for when you need **fast, direct access.** This is not recommended if you are creating a program that a user might want to run along side a existing node or if the user would like to create more than one instance of this program.
This is **the fastest approach** as you directly interface with the node, without any translation layer in between.

1.
    Create a new node instance (**WARNING:** Only one instance can exist in one program at once, otherwise a panic will happen!)
    ```rust
    let (blockchain, node_state) = create_full_node("./node-path", false); // Path where the node will be stored, do not disable stdout
    ```
    Notice how `create_full_node()` returns a `(SharedBlockchain, SharedNodeState)` instead of just a node. This is because there isn't a node struct and interacting with any blockchain or node functions is done through these references. The `SharedBlockchain` type represents a internally mutable blockchain, that can be used to atomically get blockchain data. The `SharedNodeState` type represents the mutable node state (internally hidden behind `RwLock`'s).
2.
    Call and access functions of the node
    ```rust
    accept_block(&blockchain, &node_state, some_new_block).await?;
    println!("Last block: {}", blockchain.block_store().get_last_block_hash().dump_base_36());
    ```
3. Full example:
    ```rust
    use snap_coin::{build_block, crypto::keys::Private, full_node::{accept_block, create_full_node}};

    #[tokio::main]
    async fn main() -> Result<(), anyhow::Error> {
        let (blockchain, node_state) = create_full_node("./node-devnet", false);

        let mut some_block = build_block(&*blockchain, &vec![], Private::new_random().to_public()).await?; // Path where the node will be stored, do not disable stdout
        #[allow(deprecated)] // This is deprecated because it only works on a not congested network, with only 1 miner. Okay for creating genesis blocks
        some_block.compute_pow()?;

        accept_block(&blockchain, &node_state, some_block).await?; // Notice we borrow the node references
        println!("Last block: {}", blockchain.block_store().get_last_block_hash().dump_base36());

        Ok(())
    }
    ```
    This example only includes basic node functions that allow your project to directly participate in the network. To connect to other peers look into `connect_peer()`, to allow other peers to connect to your node look into `start_p2p_server()`. To listen to chain events look into the `NodeState`'s `ChainEvent`.

### As a Snap Coin API interface with an existing node (***EASY***)
This approach makes your program a API client to a node that is already hosted (like snap-coin-node) by your user. This approach is slower and does not have full direct access to the node, however, it is a lot more lightweight then the approach mentioned before. This should be used when **there will be more then one instance of this program running**, for example a wallet can just connect to a hosted node (by the user) instead of being its own node. It is important to understand that the node this client will be connecting too must be **100% trusted** as it can modify, spoof, and fake all interactions with this program.

1.
    Connect to a already running (in a separate program) node, that has a Snap Coin API server exposed
    ```rust
    let client = Client::connect("127.0.0.1:3003".parse().unwrap()).await?;
    ```
2.
    Call functions on the client to obtain and change blockchain / node state
    ```rust
    println!("Last block: {}", client.get_block_hash_by_height(last_block_height).await?.unwrap().dump_base36());
    ```
3. Full Example:
    ```rust
    use snap_coin::{api::client::Client, blockchain_data_provider::BlockchainDataProvider, build_block, crypto::keys::Private};

    #[tokio::main]
    async fn main() -> Result<(), anyhow::Error> {
        let client = Client::connect("127.0.0.1:3003".parse().unwrap()).await?; // Connect to a local node API

        let mut some_block = build_block(&client, &vec![], Private::new_random().to_public()).await?; // Path where the node will be stored, port to host node
        #[allow(deprecated)] // This is deprecated because it only works on a not congested network, with only 1 miner. Okay for creating genesis blocks
        some_block.compute_pow()?;

        client.submit_block(some_block).await??; // NOTE: This function is not part of the BlockchainDataProvider trait
        let last_block_height = client.get_height().await?.saturating_sub(1); // NOTE: using saturating sub because height is a usize to avoid overflow
        println!("Last block: {}", client.get_block_hash_by_height(last_block_height).await?.unwrap().dump_base36()); // unwrap is okay because we know a block exists since we just added one

        Ok(())
    }
    ```

# Documentation and Development Reference
Available here: [docs.rs](https://docs.rs/snap-coin/latest/)

# Support this Project
You can support this project in many ways, but it is best to just develop and use Snap Coin. I take pride in this project, and by extent in this code. You can help us grow, as Snap Coin is a community effort, by creating apps that utilize Snap Coin, trading, using it as a medium of exchange for things like jobs.

## Help Develop Snap Coin
This repo is always available for pull requests, i highly incentivize reading the code, documentation, and making new features. If you need any help, reach out to me on discord @ice.is.this or via email ice.is.this@gmail.com. Any issues can be reported in the issues tab.

## Join the discord
Join and grow the community: [discord.gg](https://discord.gg/ZK3gMmr3aR)

## Donate
You can buy the developer a coffee and help me keep my motivation:

Snap Coin: `5wpj4mklmxjrvus1ct3b3idvrvfymjq255ne7jm0tspavqrfyz`

Bitcoin: `bc1qacw3l33kzdg96tu268az3chsyrg3pcup0dat9j`

Etherum: `0xef98b5ea67248e8a3ee4f4d3674c8ebb2be4e39a`

Solana: `8ST3miN2KLdTNXa7pkK1g2qFB3xKzpe1bvCC2QuVBDHG`

BNB Smart Chain `0xef98b5ea67248e8a3ee4f4d3674c8ebb2be4e39a`