### StorageMap Set and Get Example Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-support.md Shows how to initialize a StorageMap, set a key-value pair, and retrieve a value. ```rust let mut storage = StorageMap::default(); storage.set(b"counter".to_vec(), 42u128.to_le_bytes().to_vec()); let value = storage.get(b"counter"); ``` -------------------------------- ### Install Build Prerequisites Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/README.md Installs the necessary toolchain components for building Alkanes contracts for WebAssembly. ```bash rustup target add wasm32-unknown-unknown cargo install -f wasm-bindgen-cli --version 0.2.100 ``` -------------------------------- ### Install Rust Toolchain Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/techContext.md Installs the Rust programming language toolchain. This is a prerequisite for building the project. ```Shell curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -------------------------------- ### AlkaneId Usage Example Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-support.md Provides a basic example of creating an AlkaneId and checking its properties like is_create and is_deployment. ```rust use alkanes_support::id::AlkaneId; let token = AlkaneId::new(880000, 42); assert!(!token.is_create()); assert!(!token.is_deployment()); ``` -------------------------------- ### Context Usage Example Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-support.md An example demonstrating how to access and utilize the Context within a contract method. ```APIDOC ## Example Usage ```rust use alkanes_runtime::runtime::AlkaneResponder; fn my_method(&self) -> Result { let ctx = self.context()?; // Access caller information println!("Called by: {:?}", ctx.caller); // Check incoming transfers for transfer in &ctx.incoming_alkanes.0 { println!("Received {} of {:?}", transfer.value, transfer.id); } // Access parameters (skip opcode at index 0) let param1 = ctx.inputs.get(1); Ok(CallResponse::default()) } ``` ``` -------------------------------- ### Documenting Opcodes with Transfer Example Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/message-dispatch-macro.md Document your opcodes using Rustdoc comments. This example shows how to document a 'Transfer' operation with its parameters. ```rust /// Transfers tokens to a recipient (opcode 1) #[opcode(1)] Transfer { to: AlkaneId, amount: u128 }, ``` -------------------------------- ### Install wasm-bindgen-cli Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/techContext.md Installs the wasm-bindgen command-line interface, used for testing WebAssembly code. Ensure to use version 0.2.99. ```Shell cargo install -f wasm-bindgen-cli --version 0.2.99 ``` -------------------------------- ### Precompiled Contract Host Function Example Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/systemPatterns.md An example implementation of the `staticcall` host function demonstrating how to handle precompiled contracts by checking specific AlkaneId values. ```rust // Example implementation in the staticcall host function fn staticcall(target: AlkaneId, inputs: Vec, fuel: u64) -> Result { // Check for precompiled contract addresses if target.block == 800000000 { // 8e8 match target.tx { 0 => { // Return the current block header let block_header = get_current_block_header(); let mut response = CallResponse::default(); response.data = block_header.to_vec(); Ok(response) }, 1 => { // Return the coinbase transaction bytes let coinbase_tx = get_coinbase_transaction(); let mut response = CallResponse::default(); response.data = coinbase_tx.to_vec(); Ok(response) }, _ => Err(anyhow!("Unknown precompiled contract")), } } else { // Regular contract call logic // ... } } ``` -------------------------------- ### Install wasm-bindgen-cli for Testing Source: https://github.com/kungfuflex/alkanes-rs/blob/main/README.md Install or update wasm-bindgen-cli to version 0.2.100. This is sometimes necessary to resolve issues when running `wasm-bindgen-test-runner`. ```sh cargo install -f wasm-bindgen-cli --version 0.2.100 ``` -------------------------------- ### Returns Attribute Examples Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/message-dispatch-macro.md Shows how to use the optional #[returns(Type)] attribute to specify the return type for ABI metadata. ```rust #[returns(u128)] #[returns(Vec)] #[returns(AlkaneTransfer)] ``` -------------------------------- ### Minimal ALKANE Example Source: https://github.com/kungfuflex/alkanes-rs/wiki/Designing-an-ALKANE A basic ALKANE implementation that does nothing. It requires the `__execute` function export to be usable. This example demonstrates the minimal structure needed for an ALKANE. ```rs use alkanes_runtime::{runtime::AlkaneResponder}; use metashrew_support::compat::{to_ptr, to_arraybuffer_layout}; use alkanes_support::response::{CallResponse}; #[derive(Default)] pub struct MinimalExample(()); impl AlkaneResponder for MinimalExample { fn execute(&self) -> CallResponse { CallResponse::default() } } #[no_mangle] pub extern "C" fn __execute() -> i32 { let mut response = to_arraybuffer_layout(&MinimalExample::default().execute().serialize()); to_ptr(&mut response) + 4 } ``` -------------------------------- ### Run Alkanes Indexer Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/README.md Starts the Alkanes indexer service, connecting to a Bitcoin RPC endpoint and specifying the WASM contract to use. ```bash rockshrew-mono \ --daemon-rpc-url http://localhost:8332 \ --auth bitcoinrpc:bitcoinrpc \ --db-path ~/.metashrew \ --indexer ~/alkanes-rs/target/wasm32-unknown-unknown/release/alkanes.wasm \ --start-block 880000 \ --host 0.0.0.0 \ --port 8080 \ --cors '*' ``` -------------------------------- ### Running the Alkane.rs Indexer Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/indexer-integration.md Command to launch the indexer with specified configurations for RPC, authentication, database path, indexer Wasm file, start block, host, and port. ```bash ~/metashrew/target/release/rockshrew-mono \ --daemon-rpc-url http://localhost:8332 \ --auth bitcoinrpc:bitcoinrpc \ --db-path ~/.metashrew \ --indexer ~/alkanes-rs/target/wasm32-unknown-unknown/release/alkanes.wasm \ --start-block 880000 \ --host 0.0.0.0 \ --port 8080 \ --cors '*' ``` -------------------------------- ### Run Protorune Tests with Test-Utils Feature Source: https://github.com/kungfuflex/alkanes-rs/blob/main/README.md Run tests for the 'protorune' crate, enabling the 'test-utils' feature. This command is an example of testing a specific crate with additional features. ```sh cargo test --features test-utils -p protorune ``` -------------------------------- ### Get Protorunes by Address Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/techContext.md Retrieves all protorunes held by a specific address. It queries the OUTPOINTS_FOR_ADDRESS and OUTPOINT_TO_RUNES tables. Expects a ProtorunesWalletRequest and returns a WalletResponse. ```rust pub fn protorunes_by_address(input: &Vec) -> Result ``` -------------------------------- ### Run Alkanes Indexer with Metashrew Source: https://github.com/kungfuflex/alkanes-rs/blob/main/README.md This command demonstrates how to run the Alkanes indexer using Metashrew. Ensure Metashrew is built and configured correctly. Adjust RPC URL, authentication, database path, and other parameters as per your setup. ```sh ~/metashrew/target/release/rockshrew-mono --daemon-rpc-url http://localhost:8332 --auth bitcoinrpc:bitcoinrpc --db-path ~/.metashrew --indexer ~/alkanes-rs/target/wasm32-unknown-unknown/release/alkanes.wasm --start-block 880000 --host 0.0.0.0 --port 8080 --cors '*' ``` -------------------------------- ### Get Protorunes by Outpoint Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/techContext.md Retrieves protorune balances for a specific outpoint. Directly queries the OUTPOINT_TO_RUNES table. Expects an OutpointRequest and returns an OutpointResponse. ```rust pub fn protorunes_by_outpoint(input: &Vec) -> Result ``` -------------------------------- ### Reasonable Memory Usage for User Lists Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/advanced-topics.md Storing a list of users in memory during execution is generally acceptable if the count is manageable. This example shows a reasonable approach. ```rust // Reasonable: Store user list in memory during execution let mut users = Vec::new(); for i in 0..count { users.push(get_user(i)?); } ``` -------------------------------- ### Call Contract with Encoded Parameters in Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/advanced-topics.md Prepare and execute a contract call using pre-encoded parameters. This example shows calling a contract with a specific opcode, user, and amount. ```rust fn call_encoded(&self, target: AlkaneId) -> Result { let inputs = encode_parameters(5, AlkaneId::new(880000, 10), 1000); let cellpack = Cellpack { target, inputs }; self.call(&cellpack, &AlkaneTransferParcel::default(), self.fuel()) } ``` -------------------------------- ### Run ALKANES Indexer with METASHREW Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/projectBrief.md Launch the METASHREW indexer stack with the ALKANES WASM binary. Replace placeholders with actual URLs and paths. ```bash metashrew-keydb --redis --rpc-url --auth --indexer ``` -------------------------------- ### Basic Pattern with External Token Deployment Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-auth.md Illustrates a basic implementation pattern for Alkanes contracts using an external token for authentication. It shows how to deploy an authentication token during initialization and then use `only_owner` to protect a privileged operation. ```rust use alkanes_runtime::runtime::{AlkaneResponder, AuthenticatedResponder}; use alkanes_support::response::CallResponse; use anyhow::Result; #[derive(Default)] pub struct MyContract(()); impl AlkaneResponder for MyContract {} impl AuthenticatedResponder for MyContract {} impl MyContract { fn initialize(&self) -> Result { self.observe_initialization()?; // Deploy a token to serve as auth mechanism let auth_transfer = self.deploy_auth_token(1)?; println!("Auth token: {:?}", auth_transfer); Ok(CallResponse::default()) } fn privileged_operation(&self) -> Result { // Only allow token holders self.only_owner()?; let context = self.context()?; Ok(CallResponse::forward(&context.incoming_alkanes)) } } ``` -------------------------------- ### __fuel Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/indexer-integration.md Gets the remaining fuel and stores it in a provided output buffer. ```APIDOC ## __fuel(output: i32) ### Description Get remaining fuel. ### Parameters - `output` (i32) - Pointer to u64 buffer ``` -------------------------------- ### __height Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/indexer-integration.md Gets the current block height and stores it in a provided output buffer. ```APIDOC ## __height(output: i32) ### Description Get current block height. ### Parameters - `output` (i32) - Pointer to u64 buffer ``` -------------------------------- ### __sequence Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/indexer-integration.md Gets the sequence number for new alkane IDs and stores it in a provided output buffer. ```APIDOC ## __sequence(output: i32) ### Description Get sequence number for new alkane IDs. ### Parameters - `output` (i32) - Pointer to u128 buffer ``` -------------------------------- ### Build ALKANES with Full Feature Set Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Build ALKANES for the mainnet with all optional features enabled. This provides the complete set of ALKANES functionality. ```bash cargo build --release --features mainnet,all ``` -------------------------------- ### Get Simple Counter Value Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/contract-patterns.md Retrieves a u128 value stored under '/counter' and returns it as a byte vector in CallResponse. ```rust fn get_counter(&self) -> Result { let pointer = StoragePointer::from_keyword("/counter"); let value = pointer.get_value::(); let context = self.context()?; let mut response = CallResponse::forward(&context.incoming_alkanes); response.data = value.to_le_bytes().to_vec(); Ok(response) } ``` -------------------------------- ### Unit Variants for Simple Methods Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/message-dispatch-macro.md Example of using unit variants for methods that do not require parameters. The generated methods will have no arguments. ```rust #[derive(MessageDispatch)] enum Message { #[opcode(0)] Initialize, #[opcode(1)] TransferAll, } ``` -------------------------------- ### Opcode Attribute Examples Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/message-dispatch-macro.md Demonstrates the usage of the #[opcode(n)] attribute to assign unique numeric identifiers to enum variants. ```rust #[opcode(0)] // opcode 0 #[opcode(1)] // opcode 1 #[opcode(255)] // opcode 255 #[opcode(0xffed)] // hexadecimal notation ``` -------------------------------- ### Access Contract ABI at Runtime Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/advanced-topics.md Demonstrates how to retrieve and convert the exported ABI from a contract to a UTF-8 string at runtime. ```rust let abi = MyMessage::export_abi(); let abi_json = String::from_utf8(abi)?; ``` -------------------------------- ### Get User Balance Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/contract-patterns.md Retrieves a user's balance using a dynamically generated key and returns it as a byte vector. ```rust fn get_balance(&self, user: AlkaneId) -> Result { let mut key = b"/balances/".to_vec(); key.extend(Vec::::from(user)); let pointer = StoragePointer::wrap(&key); let balance = pointer.get_value::(); let context = self.context()?; let mut response = CallResponse::forward(&context.incoming_alkanes); response.data = balance.to_le_bytes().to_vec(); Ok(response) } ``` -------------------------------- ### Get Transaction ID - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Obtain the unique transaction ID (Txid) of the current transaction. This is a fundamental identifier for any transaction. ```rust let txid = self.transaction_id()?; ``` -------------------------------- ### Build ALKANES with Minimal Contracts Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Build ALKANES for the mainnet with a minimal set of standard contracts enabled. This includes refunder, merkle distributor, free mint, upgradeable, and proxy contracts. ```bash cargo build --release --features mainnet,minimal ``` -------------------------------- ### Observe Contract Initialization - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Mark the contract as initialized. This method can only be called once per contract to ensure proper setup. ```rust fn initialize(&self) -> Result { self.observe_initialization()?; Ok(CallResponse::default()) } ``` -------------------------------- ### Build Alkanes Release with Mainnet Feature Source: https://github.com/kungfuflex/alkanes-rs/blob/main/README.md Use this command to build the Alkanes project in release mode with the 'mainnet' feature enabled. Replace 'mainnet' with other network features like 'luckycoin', 'regtest', 'dogecoin', 'bellscoin', or 'fractal' as needed. For test networks, use the 'regtest' feature. ```sh cargo build --release --features mainnet ``` -------------------------------- ### Create and Use Cellpack for Contract Calls Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-support.md Demonstrates how to construct a Cellpack with a target AlkaneId and input parameters, and then use it to make a contract call. Ensure the necessary imports for Cellpack and AlkaneId are present. ```rust use alkanes_support::cellpack::Cellpack; use alkanes_support::id::AlkaneId; let target = AlkaneId::new(880000, 42); let cellpack = Cellpack { target, inputs: vec![1, 50, 100], // opcode 1 with params 50, 100 }; // Call the contract let response = self.call(&cellpack, &AlkaneTransferParcel::default(), fuel)?; ``` -------------------------------- ### Get Serialized Transaction - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Retrieve the raw, serialized bytes of the current transaction. This can be useful for detailed analysis or external processing. ```rust let tx_bytes = self.transaction(); ``` -------------------------------- ### Test ALKANES with Specific Target and Features Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Run tests for the 'protorune' crate with a specific target architecture and testing utilities enabled. ```bash cargo test -p protorune --target x86_64-unknown-linux-gnu --features test-utils ``` -------------------------------- ### Export ABI and Print JSON Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/message-dispatch-macro.md Demonstrates how to export the contract's ABI as bytes, convert it to a UTF-8 string, and print the resulting JSON representation at runtime. ```rust let abi_bytes = VaultMessage::export_abi(); let abi_json = String::from_utf8(abi_bytes)?; println!("{}", abi_json); // Output: // {"contract":"Vault","methods":[ // {"name":"initialize","opcode":0,"params":[],"returns":"void"}, // {"name":"deposit","opcode":1,"params":[{"type":"u128","name":"amount"}],"returns":"u128"}, // ... // ]} ``` -------------------------------- ### Create StoragePointer from Keyword Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Creates a `StoragePointer` instance from a string keyword. Used to reference storage keys. ```rust let ptr = StoragePointer::from_keyword("/balance"); ``` -------------------------------- ### Get Coinbase Transaction - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Retrieve the coinbase transaction of the current block. This transaction is generated by the miner and typically includes block rewards. ```rust let cb = self.coinbase_tx()?; ``` -------------------------------- ### Build Project with Cargo Source: https://github.com/kungfuflex/alkanes-rs/blob/main/crates/protorune/README.md Use this command to build the entire Rust project. ```bash cargo build ``` -------------------------------- ### Get Serialized Block - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Retrieve the raw, serialized bytes of the current block. This can be used for detailed block analysis or integration with other systems. ```rust let block_bytes = self.block(); ``` -------------------------------- ### Run Specific Unit Tests with Target Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Run unit tests for a specific crate (`protorune`) targeting a particular architecture (`x86_64-unknown-linux-gnu`). ```bash cargo test -p protorune --target x86_64-unknown-linux-gnu ``` -------------------------------- ### Get Current Block Height - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Obtain the current block height of the Alkanes blockchain. Useful for time-sensitive operations or block-based logic. ```rust let current_height = self.height(); ``` -------------------------------- ### StoragePointer Methods Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Provides abstractions for accessing and manipulating storage using keywords. ```APIDOC ## `StoragePointer::from_keyword` ### Description Creates a `StoragePointer` from a string keyword. ### Method `from_keyword(keyword: &str) -> Self` ### Parameters - `keyword`: The string keyword to create the pointer from. ### Returns - `Self`: A new `StoragePointer` instance. ### Example ```rust let ptr = StoragePointer::from_keyword("/balance"); ``` ``` ```APIDOC ## `StoragePointer::get` ### Description Retrieves the value stored at the key associated with this `StoragePointer`. ### Method `get() -> Arc>` ### Returns - `Arc>`: The value bytes wrapped in an `Arc`. ``` ```APIDOC ## `StoragePointer::set` ### Description Stores a value at the key associated with this `StoragePointer`. ### Method `set(value: Arc>)` ### Parameters - `value`: The value bytes wrapped in an `Arc` to store. ### Example ```rust let mut ptr = StoragePointer::from_keyword("/counter"); ptr.set(Arc::new(42u128.to_le_bytes().to_vec())); ``` ``` ```APIDOC ## `StoragePointer::get_value` ### Description Retrieves and deserializes the value stored at the key associated with this `StoragePointer` into a specified type `T`. ### Method `get_value() -> T` ### Parameters - `T`: The type to deserialize the value into, which must implement `FromLe`. ### Returns - `T`: The deserialized value. ``` ```APIDOC ## `StoragePointer::set_value` ### Description Serializes a value of type `T` and stores it at the key associated with this `StoragePointer`. ### Method `set_value(value: T)` ### Parameters - `T`: The type of the value to serialize, which must implement `ToLe`. - `value`: The value to serialize and store. ### Example ```rust let mut ptr = StoragePointer::from_keyword("/count"); ptr.set_value::(100); let val: u128 = ptr.get_value::(); ``` ``` -------------------------------- ### Set and Get Storage Value Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Serializes a value of type `T` and stores it at the `StoragePointer` key, then retrieves and deserializes it back into type `T`. Demonstrates `set_value` and `get_value`. ```rust let mut ptr = StoragePointer::from_keyword("/count"); ptr.set_value::(100); let val: u128 = ptr.get_value::(); ``` -------------------------------- ### Get Remaining Fuel - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Check the amount of remaining fuel for the current execution. Essential for managing computational resources and preventing excessive usage. ```rust let remaining = self.fuel(); if remaining < 1000 { return Err(anyhow!("Insufficient fuel")); } ``` -------------------------------- ### Initialization Method Implementation Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/contract-patterns.md Implements the one-time initialization logic for an ALKANES contract. It uses `observe_initialization` to prevent multiple calls and stores initial state. ```rust fn initialize(&self) -> Result { // Prevent multiple initializations self.observe_initialization()?; // Perform setup let context = self.context()?; // Store initial state let mut pointer = StoragePointer::from_keyword("/initialized"); pointer.set_value::(0x01); // Return response Ok(CallResponse::default()) } ``` -------------------------------- ### Get Sequence Number - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Retrieve the current sequence number, which is used for generating new Alkanes IDs. This ensures unique ID generation. ```rust let seq = self.sequence(); ``` -------------------------------- ### Build ALKANES Indexer WASM Binary Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/projectBrief.md Compile the ALKANES indexer as a release-optimized WASM binary. The `` feature flag must be specified. ```bash cargo build --release --features all, ``` -------------------------------- ### Enable Authentication Token Support Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Build ALKANES with authentication token support enabled. This includes the 'AuthenticatedResponder' trait and token deployment factories. ```bash cargo build --features auth_token ``` -------------------------------- ### Get Account Balance - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Query the balance of a specific alkane token held by an account. Requires the account ID and the alkane token ID. ```rust let bal = self.balance(&context.myself, &some_token); println!("Balance: {}", bal); ``` -------------------------------- ### Get Execution Context Size Source: https://github.com/kungfuflex/alkanes-rs/wiki/Runtime-Environment Retrieves the size in bytes of the read-only context object for the current execution. This context contains information about the current state. ```rust fn __request_context() -> i32; ``` -------------------------------- ### Add Anyhow Dependency Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/techContext.md Add the anyhow crate for error handling utilities in your Cargo.toml. ```toml anyhow = "1.0.90" ``` -------------------------------- ### Build Alkanes for Mainnet Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/README.md Compiles the Alkanes project for the mainnet environment, targeting WebAssembly. ```bash cargo build --release --features mainnet --target wasm32-unknown-unknown ``` -------------------------------- ### StorageMap Methods Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-support.md Details the StorageMap type, used for persistent key-value storage in contract state, including methods for parsing, getting, setting, and serializing data. ```APIDOC ## `StorageMap` Type Persistent key-value store for contract state. ### Definition ```rust #[derive(Default, Clone, Debug, PartialEq, Eq)] pub struct StorageMap(pub BTreeMap, Vec>); ``` ### Methods #### `parse(cursor: &mut Cursor>) -> Result` Parses storage map from a byte stream. #### `get>(&self, k: T) -> Option<&Vec>` Retrieves a value by key. **Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | k | T | Key (any type convertible to bytes) | **Returns:** Reference to value or None #### `get_mut>(&mut self, k: T) -> Option<&mut Vec>` Retrieves a mutable reference to a value. #### `set, VT: AsRef<[u8]>>(&mut self, k: KT, v: VT)` Stores a key-value pair. **Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | k | KT | Key | | v | VT | Value | #### `serialize(&self) -> Vec` Serializes the entire storage map. **Returns:** Serialized bytes with format: count + (key_len + key + val_len + val)* ### Example ```rust let mut storage = StorageMap::default(); storage.set(b"counter".to_vec(), 42u128.to_le_bytes().to_vec()); let value = storage.get(b"counter"); ``` ``` -------------------------------- ### Get Number of Diesel Mints - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Query the total number of Diesel mints within the current block. Useful for tracking token creation events. ```rust let mints = self.number_diesel_mints()?; ``` -------------------------------- ### Run Integration Tests with Test Utilities Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Execute integration tests for the project, enabling the `test-utils` feature. This is useful for tests that require additional testing infrastructure. ```bash cargo test --features test-utils ``` -------------------------------- ### Deploy Alkane with [3, n] Header Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/systemPatterns.md Use the [3, n] header to deploy an alkane to a predictable address [4, n], provided the address is not occupied. The first input is the initialization opcode (0). ```rust let cellpack = Cellpack { target: AlkaneId { block: 3, tx: some_value }, inputs: vec![ 0, /* opcode (initialization) */ // Additional parameters... ], }; ``` -------------------------------- ### Get Runes by Address Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/techContext.md Retrieves all runes (not just protorunes) held by a specific address. Similar to protorunes_by_address but does not filter by protocol_tag. Uses the same tables and expects a ProtorunesWalletRequest, returning a WalletResponse. ```rust pub fn runes_by_address(input: &Vec) -> Result ``` -------------------------------- ### Run Unit Tests Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/techContext.md Executes unit tests for a specific crate within the project. Replace with the target crate. ```Shell cargo test -p ``` -------------------------------- ### Enable Testing Utilities Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Build ALKANES with testing utilities enabled. This includes a mock environment, test helpers, and WASM test runner support. ```bash cargo test -p protorune --features test-utils ``` -------------------------------- ### Get Total Miner Fee - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Retrieve the total miner fees collected in the current block. This value is important for understanding transaction costs and miner incentives. ```rust let fees = self.total_miner_fee()?; ``` -------------------------------- ### Get Block Header - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Decode and retrieve the current block's header. Provides access to metadata such as block time, previous block hash, and nonce. ```rust let header = self.block_header()?; println!("Block time: {}", header.time); ``` -------------------------------- ### Configure Mainnet Network Parameters Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/systemPatterns.md Configures network parameters specifically for the mainnet using feature flags. Requires the 'mainnet' feature to be enabled. ```rust #[cfg(feature = "mainnet")] pub fn configure_network() { set_network(NetworkParams { bech32_prefix: String::from("bc"), p2sh_prefix: 0x05, p2pkh_prefix: 0x00, }); } ``` -------------------------------- ### Build Individual Alkanes Contract Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/README.md Compiles a specific Alkanes contract (e.g., alkanes-std-auth-token) for WebAssembly. ```bash cargo build --release -p alkanes-std-auth-token --target wasm32-unknown-unknown ``` -------------------------------- ### Get Parsed Transaction Object - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Decode and retrieve the current transaction as a parsed object. Provides structured access to transaction details like inputs and outputs. ```rust let tx = self.transaction_object()?; println!("Input count: {}", tx.input.len()); ``` -------------------------------- ### Get Execution Context - Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Retrieve the current execution context, including caller, incoming transfers, and input parameters. Use this to access contract-specific information during execution. ```rust fn my_method(&self) -> Result { let context = self.context()?; println!("Caller: {:?}", context.caller); Ok(CallResponse::default()) } ``` -------------------------------- ### Auth Token Contract Implementation Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/systemPatterns.md Handles authentication and access control. Opcode 0 initializes the token, and opcode 1 verifies authentication by checking for the presence of the auth token. ```rust impl AlkaneResponder for AuthToken { fn execute(&self) -> Result { match shift_or_err(&mut inputs)? { 0 => { // Initialization logic let amount = shift_or_err(&mut inputs)?; response.alkanes.0.push(AlkaneTransfer { id: context.myself.clone(), value: amount, }); pointer.set(Arc::new(vec![0x01])); Ok(response) } 1 => { // Authentication logic if context.incoming_alkanes.0.len() != 1 { return Err(anyhow!("did not authenticate with only the authentication token")); } let transfer = context.incoming_alkanes.0[0].clone(); if transfer.id != context.myself.clone() { return Err(anyhow!("supplied alkane is not authentication token")); } if transfer.value < 1 { return Err(anyhow!("less than 1 unit of authentication token supplied")); } response.data = vec![0x01]; response.alkanes.0.push(transfer); Ok(response) } // Other opcodes... } } } ``` -------------------------------- ### Get Auth Token Storage Pointer Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-auth.md Retrieves the storage location for the authentication token ID. Implement this method to access the contract's auth token storage. ```rust impl MyContract { fn get_auth_storage(&self) -> StoragePointer { self.auth_token_pointer() } } ``` -------------------------------- ### Native Tests Build Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Builds the project for native execution, typically for running tests. ```bash cargo test --target x86_64-unknown-linux-gnu ``` -------------------------------- ### Load Data from Storage with Cache Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/indexer-integration.md Illustrates loading data from storage, prioritizing the in-memory cache before accessing the indexer database. Writes within a transaction are cached and immediately visible to subsequent reads. ```rust fn load_data(&self) -> Result { // First call: reads from indexer database let data1 = self.load(b"key".to_vec()); // Store new value self.store(b"key".to_vec(), b"new_value".to_vec()); // Second call: reads from cache (in this transaction) let data2 = self.load(b"key".to_vec()); // data2 == b"new_value" Ok(CallResponse::default()) } ``` -------------------------------- ### Deploy Alkane with [1, 0] Header Source: https://github.com/kungfuflex/alkanes-rs/blob/main/memory-bank/systemPatterns.md Use the [1, 0] header to deploy a WASM at the next available sequence number address. The first input is conventionally the initialization opcode (0). ```rust let cellpack = Cellpack { target: AlkaneId { block: 1, tx: 0 }, inputs: vec![ 0, /* opcode (initialization) */ // Additional parameters... ], }; ``` -------------------------------- ### Unreasonable Memory Usage for Unbounded Data Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/advanced-topics.md Loading an unbounded amount of user data into memory can exceed WASM's linear memory limits. This example demonstrates an unreasonable approach. ```rust // Unreasonable: Store unbounded user data fn load_all_users(&self) -> Result> { let count = self.get_user_count(); let mut users = Vec::with_capacity(count as usize); for i in 0..count { users.push(self.get_user(i)?); } Ok(users) // Could exceed memory } ``` -------------------------------- ### Implement Contract Message Handlers in Rust Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/advanced-topics.md Implement handler functions for different message variants defined in an enum. This example shows separate methods for handling single and multiple transfers. ```rust impl Contract { fn transfer(&self, to: AlkaneId, amount: u128) -> Result { // ... handle single transfer Ok(CallResponse::default()) } fn transfer_many(&self, recipients: Vec, amount: u128) -> Result { // ... handle multiple transfers for recipient in recipients { // Process each } Ok(CallResponse::default()) } } ``` -------------------------------- ### __load_storage Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/indexer-integration.md Loads a value from storage using a key and stores it in a provided buffer. Returns a result code. ```APIDOC ## __load_storage(k: i32, v: i32) -> i32 ### Description Load a value from storage. ### Parameters - `k` (i32) - Pointer to key buffer - `v` (i32) - Pointer to value buffer ### Returns i32 result code ### Usage Internal to AlkaneResponder, rarely called directly ``` -------------------------------- ### Rust Unit Test Pattern Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/advanced-topics.md Demonstrates the structure for unit tests in Rust, focusing on testing contract logic independent of WASM execution. Includes setup for tests and specific test cases. ```rust #[cfg(test)] mod tests { use super::*; use alkanes_support::id::AlkaneId; #[test] fn test_initialize() { let contract = MyContract::default(); // Note: Cannot run WASM code in unit tests // These test Rust logic only } #[test] fn test_parameter_encoding() { let id = AlkaneId::new(880000, 42); let bytes: Vec = id.into(); assert_eq!(bytes.len(), 32); } } ``` -------------------------------- ### __load_context Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/indexer-integration.md Loads the execution context into a provided output buffer. Returns a result code. ```APIDOC ## __load_context(output: i32) -> i32 ### Description Load execution context. ### Parameters - `output` (i32) - Pointer to output buffer ### Returns i32 result code ### Provides - myself: AlkaneId - caller: AlkaneId - vout: u32 - incoming_alkanes: AlkaneTransferParcel - inputs: Vec ``` -------------------------------- ### Development/Testing Feature Combination Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/configuration.md Build ALKANES with all features enabled for comprehensive testing, including testing utilities. ```bash cargo test --all --features test-utils ``` -------------------------------- ### Build Alkanes for Testnet Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/README.md Compiles the Alkanes project for a testnet (regtest) environment, targeting WebAssembly. ```bash cargo build --release --features regtest --target wasm32-unknown-unknown ``` -------------------------------- ### Derive MessageDispatch for Message Enum Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/api-reference-alkanes-runtime.md Use the `#[derive(MessageDispatch)]` macro to automatically implement the MessageDispatch trait for your message enum. Define message variants with unique opcodes using the `#[opcode(...)]` attribute. This example shows how to define an enum for initialization and transfer messages. ```rust #[derive(MessageDispatch)] enum MyMessage { #[opcode(0)] Initialize, #[opcode(1)] Transfer { amount: u128 }, } // ABI export will contain: // {"contract": "My", "methods": [ // {"name": "initialize", "opcode": 0, "params": [], "returns": "void"}, // {"name": "transfer", "opcode": 1, "params": [{"type": "u128", "name": "amount"}], "returns": "void"} // ]} ``` -------------------------------- ### Create a Basic Alkane Contract Source: https://github.com/kungfuflex/alkanes-rs/blob/main/_autodocs/README.md Defines a simple Alkane contract with initialization logic. Ensure necessary imports are present. ```rust use alkanes_runtime::{declare_alkane, message::MessageDispatch, runtime::AlkaneResponder}; use alkanes_support::response::CallResponse; use anyhow::Result; #[derive(Default)] pub struct MyContract(()); #[derive(MessageDispatch)] enum MyMessage { #[opcode(0)] Initialize, } impl MyContract { fn initialize(&self) -> Result { self.observe_initialization()?; Ok(CallResponse::default()) } } impl AlkaneResponder for MyContract {} declare_alkane! { impl AlkaneResponder for MyContract { type Message = MyMessage; } } ```