From 292c87bb8d96620a75d567541493dbf063ef9ad6 Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Mon, 16 Feb 2026 14:39:39 +0700 Subject: [PATCH 01/17] initial commit --- docs.json | 15 + hackathon/builder-guide.mdx | 108 +++++ hackathon/example-appchain-tutorial.mdx | 541 +++++++++++++++++++++++ hackathon/hackathon-landing.mdx | 544 ++++++++++++++++++++++++ hackathon/submission-requirements.mdx | 61 +++ 5 files changed, 1269 insertions(+) create mode 100644 hackathon/builder-guide.mdx create mode 100644 hackathon/example-appchain-tutorial.mdx create mode 100644 hackathon/hackathon-landing.mdx create mode 100644 hackathon/submission-requirements.mdx diff --git a/docs.json b/docs.json index df76bee..5cd1072 100644 --- a/docs.json +++ b/docs.json @@ -536,6 +536,21 @@ "pages": ["/resources/security/audits"] } ] + }, + { + "tab": "Hackathon", + "hidden": true, + "groups": [ + { + "group": "Hackathon 2026", + "pages": [ + "hackathon/hackathon-landing", + "hackathon/builder-guide", + "hackathon/example-appchain-tutorial", + "hackathon/submission-requirements" + ] + } + ] } ], "global": { diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx new file mode 100644 index 0000000..af02915 --- /dev/null +++ b/hackathon/builder-guide.mdx @@ -0,0 +1,108 @@ +--- +title: 'Hackathon Builder Guide' +--- + +# 🚀 Transitioning to Your Own Idea + +The Builder Guide is designed for developers who have already completed the initial environment setup. If you haven't yet launched your first appchain, please start with the **[Step-by-Step Guide](./hackathon-landing)**. + +### ✅ Readiness Checklist +Before proceeding, ensure you have completed these milestones: +- [ ] **Tools Installed**: You have `weave`, `initiad`, and your chosen VM CLI (`minitiad`) in your PATH. ([Step 4](./hackathon-landing#step-4:-install-required-tools)) +- [ ] **Infrastructure Live**: Your rollup is running and your OPinit/Relayer bots are active. ([Step 6](./hackathon-landing#step-6:-setup-interwoven-bots-[terminal])) +- [ ] **Keys Imported**: Your Gas Station mnemonic is imported into your local `initiad` and `minitiad` keyrings. ([Step 7](./hackathon-landing#step-7:-final-key-setup-[terminal])) + +--- + +# ⚡ Quick Reference: The Essentials + +Use these common commands and AI prompts to manage your project during the hackathon. + +| Task | Command / AI Prompt | +| :--- | :--- | +| **Resume Appchain** | `weave start` | +| **Health Check** | *"Using the `initia-appchain-dev` skill, please verify that my appchain is producing blocks and show my gas-station balances."* | +| **Key Import** | See the [Local Keyring Import](#key-import) section below. | + +### Local Keyring Import +The **Gas Station** account acts as your **Universal Developer Key**. Run these commands in your terminal to import it into your local keychains so you can sign transactions via the CLI. + +```bash wrap +# 1. Extract your mnemonic from the weave config +MNEMONIC=$(jq -r '.common.gas_station.mnemonic' ~/.weave/config.json) + +# 2. Import into initiad (L1) +initiad keys add gas-station --recover --keyring-backend test --coin-type 60 --key-type eth_secp256k1 --source <(echo -n "$MNEMONIC") + +# 3. Import into minitiad (L2) +minitiad keys add gas-station --recover --keyring-backend test --coin-type 60 --key-type eth_secp256k1 --source <(echo -n "$MNEMONIC") +``` + +--- + +# Part 1: Development Workflow + +Master the **Describe → Build → Test** cycle. This is how you win the hackathon. + +### The Core Loop +1. **Describe the Goal**: Tell the AI *what* you want to achieve and *why*. +2. **Build & Test (Unit)**: Let the AI write the code AND the unit tests. + + **Prompt:** + ```terminal wrap + Using the `initia-appchain-dev` skill, please write a Move module for a marketplace and a unit test to verify the 'list_item' function. + ``` +3. **Deploy & Interact**: Instruct the AI to deploy to your appchain. + + **Prompt:** + ```terminal wrap + Using the `initia-appchain-dev` skill, please deploy this module to my appchain and execute the 'list_item' function. + ``` +4. **Verify State**: Ask the AI to query the chain to prove the logic works. + + + **Submission Receipt:** To qualify for the hackathon prizes, you must provide the **Contract Address** of your primary logic and a **Transaction Hash** of a user interacting with it. Save these as soon as you have a working version! + + +--- + +# Part 2: Power-Up with Native Features + +To qualify for the prize pool, you must implement at least **one** of these. + +### 1. Built-in Indexer (Rich Data) +Query transaction history and NFT holdings via REST APIs. + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, how do I query the built-in indexer to show my transaction history in my React frontend? +``` + +### 2. Connect Oracle (Skip/Slinky) +Access fast, enshrined price data directly in your smart contracts. + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, show me how to use the `initia_std::oracle` to get the current price of ETH in my Move module. +``` + +### 3. Auto-signing (Web2 UX) +Enable frictionless, session-based signing for high-frequency interactions. + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, modify my InterwovenKit frontend to enable auto-signing for 1 hour. +``` + +--- + +# Part 3: Making It Demo-Ready + +Judges want to see **On-chain Proof**. Use this checklist before submitting. + +- [ ] **Contract Address**: Your primary logic is deployed. +- [ ] **Interaction TX**: You have a transaction hash of a user *interacting* with your contract. +- [ ] **Frontend**: You are using **InterwovenKit** for the wallet connection. +- [ ] **Native Feature**: You've pointed to the code implementing an Initia-native feature. + +> **Mandatory:** Review the **[Submission & Technical Requirements](./submission-requirements)** to ensure you are eligible for prizes. diff --git a/hackathon/example-appchain-tutorial.mdx b/hackathon/example-appchain-tutorial.mdx new file mode 100644 index 0000000..4bd647d --- /dev/null +++ b/hackathon/example-appchain-tutorial.mdx @@ -0,0 +1,541 @@ +--- +title: 'Example Tutorial: BlockForge Game' +--- + +**Prerequisite:** Before starting this tutorial, you should have completed the **[Your First Appchain: A Step-by-Step Guide](./hackathon-landing.mdx)** and have your own appchain running locally. + +--- + +This tutorial will guide you through building a complete, functioning appchain project on top of your existing appchain: **BlockForge**, a tiny on-chain game engine where players can mint and craft items. + +By the end of this tutorial, you will have instructed your AI assistant to: + +* Generate and publish a Move smart contract for the game's logic on your appchain. +* Scaffold and connect a React frontend for players to interact with the game. +* Test the game's functionality. + +--- + +## Step 1: Create the Game's Smart Contract + +Instead of writing the code yourself, instruct your assistant to do it for you using the `initia-appchain-dev` skill. We will build this on your existing appchain. + +**Example Prompt:** + +``` +Using the `initia-appchain-dev` skill, please create a Move module for our BlockForge game. The module should be named `items` inside a `blockforge` project. The game has the following rules: +- Players can mint basic items called "Shards". +- Players can craft "Relics" by burning 2 "Shards". +- Players should have an inventory to store their items. +- I need a way to view a player's inventory. +``` +Your assistant will now generate the necessary `Move.toml` file and the `items.move` module with the complete game logic. + + +If you prefer to create the Move module and project manually, follow these steps. This is what your AI assistant would generate for you. + +First, create a new Move package named `blockforge`: + +```bash wrap +minitiad move new blockforge +``` + +To ensure fast builds and access to the latest Initia features, we recommend setting up local dependencies by cloning the `movevm` repository into a `deps` folder: + +```bash wrap +mkdir -p blockforge/deps && cd blockforge/deps +git clone --depth 1 https://github.com/initia-labs/movevm.git +cd ../.. +``` + +Now, update the `Move.toml` file to use these local dependencies and enable Move 2.1 features. Replace the content of `blockforge/Move.toml` with the following: + +```toml +[package] +name = "blockforge" +version = "0.0.1" +edition = "2024.alpha" + +[dependencies] +InitiaStdlib = { local = "deps/movevm/precompile/modules/initia_stdlib" } +MoveStdlib = { local = "deps/movevm/precompile/modules/move_stdlib" } + +[addresses] +blockforge = "0x2" # Use a placeholder hex address for local builds +std = "0x1" +``` + +Next, delete the default `blockforge.move` file and create a new file named `blockforge/sources/items.move` with the following content. This module implements the game logic for minting shards and crafting relics using standard Move 2.1 patterns. + +```move +module blockforge::items { + use std::signer; + + /// Error codes + const E_INSUFFICIENT_SHARDS: u64 = 1; + + struct Inventory has key { + shards: u64, + relics: u64, + } + + /// Mint basic items called "Shards". + /// Automatically initializes inventory if it doesn't exist. + public entry fun mint_shard(account: &signer) acquires Inventory { + let addr = signer::address_of(account); + if (!exists(addr)) { + move_to(account, Inventory { shards: 1, relics: 0 }); + } else { + let inventory = borrow_global_mut(addr); + inventory.shards = inventory.shards + 1; + } + } + + /// Craft a "Relic" by burning 2 "Shards" + public entry fun craft_relic(account: &signer) acquires Inventory { + let addr = signer::address_of(account); + assert!(exists(addr), E_INSUFFICIENT_SHARDS); + + let inventory = borrow_global_mut(addr); + assert!(inventory.shards >= 2, E_INSUFFICIENT_SHARDS); + + inventory.shards = inventory.shards - 2; + inventory.relics = inventory.relics + 1; + } + + #[view] + /// View a player's inventory + public fun view_inventory(addr: address): (u64, u64) acquires Inventory { + if (exists(addr)) { + let inventory = borrow_global(addr); + (inventory.shards, inventory.relics) + } else { + (0, 0) + } + } +} +``` + +Once the files are created, you can verify everything is correct by building the project. **Note:** You may see a warning about an "unknown field name" for `edition`. This is normal for Move 2.1 projects and can be safely ignored. + +```bash wrap +minitiad move build --language-version=2.1 --named-addresses blockforge=0x2 +``` +If you see `BUILDING blockforge`, then **BlockForge was built successfully! 🛠️** + + +--- + +## Step 2: Build and Play the Game + +Now, let's build and publish the smart contract to your appchain, and then play the game by interacting with it. We will use the gas station account that was created and funded during `weave init`. + +**1. Build and Publish:** +```terminal wrap +Using the `initia-appchain-dev` skill, please build and publish the `blockforge` Move module to my appchain using my gas station account. +``` + +**2. Play the Game:** +```terminal wrap +Using the `initia-appchain-dev` skill and my gas station account on my appchain, please do the following: +1. Mint 3 shards. +2. Check my inventory. +3. Craft a relic. +4. Check my inventory again. +``` +Your assistant will execute the transactions and show you the results. You've just built and played an on-chain game! + + + +Here are the equivalent `minitiad` commands to build the module, publish it, and interact with it on your appchain. + + +**1. Build and Publish:** + +Before publishing, you must ensure the address in the compiled module matches your signing account's hex address. The easiest way to do this without manually editing `Move.toml` is to use the `--named-addresses` flag. + + + **Find your Chain ID:** If you aren't sure what your appchain's ID is, run `minitiad status | jq .node_info.network`. + + +First, get your gas station's hex address: + +```bash wrap +# Get the hex address +minitiad keys show gas-station -a --keyring-backend test | xargs minitiad keys parse +``` + + + **Compatibility Error:** If you see `BACKWARD_INCOMPATIBLE_MODULE_UPDATE`, it means you've already deployed a different version of this module to the same account. In this case, either create a new account or revert your changes to be compatible. + + +Then, build and publish the compiled module to your appchain, substituting `0xYOUR_HEX_ADDRESS` with the value from the previous step: + +```bash wrap +cd blockforge + +# Replace `your-chain-id` with your appchain's ID +minitiad move deploy \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --named-addresses blockforge=0xYOUR_HEX_ADDRESS \ + --gas auto --gas-adjustment 1.4 --yes \ + --build --force +``` + +**2. Play the Game (Interact with the Contract):** + +Now, let's call the functions on the published module. + +**Mint 3 shards:** +```bash wrap +# Note: Since mint_shard is now 1 at a time, we run it 3 times or use a loop +for i in {1..3}; do + minitiad tx move execute items mint_shard \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --gas auto --gas-adjustment 1.4 --yes + sleep 2 +done +``` + +**Check your inventory (View function):** +You can use a `query` command to call the `view_inventory` function. Remember to prefix the address argument with `address:`. + +```bash wrap +# Get your account address +GAS_STATION_ADDRESS=$(minitiad keys show gas-station -a --keyring-backend test) + +minitiad query move view items view_inventory \ + --args "[\"address:${GAS_STATION_ADDRESS}\"]" +``` + +**Craft a relic:** +This requires burning 2 shards. + +```bash wrap +minitiad tx move execute items craft_relic \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --gas auto --gas-adjustment 1.4 --yes +``` + +**Check your inventory again:** +Run the same query command as before to see the updated inventory. + +```bash wrap +minitiad query move view items get_inventory \ + --args "[\"address:${GAS_STATION_ADDRESS}\"]" +``` + +These commands allow you to build and interact with your smart contract directly, giving you a deeper understanding of the development process. + + + + +--- + +## Step 3: Fund your Browser Wallet + +Before you can interact with the game through a frontend, your browser wallet (like **Keplr** or **Leap**) needs tokens to pay for transaction fees. Since we only funded the **gas station** during genesis, we need to send some tokens from the gas station to your personal address. + +**1. Get your Wallet Address:** +Open your browser wallet and copy your address (it starts with `init1...`). + +**2. Send Tokens from Gas Station:** +The easiest way is to ask your assistant to fund you on both layers! + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +``` + +Your assistant will use the gas station account to send both L1 tokens (INIT) and your rollup's native tokens. Once the transactions are confirmed, you're ready to build the UI! + +--- + +## Step 4: Create a Frontend for the Game + +A game needs a user interface. Let's create one using the `initia-appchain-dev` skill. + +**1. Scaffold the Frontend:** +``` +Using the `initia-appchain-dev` skill, please scaffold a new React application for our BlockForge game using Vite. Then, create a simple component named `Game.jsx`. This component should have two buttons: "Mint Shard" and "Craft Relic". For now, make the buttons log a message to the console when clicked. Finally, add the `Game` component to the main `App.jsx` file. +``` + +**2. Connect the Frontend to the Appchain:** +``` +Now, using the `initia-appchain-dev`, please modify the `Game.jsx` component to interact with our deployed "blockforge" smart contract on my appchain. + +The "Mint Shard" button should call the `mint_shard` function, and the "Craft Relic" button should call the `craft_relic` function. Also, please display the player's current inventory of shards and relics. Finally, add a button to enable/disable the native auto-signing feature for a smoother game experience. +``` +Your assistant will use the `@initia/interwoven-kit` to connect your new frontend to your appchain and its smart contract. + + + +The **Interwoven Kit** is the most powerful way to connect your frontend to the Initia ecosystem. It provides a unified interface for wallet management and transaction signing across all Initia rollups. + +First, install the necessary libraries and polyfills (required for browser compatibility with Initia SDKs): + +```bash wrap +npm install @initia/interwovenkit-react @initia/initia.js @initia/initia.proto @tanstack/react-query @privy-io/react-auth wagmi buffer util +npm install --save-dev vite-plugin-node-polyfills +``` + +Update your `vite.config.js` to include the polyfills: + +```javascript +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import { nodePolyfills } from 'vite-plugin-node-polyfills' + +export default defineConfig({ + plugins: [ + react(), + nodePolyfills({ protocolImports: true }), + ], +}) +``` + +Next, set up the polyfills and providers in your main application file. + +**`main.jsx`:** +```jsx +import { Buffer } from 'buffer' +window.Buffer = Buffer +window.process = { env: {} } + +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App.jsx'; +import "@initia/interwovenkit-react/styles.css"; +import { injectStyles, InterwovenKitProvider, TESTNET } from "@initia/interwovenkit-react"; +import InterwovenKitStyles from "@initia/interwovenkit-react/styles.js"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { WagmiProvider, createConfig, http } from "wagmi"; +import { mainnet } from "wagmi/chains"; + +// Inject styles for the widget +injectStyles(InterwovenKitStyles); + +const queryClient = new QueryClient(); +const wagmiConfig = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, +}); + +// Define your local appchain configuration +const customChain = { + chain_id: 'your-chain-id', + chain_name: 'mygame', + pretty_name: 'BlockForge Appchain', + network_type: 'testnet', + bech32_prefix: 'init', + apis: { + rpc: [{ address: 'http://localhost:26657' }], + rest: [{ address: 'http://localhost:1317' }], + indexer: [{ address: 'http://localhost:8080' }], // Required placeholder + }, + fees: { + fee_tokens: [{ denom: 'umin', fixed_min_gas_price: 0.015 }], + }, +}; + +ReactDOM.createRoot(document.getElementById('root')).render( + + + + + + + + + +); +``` + +Now, update your `Game.jsx` to use the `useInterwovenKit` hook. We use `RESTClient` for queries and `MsgExecute` for transactions. + +**`Game.jsx`:** +```jsx +import React, { useState, useEffect } from 'react'; +import { useInterwovenKit } from "@initia/interwovenkit-react"; +import { RESTClient, bcs } from '@initia/initia.js'; +import { MsgExecute } from "@initia/initia.proto/initia/move/v1/tx"; + +const CHAIN_ID = 'your-chain-id'; +const REST_URL = 'http://localhost:1317'; +const MODULE_ADDRESS = '0x00...'; // PASTE YOUR MODULE HEX ADDRESS HERE + +function Game() { + const { address, initiaAddress, openConnect, requestTxBlock, autoSign } = useInterwovenKit(); + const [inventory, setInventory] = useState({ shards: 0, relics: 0 }); + const [loading, setLoading] = useState(false); + + const rest = new RESTClient(REST_URL, { chainID: CHAIN_ID }); + + const fetchInventory = async () => { + if (!initiaAddress) return; + try { + // Query the Resource directly for best reliability + const structTag = `${MODULE_ADDRESS}::items::Inventory`; + const res = await rest.move.resource(initiaAddress, structTag); + if (res && res.data) { + setInventory({ + shards: parseInt(res.data.shards || 0), + relics: parseInt(res.data.relics || 0) + }); + } + } catch (e) { + console.log("Inventory not found (player hasn't minted yet)"); + } + }; + + useEffect(() => { fetchInventory(); }, [initiaAddress]); + + const handleAction = async (functionName, args = []) => { + if (!initiaAddress) return; + setLoading(true); + + const messages = [ + { + typeUrl: "/initia.move.v1.MsgExecute", + value: MsgExecute.fromPartial({ + sender: initiaAddress, + moduleAddress: MODULE_ADDRESS, + moduleName: "items", + functionName: functionName, + args: args, + typeArgs: [], + }), + }, + ]; + + try { + await requestTxBlock({ messages, chainId: CHAIN_ID }); + setTimeout(fetchInventory, 2000); + } catch (e) { + console.error(e); + } finally { + setLoading(false); + } + }; + + if (!address) return ; + + const isAutoSignEnabled = autoSign?.isEnabledByChain[CHAIN_ID]; + + return ( +
+

BlockForge Game

+

Address: {initiaAddress}

+ +
+ +
+ +
+

Your Inventory

+

Shards: {inventory.shards} | Relics: {inventory.relics}

+
+ + + + +
+ ); +} + +export default Game; +``` + +This guide uses the modern **Interwoven Kit** patterns for the best user experience on Initia. + +
+ +--- + +## Step 5: Testing Your Project + +Testing is crucial to ensure your game logic is sound. Instead of writing a test script yourself, instruct your AI assistant to act as your QA team. It will analyze the contract it just wrote and verify the logic. + +**Example Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, I want to verify our BlockForge game. Please: +1. Inspect the `items.move` module to understand the function names and arguments. +2. Generate a bash test script that mints 5 shards, crafts 2 relics, and verifies the final inventory balance. +3. Run the script and show me the output. +``` + + + **AI-Driven QA:** Because your AI assistant generated the code, it is the best tool to test it. It will automatically adjust the test script if it used different function names (like `mint_shards` instead of `mint_shard`) or logic during Step 1. + + + +If you want to write a manual test script, you can use `minitiad` to automate transactions. **Note:** Ensure the function names and arguments match your specific contract. + +```bash wrap +#!/bin/bash +set -ex + +# --- Configuration --- +CHAIN_ID="your-chain-id" +MODULE_ADDRESS="0x00..." # Your module hex address +GAS_STATION_ADDRESS=$(minitiad keys show gas-station -a --keyring-backend test) + +# --- Test Execution --- +echo "Starting test..." + +# 1. Mint 5 Shards +echo "🛠️ Minting 5 shards..." +for i in {1..5}; do + minitiad tx move execute "$MODULE_ADDRESS" items mint_shard \ + --from gas-station \ + --keyring-backend test \ + --chain-id "$CHAIN_ID" \ + --gas auto --gas-adjustment 1.4 --yes + sleep 2 +done + +# 2. Craft 2 Relics (One at a time, each costs 2 shards) +for i in {1..2}; do + echo "⚒️ Crafting relic $i..." + minitiad tx move execute "$MODULE_ADDRESS" items craft_relic \ + --from gas-station \ + --keyring-backend test \ + --chain-id "$CHAIN_ID" \ + --gas auto --gas-adjustment 1.4 --yes + sleep 2 +done + +# 3. Verify Final Inventory +minitiad query move view "$MODULE_ADDRESS" items view_inventory \ + --args "[\"address:${GAS_STATION_ADDRESS}\"]" +``` + + +--- + +## You've Built a Full-Stack dApp! + +Congratulations! You have successfully launched a dedicated appchain, created a smart contract, and built a frontend to interact with it. You've experienced the full development loop, from idea to a working decentralized application. Now you can apply these skills to your own hackathon project. \ No newline at end of file diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx new file mode 100644 index 0000000..c3ede87 --- /dev/null +++ b/hackathon/hackathon-landing.mdx @@ -0,0 +1,544 @@ +--- +title: 'Your First Appchain: A Step-by-Step Guide' +--- + +## Build a Sovereign Blockchain with Your AI Co-pilot + +Welcome to the hackathon! This guide will walk you through building a sovereign blockchain from scratch. You'll go from a simple idea to a functioning appchain with a frontend in record time. + +--- + +## Step 1: Prepare Your Workspace + +Before installing tools or initializing your appchain, create a dedicated directory for your project. This keeps your configuration files, VM binaries, and smart contracts organized in one place. + +**Run the following commands in your terminal:** + +```bash wrap +mkdir my-initia-project +cd my-initia-project +``` + +--- + +## Step 2: Install Your AI Skill [Terminal] + +Your AI assistant needs the **Initia Appchain Dev** skill to help you manage your appchain, write smart contracts, and build your frontend. + +**Run the following command in your terminal:** + +```bash wrap +npx skills add initia-labs/hackathon-skills +``` + +--- + +## 🖥️ Recommended Setup + +To get the most out of this guide, we recommend having two terminal tabs or a split-screen setup: + +1. **AI Co-pilot**: For high-level tasks, contract generation, and troubleshooting. +2. **Standard Terminal**: For interactive CLI commands (like `weave init`) and long-running builds. + +--- + +## Step 3: Choose Your Track & VM [Planning] + +Before installing tools, decide what you want to build. This choice determines which **Virtual Machine (VM)** you will need for your appchain. + +| Track | Recommended VM | Why? | +| :--- | :--- | :--- | +| **Gaming / Consumer** | `Move` | Best for complex on-chain logic and object-oriented assets. | +| **DeFi / Institutional** | `EVM` (Solidity) | Best for leveraging existing Ethereum tooling and libraries. | +| **Agents / Tooling** | `Wasm` (Rust) | Best for performance-critical logic and Rust ecosystem integration. | + +--- + +## Step 4: Install Required Tools + + + **Docker Desktop must be running.** Ensure it is installed and active before running the installation command. If you don't have it, **[download Docker Desktop here](https://www.docker.com/products/docker-desktop/)**. + + +### 4.1 Install the Core CLI Tools [AI Assistant] +The fastest way to install the core CLIs (`weave`, `initiad`, `jq`) is to ask your AI assistant. It will handle the environment setup for you. + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please install the core tools for Initia development. +``` + +### 4.2 Install Your Appchain VM [Terminal] +Because each Virtual Machine (`Move`, `EVM`, `Wasm`) requires building a specific `minitiad` binary from source, this step can take **5-15 minutes**. Run the commands for your chosen VM directly in your standard terminal: + + + + ```bash wrap + git clone --depth 1 https://github.com/initia-labs/minimove.git + cd minimove && make install + cd .. && rm -rf minimove + ``` + + + ```bash wrap + git clone --depth 1 https://github.com/initia-labs/minievm.git + cd minievm && make install + cd .. && rm -rf minievm + ``` + + + ```bash wrap + git clone --depth 1 https://github.com/initia-labs/miniwasm.git + cd miniwasm && make install + cd .. && rm -rf miniwasm + ``` + + + +### 4.3 Verify Installation & PATH [AI Assistant] +After the build completes, your AI assistant can ensure the tools are accessible from anywhere in your system. This is especially helpful if you aren't sure how to configure your `PATH` for your specific shell (Zsh, Bash, etc.). + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please verify that `minitiad` is properly installed and accessible. If it isn't in my PATH, help me add the Go binary directory to my shell configuration. +``` + +--- + +## Step 5: Initial Setup with `weave init` [Terminal] + +Your AI assistant is your partner in this hackathon, but the `weave` CLI requires an initial interactive setup to prepare your environment and launch your first appchain. This is a one-time process. + +**Run the following command in your terminal:** + +```bash wrap +weave init +``` + +Here's a guide on how to navigate the interactive setup: + + + + ### 1. Generate Gas Station Account + The Gas Station is an account on the Initia L1 that will fund your rollup's infrastructure. + + **Prompt:** + ```terminal wrap + ? How would you like to setup your Gas station account? + ``` + + **Action:** + Select `Generate new account (recommended)`. + + **Result:** + You will see your new Gas Station Address. 💡 **Copy this address.** + + ### 2. Fund Your Gas Station Account + **Action:** + Go to the **[Initia Testnet Faucet](https://app.testnet.initia.xyz/faucet)**. + + **Action:** + Paste your address and click **Submit** to receive testnet INIT tokens. + + **Prompt:** + ```terminal wrap + ? Type 'continue' to proceed. + ``` + + **Action:** + Type `continue` and press Enter. + + + + ### 3. Choose Your Action + **Prompt:** + ```terminal wrap + ? What do you want to do? + ``` + + **Action:** + Select `Launch a new rollup`. + + ### 4. Select L1 Network + **Prompt:** + ```terminal wrap + ? Select the Initia L1 network + ``` + + **Action:** + Select `Testnet (initiation-2)`. + + ### 5. Select Virtual Machine (VM) + **Prompt:** + ```terminal wrap + ? Select the Virtual Machine (VM) + ``` + + **Action:** + Select your desired VM (e.g., `Move`). + + ### 6. Specify Rollup Chain ID + **Prompt:** + ```terminal wrap + ? Specify rollup chain ID + ``` + + **Action:** + Enter a unique ID (e.g., `mygame-1`). + + + **Save your Chain ID!** You will need to provide this unique identifier in your final hackathon submission. + + + ### 7. Specify Rollup Gas Denom + **Prompt:** + ```terminal wrap + ? Specify rollup gas denom + ``` + + **Action:** + Press `Tab` for default (`umin`) or enter your own. + + ### 8. Specify Rollup Node Moniker + **Prompt:** + ```terminal wrap + ? Specify rollup node moniker + ``` + + **Action:** + Press `Tab` for default (`operator`). + + + + ### 9. Submission Interval + **Prompt:** + ```terminal wrap + ? Specify OP bridge config: Submission Interval + ``` + + **Action:** + Press `Tab` for default (`1m`). + + ### 10. Finalization Period + **Prompt:** + ```terminal wrap + ? Specify OP bridge config: Output Finalization Period + ``` + + **Action:** + Press `Tab` for default (`168h`). + + ### 11. Data Availability + **Prompt:** + ```terminal wrap + ? Where should the rollup blocks data be submitted? + ``` + + **Action:** + Select `Initia L1`. + + ### 12. Enable Oracle Price Feed + **Prompt:** + ```terminal wrap + ? Would you like to enable oracle price feed from L1? + ``` + + **Action:** + Select `Enable`. + + + + ### 13. Setup Method for System Keys + **Prompt:** + ```terminal wrap + ? Select a setup method for the system keys + ``` + + **Action:** + Select `Generate new system keys`. + + ### 14. System Accounts Funding Option + **Prompt:** + ```terminal wrap + ? Select system accounts funding option + ``` + + **Action:** + Select `Use the default preset`. + + ### 15. Specify Fee Whitelist Addresses + **Prompt:** + ```terminal wrap + ? Specify fee whitelist addresses + ``` + + **Action:** + Press `Enter` to leave empty. + + ### 16. Add Gas Station Account to Genesis + **Prompt:** + ```terminal wrap + ? Would you like to add the gas station account to genesis accounts? + ``` + + **Action:** + Select `Yes`. + + ### 17. Specify Genesis Balance + **Prompt:** + ```terminal wrap + ? Specify the genesis balance for the gas station account + ``` + + **Action:** + Enter `1000000000`. + + ### 18. Add Additional Genesis Accounts + **Prompt:** + ```terminal wrap + ? Would you like to add genesis accounts? + ``` + + **Action:** + Select `No`. + + + + ### 19. Verify System Keys & Continue + **Prompt:** + ```terminal wrap + ? Type 'continue' to proceed. + ``` + + **Action:** + Type `continue` and press Enter. + + ### 20. Confirm Transactions + **Prompt:** + ```terminal wrap + ? Confirm to proceed with signing and broadcasting the following transactions? [y]: + ``` + + **Action:** + Type `y` and press Enter. + +Your appchain will now launch and start producing blocks! + + + +--- + +## Step 6: Setup Interwoven Bots [Terminal] + +To enable the Optimistic bridge and cross-chain communication (IBC) between Initia L1 and your appchain, you need to start the **OPinit Executor** and the **IBC Relayer**. These bots handle the "interweaving" of your chain. + + + **Prerequisite:** Your appchain must be running in another terminal (via `weave init` or `weave start`) before configuring these bots. + + +### 6.1 Start the OPinit Executor +The executor handles the submission of rollup data and bridge operations. + +**Run the following command:** +```bash wrap +weave opinit init executor +``` + +Follow the interactive guide: + + + **Prompt:** + ```terminal wrap + ? Existing keys in config.json detected. Would you like to add these to the keyring before proceeding? + ``` + + **Action:** + Select `Yes, use detected keys`. + + + **Prompt:** + ```terminal wrap + ? Please select an option for the system key for Oracle Bridge Executor + ``` + + **Action:** + Select `Generate new system key`. + + + **Prompt:** + ```terminal wrap + ? Existing config.json detected. Would you like to use the data in this file to pre-fill some fields? + ``` + + **Action:** + Select `Yes, prefill`. + + + **Prompt:** + ```terminal wrap + ? Specify listen address of the bot + ``` + + **Action:** + Press `Tab` to use `localhost:3000` (ensure nothing else is running on this port). + + + **Action:** + Press `Enter` for **L1 RPC**, **Chain ID**, and **Gas Denom**. For **Rollup RPC**, press `Tab` to use `http://localhost:26657`. + + + Once initialized, start the bot in the background: + ```bash wrap + weave opinit start executor -d + ``` + + + +### 6.2 Start the IBC Relayer +The relayer enables asset transfers (like INIT) between the L1 and your appchain. + + + **Docker Desktop** must be running to launch the relayer. + + +**Run the following command:** +```bash wrap +weave relayer init +``` + +Follow the interactive guide: + + + **Prompt:** + ```terminal wrap + ? Select the type of Interwoven rollup you want to relay + ``` + + **Action:** + Select `Local Rollup (your-chain-id)`. + + + **Action:** + Press `Tab` for both **RPC** (`http://localhost:26657`) and **REST** (`http://localhost:1317`) endpoints. + + + **Prompt:** + ```terminal wrap + ? Select method to setup IBC channels for the relayer + ``` + + **Action:** + Select `Subscribe to only transfer and nft-transfer IBC Channels (minimal setup)`. + + + **Prompt:** + ```terminal wrap + ? Select the IBC channels you would like to relay + ``` + + **Action:** + Press `Space` to select all (transfer and nft-transfer), then press `Enter`. + + + **Prompt:** + ```terminal wrap + ? Do you want to setup relayer with the challenger key + ``` + + **Action:** + Select `Yes (recommended)`. + + + Start the relayer process: + ```bash wrap + weave relayer start + ``` + + + You can view relayer logs at any time by running `weave relayer log` in your terminal. + + + + +--- + +## Step 7: Final Key Setup [Terminal] + +💡 **Why:** The **Gas Station** account acts as your **Universal Developer Key**. Importing it allows you to sign transactions manually via the CLI, and it enables your AI co-pilot to deploy contracts and interact with your appchain. + +**Action:** Run these commands to import your account into both the L1 (`initiad`) and L2 (`minitiad`) keychains: +```bash wrap +# Extract your mnemonic from the weave config +MNEMONIC=$(jq -r '.common.gas_station.mnemonic' ~/.weave/config.json) + +# Import into initiad (L1) +initiad keys add gas-station --recover --keyring-backend test --coin-type 60 --key-type eth_secp256k1 --source <(echo -n "$MNEMONIC") + +# Import into minitiad (L2) +minitiad keys add gas-station --recover --keyring-backend test --coin-type 60 --key-type eth_secp256k1 --source <(echo -n "$MNEMONIC") +``` + +**Action:** Verify the import by listing your keys to ensure `gas-station` appears in both: +```bash wrap +# Verify L1 keys +initiad keys list --keyring-backend test + +# Verify L2 keys +minitiad keys list --keyring-backend test +``` + +--- + +## Step 8: Verifying Your Appchain [AI Assistant] + +After completing the infrastructure setup, verify that everything is healthy. + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please verify that my appchain is running and that my Gas Station account has a balance. +``` + +--- + +## Step 9: Funding Your Personal Wallet [AI Assistant] + +To interact with your appchain using a browser wallet (like **Keplr** or **Leap**), you'll need to send tokens from your **gas station** to your personal address. + +**1. Copy your personal address from your wallet.** + +**2. Ask your assistant to fund you:** + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please fund my personal wallet with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +``` + +--- + +## Step 10: Next Steps + +Congratulations! You have successfully launched your first appchain. You now understand the basic workflow of using your AI assistant to manage your own blockchain. + +Now that you have the basics down, you can dive into a full example or start building your own idea. + +### Option 1: Follow the BlockForge Example + +See a complete working example of a game economy with a smart contract and frontend. + +**[→ Go to BlockForge Example](./example-appchain-tutorial)** + +### Option 2: Build Your Own Idea + +Jump straight into building your hackathon project. + +**[→ Go to Builder Guide](./builder-guide)** + +--- + +## 🚨 Security & Production Note + +The workflows described in this guide are optimized for **rapid prototyping during a hackathon or testnet development**. + +* **Key Storage:** Storing mnemonics in `config.json` and using the `--keyring-backend test` flag is convenient but insecure for production. +* **Mainnet Deployment:** When moving to Mainnet, you must use a secure keyring (like your OS keychain or a hardware wallet) and never share or store your mnemonics in plaintext. +* **Account Roles:** For production rollups, it is best practice to use separate accounts for the Gas Station, Validator, and Developer roles. diff --git a/hackathon/submission-requirements.mdx b/hackathon/submission-requirements.mdx new file mode 100644 index 0000000..1f54ea7 --- /dev/null +++ b/hackathon/submission-requirements.mdx @@ -0,0 +1,61 @@ +--- +title: 'Submission & Eligibility Criteria' +--- + +Welcome to the Initia hackathon! Our goal is to empower builders to push the boundaries of what's possible with Interwoven Rollups. To ensure your project is eligible for judging and showcases the best of the Initia ecosystem, please adhere to the following technical pillars. + +--- + +# 1. Eligibility Pillars + +To qualify for the prize pool, projects must demonstrate meaningful integration with the Initia stack. + +### 🏗️ Pillar 1: Dedicated Rollup Architecture +This hackathon is dedicated to the power of appchains. Your project should be deployed as its own sovereign rollup. +* **Requirement:** Provide your rollup's **Chain ID** and a link to a transaction or contract deployment on your rollup. +* **Getting Started:** Use the `weave` CLI to launch and manage your environment. + +### ⚛️ Pillar 2: Optimized Frontend Experience +We encourage builders to use the flagship tooling designed for the Interwoven ecosystem. This ensures your application is "Interwoven-ready" and provides a seamless experience for users across Initia. +* **Requirement:** Utilize **InterwovenKit** (`@initia/interwovenkit-react`) for wallet connections and transaction handling. +* **Why:** This stack enables advanced Initia features like social logins via Privy and cross-chain visibility. + +### ⚡ Pillar 3: Showcasing Initia Native Features +High-value projects go beyond "Hello World" by leveraging Initia's native features. Your submission should implement at least **one** of the following: +1. **Auto-signing:** Create a frictionless UX for high-frequency interactions (e.g., games or trading). +2. **Built-in Indexer:** Query rich historical data or NFT holdings using the native REST APIs. +3. **Connect Oracle:** Integrate Skip's enshrined price feeds for DeFi or economic logic. +4. **Initia Usernames:** Resolve and display `.init` names to improve user onboarding. + +--- + +# 2. Technical Resource Hub + +Access the official tools and documentation to build your project: + +### Official Repositories +* **[Initia L1](https://github.com/initia-labs/initia):** Core Layer 1 source code. +* **[Weave CLI](https://github.com/initia-labs/weave):** Essential for launching appchains. +* **[InterwovenKit](https://github.com/initia-labs/interwovenkit):** The standard React SDK for Initia frontends. +* **[Initia.js](https://github.com/initia-labs/initia.js):** The primary JavaScript library for blockchain interactions. + +### APIs & Endpoints +* **Rollup Indexer (Rollytics):** [View Swagger](https://rollytics-api-echelon-1.anvil.asia-southeast.initia.xyz/swagger/index.html) — Use this to query transactions and assets **on your appchain**. +* **L1 Indexer:** [View Swagger](https://indexer.initia.xyz/swagger/index.html) — Use this to query global data like **Initia Usernames**. +* **L1 Testnet RPC:** `https://rpc.testnet.initia.xyz` +* **L1 Testnet LCD:** `https://lcd.testnet.initia.xyz` +* **Faucets:** [faucet.testnet.initia.xyz](https://faucet.testnet.initia.xyz) + +--- + +# 3. Submission Summary (Add to your README) + +To help our technical reviewers understand your project, please include this summary in your project's `README.md`: + +| Feature | Details | +| :--- | :--- | +| **Rollup Chain ID** | (e.g., `my-game-1`) | +| **Contract/Module Address** | (The address of your deployed smart contract) | +| **L2 Interaction TX** | [Link to a transaction that *calls your contract*] | +| **Frontend Stack** | InterwovenKit | +| **Native Feature(s)** | (e.g., Auto-signing / Indexer / Oracle / Usernames) | From b428205deb344ce0ceba84c15527ccc7463046c6 Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Mon, 16 Feb 2026 14:40:53 +0700 Subject: [PATCH 02/17] style: formatting --- hackathon/builder-guide.mdx | 65 +++-- hackathon/example-appchain-tutorial.mdx | 301 +++++++++++++++--------- hackathon/hackathon-landing.mdx | 169 ++++++++----- hackathon/submission-requirements.mdx | 92 +++++--- 4 files changed, 410 insertions(+), 217 deletions(-) diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index af02915..1a888f1 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -4,28 +4,42 @@ title: 'Hackathon Builder Guide' # 🚀 Transitioning to Your Own Idea -The Builder Guide is designed for developers who have already completed the initial environment setup. If you haven't yet launched your first appchain, please start with the **[Step-by-Step Guide](./hackathon-landing)**. +The Builder Guide is designed for developers who have already completed the +initial environment setup. If you haven't yet launched your first appchain, +please start with the **[Step-by-Step Guide](./hackathon-landing)**. ### ✅ Readiness Checklist + Before proceeding, ensure you have completed these milestones: -- [ ] **Tools Installed**: You have `weave`, `initiad`, and your chosen VM CLI (`minitiad`) in your PATH. ([Step 4](./hackathon-landing#step-4:-install-required-tools)) -- [ ] **Infrastructure Live**: Your rollup is running and your OPinit/Relayer bots are active. ([Step 6](./hackathon-landing#step-6:-setup-interwoven-bots-[terminal])) -- [ ] **Keys Imported**: Your Gas Station mnemonic is imported into your local `initiad` and `minitiad` keyrings. ([Step 7](./hackathon-landing#step-7:-final-key-setup-[terminal])) + +- [ ] **Tools Installed**: You have `weave`, `initiad`, and your chosen VM CLI + (`minitiad`) in your PATH. + ([Step 4](./hackathon-landing#step-4:-install-required-tools)) +- [ ] **Infrastructure Live**: Your rollup is running and your OPinit/Relayer + bots are active. + ([Step 6](./hackathon-landing#step-6:-setup-interwoven-bots-[terminal])) +- [ ] **Keys Imported**: Your Gas Station mnemonic is imported into your local + `initiad` and `minitiad` keyrings. + ([Step 7](./hackathon-landing#step-7:-final-key-setup-[terminal])) --- # ⚡ Quick Reference: The Essentials -Use these common commands and AI prompts to manage your project during the hackathon. +Use these common commands and AI prompts to manage your project during the +hackathon. -| Task | Command / AI Prompt | -| :--- | :--- | -| **Resume Appchain** | `weave start` | -| **Health Check** | *"Using the `initia-appchain-dev` skill, please verify that my appchain is producing blocks and show my gas-station balances."* | -| **Key Import** | See the [Local Keyring Import](#key-import) section below. | +| Task | Command / AI Prompt | +| :------------------ | :------------------------------------------------------------------------------------------------------------------------------ | +| **Resume Appchain** | `weave start` | +| **Health Check** | _"Using the `initia-appchain-dev` skill, please verify that my appchain is producing blocks and show my gas-station balances."_ | +| **Key Import** | See the [Local Keyring Import](#key-import) section below. | ### Local Keyring Import -The **Gas Station** account acts as your **Universal Developer Key**. Run these commands in your terminal to import it into your local keychains so you can sign transactions via the CLI. + +The **Gas Station** account acts as your **Universal Developer Key**. Run these +commands in your terminal to import it into your local keychains so you can sign +transactions via the CLI. ```bash wrap # 1. Extract your mnemonic from the weave config @@ -45,51 +59,64 @@ minitiad keys add gas-station --recover --keyring-backend test --coin-type 60 -- Master the **Describe → Build → Test** cycle. This is how you win the hackathon. ### The Core Loop -1. **Describe the Goal**: Tell the AI *what* you want to achieve and *why*. + +1. **Describe the Goal**: Tell the AI _what_ you want to achieve and _why_. 2. **Build & Test (Unit)**: Let the AI write the code AND the unit tests. **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, please write a Move module for a marketplace and a unit test to verify the 'list_item' function. ``` + 3. **Deploy & Interact**: Instruct the AI to deploy to your appchain. **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, please deploy this module to my appchain and execute the 'list_item' function. ``` + 4. **Verify State**: Ask the AI to query the chain to prove the logic works. - **Submission Receipt:** To qualify for the hackathon prizes, you must provide the **Contract Address** of your primary logic and a **Transaction Hash** of a user interacting with it. Save these as soon as you have a working version! + **Submission Receipt:** To qualify for the hackathon prizes, you must provide + the **Contract Address** of your primary logic and a **Transaction Hash** of a + user interacting with it. Save these as soon as you have a working version! --- # Part 2: Power-Up with Native Features -To qualify for the prize pool, you must implement at least **one** of these. +To qualify for the prize pool, you must implement at least **one** of these. ### 1. Built-in Indexer (Rich Data) + Query transaction history and NFT holdings via REST APIs. **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, how do I query the built-in indexer to show my transaction history in my React frontend? ``` ### 2. Connect Oracle (Skip/Slinky) + Access fast, enshrined price data directly in your smart contracts. **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, show me how to use the `initia_std::oracle` to get the current price of ETH in my Move module. ``` ### 3. Auto-signing (Web2 UX) + Enable frictionless, session-based signing for high-frequency interactions. **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, modify my InterwovenKit frontend to enable auto-signing for 1 hour. ``` @@ -101,8 +128,12 @@ Using the `initia-appchain-dev` skill, modify my InterwovenKit frontend to enabl Judges want to see **On-chain Proof**. Use this checklist before submitting. - [ ] **Contract Address**: Your primary logic is deployed. -- [ ] **Interaction TX**: You have a transaction hash of a user *interacting* with your contract. +- [ ] **Interaction TX**: You have a transaction hash of a user _interacting_ + with your contract. - [ ] **Frontend**: You are using **InterwovenKit** for the wallet connection. -- [ ] **Native Feature**: You've pointed to the code implementing an Initia-native feature. +- [ ] **Native Feature**: You've pointed to the code implementing an + Initia-native feature. -> **Mandatory:** Review the **[Submission & Technical Requirements](./submission-requirements)** to ensure you are eligible for prizes. +> **Mandatory:** Review the +> **[Submission & Technical Requirements](./submission-requirements)** to ensure +> you are eligible for prizes. diff --git a/hackathon/example-appchain-tutorial.mdx b/hackathon/example-appchain-tutorial.mdx index 4bd647d..da78949 100644 --- a/hackathon/example-appchain-tutorial.mdx +++ b/hackathon/example-appchain-tutorial.mdx @@ -2,23 +2,30 @@ title: 'Example Tutorial: BlockForge Game' --- -**Prerequisite:** Before starting this tutorial, you should have completed the **[Your First Appchain: A Step-by-Step Guide](./hackathon-landing.mdx)** and have your own appchain running locally. +**Prerequisite:** Before starting this tutorial, you should have completed the +**[Your First Appchain: A Step-by-Step Guide](./hackathon-landing.mdx)** and +have your own appchain running locally. --- -This tutorial will guide you through building a complete, functioning appchain project on top of your existing appchain: **BlockForge**, a tiny on-chain game engine where players can mint and craft items. +This tutorial will guide you through building a complete, functioning appchain +project on top of your existing appchain: **BlockForge**, a tiny on-chain game +engine where players can mint and craft items. By the end of this tutorial, you will have instructed your AI assistant to: -* Generate and publish a Move smart contract for the game's logic on your appchain. -* Scaffold and connect a React frontend for players to interact with the game. -* Test the game's functionality. +- Generate and publish a Move smart contract for the game's logic on your + appchain. +- Scaffold and connect a React frontend for players to interact with the game. +- Test the game's functionality. --- ## Step 1: Create the Game's Smart Contract -Instead of writing the code yourself, instruct your assistant to do it for you using the `initia-appchain-dev` skill. We will build this on your existing appchain. +Instead of writing the code yourself, instruct your assistant to do it for you +using the `initia-appchain-dev` skill. We will build this on your existing +appchain. **Example Prompt:** @@ -29,7 +36,9 @@ Using the `initia-appchain-dev` skill, please create a Move module for our Block - Players should have an inventory to store their items. - I need a way to view a player's inventory. ``` -Your assistant will now generate the necessary `Move.toml` file and the `items.move` module with the complete game logic. + +Your assistant will now generate the necessary `Move.toml` file and the +`items.move` module with the complete game logic. If you prefer to create the Move module and project manually, follow these steps. This is what your AI assistant would generate for you. @@ -40,7 +49,9 @@ First, create a new Move package named `blockforge`: minitiad move new blockforge ``` -To ensure fast builds and access to the latest Initia features, we recommend setting up local dependencies by cloning the `movevm` repository into a `deps` folder: +To ensure fast builds and access to the latest Initia features, we recommend +setting up local dependencies by cloning the `movevm` repository into a `deps` +folder: ```bash wrap mkdir -p blockforge/deps && cd blockforge/deps @@ -48,7 +59,8 @@ git clone --depth 1 https://github.com/initia-labs/movevm.git cd ../.. ``` -Now, update the `Move.toml` file to use these local dependencies and enable Move 2.1 features. Replace the content of `blockforge/Move.toml` with the following: +Now, update the `Move.toml` file to use these local dependencies and enable Move +2.1 features. Replace the content of `blockforge/Move.toml` with the following: ```toml [package] @@ -65,7 +77,10 @@ blockforge = "0x2" # Use a placeholder hex address for local builds std = "0x1" ``` -Next, delete the default `blockforge.move` file and create a new file named `blockforge/sources/items.move` with the following content. This module implements the game logic for minting shards and crafting relics using standard Move 2.1 patterns. +Next, delete the default `blockforge.move` file and create a new file named +`blockforge/sources/items.move` with the following content. This module +implements the game logic for minting shards and crafting relics using standard +Move 2.1 patterns. ```move module blockforge::items { @@ -79,7 +94,7 @@ module blockforge::items { relics: u64, } - /// Mint basic items called "Shards". + /// Mint basic items called "Shards". /// Automatically initializes inventory if it doesn't exist. public entry fun mint_shard(account: &signer) acquires Inventory { let addr = signer::address_of(account); @@ -95,10 +110,10 @@ module blockforge::items { public entry fun craft_relic(account: &signer) acquires Inventory { let addr = signer::address_of(account); assert!(exists(addr), E_INSUFFICIENT_SHARDS); - + let inventory = borrow_global_mut(addr); assert!(inventory.shards >= 2, E_INSUFFICIENT_SHARDS); - + inventory.shards = inventory.shards - 2; inventory.relics = inventory.relics + 1; } @@ -116,26 +131,34 @@ module blockforge::items { } ``` -Once the files are created, you can verify everything is correct by building the project. **Note:** You may see a warning about an "unknown field name" for `edition`. This is normal for Move 2.1 projects and can be safely ignored. +Once the files are created, you can verify everything is correct by building the +project. **Note:** You may see a warning about an "unknown field name" for +`edition`. This is normal for Move 2.1 projects and can be safely ignored. ```bash wrap minitiad move build --language-version=2.1 --named-addresses blockforge=0x2 ``` + If you see `BUILDING blockforge`, then **BlockForge was built successfully! 🛠️** + --- ## Step 2: Build and Play the Game -Now, let's build and publish the smart contract to your appchain, and then play the game by interacting with it. We will use the gas station account that was created and funded during `weave init`. +Now, let's build and publish the smart contract to your appchain, and then play +the game by interacting with it. We will use the gas station account that was +created and funded during `weave init`. **1. Build and Publish:** + ```terminal wrap Using the `initia-appchain-dev` skill, please build and publish the `blockforge` Move module to my appchain using my gas station account. ``` **2. Play the Game:** + ```terminal wrap Using the `initia-appchain-dev` skill and my gas station account on my appchain, please do the following: 1. Mint 3 shards. @@ -143,19 +166,24 @@ Using the `initia-appchain-dev` skill and my gas station account on my appchain, 3. Craft a relic. 4. Check my inventory again. ``` -Your assistant will execute the transactions and show you the results. You've just built and played an on-chain game! - +Your assistant will execute the transactions and show you the results. You've +just built and played an on-chain game! -Here are the equivalent `minitiad` commands to build the module, publish it, and interact with it on your appchain. + +Here are the equivalent `minitiad` commands to build the module, publish it, and +interact with it on your appchain. **1. Build and Publish:** -Before publishing, you must ensure the address in the compiled module matches your signing account's hex address. The easiest way to do this without manually editing `Move.toml` is to use the `--named-addresses` flag. +Before publishing, you must ensure the address in the compiled module matches +your signing account's hex address. The easiest way to do this without manually +editing `Move.toml` is to use the `--named-addresses` flag. - **Find your Chain ID:** If you aren't sure what your appchain's ID is, run `minitiad status | jq .node_info.network`. + **Find your Chain ID:** If you aren't sure what your appchain's ID is, run + `minitiad status | jq .node_info.network`. First, get your gas station's hex address: @@ -166,10 +194,14 @@ minitiad keys show gas-station -a --keyring-backend test | xargs minitiad keys p ``` - **Compatibility Error:** If you see `BACKWARD_INCOMPATIBLE_MODULE_UPDATE`, it means you've already deployed a different version of this module to the same account. In this case, either create a new account or revert your changes to be compatible. + **Compatibility Error:** If you see `BACKWARD_INCOMPATIBLE_MODULE_UPDATE`, it + means you've already deployed a different version of this module to the same + account. In this case, either create a new account or revert your changes to + be compatible. -Then, build and publish the compiled module to your appchain, substituting `0xYOUR_HEX_ADDRESS` with the value from the previous step: +Then, build and publish the compiled module to your appchain, substituting +`0xYOUR_HEX_ADDRESS` with the value from the previous step: ```bash wrap cd blockforge @@ -189,6 +221,7 @@ minitiad move deploy \ Now, let's call the functions on the published module. **Mint 3 shards:** + ```bash wrap # Note: Since mint_shard is now 1 at a time, we run it 3 times or use a loop for i in {1..3}; do @@ -201,8 +234,9 @@ for i in {1..3}; do done ``` -**Check your inventory (View function):** -You can use a `query` command to call the `view_inventory` function. Remember to prefix the address argument with `address:`. +**Check your inventory (View function):** You can use a `query` command to call +the `view_inventory` function. Remember to prefix the address argument with +`address:`. ```bash wrap # Get your account address @@ -212,8 +246,7 @@ minitiad query move view items view_inventory \ --args "[\"address:${GAS_STATION_ADDRESS}\"]" ``` -**Craft a relic:** -This requires burning 2 shards. +**Craft a relic:** This requires burning 2 shards. ```bash wrap minitiad tx move execute items craft_relic \ @@ -223,62 +256,76 @@ minitiad tx move execute items craft_relic \ --gas auto --gas-adjustment 1.4 --yes ``` -**Check your inventory again:** -Run the same query command as before to see the updated inventory. +**Check your inventory again:** Run the same query command as before to see the +updated inventory. ```bash wrap minitiad query move view items get_inventory \ --args "[\"address:${GAS_STATION_ADDRESS}\"]" ``` -These commands allow you to build and interact with your smart contract directly, giving you a deeper understanding of the development process. +These commands allow you to build and interact with your smart contract +directly, giving you a deeper understanding of the development process. - --- ## Step 3: Fund your Browser Wallet -Before you can interact with the game through a frontend, your browser wallet (like **Keplr** or **Leap**) needs tokens to pay for transaction fees. Since we only funded the **gas station** during genesis, we need to send some tokens from the gas station to your personal address. +Before you can interact with the game through a frontend, your browser wallet +(like **Keplr** or **Leap**) needs tokens to pay for transaction fees. Since we +only funded the **gas station** during genesis, we need to send some tokens from +the gas station to your personal address. -**1. Get your Wallet Address:** -Open your browser wallet and copy your address (it starts with `init1...`). +**1. Get your Wallet Address:** Open your browser wallet and copy your address +(it starts with `init1...`). -**2. Send Tokens from Gas Station:** -The easiest way is to ask your assistant to fund you on both layers! +**2. Send Tokens from Gas Station:** The easiest way is to ask your assistant to +fund you on both layers! **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` -Your assistant will use the gas station account to send both L1 tokens (INIT) and your rollup's native tokens. Once the transactions are confirmed, you're ready to build the UI! +Your assistant will use the gas station account to send both L1 tokens (INIT) +and your rollup's native tokens. Once the transactions are confirmed, you're +ready to build the UI! --- ## Step 4: Create a Frontend for the Game -A game needs a user interface. Let's create one using the `initia-appchain-dev` skill. +A game needs a user interface. Let's create one using the `initia-appchain-dev` +skill. **1. Scaffold the Frontend:** + ``` Using the `initia-appchain-dev` skill, please scaffold a new React application for our BlockForge game using Vite. Then, create a simple component named `Game.jsx`. This component should have two buttons: "Mint Shard" and "Craft Relic". For now, make the buttons log a message to the console when clicked. Finally, add the `Game` component to the main `App.jsx` file. ``` **2. Connect the Frontend to the Appchain:** + ``` Now, using the `initia-appchain-dev`, please modify the `Game.jsx` component to interact with our deployed "blockforge" smart contract on my appchain. The "Mint Shard" button should call the `mint_shard` function, and the "Craft Relic" button should call the `craft_relic` function. Also, please display the player's current inventory of shards and relics. Finally, add a button to enable/disable the native auto-signing feature for a smoother game experience. ``` -Your assistant will use the `@initia/interwoven-kit` to connect your new frontend to your appchain and its smart contract. + +Your assistant will use the `@initia/interwoven-kit` to connect your new +frontend to your appchain and its smart contract. -The **Interwoven Kit** is the most powerful way to connect your frontend to the Initia ecosystem. It provides a unified interface for wallet management and transaction signing across all Initia rollups. +The **Interwoven Kit** is the most powerful way to connect your frontend to the +Initia ecosystem. It provides a unified interface for wallet management and +transaction signing across all Initia rollups. -First, install the necessary libraries and polyfills (required for browser compatibility with Initia SDKs): +First, install the necessary libraries and polyfills (required for browser +compatibility with Initia SDKs): ```bash wrap npm install @initia/interwovenkit-react @initia/initia.js @initia/initia.proto @tanstack/react-query @privy-io/react-auth wagmi buffer util @@ -293,39 +340,41 @@ import react from '@vitejs/plugin-react' import { nodePolyfills } from 'vite-plugin-node-polyfills' export default defineConfig({ - plugins: [ - react(), - nodePolyfills({ protocolImports: true }), - ], + plugins: [react(), nodePolyfills({ protocolImports: true })], }) ``` Next, set up the polyfills and providers in your main application file. **`main.jsx`:** + ```jsx import { Buffer } from 'buffer' window.Buffer = Buffer window.process = { env: {} } -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import App from './App.jsx'; -import "@initia/interwovenkit-react/styles.css"; -import { injectStyles, InterwovenKitProvider, TESTNET } from "@initia/interwovenkit-react"; -import InterwovenKitStyles from "@initia/interwovenkit-react/styles.js"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { WagmiProvider, createConfig, http } from "wagmi"; -import { mainnet } from "wagmi/chains"; +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App.jsx' +import '@initia/interwovenkit-react/styles.css' +import { + injectStyles, + InterwovenKitProvider, + TESTNET, +} from '@initia/interwovenkit-react' +import InterwovenKitStyles from '@initia/interwovenkit-react/styles.js' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider, createConfig, http } from 'wagmi' +import { mainnet } from 'wagmi/chains' // Inject styles for the widget -injectStyles(InterwovenKitStyles); +injectStyles(InterwovenKitStyles) -const queryClient = new QueryClient(); +const queryClient = new QueryClient() const wagmiConfig = createConfig({ chains: [mainnet], transports: { [mainnet.id]: http() }, -}); +}) // Define your local appchain configuration const customChain = { @@ -342,134 +391,150 @@ const customChain = { fees: { fee_tokens: [{ denom: 'umin', fixed_min_gas_price: 0.015 }], }, -}; +} ReactDOM.createRoot(document.getElementById('root')).render( - - -); + , +) ``` -Now, update your `Game.jsx` to use the `useInterwovenKit` hook. We use `RESTClient` for queries and `MsgExecute` for transactions. +Now, update your `Game.jsx` to use the `useInterwovenKit` hook. We use +`RESTClient` for queries and `MsgExecute` for transactions. **`Game.jsx`:** + ```jsx -import React, { useState, useEffect } from 'react'; -import { useInterwovenKit } from "@initia/interwovenkit-react"; -import { RESTClient, bcs } from '@initia/initia.js'; -import { MsgExecute } from "@initia/initia.proto/initia/move/v1/tx"; +import React, { useState, useEffect } from 'react' +import { useInterwovenKit } from '@initia/interwovenkit-react' +import { RESTClient, bcs } from '@initia/initia.js' +import { MsgExecute } from '@initia/initia.proto/initia/move/v1/tx' -const CHAIN_ID = 'your-chain-id'; -const REST_URL = 'http://localhost:1317'; -const MODULE_ADDRESS = '0x00...'; // PASTE YOUR MODULE HEX ADDRESS HERE +const CHAIN_ID = 'your-chain-id' +const REST_URL = 'http://localhost:1317' +const MODULE_ADDRESS = '0x00...' // PASTE YOUR MODULE HEX ADDRESS HERE function Game() { - const { address, initiaAddress, openConnect, requestTxBlock, autoSign } = useInterwovenKit(); - const [inventory, setInventory] = useState({ shards: 0, relics: 0 }); - const [loading, setLoading] = useState(false); + const { address, initiaAddress, openConnect, requestTxBlock, autoSign } = + useInterwovenKit() + const [inventory, setInventory] = useState({ shards: 0, relics: 0 }) + const [loading, setLoading] = useState(false) - const rest = new RESTClient(REST_URL, { chainID: CHAIN_ID }); + const rest = new RESTClient(REST_URL, { chainID: CHAIN_ID }) const fetchInventory = async () => { - if (!initiaAddress) return; + if (!initiaAddress) return try { // Query the Resource directly for best reliability - const structTag = `${MODULE_ADDRESS}::items::Inventory`; - const res = await rest.move.resource(initiaAddress, structTag); + const structTag = `${MODULE_ADDRESS}::items::Inventory` + const res = await rest.move.resource(initiaAddress, structTag) if (res && res.data) { - setInventory({ - shards: parseInt(res.data.shards || 0), - relics: parseInt(res.data.relics || 0) - }); + setInventory({ + shards: parseInt(res.data.shards || 0), + relics: parseInt(res.data.relics || 0), + }) } } catch (e) { - console.log("Inventory not found (player hasn't minted yet)"); + console.log("Inventory not found (player hasn't minted yet)") } - }; + } - useEffect(() => { fetchInventory(); }, [initiaAddress]); + useEffect(() => { + fetchInventory() + }, [initiaAddress]) const handleAction = async (functionName, args = []) => { - if (!initiaAddress) return; - setLoading(true); - + if (!initiaAddress) return + setLoading(true) + const messages = [ { - typeUrl: "/initia.move.v1.MsgExecute", + typeUrl: '/initia.move.v1.MsgExecute', value: MsgExecute.fromPartial({ sender: initiaAddress, moduleAddress: MODULE_ADDRESS, - moduleName: "items", + moduleName: 'items', functionName: functionName, args: args, typeArgs: [], }), }, - ]; + ] try { - await requestTxBlock({ messages, chainId: CHAIN_ID }); - setTimeout(fetchInventory, 2000); + await requestTxBlock({ messages, chainId: CHAIN_ID }) + setTimeout(fetchInventory, 2000) } catch (e) { - console.error(e); + console.error(e) } finally { - setLoading(false); + setLoading(false) } - }; + } - if (!address) return ; + if (!address) return - const isAutoSignEnabled = autoSign?.isEnabledByChain[CHAIN_ID]; + const isAutoSignEnabled = autoSign?.isEnabledByChain[CHAIN_ID] return (

BlockForge Game

Address: {initiaAddress}

- +
-

Your Inventory

-

Shards: {inventory.shards} | Relics: {inventory.relics}

+

+ Shards: {inventory.shards} | Relics: {inventory.relics} +

- - - -
- ); + ) } -export default Game; +export default Game ``` -This guide uses the modern **Interwoven Kit** patterns for the best user experience on Initia. +This guide uses the modern **Interwoven Kit** patterns for the best user +experience on Initia.
@@ -477,9 +542,12 @@ This guide uses the modern **Interwoven Kit** patterns for the best user experie ## Step 5: Testing Your Project -Testing is crucial to ensure your game logic is sound. Instead of writing a test script yourself, instruct your AI assistant to act as your QA team. It will analyze the contract it just wrote and verify the logic. +Testing is crucial to ensure your game logic is sound. Instead of writing a test +script yourself, instruct your AI assistant to act as your QA team. It will +analyze the contract it just wrote and verify the logic. **Example Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, I want to verify our BlockForge game. Please: 1. Inspect the `items.move` module to understand the function names and arguments. @@ -488,7 +556,10 @@ Using the `initia-appchain-dev` skill, I want to verify our BlockForge game. Ple ``` - **AI-Driven QA:** Because your AI assistant generated the code, it is the best tool to test it. It will automatically adjust the test script if it used different function names (like `mint_shards` instead of `mint_shard`) or logic during Step 1. + **AI-Driven QA:** Because your AI assistant generated the code, it is the best + tool to test it. It will automatically adjust the test script if it used + different function names (like `mint_shards` instead of `mint_shard`) or logic + during Step 1. @@ -532,10 +603,14 @@ done minitiad query move view "$MODULE_ADDRESS" items view_inventory \ --args "[\"address:${GAS_STATION_ADDRESS}\"]" ``` + --- ## You've Built a Full-Stack dApp! -Congratulations! You have successfully launched a dedicated appchain, created a smart contract, and built a frontend to interact with it. You've experienced the full development loop, from idea to a working decentralized application. Now you can apply these skills to your own hackathon project. \ No newline at end of file +Congratulations! You have successfully launched a dedicated appchain, created a +smart contract, and built a frontend to interact with it. You've experienced the +full development loop, from idea to a working decentralized application. Now you +can apply these skills to your own hackathon project. diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index c3ede87..b44191e 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -4,13 +4,17 @@ title: 'Your First Appchain: A Step-by-Step Guide' ## Build a Sovereign Blockchain with Your AI Co-pilot -Welcome to the hackathon! This guide will walk you through building a sovereign blockchain from scratch. You'll go from a simple idea to a functioning appchain with a frontend in record time. +Welcome to the hackathon! This guide will walk you through building a sovereign +blockchain from scratch. You'll go from a simple idea to a functioning appchain +with a frontend in record time. --- ## Step 1: Prepare Your Workspace -Before installing tools or initializing your appchain, create a dedicated directory for your project. This keeps your configuration files, VM binaries, and smart contracts organized in one place. +Before installing tools or initializing your appchain, create a dedicated +directory for your project. This keeps your configuration files, VM binaries, +and smart contracts organized in one place. **Run the following commands in your terminal:** @@ -23,7 +27,8 @@ cd my-initia-project ## Step 2: Install Your AI Skill [Terminal] -Your AI assistant needs the **Initia Appchain Dev** skill to help you manage your appchain, write smart contracts, and build your frontend. +Your AI assistant needs the **Initia Appchain Dev** skill to help you manage +your appchain, write smart contracts, and build your frontend. **Run the following command in your terminal:** @@ -35,70 +40,77 @@ npx skills add initia-labs/hackathon-skills ## 🖥️ Recommended Setup -To get the most out of this guide, we recommend having two terminal tabs or a split-screen setup: +To get the most out of this guide, we recommend having two terminal tabs or a +split-screen setup: -1. **AI Co-pilot**: For high-level tasks, contract generation, and troubleshooting. -2. **Standard Terminal**: For interactive CLI commands (like `weave init`) and long-running builds. +1. **AI Co-pilot**: For high-level tasks, contract generation, and + troubleshooting. +2. **Standard Terminal**: For interactive CLI commands (like `weave init`) and + long-running builds. --- ## Step 3: Choose Your Track & VM [Planning] -Before installing tools, decide what you want to build. This choice determines which **Virtual Machine (VM)** you will need for your appchain. +Before installing tools, decide what you want to build. This choice determines +which **Virtual Machine (VM)** you will need for your appchain. -| Track | Recommended VM | Why? | -| :--- | :--- | :--- | -| **Gaming / Consumer** | `Move` | Best for complex on-chain logic and object-oriented assets. | -| **DeFi / Institutional** | `EVM` (Solidity) | Best for leveraging existing Ethereum tooling and libraries. | -| **Agents / Tooling** | `Wasm` (Rust) | Best for performance-critical logic and Rust ecosystem integration. | +| Track | Recommended VM | Why? | +| :----------------------- | :--------------- | :------------------------------------------------------------------ | +| **Gaming / Consumer** | `Move` | Best for complex on-chain logic and object-oriented assets. | +| **DeFi / Institutional** | `EVM` (Solidity) | Best for leveraging existing Ethereum tooling and libraries. | +| **Agents / Tooling** | `Wasm` (Rust) | Best for performance-critical logic and Rust ecosystem integration. | --- ## Step 4: Install Required Tools - **Docker Desktop must be running.** Ensure it is installed and active before running the installation command. If you don't have it, **[download Docker Desktop here](https://www.docker.com/products/docker-desktop/)**. + **Docker Desktop must be running.** Ensure it is installed and active before + running the installation command. If you don't have it, **[download Docker + Desktop here](https://www.docker.com/products/docker-desktop/)**. ### 4.1 Install the Core CLI Tools [AI Assistant] -The fastest way to install the core CLIs (`weave`, `initiad`, `jq`) is to ask your AI assistant. It will handle the environment setup for you. + +The fastest way to install the core CLIs (`weave`, `initiad`, `jq`) is to ask +your AI assistant. It will handle the environment setup for you. **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, please install the core tools for Initia development. ``` ### 4.2 Install Your Appchain VM [Terminal] -Because each Virtual Machine (`Move`, `EVM`, `Wasm`) requires building a specific `minitiad` binary from source, this step can take **5-15 minutes**. Run the commands for your chosen VM directly in your standard terminal: + +Because each Virtual Machine (`Move`, `EVM`, `Wasm`) requires building a +specific `minitiad` binary from source, this step can take **5-15 minutes**. Run +the commands for your chosen VM directly in your standard terminal: - ```bash wrap - git clone --depth 1 https://github.com/initia-labs/minimove.git - cd minimove && make install - cd .. && rm -rf minimove - ``` + ```bash wrap git clone --depth 1 https://github.com/initia-labs/minimove.git + cd minimove && make install cd .. && rm -rf minimove ``` - ```bash wrap - git clone --depth 1 https://github.com/initia-labs/minievm.git - cd minievm && make install - cd .. && rm -rf minievm - ``` + ```bash wrap git clone --depth 1 https://github.com/initia-labs/minievm.git + cd minievm && make install cd .. && rm -rf minievm ``` - ```bash wrap - git clone --depth 1 https://github.com/initia-labs/miniwasm.git - cd miniwasm && make install - cd .. && rm -rf miniwasm - ``` + ```bash wrap git clone --depth 1 https://github.com/initia-labs/miniwasm.git + cd miniwasm && make install cd .. && rm -rf miniwasm ``` ### 4.3 Verify Installation & PATH [AI Assistant] -After the build completes, your AI assistant can ensure the tools are accessible from anywhere in your system. This is especially helpful if you aren't sure how to configure your `PATH` for your specific shell (Zsh, Bash, etc.). + +After the build completes, your AI assistant can ensure the tools are accessible +from anywhere in your system. This is especially helpful if you aren't sure how +to configure your `PATH` for your specific shell (Zsh, Bash, etc.). **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, please verify that `minitiad` is properly installed and accessible. If it isn't in my PATH, help me add the Go binary directory to my shell configuration. ``` @@ -107,7 +119,9 @@ Using the `initia-appchain-dev` skill, please verify that `minitiad` is properly ## Step 5: Initial Setup with `weave init` [Terminal] -Your AI assistant is your partner in this hackathon, but the `weave` CLI requires an initial interactive setup to prepare your environment and launch your first appchain. This is a one-time process. +Your AI assistant is your partner in this hackathon, but the `weave` CLI +requires an initial interactive setup to prepare your environment and launch +your first appchain. This is a one-time process. **Run the following command in your terminal:** @@ -147,6 +161,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Type `continue` and press Enter. + @@ -207,6 +222,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Press `Tab` for default (`operator`). + @@ -245,6 +261,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select `Enable`. + @@ -301,6 +318,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select `No`. + @@ -323,6 +341,7 @@ Here's a guide on how to navigate the interactive setup: Type `y` and press Enter. Your appchain will now launch and start producing blocks! + @@ -330,21 +349,27 @@ Your appchain will now launch and start producing blocks! ## Step 6: Setup Interwoven Bots [Terminal] -To enable the Optimistic bridge and cross-chain communication (IBC) between Initia L1 and your appchain, you need to start the **OPinit Executor** and the **IBC Relayer**. These bots handle the "interweaving" of your chain. +To enable the Optimistic bridge and cross-chain communication (IBC) between +Initia L1 and your appchain, you need to start the **OPinit Executor** and the +**IBC Relayer**. These bots handle the "interweaving" of your chain. - **Prerequisite:** Your appchain must be running in another terminal (via `weave init` or `weave start`) before configuring these bots. + **Prerequisite:** Your appchain must be running in another terminal (via + `weave init` or `weave start`) before configuring these bots. ### 6.1 Start the OPinit Executor + The executor handles the submission of rollup data and bridge operations. **Run the following command:** + ```bash wrap weave opinit init executor ``` Follow the interactive guide: + **Prompt:** @@ -352,8 +377,9 @@ Follow the interactive guide: ? Existing keys in config.json detected. Would you like to add these to the keyring before proceeding? ``` - **Action:** + **Action:** Select `Yes, use detected keys`. + **Prompt:** @@ -361,8 +387,9 @@ Follow the interactive guide: ? Please select an option for the system key for Oracle Bridge Executor ``` - **Action:** + **Action:** Select `Generate new system key`. + **Prompt:** @@ -370,8 +397,9 @@ Follow the interactive guide: ? Existing config.json detected. Would you like to use the data in this file to pre-fill some fields? ``` - **Action:** + **Action:** Select `Yes, prefill`. + **Prompt:** @@ -379,8 +407,9 @@ Follow the interactive guide: ? Specify listen address of the bot ``` - **Action:** + **Action:** Press `Tab` to use `localhost:3000` (ensure nothing else is running on this port). + **Action:** @@ -395,18 +424,20 @@ Follow the interactive guide: ### 6.2 Start the IBC Relayer -The relayer enables asset transfers (like INIT) between the L1 and your appchain. - - **Docker Desktop** must be running to launch the relayer. - +The relayer enables asset transfers (like INIT) between the L1 and your +appchain. + +**Docker Desktop** must be running to launch the relayer. **Run the following command:** + ```bash wrap weave relayer init ``` Follow the interactive guide: + **Prompt:** @@ -414,8 +445,9 @@ Follow the interactive guide: ? Select the type of Interwoven rollup you want to relay ``` - **Action:** + **Action:** Select `Local Rollup (your-chain-id)`. + **Action:** @@ -427,8 +459,9 @@ Follow the interactive guide: ? Select method to setup IBC channels for the relayer ``` - **Action:** + **Action:** Select `Subscribe to only transfer and nft-transfer IBC Channels (minimal setup)`. + **Prompt:** @@ -436,8 +469,9 @@ Follow the interactive guide: ? Select the IBC channels you would like to relay ``` - **Action:** + **Action:** Press `Space` to select all (transfer and nft-transfer), then press `Enter`. + **Prompt:** @@ -445,8 +479,9 @@ Follow the interactive guide: ? Do you want to setup relayer with the challenger key ``` - **Action:** + **Action:** Select `Yes (recommended)`. + Start the relayer process: @@ -457,6 +492,7 @@ Follow the interactive guide: You can view relayer logs at any time by running `weave relayer log` in your terminal. + @@ -464,9 +500,13 @@ Follow the interactive guide: ## Step 7: Final Key Setup [Terminal] -💡 **Why:** The **Gas Station** account acts as your **Universal Developer Key**. Importing it allows you to sign transactions manually via the CLI, and it enables your AI co-pilot to deploy contracts and interact with your appchain. +💡 **Why:** The **Gas Station** account acts as your **Universal Developer +Key**. Importing it allows you to sign transactions manually via the CLI, and it +enables your AI co-pilot to deploy contracts and interact with your appchain. + +**Action:** Run these commands to import your account into both the L1 +(`initiad`) and L2 (`minitiad`) keychains: -**Action:** Run these commands to import your account into both the L1 (`initiad`) and L2 (`minitiad`) keychains: ```bash wrap # Extract your mnemonic from the weave config MNEMONIC=$(jq -r '.common.gas_station.mnemonic' ~/.weave/config.json) @@ -478,7 +518,9 @@ initiad keys add gas-station --recover --keyring-backend test --coin-type 60 --k minitiad keys add gas-station --recover --keyring-backend test --coin-type 60 --key-type eth_secp256k1 --source <(echo -n "$MNEMONIC") ``` -**Action:** Verify the import by listing your keys to ensure `gas-station` appears in both: +**Action:** Verify the import by listing your keys to ensure `gas-station` +appears in both: + ```bash wrap # Verify L1 keys initiad keys list --keyring-backend test @@ -494,6 +536,7 @@ minitiad keys list --keyring-backend test After completing the infrastructure setup, verify that everything is healthy. **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, please verify that my appchain is running and that my Gas Station account has a balance. ``` @@ -502,13 +545,16 @@ Using the `initia-appchain-dev` skill, please verify that my appchain is running ## Step 9: Funding Your Personal Wallet [AI Assistant] -To interact with your appchain using a browser wallet (like **Keplr** or **Leap**), you'll need to send tokens from your **gas station** to your personal address. +To interact with your appchain using a browser wallet (like **Keplr** or +**Leap**), you'll need to send tokens from your **gas station** to your personal +address. **1. Copy your personal address from your wallet.** **2. Ask your assistant to fund you:** **Prompt:** + ```terminal wrap Using the `initia-appchain-dev` skill, please fund my personal wallet with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` @@ -517,13 +563,17 @@ Using the `initia-appchain-dev` skill, please fund my personal wallet Date: Mon, 16 Feb 2026 15:05:32 +0700 Subject: [PATCH 03/17] fix: formatting error --- home/tools/wallet.mdx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/home/tools/wallet.mdx b/home/tools/wallet.mdx index e9d5263..53e0a57 100644 --- a/home/tools/wallet.mdx +++ b/home/tools/wallet.mdx @@ -3,13 +3,11 @@ title: Initia Wallet icon: wallet --- -One of the barriers for users to onboard into a new ecosystem has always been -the need to download, install, and use a new wallet. The Initia Wallet solves -this by allowing users to connect and use their existing EVM-compatible wallets -to interact with applications on Initia and all Interwoven Rollups, regardless -of the VM or smart contract language they use. +One major barrier for users onboarding into a new ecosystem has always been the +need to download and install a new wallet. With the Initia Wallet, users can +sign in to any application using their existing EVM-compatible wallet, +regardless of the VM or smart contract language the application uses. -- For users, they just need to click "Connect Wallet" and then select their - preferred wallet, just like they do on any other chain or application -- For developers, the Wallet is a simple and lightweight library that can be - easily integrated into any application. +For those without an existing wallet, the Initia Wallet also allows users to +create a new account using their email address or social media accounts (Google +or X), powered by [Privy](https://privy.io/). From 33e10b26a7e4a3962fe1c5ff013dc5fdcba5e9e5 Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Mon, 16 Feb 2026 15:18:26 +0700 Subject: [PATCH 04/17] fix: formatting error --- .prettierignore | 1 + hackathon/hackathon-landing.mdx | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.prettierignore b/.prettierignore index 7085120..b985c21 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,4 @@ developers/developer-guides/vm-specific-tutorials/movevm/building-move-modules.m developers/developer-guides/vm-specific-tutorials/movevm/setting-up.mdx developers/developer-guides/vm-specific-tutorials/movevm/your-first-module.mdx developers/developer-guides/integrating-initia-apps/initiadex.mdx +hackathon/hackathon-landing.mdx diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index b44191e..0a602b7 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -90,16 +90,22 @@ the commands for your chosen VM directly in your standard terminal: - ```bash wrap git clone --depth 1 https://github.com/initia-labs/minimove.git - cd minimove && make install cd .. && rm -rf minimove ``` + ```bash wrap + git clone --depth 1 https://github.com/initia-labs/minimove.git + cd minimove && make install cd .. && rm -rf minimove + ``` - ```bash wrap git clone --depth 1 https://github.com/initia-labs/minievm.git - cd minievm && make install cd .. && rm -rf minievm ``` + ```bash wrap + git clone --depth 1 https://github.com/initia-labs/minievm.git + cd minievm && make install cd .. && rm -rf minievm + ``` - ```bash wrap git clone --depth 1 https://github.com/initia-labs/miniwasm.git - cd miniwasm && make install cd .. && rm -rf miniwasm ``` + ```bash wrap + git clone --depth 1 https://github.com/initia-labs/miniwasm.git + cd miniwasm && make install cd .. && rm -rf miniwasm + ``` From acc5286783217acbac1908ea9c16614aa18f52a7 Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Mon, 16 Feb 2026 16:35:02 +0700 Subject: [PATCH 05/17] docs: extra example tutorials and project inspiration section --- docs.json | 9 +- hackathon/builder-guide.mdx | 37 +++- hackathon/examples/evm-bank.mdx | 184 ++++++++++++++++++ .../move-game.mdx} | 20 +- hackathon/examples/wasm-social.mdx | 181 +++++++++++++++++ hackathon/hackathon-landing.mdx | 33 +++- 6 files changed, 442 insertions(+), 22 deletions(-) create mode 100644 hackathon/examples/evm-bank.mdx rename hackathon/{example-appchain-tutorial.mdx => examples/move-game.mdx} (94%) create mode 100644 hackathon/examples/wasm-social.mdx diff --git a/docs.json b/docs.json index 5cd1072..d2770fa 100644 --- a/docs.json +++ b/docs.json @@ -546,9 +546,16 @@ "pages": [ "hackathon/hackathon-landing", "hackathon/builder-guide", - "hackathon/example-appchain-tutorial", "hackathon/submission-requirements" ] + }, + { + "group": "Examples", + "pages": [ + "hackathon/examples/move-game", + "hackathon/examples/evm-bank", + "hackathon/examples/wasm-social" + ] } ] } diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index 1a888f1..0e699e9 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -85,9 +85,42 @@ Master the **Describe → Build → Test** cycle. This is how you win the hackat user interacting with it. Save these as soon as you have a working version! +# Part 2: Project Inspiration + +Not sure where to start? Map your vision to the Initia stack. Here are three +high-value paths that leverage the unique Interwoven capabilities of your +appchain: + +### 🎮 High-Speed Gaming (Move/EVM) + +- **The Idea**: A fast-paced survival or strategy game where every action + (crafting, moving, attacking) is recorded on-chain. +- **Key Integration**: Use Auto-signing so players never see a wallet popup + during gameplay. +- **The Goal**: A Web2-feeling experience where the blockchain handles the logic + silently in the background. + +### 📈 Data-Rich DeFi (EVM/Wasm) + +- **The Idea**: A localized lending market or an automated trading bot + specifically for your rollup's native tokens. +- **Key Integration**: Use the Connect Oracle for real-time price feeds and the + Built-in Indexer to build a Leaderboard or Analytics Dashboard for your users. +- **The Goal**: A deep, transparent financial primitive that provides + professional-grade data to retail users. + +### 👤 Social & Consumer (Move) + +- **The Idea**: A decentralized achievement system or a social tipping platform + for creators. +- **Key Integration**: Integrate Initia Usernames to let people send assets + or rewards to name.init instead of long hex addresses. +- **The Goal**: A user-friendly application that prioritizes onboarding and + human-readable identities. + --- -# Part 2: Power-Up with Native Features +# Part 3: Power-Up with Native Features To qualify for the prize pool, you must implement at least **one** of these. @@ -123,7 +156,7 @@ Using the `initia-appchain-dev` skill, modify my InterwovenKit frontend to enabl --- -# Part 3: Making It Demo-Ready +# Part 4: Making It Demo-Ready Judges want to see **On-chain Proof**. Use this checklist before submitting. diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx new file mode 100644 index 0000000..4697a1d --- /dev/null +++ b/hackathon/examples/evm-bank.mdx @@ -0,0 +1,184 @@ +--- +title: 'EVM Tutorial: MiniBank' +--- + +**Prerequisite:** Before starting this tutorial, you should have completed the **[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have an EVM-compatible appchain running locally. + +--- + +This tutorial will guide you through building a simple digital Piggy Bank on your EVM appchain. Users can deposit tokens, withdraw them, and check their savings balance. + +By the end of this tutorial, you will have: +- Generated and published a Solidity smart contract for the bank logic. +- Scaffolded and connected a React frontend. +- Tested the bank's functionality. + +--- + +## Step 1: Create the Bank's Smart Contract + +Instruct your AI assistant to create the Solidity contract using the `initia-appchain-dev` skill. + +**Example Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please create a Solidity smart contract for our MiniBank. The contract should: +- Allow users to deposit native tokens. +- Allow users to withdraw their own deposited tokens. +- Keep track of each user's total savings. +- Include a function to view the caller's current balance. +``` + + +If you prefer to create the contract manually, here is the Solidity code your assistant would generate. + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract MiniBank { + mapping(address => uint256) private balances; + + event Deposit(address indexed user, uint256 amount); + event Withdrawal(address indexed user, uint256 amount); + + function deposit() public payable { + require(msg.value > 0, "Cannot deposit 0"); + balances[msg.sender] += msg.value; + emit Deposit(msg.sender, msg.value); + } + + function withdraw(uint256 amount) public { + require(balances[msg.sender] >= amount, "Insufficient balance"); + balances[msg.sender] -= amount; + payable(msg.sender).transfer(amount); + emit Withdrawal(msg.sender, amount); + } + + function getBalance(address user) public view returns (uint256) { + return balances[user]; + } +} +``` + + +--- + +## Step 2: Build and Play the Bank + +Now, build and publish the contract to your appchain using the gas station account. + +**1. Build and Publish:** +```terminal wrap +Using the `initia-appchain-dev` skill, please build and publish the MiniBank Solidity contract to my appchain using my gas station account. +``` + +**2. Interact with the Bank:** +```terminal wrap +Using my gas station account on my appchain, please do the following: +1. Deposit 5 tokens. +2. Check my balance. +3. Withdraw 2 tokens. +4. Check my balance again. +``` + + +Here are the equivalent `minitiad` commands to manage your Solidity contract. + +**1. Build and Publish:** +```bash wrap +# Replace `your-chain-id` with your appchain ID +minitiad evm deploy \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --path ./MiniBank.sol \ + --gas auto --gas-adjustment 1.4 --yes +``` + +**2. Interact (Deposit):** +```bash wrap +minitiad tx evm call "deposit()" \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --value 5000000 \ + --gas auto --gas-adjustment 1.4 --yes +``` + + +--- + +## Step 3: Fund your Browser Wallet + +Before using the frontend, ensure your personal wallet has tokens. + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +``` + +--- + +## Step 4: Create a Frontend + +Let's create a simple UI to interact with our bank. + +**1. Scaffold the Frontend:** +```terminal wrap +Using the `initia-appchain-dev` skill, please scaffold a React application for our MiniBank using Vite. Create a component named Bank.jsx with Deposit and Withdraw buttons and an input field for the amount. +``` + +**2. Connect to Appchain:** +```terminal wrap +Using the `initia-appchain-dev` skill, modify Bank.jsx to connect to our MiniBank contract on my appchain. Use the @initia/interwovenkit-react for wallet connection and transaction signing. +``` + + +When using Interwoven Kit with EVM, you use standard Ethereum providers or the Initia `MsgExecute` for EVM. + +**Example snippet for an EVM call:** +```javascript wrap +const messages = [ + { + typeUrl: "/initia.evm.v1.MsgExecute", + value: MsgExecute.fromPartial({ + sender: initiaAddress, + contractAddress: CONTRACT_ADDRESS, + data: encodedData, // ABI encoded function call + value: "1000000", + }), + }, +]; +``` + + +--- + +## Step 5: Testing + +Verify that the logic is working as expected. + +**Example Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, I want to verify our MiniBank contract. Please: +1. Inspect the MiniBank contract to find the function signatures. +2. Generate a test script that deposits 10 tokens, withdraws 5, and verifies the final balance is 5. +3. Run the script and show me the output. +``` + + +```bash wrap +#!/bin/bash +# 1. Deposit +minitiad tx evm call $ADDR "deposit()" --from gas-station --value 10 --yes +# 2. Withdraw +minitiad tx evm call $ADDR "withdraw(uint256)" --args "[5]" --from gas-station --yes +# 3. Query Balance +minitiad query evm call $ADDR "getBalance(address)" --args "[\"$SENDER\"]" +``` + + +--- + +## Conclusion +You've successfully built an EVM-powered digital bank! This demonstrates how easily you can deploy standard Solidity logic onto an Initia appchain while leveraging Interwoven features for a seamless user experience. diff --git a/hackathon/example-appchain-tutorial.mdx b/hackathon/examples/move-game.mdx similarity index 94% rename from hackathon/example-appchain-tutorial.mdx rename to hackathon/examples/move-game.mdx index da78949..67e47e2 100644 --- a/hackathon/example-appchain-tutorial.mdx +++ b/hackathon/examples/move-game.mdx @@ -1,5 +1,5 @@ --- -title: 'Example Tutorial: BlockForge Game' +title: 'Move Tutorial: BlockForge Game' --- **Prerequisite:** Before starting this tutorial, you should have completed the @@ -29,10 +29,10 @@ appchain. **Example Prompt:** -``` -Using the `initia-appchain-dev` skill, please create a Move module for our BlockForge game. The module should be named `items` inside a `blockforge` project. The game has the following rules: -- Players can mint basic items called "Shards". -- Players can craft "Relics" by burning 2 "Shards". +```terminal wrap +Using the `initia-appchain-dev` skill, please create a Move module for our BlockForge game. The module should be named items inside a blockforge project. The game has the following rules: +- Players can mint basic items called shards. +- Players can craft relics by burning 2 shards. - Players should have an inventory to store their items. - I need a way to view a player's inventory. ``` @@ -303,16 +303,16 @@ skill. **1. Scaffold the Frontend:** -``` -Using the `initia-appchain-dev` skill, please scaffold a new React application for our BlockForge game using Vite. Then, create a simple component named `Game.jsx`. This component should have two buttons: "Mint Shard" and "Craft Relic". For now, make the buttons log a message to the console when clicked. Finally, add the `Game` component to the main `App.jsx` file. +```terminal wrap +Using the `initia-appchain-dev` skill, please scaffold a new React application for our BlockForge game using Vite. Then, create a simple component named Game.jsx. This component should have two buttons: Mint Shard and Craft Relic. For now, make the buttons log a message to the console when clicked. Finally, add the Game component to the main App.jsx file. ``` **2. Connect the Frontend to the Appchain:** -``` -Now, using the `initia-appchain-dev`, please modify the `Game.jsx` component to interact with our deployed "blockforge" smart contract on my appchain. +```terminal wrap +Now, using the `initia-appchain-dev`, please modify the Game.jsx component to interact with our deployed blockforge smart contract on my appchain. -The "Mint Shard" button should call the `mint_shard` function, and the "Craft Relic" button should call the `craft_relic` function. Also, please display the player's current inventory of shards and relics. Finally, add a button to enable/disable the native auto-signing feature for a smoother game experience. +The Mint Shard button should call the mint_shard function, and the Craft Relic button should call the craft_relic function. Also, please display the player's current inventory of shards and relics. Finally, add a button to enable/disable the native auto-signing feature for a smoother game experience. ``` Your assistant will use the `@initia/interwoven-kit` to connect your new diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx new file mode 100644 index 0000000..eb0a2de --- /dev/null +++ b/hackathon/examples/wasm-social.mdx @@ -0,0 +1,181 @@ +--- +title: 'Wasm Tutorial: MemoBoard' +--- + +**Prerequisite:** Before starting this tutorial, you should have completed the **[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have a Wasm-compatible appchain running locally. + +--- + +This tutorial will guide you through building a lightning-fast on-chain guestbook called **MemoBoard**. Users can post short public messages (memos), and anyone can read the board. + +By the end of this tutorial, you will have: +- Generated and published a Rust smart contract for the guestbook. +- Scaffolded and connected a React frontend. +- Tested the messaging functionality. + +--- + +## Step 1: Create the Board's Smart Contract + +Instruct your AI assistant to create the Rust (Wasm) contract using the `initia-appchain-dev` skill. + +**Example Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please create a Rust smart contract for our MemoBoard. The contract should: +- Allow users to post a message (string). +- Store a list of all messages with the sender's address. +- Include a function to query all messages on the board. +``` + + +If you prefer to see the Rust logic, here is a simplified version of what your assistant would generate using the standard Wasm contract patterns. + +```rust +use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdResult}; +use cw_storage_plus::Item; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct Memo { + pub sender: String, + pub content: String, +} + +pub const BOARD: Item> = Item::new("board"); + +#[entry_point] +pub fn instantiate(_deps: DepsMut, _env: Env, _info: MessageInfo, _msg: InstantiateMsg) -> StdResult { + BOARD.save(_deps.storage, &vec![])?; + Ok(Response::default()) +} + +#[entry_point] +pub fn execute(deps: DepsMut, _env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { + match msg { + ExecuteMsg::PostMemo { content } => { + let mut board = BOARD.load(deps.storage)?; + board.push(Memo { sender: info.sender.to_string(), content }); + BOARD.save(deps.storage, &board)?; + Ok(Response::new().add_attribute("action", "post_memo")) + } + } +} +``` + + +--- + +## Step 2: Build and Play with the Board + +Now, build and publish the contract to your appchain using the gas station account. + +**1. Build and Publish:** +```terminal wrap +Using the `initia-appchain-dev` skill, please build and publish the MemoBoard Rust contract to my appchain using my gas station account. +``` + +**2. Interact with the Board:** +```terminal wrap +Using my gas station account on my appchain, please do the following: +1. Post a memo: "Hello from Initia!" +2. Query the board to see all messages. +``` + + +Here are the equivalent `minitiad` commands to manage your Rust (Wasm) contract. + +**1. Build and Publish:** +```bash wrap +# Replace `your-chain-id` with your appchain ID +minitiad wasm deploy \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --path ./target/wasm32-unknown-unknown/release/memoboard.wasm \ + --gas auto --gas-adjustment 1.4 --yes +``` + +**2. Interact (Post Memo):** +```bash wrap +minitiad tx wasm execute '{"post_memo":{"content":"Hello!"}}' \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --gas auto --gas-adjustment 1.4 --yes +``` + + +--- + +## Step 3: Fund your Browser Wallet + +Ensure your personal wallet has tokens to pay for the transaction to post a memo. + +**Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +``` + +--- + +## Step 4: Create a Frontend + +Let's create a UI to display and post messages. + +**1. Scaffold the Frontend:** +```terminal wrap +Using the `initia-appchain-dev` skill, please scaffold a React application for our MemoBoard using Vite. Create a component named Board.jsx that displays a list of messages and a text input to post a new one. +``` + +**2. Connect to Appchain:** +```terminal wrap +Using the `initia-appchain-dev` skill, modify Board.jsx to connect to our MemoBoard contract on my appchain. Use the @initia/interwovenkit-react for wallet connection and transaction signing. +``` + + +For Wasm contracts, you use the `MsgExecute` message from the Wasm module. + +**Example snippet:** +```javascript wrap +const messages = [ + { + typeUrl: "/initia.wasm.v1.MsgExecute", + value: MsgExecute.fromPartial({ + sender: initiaAddress, + contractAddress: CONTRACT_ADDRESS, + msg: Buffer.from(JSON.stringify({ post_memo: { content: "Hello!" } })), + funds: [], + }), + }, +]; +``` + + +--- + +## Step 5: Testing + +Verify that your messages are being recorded on-chain. + +**Example Prompt:** +```terminal wrap +Using the `initia-appchain-dev` skill, I want to verify our MemoBoard contract. Please: +1. Inspect the MemoBoard contract to find the execution entry points. +2. Generate a test script that posts 3 different messages from the gas station account. +3. Query the contract state to prove all 3 messages are stored correctly. +``` + + +```bash wrap +#!/bin/bash +# 1. Post Memo +minitiad tx wasm execute $ADDR '{"post_memo":{"content":"Message 1"}}' --from gas-station --yes +# 2. Query Board +minitiad query wasm contract-state smart $ADDR '{"get_messages":{}}' +``` + + +--- + +## Conclusion +You've built an on-chain guestbook using Rust and Wasm! This tutorial highlights the performance and flexibility of using Wasm for social and data-driven applications on Initia. diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index 0a602b7..3b257f0 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -92,19 +92,19 @@ the commands for your chosen VM directly in your standard terminal: ```bash wrap git clone --depth 1 https://github.com/initia-labs/minimove.git - cd minimove && make install cd .. && rm -rf minimove + cd minimove && make install && cd .. && rm -rf minimove ``` ```bash wrap git clone --depth 1 https://github.com/initia-labs/minievm.git - cd minievm && make install cd .. && rm -rf minievm + cd minievm && make install && cd .. && rm -rf minievm ``` ```bash wrap git clone --depth 1 https://github.com/initia-labs/miniwasm.git - cd miniwasm && make install cd .. && rm -rf miniwasm + cd miniwasm && make install && cd .. && rm -rf miniwasm ``` @@ -559,10 +559,12 @@ address. **2. Ask your assistant to fund you:** +Replace `` in the prompt below with the address you just copied from your browser wallet. + **Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please fund my personal wallet with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +Using the `initia-appchain-dev` skill, please fund my personal wallet with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` --- @@ -576,16 +578,29 @@ blockchain. Now that you have the basics down, you can dive into a full example or start building your own idea. -### Option 1: Follow the BlockForge Example +### Option 1: Explore an Example Tutorial + + + +Pick a tutorial based on your preferred Virtual Machine (VM) and use case: + + + +* **[BlockForge Game (Move)](./examples/move-game)**: Build a simple crafting game using Move's resource safety. + +* **[MiniBank (EVM)](./examples/evm-bank)**: Create a digital piggy bank using standard Solidity. + +* **[MemoBoard (Wasm)](./examples/wasm-social)**: Build an on-chain guestbook using high-performance Rust. -See a complete working example of a game economy with a smart contract and -frontend. -**[→ Go to BlockForge Example](./example-appchain-tutorial)** ### Option 2: Build Your Own Idea -Jump straight into building your hackathon project. + + +Jump straight into building your unique hackathon project. + + **[→ Go to Builder Guide](./builder-guide)** From e25ca61de08eb4c68107beb5d3e370684c6f5adf Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Mon, 16 Feb 2026 17:53:28 +0700 Subject: [PATCH 06/17] docs: combine contract creation and verification steps --- .prettierignore | 1 + hackathon/builder-guide.mdx | 4 +- hackathon/examples/evm-bank.mdx | 151 +++++----- hackathon/examples/move-game.mdx | 454 ++++------------------------- hackathon/examples/wasm-social.mdx | 131 +++++---- 5 files changed, 192 insertions(+), 549 deletions(-) diff --git a/.prettierignore b/.prettierignore index b985c21..e7d6834 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,3 +3,4 @@ developers/developer-guides/vm-specific-tutorials/movevm/setting-up.mdx developers/developer-guides/vm-specific-tutorials/movevm/your-first-module.mdx developers/developer-guides/integrating-initia-apps/initiadex.mdx hackathon/hackathon-landing.mdx +hackathon/examples/evm-bank.mdx diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index 0e699e9..c4a07c9 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -113,8 +113,8 @@ appchain: - **The Idea**: A decentralized achievement system or a social tipping platform for creators. -- **Key Integration**: Integrate Initia Usernames to let people send assets - or rewards to name.init instead of long hex addresses. +- **Key Integration**: Integrate Initia Usernames to let people send assets or + rewards to name.init instead of long hex addresses. - **The Goal**: A user-friendly application that prioritizes onboarding and human-readable identities. diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx index 4697a1d..e2349ed 100644 --- a/hackathon/examples/evm-bank.mdx +++ b/hackathon/examples/evm-bank.mdx @@ -2,36 +2,49 @@ title: 'EVM Tutorial: MiniBank' --- -**Prerequisite:** Before starting this tutorial, you should have completed the **[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have an EVM-compatible appchain running locally. +**Prerequisite:** Before starting this tutorial, you should have completed the +**[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have +an EVM-compatible appchain running locally. --- -This tutorial will guide you through building a simple digital Piggy Bank on your EVM appchain. Users can deposit tokens, withdraw them, and check their savings balance. +This tutorial will guide you through building a simple digital piggy bank on +your EVM appchain. Users can deposit tokens, withdraw them, and check their +savings balance. By the end of this tutorial, you will have: -- Generated and published a Solidity smart contract for the bank logic. + +- Generated and verified a Solidity smart contract for the bank logic. +- Deployed the contract to your live appchain. - Scaffolded and connected a React frontend. -- Tested the bank's functionality. +- Verified the on-chain functionality. --- -## Step 1: Create the Bank's Smart Contract +## Step 1: Create and Verify the Smart Contract -Instruct your AI assistant to create the Solidity contract using the `initia-appchain-dev` skill. +Instruct your AI assistant to create the Solidity contract using the +`initia-appchain-dev` skill. Your assistant will generate the contract and +automatically run unit tests to ensure the logic is sound. **Example Prompt:** + ```terminal wrap -Using the `initia-appchain-dev` skill, please create a Solidity smart contract for our MiniBank. The contract should: +Using the `initia-appchain-dev` skill, please create a Solidity smart contract for our MiniBank in my current directory. The contract should: - Allow users to deposit native tokens. - Allow users to withdraw their own deposited tokens. - Keep track of each user's total savings. - Include a function to view the caller's current balance. +Please also create and run a unit test to verify these features. ``` +Your assistant will generate the `minibank` project and confirm that the tests +(likely using Foundry or Hardhat) pass successfully. + -If you prefer to create the contract manually, here is the Solidity code your assistant would generate. +If you prefer to create the contract manually, here is the Solidity code your assistant would generate. Save this as MiniBank.sol in your current directory. -```solidity +```solidity wrap // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -54,67 +67,45 @@ contract MiniBank { emit Withdrawal(msg.sender, amount); } - function getBalance(address user) public view returns (uint256) { - return balances[user]; + function getBalance() public view returns (uint256) { + return balances[msg.sender]; } } ``` + --- -## Step 2: Build and Play the Bank +## Step 2: Deploy to your Appchain -Now, build and publish the contract to your appchain using the gas station account. +Now that the logic is verified, build and publish the contract to your live +appchain using the gas station account. -**1. Build and Publish:** -```terminal wrap -Using the `initia-appchain-dev` skill, please build and publish the MiniBank Solidity contract to my appchain using my gas station account. -``` +**Prompt:** -**2. Interact with the Bank:** ```terminal wrap -Using my gas station account on my appchain, please do the following: -1. Deposit 5 tokens. -2. Check my balance. -3. Withdraw 2 tokens. -4. Check my balance again. +Using the `initia-appchain-dev` skill, please build and publish the MiniBank Solidity contract located in my current directory to my appchain using my gas station account. ``` - -Here are the equivalent `minitiad` commands to manage your Solidity contract. - -**1. Build and Publish:** -```bash wrap -# Replace `your-chain-id` with your appchain ID -minitiad evm deploy \ - --from gas-station \ - --keyring-backend test \ - --chain-id your-chain-id \ - --path ./MiniBank.sol \ - --gas auto --gas-adjustment 1.4 --yes -``` - -**2. Interact (Deposit):** -```bash wrap -minitiad tx evm call "deposit()" \ - --from gas-station \ - --keyring-backend test \ - --chain-id your-chain-id \ - --value 5000000 \ - --gas auto --gas-adjustment 1.4 --yes -``` + + ```bash wrap + # Replace `your-chain-id` with your appchain ID minitiad evm + deploy \ --from gas-station \ --keyring-backend test \ --chain-id + your-chain-id \ --path ./MiniBank.sol \ --gas auto --gas-adjustment 1.4 --yes + ``` --- ## Step 3: Fund your Browser Wallet -Before using the frontend, ensure your personal wallet has tokens. +Ensure your personal wallet has tokens to interact with the bank. **Prompt:** + ```terminal wrap -Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` --- @@ -124,61 +115,51 @@ Using the `initia-appchain-dev` skill, please fund my wallet address -When using Interwoven Kit with EVM, you use standard Ethereum providers or the Initia `MsgExecute` for EVM. - -**Example snippet for an EVM call:** -```javascript wrap -const messages = [ - { - typeUrl: "/initia.evm.v1.MsgExecute", - value: MsgExecute.fromPartial({ - sender: initiaAddress, - contractAddress: CONTRACT_ADDRESS, - data: encodedData, // ABI encoded function call - value: "1000000", - }), - }, -]; +```terminal wrap +Using the `initia-appchain-dev` skill, modify the Bank.jsx component in my current directory to connect to our MiniBank contract on my appchain. Use the @initia/interwovenkit-react for wallet connection and transaction signing. ``` - --- -## Step 5: Testing +## Step 5: On-Chain Verification -Verify that the logic is working as expected. +Finally, ask your AI assistant to interact with your **live** appchain to prove +the deployed contract works as expected. **Example Prompt:** + ```terminal wrap -Using the `initia-appchain-dev` skill, I want to verify our MiniBank contract. Please: -1. Inspect the MiniBank contract to find the function signatures. -2. Generate a test script that deposits 10 tokens, withdraws 5, and verifies the final balance is 5. -3. Run the script and show me the output. +Using the `initia-appchain-dev` skill, I want to verify our live MiniBank contract. Using my gas station account on my appchain, please: +1. Deposit 5 tokens. +2. Check my balance. +3. Withdraw 2 tokens. +4. Check my balance again. ``` - + +**Interact (Deposit):** ```bash wrap -#!/bin/bash -# 1. Deposit -minitiad tx evm call $ADDR "deposit()" --from gas-station --value 10 --yes -# 2. Withdraw -minitiad tx evm call $ADDR "withdraw(uint256)" --args "[5]" --from gas-station --yes -# 3. Query Balance -minitiad query evm call $ADDR "getBalance(address)" --args "[\"$SENDER\"]" +minitiad tx evm call "deposit()" \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --value 5000000 \ + --gas auto --gas-adjustment 1.4 --yes ``` --- -## Conclusion -You've successfully built an EVM-powered digital bank! This demonstrates how easily you can deploy standard Solidity logic onto an Initia appchain while leveraging Interwoven features for a seamless user experience. +## Next Steps + +Now that you've mastered an EVM application, you're ready to build your own +idea! + +**[→ Go to Builder Guide](../builder-guide)** diff --git a/hackathon/examples/move-game.mdx b/hackathon/examples/move-game.mdx index 67e47e2..a42ad6c 100644 --- a/hackathon/examples/move-game.mdx +++ b/hackathon/examples/move-game.mdx @@ -3,8 +3,8 @@ title: 'Move Tutorial: BlockForge Game' --- **Prerequisite:** Before starting this tutorial, you should have completed the -**[Your First Appchain: A Step-by-Step Guide](./hackathon-landing.mdx)** and -have your own appchain running locally. +**[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have +your own appchain running locally. --- @@ -14,34 +14,35 @@ engine where players can mint and craft items. By the end of this tutorial, you will have instructed your AI assistant to: -- Generate and publish a Move smart contract for the game's logic on your - appchain. +- Generate and verify a Move smart contract for the game logic. +- Deploy the contract to your live appchain. - Scaffold and connect a React frontend for players to interact with the game. -- Test the game's functionality. +- Verify the on-chain functionality. --- -## Step 1: Create the Game's Smart Contract +## Step 1: Create and Verify the Smart Contract Instead of writing the code yourself, instruct your assistant to do it for you -using the `initia-appchain-dev` skill. We will build this on your existing -appchain. +using the `initia-appchain-dev` skill. Your assistant will generate the contract +and automatically run unit tests to ensure the logic is sound. **Example Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please create a Move module for our BlockForge game. The module should be named items inside a blockforge project. The game has the following rules: +Using the `initia-appchain-dev` skill, please create a Move module for our BlockForge game in my current directory. The module should be named items inside a blockforge project. The game has the following rules: - Players can mint basic items called shards. - Players can craft relics by burning 2 shards. - Players should have an inventory to store their items. - I need a way to view a player's inventory. +Please also create and run a unit test to verify these rules. ``` -Your assistant will now generate the necessary `Move.toml` file and the -`items.move` module with the complete game logic. +Your assistant will generate the `blockforge` project, including the +`items.move` module and a test script, and confirm that everything passes. -If you prefer to create the Move module and project manually, follow these steps. This is what your AI assistant would generate for you. +If you prefer to create the Move module and project manually, follow these steps in your current project directory. This is what your AI assistant would generate for you. First, create a new Move package named `blockforge`: @@ -62,7 +63,7 @@ cd ../.. Now, update the `Move.toml` file to use these local dependencies and enable Move 2.1 features. Replace the content of `blockforge/Move.toml` with the following: -```toml +```toml wrap [package] name = "blockforge" version = "0.0.1" @@ -78,11 +79,9 @@ std = "0x1" ``` Next, delete the default `blockforge.move` file and create a new file named -`blockforge/sources/items.move` with the following content. This module -implements the game logic for minting shards and crafting relics using standard -Move 2.1 patterns. +`blockforge/sources/items.move` with the following content. -```move +```move wrap module blockforge::items { use std::signer; @@ -94,7 +93,7 @@ module blockforge::items { relics: u64, } - /// Mint basic items called "Shards". + /// Mint basic items called shards. /// Automatically initializes inventory if it doesn't exist. public entry fun mint_shard(account: &signer) acquires Inventory { let addr = signer::address_of(account); @@ -106,7 +105,7 @@ module blockforge::items { } } - /// Craft a "Relic" by burning 2 "Shards" + /// Craft a relic by burning 2 shards public entry fun craft_relic(account: &signer) acquires Inventory { let addr = signer::address_of(account); assert!(exists(addr), E_INSUFFICIENT_SHARDS); @@ -132,8 +131,7 @@ module blockforge::items { ``` Once the files are created, you can verify everything is correct by building the -project. **Note:** You may see a warning about an "unknown field name" for -`edition`. This is normal for Move 2.1 projects and can be safely ignored. +project. ```bash wrap minitiad move build --language-version=2.1 --named-addresses blockforge=0x2 @@ -145,61 +143,24 @@ If you see `BUILDING blockforge`, then **BlockForge was built successfully! 🛠 --- -## Step 2: Build and Play the Game +## Step 2: Deploy to your Appchain -Now, let's build and publish the smart contract to your appchain, and then play -the game by interacting with it. We will use the gas station account that was -created and funded during `weave init`. +Now that the logic is verified, build and publish the contract to your live +appchain using the gas station account. -**1. Build and Publish:** +**Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please build and publish the `blockforge` Move module to my appchain using my gas station account. +Using the `initia-appchain-dev` skill, please build and publish the blockforge Move module located in my current directory to my appchain using my gas station account. ``` -**2. Play the Game:** - -```terminal wrap -Using the `initia-appchain-dev` skill and my gas station account on my appchain, please do the following: -1. Mint 3 shards. -2. Check my inventory. -3. Craft a relic. -4. Check my inventory again. -``` - -Your assistant will execute the transactions and show you the results. You've -just built and played an on-chain game! - - - -Here are the equivalent `minitiad` commands to build the module, publish it, and -interact with it on your appchain. - -**1. Build and Publish:** - -Before publishing, you must ensure the address in the compiled module matches -your signing account's hex address. The easiest way to do this without manually -editing `Move.toml` is to use the `--named-addresses` flag. - - - **Find your Chain ID:** If you aren't sure what your appchain's ID is, run - `minitiad status | jq .node_info.network`. - - + First, get your gas station's hex address: ```bash wrap -# Get the hex address minitiad keys show gas-station -a --keyring-backend test | xargs minitiad keys parse ``` - - **Compatibility Error:** If you see `BACKWARD_INCOMPATIBLE_MODULE_UPDATE`, it - means you've already deployed a different version of this module to the same - account. In this case, either create a new account or revert your changes to - be compatible. - - Then, build and publish the compiled module to your appchain, substituting `0xYOUR_HEX_ADDRESS` with the value from the previous step: @@ -216,57 +177,6 @@ minitiad move deploy \ --build --force ``` -**2. Play the Game (Interact with the Contract):** - -Now, let's call the functions on the published module. - -**Mint 3 shards:** - -```bash wrap -# Note: Since mint_shard is now 1 at a time, we run it 3 times or use a loop -for i in {1..3}; do - minitiad tx move execute items mint_shard \ - --from gas-station \ - --keyring-backend test \ - --chain-id your-chain-id \ - --gas auto --gas-adjustment 1.4 --yes - sleep 2 -done -``` - -**Check your inventory (View function):** You can use a `query` command to call -the `view_inventory` function. Remember to prefix the address argument with -`address:`. - -```bash wrap -# Get your account address -GAS_STATION_ADDRESS=$(minitiad keys show gas-station -a --keyring-backend test) - -minitiad query move view items view_inventory \ - --args "[\"address:${GAS_STATION_ADDRESS}\"]" -``` - -**Craft a relic:** This requires burning 2 shards. - -```bash wrap -minitiad tx move execute items craft_relic \ - --from gas-station \ - --keyring-backend test \ - --chain-id your-chain-id \ - --gas auto --gas-adjustment 1.4 --yes -``` - -**Check your inventory again:** Run the same query command as before to see the -updated inventory. - -```bash wrap -minitiad query move view items get_inventory \ - --args "[\"address:${GAS_STATION_ADDRESS}\"]" -``` - -These commands allow you to build and interact with your smart contract -directly, giving you a deeper understanding of the development process. - --- @@ -274,15 +184,13 @@ directly, giving you a deeper understanding of the development process. ## Step 3: Fund your Browser Wallet Before you can interact with the game through a frontend, your browser wallet -(like **Keplr** or **Leap**) needs tokens to pay for transaction fees. Since we -only funded the **gas station** during genesis, we need to send some tokens from -the gas station to your personal address. +needs tokens to pay for transaction fees. **1. Get your Wallet Address:** Open your browser wallet and copy your address (it starts with `init1...`). -**2. Send Tokens from Gas Station:** The easiest way is to ask your assistant to -fund you on both layers! +**2. Send Tokens from Gas Station:** Replace `` in the prompt +below with the address you just copied. **Prompt:** @@ -290,10 +198,6 @@ fund you on both layers! Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` -Your assistant will use the gas station account to send both L1 tokens (INIT) -and your rollup's native tokens. Once the transactions are confirmed, you're -ready to build the UI! - --- ## Step 4: Create a Frontend for the Game @@ -304,303 +208,61 @@ skill. **1. Scaffold the Frontend:** ```terminal wrap -Using the `initia-appchain-dev` skill, please scaffold a new React application for our BlockForge game using Vite. Then, create a simple component named Game.jsx. This component should have two buttons: Mint Shard and Craft Relic. For now, make the buttons log a message to the console when clicked. Finally, add the Game component to the main App.jsx file. +Using the `initia-appchain-dev` skill, please scaffold a new Vite + React application named blockforge-frontend in my current directory. Then, create a component named Game.jsx with Mint Shard and Craft Relic buttons and add it to the main App.jsx file. ``` **2. Connect the Frontend to the Appchain:** ```terminal wrap -Now, using the `initia-appchain-dev`, please modify the Game.jsx component to interact with our deployed blockforge smart contract on my appchain. +Now, using the `initia-appchain-dev`, please modify the Game.jsx component in my current directory to interact with our deployed blockforge smart contract on my appchain. The Mint Shard button should call the mint_shard function, and the Craft Relic button should call the craft_relic function. Also, please display the player's current inventory of shards and relics. Finally, add a button to enable/disable the native auto-signing feature for a smoother game experience. ``` -Your assistant will use the `@initia/interwoven-kit` to connect your new -frontend to your appchain and its smart contract. - - - -The **Interwoven Kit** is the most powerful way to connect your frontend to the -Initia ecosystem. It provides a unified interface for wallet management and -transaction signing across all Initia rollups. - -First, install the necessary libraries and polyfills (required for browser -compatibility with Initia SDKs): - -```bash wrap -npm install @initia/interwovenkit-react @initia/initia.js @initia/initia.proto @tanstack/react-query @privy-io/react-auth wagmi buffer util -npm install --save-dev vite-plugin-node-polyfills -``` - -Update your `vite.config.js` to include the polyfills: - -```javascript -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' -import { nodePolyfills } from 'vite-plugin-node-polyfills' - -export default defineConfig({ - plugins: [react(), nodePolyfills({ protocolImports: true })], -}) -``` - -Next, set up the polyfills and providers in your main application file. - -**`main.jsx`:** - -```jsx -import { Buffer } from 'buffer' -window.Buffer = Buffer -window.process = { env: {} } - -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.jsx' -import '@initia/interwovenkit-react/styles.css' -import { - injectStyles, - InterwovenKitProvider, - TESTNET, -} from '@initia/interwovenkit-react' -import InterwovenKitStyles from '@initia/interwovenkit-react/styles.js' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import { WagmiProvider, createConfig, http } from 'wagmi' -import { mainnet } from 'wagmi/chains' - -// Inject styles for the widget -injectStyles(InterwovenKitStyles) - -const queryClient = new QueryClient() -const wagmiConfig = createConfig({ - chains: [mainnet], - transports: { [mainnet.id]: http() }, -}) - -// Define your local appchain configuration -const customChain = { - chain_id: 'your-chain-id', - chain_name: 'mygame', - pretty_name: 'BlockForge Appchain', - network_type: 'testnet', - bech32_prefix: 'init', - apis: { - rpc: [{ address: 'http://localhost:26657' }], - rest: [{ address: 'http://localhost:1317' }], - indexer: [{ address: 'http://localhost:8080' }], // Required placeholder - }, - fees: { - fee_tokens: [{ denom: 'umin', fixed_min_gas_price: 0.015 }], - }, -} - -ReactDOM.createRoot(document.getElementById('root')).render( - - - - - - - - - , -) -``` - -Now, update your `Game.jsx` to use the `useInterwovenKit` hook. We use -`RESTClient` for queries and `MsgExecute` for transactions. - -**`Game.jsx`:** - -```jsx -import React, { useState, useEffect } from 'react' -import { useInterwovenKit } from '@initia/interwovenkit-react' -import { RESTClient, bcs } from '@initia/initia.js' -import { MsgExecute } from '@initia/initia.proto/initia/move/v1/tx' - -const CHAIN_ID = 'your-chain-id' -const REST_URL = 'http://localhost:1317' -const MODULE_ADDRESS = '0x00...' // PASTE YOUR MODULE HEX ADDRESS HERE - -function Game() { - const { address, initiaAddress, openConnect, requestTxBlock, autoSign } = - useInterwovenKit() - const [inventory, setInventory] = useState({ shards: 0, relics: 0 }) - const [loading, setLoading] = useState(false) - - const rest = new RESTClient(REST_URL, { chainID: CHAIN_ID }) - - const fetchInventory = async () => { - if (!initiaAddress) return - try { - // Query the Resource directly for best reliability - const structTag = `${MODULE_ADDRESS}::items::Inventory` - const res = await rest.move.resource(initiaAddress, structTag) - if (res && res.data) { - setInventory({ - shards: parseInt(res.data.shards || 0), - relics: parseInt(res.data.relics || 0), - }) - } - } catch (e) { - console.log("Inventory not found (player hasn't minted yet)") - } - } - - useEffect(() => { - fetchInventory() - }, [initiaAddress]) - - const handleAction = async (functionName, args = []) => { - if (!initiaAddress) return - setLoading(true) - - const messages = [ - { - typeUrl: '/initia.move.v1.MsgExecute', - value: MsgExecute.fromPartial({ - sender: initiaAddress, - moduleAddress: MODULE_ADDRESS, - moduleName: 'items', - functionName: functionName, - args: args, - typeArgs: [], - }), - }, - ] - - try { - await requestTxBlock({ messages, chainId: CHAIN_ID }) - setTimeout(fetchInventory, 2000) - } catch (e) { - console.error(e) - } finally { - setLoading(false) - } - } - - if (!address) return - - const isAutoSignEnabled = autoSign?.isEnabledByChain[CHAIN_ID] - - return ( -
-

BlockForge Game

-

Address: {initiaAddress}

- -
- -
- -
-

Your Inventory

-

- Shards: {inventory.shards} | Relics: {inventory.relics} -

-
- - - - -
- ) -} - -export default Game -``` - -This guide uses the modern **Interwoven Kit** patterns for the best user -experience on Initia. - + + Refer to the [Interwoven Kit Documentation](../../interwovenkit/introduction) + for detailed snippets on connecting your frontend to an appchain. --- -## Step 5: Testing Your Project +## Step 5: On-Chain Verification -Testing is crucial to ensure your game logic is sound. Instead of writing a test -script yourself, instruct your AI assistant to act as your QA team. It will -analyze the contract it just wrote and verify the logic. +Finally, ask your AI assistant to interact with your **live** appchain to prove +the deployed contract works as expected. **Example Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, I want to verify our BlockForge game. Please: -1. Inspect the `items.move` module to understand the function names and arguments. -2. Generate a bash test script that mints 5 shards, crafts 2 relics, and verifies the final inventory balance. -3. Run the script and show me the output. +Using the `initia-appchain-dev` skill, I want to verify our live BlockForge game. Using my gas station account on my appchain, please: +1. Mint 3 shards. +2. Check my inventory. +3. Craft a relic. +4. Check my inventory again. ``` - - **AI-Driven QA:** Because your AI assistant generated the code, it is the best - tool to test it. It will automatically adjust the test script if it used - different function names (like `mint_shards` instead of `mint_shard`) or logic - during Step 1. - + +Here are the equivalent `minitiad` commands to interact with the module. - -If you want to write a manual test script, you can use `minitiad` to automate transactions. **Note:** Ensure the function names and arguments match your specific contract. +**Mint 3 shards:** ```bash wrap -#!/bin/bash -set -ex - -# --- Configuration --- -CHAIN_ID="your-chain-id" -MODULE_ADDRESS="0x00..." # Your module hex address -GAS_STATION_ADDRESS=$(minitiad keys show gas-station -a --keyring-backend test) - -# --- Test Execution --- -echo "Starting test..." - -# 1. Mint 5 Shards -echo "🛠️ Minting 5 shards..." -for i in {1..5}; do - minitiad tx move execute "$MODULE_ADDRESS" items mint_shard \ +for i in {1..3}; do + minitiad tx move execute items mint_shard \ --from gas-station \ --keyring-backend test \ - --chain-id "$CHAIN_ID" \ + --chain-id your-chain-id \ --gas auto --gas-adjustment 1.4 --yes sleep 2 done +``` -# 2. Craft 2 Relics (One at a time, each costs 2 shards) -for i in {1..2}; do - echo "⚒️ Crafting relic $i..." - minitiad tx move execute "$MODULE_ADDRESS" items craft_relic \ - --from gas-station \ - --keyring-backend test \ - --chain-id "$CHAIN_ID" \ - --gas auto --gas-adjustment 1.4 --yes - sleep 2 -done +**Check your inventory:** + +```bash wrap +GAS_STATION_ADDRESS=$(minitiad keys show gas-station -a --keyring-backend test) -# 3. Verify Final Inventory -minitiad query move view "$MODULE_ADDRESS" items view_inventory \ +minitiad query move view items view_inventory \ --args "[\"address:${GAS_STATION_ADDRESS}\"]" ``` @@ -608,9 +270,9 @@ minitiad query move view "$MODULE_ADDRESS" items view_inventory \ --- -## You've Built a Full-Stack dApp! +## Next Steps + +Now that you've mastered a Move application, you're ready to build your own +idea! -Congratulations! You have successfully launched a dedicated appchain, created a -smart contract, and built a frontend to interact with it. You've experienced the -full development loop, from idea to a working decentralized application. Now you -can apply these skills to your own hackathon project. +**[→ Go to Builder Guide](../builder-guide)** diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index eb0a2de..7442a0d 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -2,35 +2,48 @@ title: 'Wasm Tutorial: MemoBoard' --- -**Prerequisite:** Before starting this tutorial, you should have completed the **[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have a Wasm-compatible appchain running locally. +**Prerequisite:** Before starting this tutorial, you should have completed the +**[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have a +Wasm-compatible appchain running locally. --- -This tutorial will guide you through building a lightning-fast on-chain guestbook called **MemoBoard**. Users can post short public messages (memos), and anyone can read the board. +This tutorial will guide you through building a lightning-fast on-chain +guestbook called **MemoBoard**. Users can post short public messages (memos), +and anyone can read the board. By the end of this tutorial, you will have: -- Generated and published a Rust smart contract for the guestbook. + +- Generated and verified a Rust smart contract for the guestbook. +- Deployed the contract to your live appchain. - Scaffolded and connected a React frontend. -- Tested the messaging functionality. +- Verified the on-chain functionality. --- -## Step 1: Create the Board's Smart Contract +## Step 1: Create and Verify the Smart Contract -Instruct your AI assistant to create the Rust (Wasm) contract using the `initia-appchain-dev` skill. +Instruct your AI assistant to create the Rust (Wasm) contract using the +`initia-appchain-dev` skill. Your assistant will generate the contract and +automatically run unit tests to ensure the logic is sound. **Example Prompt:** + ```terminal wrap -Using the `initia-appchain-dev` skill, please create a Rust smart contract for our MemoBoard. The contract should: +Using the `initia-appchain-dev` skill, please create a Rust smart contract for our MemoBoard in my current directory. The contract should: - Allow users to post a message (string). - Store a list of all messages with the sender's address. - Include a function to query all messages on the board. +Please also create and run a unit test to verify these features. ``` +Your assistant will generate the `memoboard` project and confirm that the Rust +tests pass. + -If you prefer to see the Rust logic, here is a simplified version of what your assistant would generate using the standard Wasm contract patterns. +If you prefer to see the Rust logic, here is a simplified version of what your assistant would generate. Save your Rust project in your current directory. -```rust +```rust wrap use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdResult}; use cw_storage_plus::Item; use serde::{Deserialize, Serialize}; @@ -61,59 +74,56 @@ pub fn execute(deps: DepsMut, _env: Env, info: MessageInfo, msg: ExecuteMsg) -> } } ``` + --- -## Step 2: Build and Play with the Board +## Step 2: Deploy to your Appchain -Now, build and publish the contract to your appchain using the gas station account. +Now that the logic is verified, build and publish the contract to your appchain +using the gas station account. -**1. Build and Publish:** -```terminal wrap -Using the `initia-appchain-dev` skill, please build and publish the MemoBoard Rust contract to my appchain using my gas station account. -``` +**Prompt:** -**2. Interact with the Board:** ```terminal wrap -Using my gas station account on my appchain, please do the following: -1. Post a memo: "Hello from Initia!" -2. Query the board to see all messages. +Using the `initia-appchain-dev` skill, please build and publish the MemoBoard Rust contract located in my current directory to my appchain using my gas station account. ``` - -Here are the equivalent `minitiad` commands to manage your Rust (Wasm) contract. - -**1. Build and Publish:** + +**1. Store the Code:** ```bash wrap -# Replace `your-chain-id` with your appchain ID -minitiad wasm deploy \ +minitiad tx wasm store ./target/wasm32-unknown-unknown/release/memoboard.wasm \ --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ - --path ./target/wasm32-unknown-unknown/release/memoboard.wasm \ --gas auto --gas-adjustment 1.4 --yes ``` -**2. Interact (Post Memo):** +**2. Instantiate the Contract:** + ```bash wrap -minitiad tx wasm execute '{"post_memo":{"content":"Hello!"}}' \ +minitiad tx wasm instantiate '{}' \ + --label "memoboard" \ --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ - --gas auto --gas-adjustment 1.4 --yes + --no-admin --yes ``` + --- ## Step 3: Fund your Browser Wallet -Ensure your personal wallet has tokens to pay for the transaction to post a memo. +Ensure your personal wallet has tokens to pay for the transaction to post a +memo. **Prompt:** + ```terminal wrap -Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` --- @@ -123,59 +133,48 @@ Using the `initia-appchain-dev` skill, please fund my wallet address -For Wasm contracts, you use the `MsgExecute` message from the Wasm module. - -**Example snippet:** -```javascript wrap -const messages = [ - { - typeUrl: "/initia.wasm.v1.MsgExecute", - value: MsgExecute.fromPartial({ - sender: initiaAddress, - contractAddress: CONTRACT_ADDRESS, - msg: Buffer.from(JSON.stringify({ post_memo: { content: "Hello!" } })), - funds: [], - }), - }, -]; +```terminal wrap +Using the `initia-appchain-dev` skill, modify the Board.jsx component in my current directory to connect to our MemoBoard contract on my appchain. Use the @initia/interwovenkit-react for wallet connection and transaction signing. ``` - --- -## Step 5: Testing +## Step 5: On-Chain Verification -Verify that your messages are being recorded on-chain. +Finally, ask your AI assistant to interact with your **live** appchain to prove +the deployed contract works as expected. **Example Prompt:** + ```terminal wrap -Using the `initia-appchain-dev` skill, I want to verify our MemoBoard contract. Please: -1. Inspect the MemoBoard contract to find the execution entry points. -2. Generate a test script that posts 3 different messages from the gas station account. -3. Query the contract state to prove all 3 messages are stored correctly. +Using the `initia-appchain-dev` skill, I want to verify our live MemoBoard contract. Using my gas station account on my appchain, please: +1. Post a memo: "Hello from Initia!" +2. Query the board to see all messages. ``` - + +**Post Memo:** ```bash wrap -#!/bin/bash -# 1. Post Memo -minitiad tx wasm execute $ADDR '{"post_memo":{"content":"Message 1"}}' --from gas-station --yes -# 2. Query Board -minitiad query wasm contract-state smart $ADDR '{"get_messages":{}}' +minitiad tx wasm execute '{"post_memo":{"content":"Hello!"}}' \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --gas auto --gas-adjustment 1.4 --yes ``` --- -## Conclusion -You've built an on-chain guestbook using Rust and Wasm! This tutorial highlights the performance and flexibility of using Wasm for social and data-driven applications on Initia. +## Next Steps + +Now that you've mastered a Wasm application, you're ready to build your own +idea! + +**[→ Go to Builder Guide](../builder-guide)** From 83fe13f7a360bc53a5c7e71f974fbc668d041b83 Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Wed, 18 Feb 2026 10:55:26 +0700 Subject: [PATCH 07/17] docs: standardize example steps and optimize manual approach for EVM example --- hackathon/builder-guide.mdx | 16 + hackathon/examples/evm-bank.mdx | 557 +++++++++++++++++++++++++++-- hackathon/examples/move-game.mdx | 32 +- hackathon/examples/wasm-social.mdx | 134 ++++++- hackathon/hackathon-landing.mdx | 50 ++- 5 files changed, 727 insertions(+), 62 deletions(-) diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index c4a07c9..e63b455 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -58,6 +58,22 @@ minitiad keys add gas-station --recover --keyring-backend test --coin-type 60 -- Master the **Describe → Build → Test** cycle. This is how you win the hackathon. +### 💰 Funding Your Personal Wallet + +Before you can interact with your appchain via a browser wallet (like Keplr, Leap, or MetaMask), you need to fund your personal address from your **Gas Station**. + +**1. Copy your wallet address:** +- **Move / Wasm Track**: Copy your `init1...` address. +- **EVM Track**: Copy your `0x...` address. + +**2. Ask your AI Assistant to fund you:** + +**Prompt:** + +```terminal wrap +Using the `initia-appchain-dev` skill, please fund my personal wallet with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +``` + ### The Core Loop 1. **Describe the Goal**: Tell the AI _what_ you want to achieve and _why_. diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx index e2349ed..992925c 100644 --- a/hackathon/examples/evm-bank.mdx +++ b/hackathon/examples/evm-bank.mdx @@ -21,6 +21,18 @@ By the end of this tutorial, you will have: --- +## 📂 Recommended Project Structure + +To keep your workspace organized, we recommend the following structure inside your `my-initia-project` directory: + +```text +my-initia-project/ +├── minibank/ # Solidity smart contract project +└── minibank-frontend/ # React frontend application +``` + +--- + ## Step 1: Create and Verify the Smart Contract Instruct your AI assistant to create the Solidity contract using the @@ -30,7 +42,7 @@ automatically run unit tests to ensure the logic is sound. **Example Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please create a Solidity smart contract for our MiniBank in my current directory. The contract should: +Using the `initia-appchain-dev` skill, please create a Solidity smart contract project for our MiniBank in a new directory named `minibank`. The contract should: - Allow users to deposit native tokens. - Allow users to withdraw their own deposited tokens. - Keep track of each user's total savings. @@ -41,35 +53,98 @@ Please also create and run a unit test to verify these features. Your assistant will generate the `minibank` project and confirm that the tests (likely using Foundry or Hardhat) pass successfully. + +To verify your contract's logic, create a test file named `MiniBank.t.sol` in the `test` directory. + +> **Pro Tip**: `testFail` is deprecated in newer versions of Foundry. Use `vm.expectRevert()` for failure testing. + +```solidity wrap +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import "forge-std/Test.sol"; +import "../src/MiniBank.sol"; + +contract MiniBankTest is Test { + MiniBank public bank; + address public user = address(0x123); + + function setUp() public { + bank = new MiniBank(); + vm.deal(user, 10 ether); + } + + function testDeposit() public { + vm.prank(user); + bank.deposit{value: 1 ether}(); + assertEq(bank.getBalanceOf(user), 1 ether); + } + + function testWithdraw() public { + vm.startPrank(user); + bank.deposit{value: 2 ether}(); + bank.withdraw(1 ether); + assertEq(bank.getBalanceOf(user), 1 ether); + vm.stopPrank(); + } + + function testWithdrawInsufficientBalance() public { + vm.prank(user); + bank.deposit{value: 1 ether}(); + + vm.prank(user); + vm.expectRevert("Insufficient balance"); + bank.withdraw(2 ether); + } +} +``` + +Run your tests: +```bash wrap +forge test +``` + + -If you prefer to create the contract manually, here is the Solidity code your assistant would generate. Save this as MiniBank.sol in your current directory. +If you prefer to create the contract manually, here is the Solidity code your assistant would generate. Save this as MiniBank.sol in your `minibank` directory. ```solidity wrap // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.24; contract MiniBank { mapping(address => uint256) private balances; - event Deposit(address indexed user, uint256 amount); - event Withdrawal(address indexed user, uint256 amount); + event Deposited(address indexed user, uint256 amount); + event Withdrawn(address indexed user, uint256 amount); function deposit() public payable { require(msg.value > 0, "Cannot deposit 0"); balances[msg.sender] += msg.value; - emit Deposit(msg.sender, msg.value); + emit Deposited(msg.sender, msg.value); } function withdraw(uint256 amount) public { + require(amount > 0, "Withdrawal amount must be greater than zero"); require(balances[msg.sender] >= amount, "Insufficient balance"); + balances[msg.sender] -= amount; - payable(msg.sender).transfer(amount); - emit Withdrawal(msg.sender, amount); + (bool success, ) = payable(msg.sender).call{value: amount}(""); + require(success, "Transfer failed"); + + emit Withdrawn(msg.sender, amount); } function getBalance() public view returns (uint256) { + // NOTE: This returns the balance for the CALLER (msg.sender). + // In tests or frontend calls, ensure the correct account is the caller. return balances[msg.sender]; } + + function getBalanceOf(address user) public view returns (uint256) { + // Helper to check the balance of any user without needing a 'from' address. + return balances[user]; + } } ``` @@ -85,14 +160,46 @@ appchain using the gas station account. **Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please build and publish the MiniBank Solidity contract located in my current directory to my appchain using my gas station account. +Using the `initia-appchain-dev` skill, please build and publish the MiniBank Solidity contract located in the `minibank` directory to my appchain using my gas station account. ``` + First, compile your contract and extract the hex bytecode: + ```bash wrap + # Navigate to the contract directory + cd minibank + + # Compile with Foundry + forge build + + # Extract bytecode (requires jq) + jq -r '.bytecode.object' out/MiniBank.sol/MiniBank.json | sed 's/^0x//' | tr -d '\n' > minibank.bin + ``` + + Then deploy the binary. **Find your Chain ID first** if you don't know it: + ```bash wrap + # Option 1: Using the skill's health check script (Recommended) + bash .agents/skills/initia-appchain-dev/scripts/verify-appchain.sh --gas-station --bots + + # Option 2: Direct CLI query + minitiad status 2>&1 | jq -r '.NodeInfo.network' + ``` + + Now deploy: ```bash wrap - # Replace `your-chain-id` with your appchain ID minitiad evm - deploy \ --from gas-station \ --keyring-backend test \ --chain-id - your-chain-id \ --path ./MiniBank.sol \ --gas auto --gas-adjustment 1.4 --yes + # Replace `your-chain-id` with the ID from the command above + minitiad tx evm create minibank.bin \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --gas auto --gas-adjustment 1.4 --yes --output json + ``` + + **Retrieve your contract address:** + The output will provide a `txhash`. Wait a few seconds for indexing, then find your contract address: + ```bash wrap + sleep 5 + minitiad q tx --output json | jq -r '.events[] | select(.type=="contract_created") | .attributes[] | select(.key=="contract") | .value' ``` @@ -102,10 +209,14 @@ Using the `initia-appchain-dev` skill, please build and publish the MiniBank Sol Ensure your personal wallet has tokens to interact with the bank. +**1. Get your EVM Address:** Open your browser wallet (like Keplr or Leap) and copy your Ethereum-style address (it starts with `0x...`). + +**2. Send Tokens from Gas Station:** Replace `` in the prompt below with the address you just copied. + **Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` --- @@ -117,15 +228,388 @@ Let's create a simple UI to interact with our bank. **1. Scaffold the Frontend:** ```terminal wrap -Using the `initia-appchain-dev` skill, please scaffold a new Vite + React application named minibank-frontend in my current directory. Create a component named Bank.jsx with Deposit and Withdraw buttons and an input field for the amount. +Using the `initia-appchain-dev` skill, please scaffold a new Vite + React application named `minibank-frontend` in my current directory. Create a component named Bank.jsx with Deposit and Withdraw buttons and an input field for the amount. ``` **2. Connect to Appchain:** ```terminal wrap -Using the `initia-appchain-dev` skill, modify the Bank.jsx component in my current directory to connect to our MiniBank contract on my appchain. Use the @initia/interwovenkit-react for wallet connection and transaction signing. +Using the `initia-appchain-dev` skill, modify the Bank.jsx component in the `minibank-frontend` directory to connect to our MiniBank contract on my appchain. Use the @initia/interwovenkit-react for wallet connection and transaction signing. +``` + + +If you prefer to set up the frontend manually, follow these steps: + +**1. Create the Project and Install Dependencies:** +```bash wrap +npm create vite@latest minibank-frontend -- --template react +cd minibank-frontend +npm install +npm install @initia/interwovenkit-react wagmi viem @tanstack/react-query @initia/initia.js @initia/initia.proto +npm install --save-dev vite-plugin-node-polyfills +npm install buffer util +``` + +**2. Create index.html:** +Create `index.html` in the root of your `minibank-frontend` directory: +```html wrap + + + + + + MiniBank Frontend + + +
+ + + +``` + +**3. Configure Vite Polyfills:** +Update `vite.config.js` to include the Node polyfills: +```javascript wrap +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import { nodePolyfills } from 'vite-plugin-node-polyfills' + +export default defineConfig({ + plugins: [ + react(), + nodePolyfills({ + globals: { + Buffer: true, + }, + }), + ], +}) +``` + +**3. Set up Providers in `main.jsx`:** +```javascript wrap +import { Buffer } from 'buffer' +window.Buffer = Buffer +window.process = { env: { NODE_ENV: 'development' } } + +import React from 'react' +import ReactDOM from 'react-dom/client' +import "@initia/interwovenkit-react/styles.css"; +import { injectStyles, InterwovenKitProvider, TESTNET } from "@initia/interwovenkit-react"; +import InterwovenKitStyles from "@initia/interwovenkit-react/styles.js"; +import { WagmiProvider, createConfig, http } from "wagmi"; +import { mainnet } from "wagmi/chains"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import App from './App.jsx' + +injectStyles(InterwovenKitStyles); + +const queryClient = new QueryClient(); +const wagmiConfig = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, +}); + +const customChain = { + chain_id: "your-chain-id", + chain_name: "minibank", + pretty_name: "MiniBank Appchain", + network_type: "testnet", + bech32_prefix: "init", + logo_URIs: { + png: "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/initia/images/initia.png", + svg: "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/initia/images/initia.svg" + }, + apis: { + rpc: [{ address: "http://localhost:26657" }], + rest: [{ address: "http://localhost:1317" }], + indexer: [{ address: "http://localhost:8080" }], + "json-rpc": [{ address: "http://localhost:8545" }] + }, + fees: { + fee_tokens: [{ + denom: "GAS", + fixed_min_gas_price: 0, + low_gas_price: 0, + average_gas_price: 0, + high_gas_price: 0 + }], + }, + staking: { + staking_tokens: [{ denom: "GAS" }] + }, + metadata: { + minitia: { type: "minievm" }, + is_evm: true + } +}; + +ReactDOM.createRoot(document.getElementById('root')).render( + + + + + + + + + , +) +``` + +**4. Create the `App.jsx` Layout:** +```javascript wrap +import React from 'react' +import { useInterwovenKit } from "@initia/interwovenkit-react"; +import Bank from './Bank'; + +function App() { + const { address, openConnect, openWallet } = useInterwovenKit(); + + const containerStyle = { + fontFamily: 'system-ui, -apple-system, sans-serif', + minHeight: '100vh', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: '#f1f5f9', + padding: '20px' + }; + + const cardStyle = { + backgroundColor: '#ffffff', + borderRadius: '16px', + boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.1)', + padding: '40px', + width: '100%', + maxWidth: '500px', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + textAlign: 'center' + }; + + const buttonStyle = { + backgroundColor: '#3b82f6', + color: 'white', + border: 'none', + padding: '12px 24px', + borderRadius: '8px', + fontSize: '16px', + fontWeight: '600', + cursor: 'pointer', + width: '100%' + }; + + const secondaryButtonStyle = { + backgroundColor: '#f1f5f9', + border: '1px solid #e2e8f0', + color: '#64748b', + padding: '12px 24px', + borderRadius: '10px', + fontSize: '14px', + fontWeight: '600', + cursor: 'pointer', + marginTop: '20px', + width: '100%' + }; + + return ( +
+
+

MiniBank

+ + {!address ? ( + <> +

+ Connect your wallet to manage your savings. +

+ + + ) : ( + <> + + + + )} +
+
+ ) +} + +export default App +``` + +**5. Create the `Bank.jsx` Component:** +Create `src/Bank.jsx` and add the contract interaction logic. + +> **Pro Tip**: For `view` functions that depend on `msg.sender` (like `getBalance`), you MUST provide a `from` address in your `eth_call` parameters so the appchain knows whose balance to check. + +```javascript wrap +import React, { useState, useEffect } from 'react'; +import { useInterwovenKit } from "@initia/interwovenkit-react"; +import { encodeFunctionData, parseEther, formatEther } from "viem"; +import { AccAddress } from "@initia/initia.js"; + +const MINI_BANK_ADDRESS = "YOUR_CONTRACT_ADDRESS"; +const MINI_BANK_ABI = [ + { name: "deposit", type: "function", stateMutability: "payable", inputs: [] }, + { name: "withdraw", type: "function", inputs: [{ name: "amount", type: "uint256" }] }, + { name: "getBalance", type: "function", stateMutability: "view", inputs: [], outputs: [{ type: "uint256" }] }, + { name: "getBalanceOf", type: "function", stateMutability: "view", inputs: [{ name: "user", type: "address" }], outputs: [{ type: "uint256" }] }, +]; + +const Bank = () => { + const [amount, setAmount] = useState(''); + const [balance, setBalance] = useState('0'); + const [isPending, setIsPending] = useState(false); + const { address, initiaAddress, requestTxBlock } = useInterwovenKit(); + + const fetchBalance = async () => { + if (!address) return; + try { + const fromAddress = address.startsWith("0x") ? address : AccAddress.toHex(address); + const data = encodeFunctionData({ abi: MINI_BANK_ABI, functionName: "getBalance" }); + const response = await fetch("http://localhost:8545", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + method: "eth_call", + params: [{ from: fromAddress, to: MINI_BANK_ADDRESS, data }, "latest"], + id: 1, + }), + }); + const result = await response.json(); + if (result.result && result.result !== "0x") { + setBalance(formatEther(BigInt(result.result))); + } + } catch (error) { + console.error("Error fetching balance:", error); + } + }; + + useEffect(() => { + fetchBalance(); + const interval = setInterval(fetchBalance, 10000); + return () => clearInterval(interval); + }, [address]); + + const handleDeposit = async () => { + if (!amount || !initiaAddress) return; + const data = encodeFunctionData({ abi: MINI_BANK_ABI, functionName: "deposit" }); + setIsPending(true); + try { + await requestTxBlock({ + chainId: "your-chain-id", + messages: [{ + typeUrl: "/minievm.evm.v1.MsgCall", + value: { + sender: initiaAddress, + contractAddr: MINI_BANK_ADDRESS, + input: data, + value: parseEther(amount).toString(), + accessList: [], + }, + }], + onSuccess: () => { + alert("Deposit successful!"); + setAmount(''); + fetchBalance(); + }, + onError: () => alert("Transaction failed or was cancelled.") + }); + } catch (error) { + console.error("Deposit error:", error); + } finally { + setIsPending(false); + } + }; + + const handleWithdraw = async () => { + if (!amount || !initiaAddress) return; + const data = encodeFunctionData({ + abi: MINI_BANK_ABI, + functionName: "withdraw", + args: [parseEther(amount)], + }); + setIsPending(true); + try { + await requestTxBlock({ + chainId: "your-chain-id", + messages: [{ + typeUrl: "/minievm.evm.v1.MsgCall", + value: { + sender: initiaAddress, + contractAddr: MINI_BANK_ADDRESS, + input: data, + value: "0", + accessList: [], + }, + }], + onSuccess: () => { + alert("Withdrawal successful!"); + setAmount(''); + fetchBalance(); + }, + onError: () => alert("Transaction failed or was cancelled.") + }); + } catch (error) { + console.error("Withdraw error:", error); + } finally { + setIsPending(false); + } + }; + + const balanceContainerStyle = { backgroundColor: '#f1f5f9', padding: '30px', borderRadius: '16px', marginBottom: '30px', border: '1px solid #e2e8f0' }; + const balanceValueStyle = { fontSize: '42px', fontWeight: '800', color: '#2563eb', margin: '10px 0', fontFamily: 'monospace' }; + const inputStyle = { width: '100%', padding: '14px', marginBottom: '20px', borderRadius: '10px', border: '2px solid #e2e8f0', fontSize: '16px', boxSizing: 'border-box' }; + const buttonContainerStyle = { display: 'flex', gap: '15px' }; + const actionButtonStyle = { flex: 1, padding: '14px', borderRadius: '10px', border: 'none', fontWeight: '700', fontSize: '16px', cursor: 'pointer', color: 'white' }; + + return ( +
+
+
Your Savings Balance
+
{balance} GAS
+
+ setAmount(e.target.value)} + placeholder="0.00" + style={inputStyle} + /> +
+ + +
+
+ ); +}; + +export default Bank; ``` +
+ --- ## Step 5: On-Chain Verification @@ -137,20 +621,53 @@ the deployed contract works as expected. ```terminal wrap Using the `initia-appchain-dev` skill, I want to verify our live MiniBank contract. Using my gas station account on my appchain, please: -1. Deposit 5 tokens. +1. Deposit 1 token. 2. Check my balance. -3. Withdraw 2 tokens. +3. Withdraw 0.5 tokens. 4. Check my balance again. ``` -**Interact (Deposit):** + +**1. Find your hex address:** +To use `eth_call`, you need your account's hex address. Run the following: +```bash wrap +# Replace with the path to the skill's scripts directory +minitiad keys show gas-station -a --keyring-backend test | xargs -I {} python3 /to_hex.py {} +``` + +**2. Interact (Deposit 1 token):** +We'll use `cast sig` to generate the function selector and `10^18` units for "1 token". +```bash wrap +SIG=$(cast sig "deposit()") +minitiad tx evm call $SIG \ + --from gas-station \ + --keyring-backend test \ + --chain-id your-chain-id \ + --value 1000000000000000000 \ + --gas auto --gas-adjustment 1.4 --yes +``` + +**3. Query Balance:** +Querying a function that uses `msg.sender` requires a `from` address in the JSON-RPC call. +```bash wrap +SIG=$(cast sig "getBalance()") +# Replace with the address from step 1 +HEX_RESULT=$(curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"from":"","to":"","data":"'$SIG'"},"latest"],"id":1}' \ + http://localhost:8545 | jq -r '.result') + +# Convert hex to decimal tokens +cast --from-wei $HEX_RESULT +``` + +**4. Withdraw (0.5 tokens):** ```bash wrap -minitiad tx evm call "deposit()" \ +DATA=$(cast calldata "withdraw(uint256)" 500000000000000000) +minitiad tx evm call $DATA \ --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ - --value 5000000 \ --gas auto --gas-adjustment 1.4 --yes ``` diff --git a/hackathon/examples/move-game.mdx b/hackathon/examples/move-game.mdx index a42ad6c..01fabba 100644 --- a/hackathon/examples/move-game.mdx +++ b/hackathon/examples/move-game.mdx @@ -21,6 +21,18 @@ By the end of this tutorial, you will have instructed your AI assistant to: --- +## 📂 Recommended Project Structure + +To keep your workspace organized, we recommend the following structure inside your `my-initia-project` directory: + +```text +my-initia-project/ +├── blockforge/ # Move smart contract project +└── blockforge-frontend/ # React frontend application +``` + +--- + ## Step 1: Create and Verify the Smart Contract Instead of writing the code yourself, instruct your assistant to do it for you @@ -30,7 +42,7 @@ and automatically run unit tests to ensure the logic is sound. **Example Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please create a Move module for our BlockForge game in my current directory. The module should be named items inside a blockforge project. The game has the following rules: +Using the `initia-appchain-dev` skill, please create a Move module project for our BlockForge game in a new directory named `blockforge`. The module should be named items inside a blockforge project. The game has the following rules: - Players can mint basic items called shards. - Players can craft relics by burning 2 shards. - Players should have an inventory to store their items. @@ -41,8 +53,8 @@ Please also create and run a unit test to verify these rules. Your assistant will generate the `blockforge` project, including the `items.move` module and a test script, and confirm that everything passes. - -If you prefer to create the Move module and project manually, follow these steps in your current project directory. This is what your AI assistant would generate for you. + +If you prefer to create the Move module and project manually, follow these steps in your `blockforge` directory. This is what your AI assistant would generate for you. First, create a new Move package named `blockforge`: @@ -151,7 +163,7 @@ appchain using the gas station account. **Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please build and publish the blockforge Move module located in my current directory to my appchain using my gas station account. +Using the `initia-appchain-dev` skill, please build and publish the blockforge Move module located in the `blockforge` directory to my appchain using my gas station account. ``` @@ -189,18 +201,18 @@ needs tokens to pay for transaction fees. **1. Get your Wallet Address:** Open your browser wallet and copy your address (it starts with `init1...`). -**2. Send Tokens from Gas Station:** Replace `` in the prompt +**2. Send Tokens from Gas Station:** Replace `` in the prompt below with the address you just copied. **Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` --- -## Step 4: Create a Frontend for the Game +## Step 4: Create a Frontend A game needs a user interface. Let's create one using the `initia-appchain-dev` skill. @@ -208,18 +220,18 @@ skill. **1. Scaffold the Frontend:** ```terminal wrap -Using the `initia-appchain-dev` skill, please scaffold a new Vite + React application named blockforge-frontend in my current directory. Then, create a component named Game.jsx with Mint Shard and Craft Relic buttons and add it to the main App.jsx file. +Using the `initia-appchain-dev` skill, please scaffold a new Vite + React application named `blockforge-frontend` in my current directory. Then, create a component named Game.jsx with Mint Shard and Craft Relic buttons and add it to the main App.jsx file. ``` **2. Connect the Frontend to the Appchain:** ```terminal wrap -Now, using the `initia-appchain-dev`, please modify the Game.jsx component in my current directory to interact with our deployed blockforge smart contract on my appchain. +Now, using the `initia-appchain-dev`, please modify the Game.jsx component in the `blockforge-frontend` directory to interact with our deployed blockforge smart contract on my appchain. The Mint Shard button should call the mint_shard function, and the Craft Relic button should call the craft_relic function. Also, please display the player's current inventory of shards and relics. Finally, add a button to enable/disable the native auto-signing feature for a smoother game experience. ``` - + Refer to the [Interwoven Kit Documentation](../../interwovenkit/introduction) for detailed snippets on connecting your frontend to an appchain. diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index 7442a0d..738b2ee 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -21,6 +21,18 @@ By the end of this tutorial, you will have: --- +## 📂 Recommended Project Structure + +To keep your workspace organized, we recommend the following structure inside your `my-initia-project` directory: + +```text +my-initia-project/ +├── memoboard/ # Rust smart contract project +└── memoboard-frontend/ # React frontend application +``` + +--- + ## Step 1: Create and Verify the Smart Contract Instruct your AI assistant to create the Rust (Wasm) contract using the @@ -30,7 +42,7 @@ automatically run unit tests to ensure the logic is sound. **Example Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please create a Rust smart contract for our MemoBoard in my current directory. The contract should: +Using the `initia-appchain-dev` skill, please create a Rust smart contract project for our MemoBoard in a new directory named `memoboard`. The contract should: - Allow users to post a message (string). - Store a list of all messages with the sender's address. - Include a function to query all messages on the board. @@ -41,7 +53,7 @@ Your assistant will generate the `memoboard` project and confirm that the Rust tests pass. -If you prefer to see the Rust logic, here is a simplified version of what your assistant would generate. Save your Rust project in your current directory. +If you prefer to see the Rust logic, here is a simplified version of what your assistant would generate. Save your Rust project in the `memoboard` directory. ```rust wrap use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdResult}; @@ -87,7 +99,7 @@ using the gas station account. **Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please build and publish the MemoBoard Rust contract located in my current directory to my appchain using my gas station account. +Using the `initia-appchain-dev` skill, please build and publish the MemoBoard Rust contract located in the `memoboard` directory to my appchain using my gas station account. ``` @@ -120,10 +132,14 @@ minitiad tx wasm instantiate '{}' \ Ensure your personal wallet has tokens to pay for the transaction to post a memo. +**1. Get your Wallet Address:** Open your browser wallet and copy your address (it starts with `init1...`). + +**2. Send Tokens from Gas Station:** Replace `` in the prompt below with the address you just copied. + **Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. ``` --- @@ -135,15 +151,121 @@ Let's create a UI to display and post messages. **1. Scaffold the Frontend:** ```terminal wrap -Using the `initia-appchain-dev` skill, please scaffold a new Vite + React application named memoboard-frontend in my current directory. Create a component named Board.jsx that displays a list of messages and a text input to post a new one. +Using the `initia-appchain-dev` skill, please scaffold a new Vite + React application named `memoboard-frontend` in my current directory. Create a component named Board.jsx that displays a list of messages and a text input to post a new one. ``` **2. Connect to Appchain:** ```terminal wrap -Using the `initia-appchain-dev` skill, modify the Board.jsx component in my current directory to connect to our MemoBoard contract on my appchain. Use the @initia/interwovenkit-react for wallet connection and transaction signing. +Using the `initia-appchain-dev` skill, modify the Board.jsx component in the `memoboard-frontend` directory to connect to our MemoBoard contract on my appchain. Use the @initia/interwovenkit-react for wallet connection and transaction signing. ``` + +If you prefer to set up the frontend manually, follow these steps: + +**1. Create the Project and Install Dependencies:** +```bash wrap +npm create vite@latest memoboard-frontend -- --template react +cd memoboard-frontend +npm install +npm install @initia/interwovenkit-react wagmi viem @tanstack/react-query @initia/initia.js @initia/initia.proto +npm install --save-dev vite-plugin-node-polyfills +npm install buffer util +``` + +**2. Configure Vite Polyfills:** +Update `vite.config.js` to include the Node polyfills: +```javascript wrap +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import { nodePolyfills } from 'vite-plugin-node-polyfills' + +export default defineConfig({ + plugins: [ + react(), + nodePolyfills({ + globals: { + Buffer: true, + }, + }), + ], +}) +``` + +**3. Set up Providers in `main.jsx`:** +```javascript wrap +import { Buffer } from 'buffer' +window.Buffer = Buffer + +import React from 'react' +import ReactDOM from 'react-dom/client' +import "@initia/interwovenkit-react/styles.css"; +import { injectStyles, InterwovenKitProvider, TESTNET } from "@initia/interwovenkit-react"; +import InterwovenKitStyles from "@initia/interwovenkit-react/styles.js"; +import { WagmiProvider, createConfig, http } from "wagmi"; +import { mainnet } from "wagmi/chains"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import App from './App.jsx' + +injectStyles(InterwovenKitStyles); + +const queryClient = new QueryClient(); +const wagmiConfig = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, +}); + +ReactDOM.createRoot(document.getElementById('root')).render( + + + + + + + + + , +) +``` + +**4. Create the `Board.jsx` Component:** +Create `src/Board.jsx` and add the contract interaction logic: +```javascript wrap +import React, { useState } from 'react'; +import { useInterwovenKit } from "@initia/interwovenkit-react"; + +const MEMO_BOARD_ADDRESS = "YOUR_CONTRACT_ADDRESS"; + +const Board = () => { + const [content, setContent] = useState(''); + const { address, requestTxBlock } = useInterwovenKit(); + + const handlePostMemo = async () => { + await requestTxBlock({ + messages: [{ + typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract", + value: { + sender: address, + contract: MEMO_BOARD_ADDRESS, + msg: btoa(JSON.stringify({ post_memo: { content } })), + funds: [] + }, + }], + }); + }; + + return ( +
+ setContent(e.target.value)} /> + +
+ ); +}; + +export default Board; +``` +
+ --- ## Step 5: On-Chain Verification diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index 3b257f0..df3e802 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -180,6 +180,12 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select `Launch a new rollup`. + + **Switching VMs?** If you are switching from one Virtual Machine to another (e.g., from Wasm to Move), you **must** reinstall the correct `minitiad` binary as described in [**Step 4.2**](#4-2-install-your-appchain-vm-[terminal]). The new installation will override your previous one. + + If you have existing rollup data, you will be prompted to delete it. Type `confirm` to proceed with the new launch. + + ### 4. Select L1 Network **Prompt:** ```terminal wrap @@ -314,7 +320,7 @@ Here's a guide on how to navigate the interactive setup: ``` **Action:** - Enter `1000000000`. + Enter `1000000000000000000000000` (10^24). This ensures you have plenty of tokens for testing, especially if you are on the EVM track. ### 18. Add Additional Genesis Accounts **Prompt:** @@ -360,8 +366,7 @@ Initia L1 and your appchain, you need to start the **OPinit Executor** and the **IBC Relayer**. These bots handle the "interweaving" of your chain. - **Prerequisite:** Your appchain must be running in another terminal (via - `weave init` or `weave start`) before configuring these bots. + **Prerequisite:** Your appchain must be running before configuring these bots. Because `weave init` (and `weave rollup start`) runs your chain in the background, you can continue using the same terminal window. ### 6.1 Start the OPinit Executor @@ -492,7 +497,7 @@ Follow the interactive guide: Start the relayer process: ```bash wrap - weave relayer start + weave relayer start -d ``` @@ -502,6 +507,19 @@ Follow the interactive guide: + + **Persistence After Restart:** + If you shut down your computer, the **Relayer** will stay active (it's managed by Docker), but you will need to manually restart your **Rollup full node** and **Executor bot** using these commands: + + ```bash wrap + # Restart the rollup full node + weave rollup start -d + + # Restart the OPinit executor bot + weave opinit start executor -d + ``` + + --- ## Step 7: Final Key Setup [Terminal] @@ -544,32 +562,12 @@ After completing the infrastructure setup, verify that everything is healthy. **Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please verify that my appchain is running and that my Gas Station account has a balance. -``` - ---- - -## Step 9: Funding Your Personal Wallet [AI Assistant] - -To interact with your appchain using a browser wallet (like **Keplr** or -**Leap**), you'll need to send tokens from your **gas station** to your personal -address. - -**1. Copy your personal address from your wallet.** - -**2. Ask your assistant to fund you:** - -Replace `` in the prompt below with the address you just copied from your browser wallet. - -**Prompt:** - -```terminal wrap -Using the `initia-appchain-dev` skill, please fund my personal wallet with 1 INIT on L1 and 100 of my appchain's native tokens on L2. +Using the `initia-appchain-dev` skill, please verify that my appchain, executor bot, and relayer are running and that my Gas Station account has a balance. ``` --- -## Step 10: Next Steps +## Step 9: Next Steps Congratulations! You have successfully launched your first appchain. You now understand the basic workflow of using your AI assistant to manage your own From 7a9aa683e6495784af0e02d69e71e1552f626dcf Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Wed, 18 Feb 2026 13:28:59 +0700 Subject: [PATCH 08/17] docs: optimizing manual approach sections for wasm example --- hackathon/examples/wasm-social.mdx | 255 +++++++++++++++++++++++++---- 1 file changed, 222 insertions(+), 33 deletions(-) diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index 738b2ee..3b932f6 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -53,38 +53,104 @@ Your assistant will generate the `memoboard` project and confirm that the Rust tests pass. -If you prefer to see the Rust logic, here is a simplified version of what your assistant would generate. Save your Rust project in the `memoboard` directory. +If you prefer to see the Rust logic, here is a simplified version of what your assistant would generate. If doing this manually, save the following code in `src/contract.rs` inside your `memoboard` directory (ensure `src/lib.rs` exports the `contract` module). + +**Important:** Ensure your `Cargo.toml` includes the following `[lib]` section to correctly generate the Wasm binary: +```toml +[lib] +crate-type = ["cdylib", "rlib"] +``` ```rust wrap -use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{entry_point, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Addr}; use cw_storage_plus::Item; -use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct Memo { - pub sender: String, - pub content: String, +#[cw_serde] +pub struct Message { + pub sender: Addr, + pub message: String, +} + +pub const MESSAGES: Item> = Item::new("messages"); + +#[cw_serde] +pub struct InstantiateMsg {} + +#[cw_serde] +pub enum ExecuteMsg { + PostMessage { message: String }, } -pub const BOARD: Item> = Item::new("board"); +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(AllMessagesResponse)] + AllMessages {}, +} -#[entry_point] -pub fn instantiate(_deps: DepsMut, _env: Env, _info: MessageInfo, _msg: InstantiateMsg) -> StdResult { - BOARD.save(_deps.storage, &vec![])?; +#[cw_serde] +pub struct AllMessagesResponse { + pub messages: Vec, +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate(deps: DepsMut, _env: Env, _info: MessageInfo, _msg: InstantiateMsg) -> StdResult { + MESSAGES.save(deps.storage, &vec![])?; Ok(Response::default()) } -#[entry_point] +#[cfg_attr(not(feature = "library"), entry_point)] pub fn execute(deps: DepsMut, _env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { - ExecuteMsg::PostMemo { content } => { - let mut board = BOARD.load(deps.storage)?; - board.push(Memo { sender: info.sender.to_string(), content }); - BOARD.save(deps.storage, &board)?; - Ok(Response::new().add_attribute("action", "post_memo")) + ExecuteMsg::PostMessage { message } => { + MESSAGES.update(deps.storage, |mut messages| -> StdResult<_> { + messages.push(Message { sender: info.sender, message }); + Ok(messages) + })?; + Ok(Response::new().add_attribute("action", "post_message")) } } } + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::AllMessages {} => { + let messages = MESSAGES.load(deps.storage)?; + to_json_binary(&AllMessagesResponse { messages }) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env}; + use cosmwasm_std::from_json; + + #[test] + fn test_post_and_query() { + let mut deps = mock_dependencies(); + let env = mock_env(); + + // Instantiate + let info = message_info(&Addr::unchecked("creator"), &[]); + instantiate(deps.as_mut(), env.clone(), info, InstantiateMsg {}).unwrap(); + + // Post Message + let info = message_info(&Addr::unchecked("user1"), &[]); + let msg = ExecuteMsg::PostMessage { message: "Hello!".to_string() }; + execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // Query + let res = query(deps.as_ref(), env, QueryMsg::AllMessages {}).unwrap(); + let val: AllMessagesResponse = from_json(&res).unwrap(); + assert_eq!(val.messages.len(), 1); + assert_eq!(val.messages[0].message, "Hello!"); + assert_eq!(val.messages[0].sender, "user1"); + } +} ``` @@ -103,23 +169,46 @@ Using the `initia-appchain-dev` skill, please build and publish the MemoBoard Ru ``` -**1. Store the Code:** +**1. Build and Store the Code:** + +Standard `cargo build` binaries often fail validation on-chain. For WasmVM deployment, it is strongly recommended to use the **CosmWasm Optimizer**. + +**Note for Apple Silicon (M1/M2/M3):** Use the `cosmwasm/optimizer-arm64:0.16.1` image variant. + +```bash wrap +# Run from the root of your project +docker run --rm -v "$(pwd)/memoboard":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/optimizer:0.16.1 +``` + +The optimized binary will be located in `./memoboard/artifacts/memoboard.wasm`. Now, store the code: + ```bash wrap -minitiad tx wasm store ./target/wasm32-unknown-unknown/release/memoboard.wasm \ +# If the chain requires fees, add the --fees flag (e.g., --fees 1000000umin) +minitiad tx wasm store ./memoboard/artifacts/memoboard.wasm \ --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ --gas auto --gas-adjustment 1.4 --yes ``` -**2. Instantiate the Contract:** +**2. Retrieve the Code ID and Instantiate:** +If the `code_id` is not returned directly, query the transaction hash: +```bash wrap +minitiad q tx +``` + +Then, instantiate the contract: ```bash wrap minitiad tx wasm instantiate '{}' \ --label "memoboard" \ --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ + --gas auto --gas-adjustment 1.4 \ --no-admin --yes ``` @@ -196,6 +285,7 @@ export default defineConfig({ ```javascript wrap import { Buffer } from 'buffer' window.Buffer = Buffer +window.process = { env: { NODE_ENV: 'development' } } import React from 'react' import ReactDOM from 'react-dom/client' @@ -215,11 +305,38 @@ const wagmiConfig = createConfig({ transports: { [mainnet.id]: http() }, }); +const customChain = { + chain_id: "your-chain-id", + chain_name: "social", + pretty_name: "Social Rollup", + network_type: "testnet", + bech32_prefix: "init", + logo_URIs: { + png: "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/initia/images/initia.png", + svg: "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/initia/images/initia.svg" + }, + apis: { + rpc: [{ address: "http://localhost:26657" }], + rest: [{ address: "http://localhost:1317" }], + indexer: [{ address: "http://localhost:8080" }], + }, + fees: { + fee_tokens: [{ denom: "umin", fixed_min_gas_price: 0 }] + }, + metadata: { + minitia: { type: "miniwasm" } + } +}; + ReactDOM.createRoot(document.getElementById('root')).render( - + @@ -229,25 +346,61 @@ ReactDOM.createRoot(document.getElementById('root')).render( ``` **4. Create the `Board.jsx` Component:** -Create `src/Board.jsx` and add the contract interaction logic: +Create `src/Board.jsx` and `src/Board.css` with the following content: + +**src/Board.css:** +```css wrap +.board-container { max-width: 600px; margin: 40px auto; padding: 32px; font-family: sans-serif; } +.board-title { font-size: 2.5rem; font-weight: 800; margin-bottom: 24px; text-align: center; } +.section-header { font-size: 0.85rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: #888; margin-bottom: 16px; display: block; } +.auth-section { display: flex; justify-content: center; margin-bottom: 24px; } +.wallet-info { background: #f0f0f0; padding: 12px 16px; border-radius: 12px; display: flex; justify-content: space-between; align-items: center; width: 100%; } +.message-card { background: white; padding: 16px; border-radius: 12px; border: 1px solid #eee; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.02); } +.message-sender { font-family: monospace; font-size: 0.75rem; color: #999; } +.input-group { display: flex; gap: 12px; margin-top: 16px; } +.memo-input { flex: 1; padding: 12px 16px; border-radius: 8px; border: 1px solid #ddd; outline: none; } +.btn-primary { background: #000; color: #fff; border: none; padding: 12px 24px; border-radius: 8px; font-weight: 600; cursor: pointer; } +``` + +**src/Board.jsx:** ```javascript wrap -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { useInterwovenKit } from "@initia/interwovenkit-react"; +import { RESTClient } from "@initia/initia.js"; +import './Board.css'; const MEMO_BOARD_ADDRESS = "YOUR_CONTRACT_ADDRESS"; +const rest = new RESTClient("http://localhost:1317", { chainId: "your-chain-id" }); const Board = () => { + const [messages, setMessages] = useState([]); const [content, setContent] = useState(''); - const { address, requestTxBlock } = useInterwovenKit(); + const { initiaAddress, requestTxBlock, openWallet, openConnect } = useInterwovenKit(); + + const fetchMessages = async () => { + // Encode query to base64 for the REST path + const queryData = btoa(JSON.stringify({ all_messages: {} })); + const res = await rest.wasm.smartContractState(MEMO_BOARD_ADDRESS, queryData); + // Use optional chaining for resilience + setMessages((res?.messages || []).reverse()); + }; + + useEffect(() => { + fetchMessages(); + }, []); + + const handlePostMessage = async () => { + // Encode execute msg to Uint8Array (bytes) + const msg = new TextEncoder().encode(JSON.stringify({ post_message: { message: content } })); - const handlePostMemo = async () => { await requestTxBlock({ + chainId: "your-chain-id", messages: [{ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract", value: { - sender: address, + sender: initiaAddress, contract: MEMO_BOARD_ADDRESS, - msg: btoa(JSON.stringify({ post_memo: { content } })), + msg, funds: [] }, }], @@ -255,9 +408,38 @@ const Board = () => { }; return ( -
- setContent(e.target.value)} /> - +
+

MemoBoard

+ {!initiaAddress ? ( +
+ +
+ ) : ( +
+
+ {initiaAddress.slice(0, 10)}...{initiaAddress.slice(-6)} + +
+
+ )} + {initiaAddress && ( +
+

Post a Memo

+
+ setContent(e.target.value)} placeholder="Write a memo..." /> + +
+
+ )} +
+

Board Feed

+ {messages.map((m, i) => ( +
+
{m.sender}
+
{m.message}
+
+ ))} +
); }; @@ -277,19 +459,26 @@ the deployed contract works as expected. ```terminal wrap Using the `initia-appchain-dev` skill, I want to verify our live MemoBoard contract. Using my gas station account on my appchain, please: -1. Post a memo: "Hello from Initia!" +1. Post a message: "Hello from Initia!" 2. Query the board to see all messages. ``` -**Post Memo:** +**Post Message:** ```bash wrap -minitiad tx wasm execute '{"post_memo":{"content":"Hello!"}}' \ +# If the chain requires fees, add the --fees flag (e.g., --fees 1000000umin) +minitiad tx wasm execute '{"post_message":{"message":"Hello!"}}' \ --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ --gas auto --gas-adjustment 1.4 --yes ``` + +**Query Messages:** +```bash wrap +# Note: minitiad query commands typically do not support the --chain-id flag +minitiad query wasm contract-state smart '{"all_messages":{}}' +``` --- From c9f6d24e50bc2fc5a476003d81c9d9d5965aefe3 Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Wed, 18 Feb 2026 13:38:30 +0700 Subject: [PATCH 09/17] fix: formatting and links --- hackathon/builder-guide.mdx | 17 +- hackathon/examples/move-game.mdx | 7 +- hackathon/examples/wasm-social.mdx | 270 ++++++++++++++++++++--------- hackathon/hackathon-landing.mdx | 16 +- 4 files changed, 205 insertions(+), 105 deletions(-) diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index e63b455..b29fe49 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -6,7 +6,7 @@ title: 'Hackathon Builder Guide' The Builder Guide is designed for developers who have already completed the initial environment setup. If you haven't yet launched your first appchain, -please start with the **[Step-by-Step Guide](./hackathon-landing)**. +please start with the **[Step-by-Step Guide](/hackathon/hackathon-landing)**. ### ✅ Readiness Checklist @@ -14,13 +14,13 @@ Before proceeding, ensure you have completed these milestones: - [ ] **Tools Installed**: You have `weave`, `initiad`, and your chosen VM CLI (`minitiad`) in your PATH. - ([Step 4](./hackathon-landing#step-4:-install-required-tools)) + ([Step 4](/hackathon/hackathon-landing#step-4:-install-required-tools)) - [ ] **Infrastructure Live**: Your rollup is running and your OPinit/Relayer bots are active. - ([Step 6](./hackathon-landing#step-6:-setup-interwoven-bots-[terminal])) + ([Step 6](/hackathon/hackathon-landing#step-6:-setup-interwoven-bots-[terminal])) - [ ] **Keys Imported**: Your Gas Station mnemonic is imported into your local `initiad` and `minitiad` keyrings. - ([Step 7](./hackathon-landing#step-7:-final-key-setup-[terminal])) + ([Step 7](/hackathon/hackathon-landing#step-7:-final-key-setup-[terminal])) --- @@ -60,9 +60,12 @@ Master the **Describe → Build → Test** cycle. This is how you win the hackat ### 💰 Funding Your Personal Wallet -Before you can interact with your appchain via a browser wallet (like Keplr, Leap, or MetaMask), you need to fund your personal address from your **Gas Station**. +Before you can interact with your appchain via a browser wallet (like Keplr, +Leap, or MetaMask), you need to fund your personal address from your **Gas +Station**. **1. Copy your wallet address:** + - **Move / Wasm Track**: Copy your `init1...` address. - **EVM Track**: Copy your `0x...` address. @@ -184,5 +187,5 @@ Judges want to see **On-chain Proof**. Use this checklist before submitting. Initia-native feature. > **Mandatory:** Review the -> **[Submission & Technical Requirements](./submission-requirements)** to ensure -> you are eligible for prizes. +> **[Submission & Technical Requirements](/hackathon/submission-requirements)** +> to ensure you are eligible for prizes. diff --git a/hackathon/examples/move-game.mdx b/hackathon/examples/move-game.mdx index 01fabba..e6d3a22 100644 --- a/hackathon/examples/move-game.mdx +++ b/hackathon/examples/move-game.mdx @@ -23,7 +23,8 @@ By the end of this tutorial, you will have instructed your AI assistant to: ## 📂 Recommended Project Structure -To keep your workspace organized, we recommend the following structure inside your `my-initia-project` directory: +To keep your workspace organized, we recommend the following structure inside +your `my-initia-project` directory: ```text my-initia-project/ @@ -201,8 +202,8 @@ needs tokens to pay for transaction fees. **1. Get your Wallet Address:** Open your browser wallet and copy your address (it starts with `init1...`). -**2. Send Tokens from Gas Station:** Replace `` in the prompt -below with the address you just copied. +**2. Send Tokens from Gas Station:** Replace `` in the +prompt below with the address you just copied. **Prompt:** diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index 3b932f6..f89ce23 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -23,7 +23,8 @@ By the end of this tutorial, you will have: ## 📂 Recommended Project Structure -To keep your workspace organized, we recommend the following structure inside your `my-initia-project` directory: +To keep your workspace organized, we recommend the following structure inside +your `my-initia-project` directory: ```text my-initia-project/ @@ -55,7 +56,9 @@ tests pass. If you prefer to see the Rust logic, here is a simplified version of what your assistant would generate. If doing this manually, save the following code in `src/contract.rs` inside your `memoboard` directory (ensure `src/lib.rs` exports the `contract` module). -**Important:** Ensure your `Cargo.toml` includes the following `[lib]` section to correctly generate the Wasm binary: +**Important:** Ensure your `Cargo.toml` includes the following `[lib]` section +to correctly generate the Wasm binary: + ```toml [lib] crate-type = ["cdylib", "rlib"] @@ -133,7 +136,7 @@ mod tests { fn test_post_and_query() { let mut deps = mock_dependencies(); let env = mock_env(); - + // Instantiate let info = message_info(&Addr::unchecked("creator"), &[]); instantiate(deps.as_mut(), env.clone(), info, InstantiateMsg {}).unwrap(); @@ -171,9 +174,11 @@ Using the `initia-appchain-dev` skill, please build and publish the MemoBoard Ru **1. Build and Store the Code:** -Standard `cargo build` binaries often fail validation on-chain. For WasmVM deployment, it is strongly recommended to use the **CosmWasm Optimizer**. +Standard `cargo build` binaries often fail validation on-chain. For WasmVM +deployment, it is strongly recommended to use the **CosmWasm Optimizer**. -**Note for Apple Silicon (M1/M2/M3):** Use the `cosmwasm/optimizer-arm64:0.16.1` image variant. +**Note for Apple Silicon (M1/M2/M3):** Use the `cosmwasm/optimizer-arm64:0.16.1` +image variant. ```bash wrap # Run from the root of your project @@ -183,7 +188,8 @@ docker run --rm -v "$(pwd)/memoboard":/code \ cosmwasm/optimizer:0.16.1 ``` -The optimized binary will be located in `./memoboard/artifacts/memoboard.wasm`. Now, store the code: +The optimized binary will be located in `./memoboard/artifacts/memoboard.wasm`. +Now, store the code: ```bash wrap # If the chain requires fees, add the --fees flag (e.g., --fees 1000000umin) @@ -197,11 +203,13 @@ minitiad tx wasm store ./memoboard/artifacts/memoboard.wasm \ **2. Retrieve the Code ID and Instantiate:** If the `code_id` is not returned directly, query the transaction hash: + ```bash wrap minitiad q tx ``` Then, instantiate the contract: + ```bash wrap minitiad tx wasm instantiate '{}' \ --label "memoboard" \ @@ -221,9 +229,11 @@ minitiad tx wasm instantiate '{}' \ Ensure your personal wallet has tokens to pay for the transaction to post a memo. -**1. Get your Wallet Address:** Open your browser wallet and copy your address (it starts with `init1...`). +**1. Get your Wallet Address:** Open your browser wallet and copy your address +(it starts with `init1...`). -**2. Send Tokens from Gas Station:** Replace `` in the prompt below with the address you just copied. +**2. Send Tokens from Gas Station:** Replace `` in the +prompt below with the address you just copied. **Prompt:** @@ -253,6 +263,7 @@ Using the `initia-appchain-dev` skill, modify the Board.jsx component in the `me If you prefer to set up the frontend manually, follow these steps: **1. Create the Project and Install Dependencies:** + ```bash wrap npm create vite@latest memoboard-frontend -- --template react cd memoboard-frontend @@ -262,8 +273,9 @@ npm install --save-dev vite-plugin-node-polyfills npm install buffer util ``` -**2. Configure Vite Polyfills:** -Update `vite.config.js` to include the Node polyfills: +**2. Configure Vite Polyfills:** Update `vite.config.js` to include the Node +polyfills: + ```javascript wrap import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' @@ -282,6 +294,7 @@ export default defineConfig({ ``` **3. Set up Providers in `main.jsx`:** + ```javascript wrap import { Buffer } from 'buffer' window.Buffer = Buffer @@ -289,51 +302,55 @@ window.process = { env: { NODE_ENV: 'development' } } import React from 'react' import ReactDOM from 'react-dom/client' -import "@initia/interwovenkit-react/styles.css"; -import { injectStyles, InterwovenKitProvider, TESTNET } from "@initia/interwovenkit-react"; -import InterwovenKitStyles from "@initia/interwovenkit-react/styles.js"; -import { WagmiProvider, createConfig, http } from "wagmi"; -import { mainnet } from "wagmi/chains"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import '@initia/interwovenkit-react/styles.css' +import { + injectStyles, + InterwovenKitProvider, + TESTNET, +} from '@initia/interwovenkit-react' +import InterwovenKitStyles from '@initia/interwovenkit-react/styles.js' +import { WagmiProvider, createConfig, http } from 'wagmi' +import { mainnet } from 'wagmi/chains' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import App from './App.jsx' -injectStyles(InterwovenKitStyles); +injectStyles(InterwovenKitStyles) -const queryClient = new QueryClient(); +const queryClient = new QueryClient() const wagmiConfig = createConfig({ chains: [mainnet], transports: { [mainnet.id]: http() }, -}); +}) const customChain = { - chain_id: "your-chain-id", - chain_name: "social", - pretty_name: "Social Rollup", - network_type: "testnet", - bech32_prefix: "init", + chain_id: 'your-chain-id', + chain_name: 'social', + pretty_name: 'Social Rollup', + network_type: 'testnet', + bech32_prefix: 'init', logo_URIs: { - png: "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/initia/images/initia.png", - svg: "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/initia/images/initia.svg" + png: 'https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/initia/images/initia.png', + svg: 'https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/initia/images/initia.svg', }, apis: { - rpc: [{ address: "http://localhost:26657" }], - rest: [{ address: "http://localhost:1317" }], - indexer: [{ address: "http://localhost:8080" }], + rpc: [{ address: 'http://localhost:26657' }], + rest: [{ address: 'http://localhost:1317' }], + indexer: [{ address: 'http://localhost:8080' }], }, fees: { - fee_tokens: [{ denom: "umin", fixed_min_gas_price: 0 }] + fee_tokens: [{ denom: 'umin', fixed_min_gas_price: 0 }], }, metadata: { - minitia: { type: "miniwasm" } - } -}; + minitia: { type: 'miniwasm' }, + }, +} ReactDOM.createRoot(document.getElementById('root')).render( - @@ -345,80 +362,157 @@ ReactDOM.createRoot(document.getElementById('root')).render( ) ``` -**4. Create the `Board.jsx` Component:** -Create `src/Board.jsx` and `src/Board.css` with the following content: +**4. Create the `Board.jsx` Component:** Create `src/Board.jsx` and +`src/Board.css` with the following content: **src/Board.css:** + ```css wrap -.board-container { max-width: 600px; margin: 40px auto; padding: 32px; font-family: sans-serif; } -.board-title { font-size: 2.5rem; font-weight: 800; margin-bottom: 24px; text-align: center; } -.section-header { font-size: 0.85rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: #888; margin-bottom: 16px; display: block; } -.auth-section { display: flex; justify-content: center; margin-bottom: 24px; } -.wallet-info { background: #f0f0f0; padding: 12px 16px; border-radius: 12px; display: flex; justify-content: space-between; align-items: center; width: 100%; } -.message-card { background: white; padding: 16px; border-radius: 12px; border: 1px solid #eee; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.02); } -.message-sender { font-family: monospace; font-size: 0.75rem; color: #999; } -.input-group { display: flex; gap: 12px; margin-top: 16px; } -.memo-input { flex: 1; padding: 12px 16px; border-radius: 8px; border: 1px solid #ddd; outline: none; } -.btn-primary { background: #000; color: #fff; border: none; padding: 12px 24px; border-radius: 8px; font-weight: 600; cursor: pointer; } +.board-container { + max-width: 600px; + margin: 40px auto; + padding: 32px; + font-family: sans-serif; +} +.board-title { + font-size: 2.5rem; + font-weight: 800; + margin-bottom: 24px; + text-align: center; +} +.section-header { + font-size: 0.85rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.1em; + color: #888; + margin-bottom: 16px; + display: block; +} +.auth-section { + display: flex; + justify-content: center; + margin-bottom: 24px; +} +.wallet-info { + background: #f0f0f0; + padding: 12px 16px; + border-radius: 12px; + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +} +.message-card { + background: white; + padding: 16px; + border-radius: 12px; + border: 1px solid #eee; + margin-bottom: 16px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02); +} +.message-sender { + font-family: monospace; + font-size: 0.75rem; + color: #999; +} +.input-group { + display: flex; + gap: 12px; + margin-top: 16px; +} +.memo-input { + flex: 1; + padding: 12px 16px; + border-radius: 8px; + border: 1px solid #ddd; + outline: none; +} +.btn-primary { + background: #000; + color: #fff; + border: none; + padding: 12px 24px; + border-radius: 8px; + font-weight: 600; + cursor: pointer; +} ``` **src/Board.jsx:** -```javascript wrap -import React, { useState, useEffect } from 'react'; -import { useInterwovenKit } from "@initia/interwovenkit-react"; -import { RESTClient } from "@initia/initia.js"; -import './Board.css'; -const MEMO_BOARD_ADDRESS = "YOUR_CONTRACT_ADDRESS"; -const rest = new RESTClient("http://localhost:1317", { chainId: "your-chain-id" }); +```javascript wrap +import React, { useState, useEffect } from 'react' +import { useInterwovenKit } from '@initia/interwovenkit-react' +import { RESTClient } from '@initia/initia.js' +import './Board.css' + +const MEMO_BOARD_ADDRESS = 'YOUR_CONTRACT_ADDRESS' +const rest = new RESTClient('http://localhost:1317', { + chainId: 'your-chain-id', +}) const Board = () => { - const [messages, setMessages] = useState([]); - const [content, setContent] = useState(''); - const { initiaAddress, requestTxBlock, openWallet, openConnect } = useInterwovenKit(); + const [messages, setMessages] = useState([]) + const [content, setContent] = useState('') + const { initiaAddress, requestTxBlock, openWallet, openConnect } = + useInterwovenKit() const fetchMessages = async () => { // Encode query to base64 for the REST path - const queryData = btoa(JSON.stringify({ all_messages: {} })); - const res = await rest.wasm.smartContractState(MEMO_BOARD_ADDRESS, queryData); + const queryData = btoa(JSON.stringify({ all_messages: {} })) + const res = await rest.wasm.smartContractState( + MEMO_BOARD_ADDRESS, + queryData, + ) // Use optional chaining for resilience - setMessages((res?.messages || []).reverse()); - }; + setMessages((res?.messages || []).reverse()) + } useEffect(() => { - fetchMessages(); - }, []); + fetchMessages() + }, []) const handlePostMessage = async () => { // Encode execute msg to Uint8Array (bytes) - const msg = new TextEncoder().encode(JSON.stringify({ post_message: { message: content } })); + const msg = new TextEncoder().encode( + JSON.stringify({ post_message: { message: content } }), + ) await requestTxBlock({ - chainId: "your-chain-id", - messages: [{ - typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract", - value: { - sender: initiaAddress, - contract: MEMO_BOARD_ADDRESS, - msg, - funds: [] + chainId: 'your-chain-id', + messages: [ + { + typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', + value: { + sender: initiaAddress, + contract: MEMO_BOARD_ADDRESS, + msg, + funds: [], + }, }, - }], - }); - }; + ], + }) + } return (

MemoBoard

{!initiaAddress ? (
- +
) : (
- {initiaAddress.slice(0, 10)}...{initiaAddress.slice(-6)} - + + {initiaAddress.slice(0, 10)}...{initiaAddress.slice(-6)} + +
)} @@ -426,8 +520,15 @@ const Board = () => {

Post a Memo

- setContent(e.target.value)} placeholder="Write a memo..." /> - + setContent(e.target.value)} + placeholder="Write a memo..." + /> +
)} @@ -441,11 +542,12 @@ const Board = () => { ))}
- ); -}; + ) +} -export default Board; +export default Board ``` +
--- @@ -475,10 +577,12 @@ minitiad tx wasm execute '{"post_message":{"message":"Hello!" ``` **Query Messages:** + ```bash wrap # Note: minitiad query commands typically do not support the --chain-id flag minitiad query wasm contract-state smart '{"all_messages":{}}' ``` +
--- diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index df3e802..04e7bef 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -582,25 +582,17 @@ building your own idea. Pick a tutorial based on your preferred Virtual Machine (VM) and use case: +* **[BlockForge Game (Move)](/hackathon/examples/move-game)**: Build a simple crafting game using Move's resource safety. +* **[MiniBank (EVM)](/hackathon/examples/evm-bank)**: Create a digital piggy bank using standard Solidity. -* **[BlockForge Game (Move)](./examples/move-game)**: Build a simple crafting game using Move's resource safety. - -* **[MiniBank (EVM)](./examples/evm-bank)**: Create a digital piggy bank using standard Solidity. - -* **[MemoBoard (Wasm)](./examples/wasm-social)**: Build an on-chain guestbook using high-performance Rust. - - +* **[MemoBoard (Wasm)](/hackathon/examples/wasm-social)**: Build an on-chain guestbook using high-performance Rust. ### Option 2: Build Your Own Idea - - Jump straight into building your unique hackathon project. - - -**[→ Go to Builder Guide](./builder-guide)** +**[→ Go to Builder Guide](/hackathon/builder-guide)** --- From 43f7f56fc6538c3894244ad641efde0460234d82 Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Wed, 18 Feb 2026 13:57:38 +0700 Subject: [PATCH 10/17] fix: redundant numbering --- hackathon/hackathon-landing.mdx | 74 ++++++++++++++++----------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index 04e7bef..86d547f 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -138,8 +138,8 @@ weave init Here's a guide on how to navigate the interactive setup: - - ### 1. Generate Gas Station Account + + ### Generate Gas Station Account The Gas Station is an account on the Initia L1 that will fund your rollup's infrastructure. **Prompt:** @@ -153,7 +153,7 @@ Here's a guide on how to navigate the interactive setup: **Result:** You will see your new Gas Station Address. 💡 **Copy this address.** - ### 2. Fund Your Gas Station Account + ### Fund Your Gas Station Account **Action:** Go to the **[Initia Testnet Faucet](https://app.testnet.initia.xyz/faucet)**. @@ -170,8 +170,8 @@ Here's a guide on how to navigate the interactive setup: - - ### 3. Choose Your Action + + ### Choose Your Action **Prompt:** ```terminal wrap ? What do you want to do? @@ -186,7 +186,7 @@ Here's a guide on how to navigate the interactive setup: If you have existing rollup data, you will be prompted to delete it. Type `confirm` to proceed with the new launch. - ### 4. Select L1 Network + ### Select L1 Network **Prompt:** ```terminal wrap ? Select the Initia L1 network @@ -195,7 +195,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select `Testnet (initiation-2)`. - ### 5. Select Virtual Machine (VM) + ### Select Virtual Machine (VM) **Prompt:** ```terminal wrap ? Select the Virtual Machine (VM) @@ -204,7 +204,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select your desired VM (e.g., `Move`). - ### 6. Specify Rollup Chain ID + ### Specify Rollup Chain ID **Prompt:** ```terminal wrap ? Specify rollup chain ID @@ -217,7 +217,7 @@ Here's a guide on how to navigate the interactive setup: **Save your Chain ID!** You will need to provide this unique identifier in your final hackathon submission. - ### 7. Specify Rollup Gas Denom + ### Specify Rollup Gas Denom **Prompt:** ```terminal wrap ? Specify rollup gas denom @@ -226,7 +226,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Press `Tab` for default (`umin`) or enter your own. - ### 8. Specify Rollup Node Moniker + ### Specify Rollup Node Moniker **Prompt:** ```terminal wrap ? Specify rollup node moniker @@ -237,8 +237,8 @@ Here's a guide on how to navigate the interactive setup: - - ### 9. Submission Interval + + ### Submission Interval **Prompt:** ```terminal wrap ? Specify OP bridge config: Submission Interval @@ -247,7 +247,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Press `Tab` for default (`1m`). - ### 10. Finalization Period + ### Finalization Period **Prompt:** ```terminal wrap ? Specify OP bridge config: Output Finalization Period @@ -256,7 +256,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Press `Tab` for default (`168h`). - ### 11. Data Availability + ### Data Availability **Prompt:** ```terminal wrap ? Where should the rollup blocks data be submitted? @@ -265,7 +265,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select `Initia L1`. - ### 12. Enable Oracle Price Feed + ### Enable Oracle Price Feed **Prompt:** ```terminal wrap ? Would you like to enable oracle price feed from L1? @@ -276,8 +276,8 @@ Here's a guide on how to navigate the interactive setup: - - ### 13. Setup Method for System Keys + + ### Setup Method for System Keys **Prompt:** ```terminal wrap ? Select a setup method for the system keys @@ -286,7 +286,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select `Generate new system keys`. - ### 14. System Accounts Funding Option + ### System Accounts Funding Option **Prompt:** ```terminal wrap ? Select system accounts funding option @@ -295,7 +295,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select `Use the default preset`. - ### 15. Specify Fee Whitelist Addresses + ### Specify Fee Whitelist Addresses **Prompt:** ```terminal wrap ? Specify fee whitelist addresses @@ -304,7 +304,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Press `Enter` to leave empty. - ### 16. Add Gas Station Account to Genesis + ### Add Gas Station Account to Genesis **Prompt:** ```terminal wrap ? Would you like to add the gas station account to genesis accounts? @@ -313,7 +313,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Select `Yes`. - ### 17. Specify Genesis Balance + ### Specify Genesis Balance **Prompt:** ```terminal wrap ? Specify the genesis balance for the gas station account @@ -322,7 +322,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Enter `1000000000000000000000000` (10^24). This ensures you have plenty of tokens for testing, especially if you are on the EVM track. - ### 18. Add Additional Genesis Accounts + ### Add Additional Genesis Accounts **Prompt:** ```terminal wrap ? Would you like to add genesis accounts? @@ -333,8 +333,8 @@ Here's a guide on how to navigate the interactive setup: - - ### 19. Verify System Keys & Continue + + ### Verify System Keys & Continue **Prompt:** ```terminal wrap ? Type 'continue' to proceed. @@ -343,7 +343,7 @@ Here's a guide on how to navigate the interactive setup: **Action:** Type `continue` and press Enter. - ### 20. Confirm Transactions + ### Confirm Transactions **Prompt:** ```terminal wrap ? Confirm to proceed with signing and broadcasting the following transactions? [y]: @@ -382,7 +382,7 @@ weave opinit init executor Follow the interactive guide: - + **Prompt:** ```terminal wrap ? Existing keys in config.json detected. Would you like to add these to the keyring before proceeding? @@ -392,7 +392,7 @@ Follow the interactive guide: Select `Yes, use detected keys`. - + **Prompt:** ```terminal wrap ? Please select an option for the system key for Oracle Bridge Executor @@ -402,7 +402,7 @@ Follow the interactive guide: Select `Generate new system key`. - + **Prompt:** ```terminal wrap ? Existing config.json detected. Would you like to use the data in this file to pre-fill some fields? @@ -412,7 +412,7 @@ Follow the interactive guide: Select `Yes, prefill`. - + **Prompt:** ```terminal wrap ? Specify listen address of the bot @@ -422,11 +422,11 @@ Follow the interactive guide: Press `Tab` to use `localhost:3000` (ensure nothing else is running on this port). - + **Action:** Press `Enter` for **L1 RPC**, **Chain ID**, and **Gas Denom**. For **Rollup RPC**, press `Tab` to use `http://localhost:26657`. - + Once initialized, start the bot in the background: ```bash wrap weave opinit start executor -d @@ -450,7 +450,7 @@ weave relayer init Follow the interactive guide: - + **Prompt:** ```terminal wrap ? Select the type of Interwoven rollup you want to relay @@ -460,11 +460,11 @@ Follow the interactive guide: Select `Local Rollup (your-chain-id)`. - + **Action:** Press `Tab` for both **RPC** (`http://localhost:26657`) and **REST** (`http://localhost:1317`) endpoints. - + **Prompt:** ```terminal wrap ? Select method to setup IBC channels for the relayer @@ -474,7 +474,7 @@ Follow the interactive guide: Select `Subscribe to only transfer and nft-transfer IBC Channels (minimal setup)`. - + **Prompt:** ```terminal wrap ? Select the IBC channels you would like to relay @@ -484,7 +484,7 @@ Follow the interactive guide: Press `Space` to select all (transfer and nft-transfer), then press `Enter`. - + **Prompt:** ```terminal wrap ? Do you want to setup relayer with the challenger key @@ -494,7 +494,7 @@ Follow the interactive guide: Select `Yes (recommended)`. - + Start the relayer process: ```bash wrap weave relayer start -d From b2ad431ab6c0c03e17679ffb31353542ec591b5f Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Wed, 18 Feb 2026 17:26:44 +0700 Subject: [PATCH 11/17] docs: added example power-ups and streamlined wasm example --- hackathon/builder-guide.mdx | 113 ++++++++------------- hackathon/examples/evm-bank.mdx | 105 ++++++++++++++++--- hackathon/examples/move-game.mdx | 91 ++++++++++++++++- hackathon/examples/wasm-social.mdx | 158 ++++++++++++++++++++++------- hackathon/hackathon-landing.mdx | 60 ++++++----- 5 files changed, 379 insertions(+), 148 deletions(-) diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index b29fe49..647558f 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -104,78 +104,53 @@ Using the `initia-appchain-dev` skill, please fund my personal wallet -# Part 2: Project Inspiration - -Not sure where to start? Map your vision to the Initia stack. Here are three -high-value paths that leverage the unique Interwoven capabilities of your -appchain: - -### 🎮 High-Speed Gaming (Move/EVM) - -- **The Idea**: A fast-paced survival or strategy game where every action - (crafting, moving, attacking) is recorded on-chain. -- **Key Integration**: Use Auto-signing so players never see a wallet popup - during gameplay. -- **The Goal**: A Web2-feeling experience where the blockchain handles the logic - silently in the background. - -### 📈 Data-Rich DeFi (EVM/Wasm) - -- **The Idea**: A localized lending market or an automated trading bot - specifically for your rollup's native tokens. -- **Key Integration**: Use the Connect Oracle for real-time price feeds and the - Built-in Indexer to build a Leaderboard or Analytics Dashboard for your users. -- **The Goal**: A deep, transparent financial primitive that provides - professional-grade data to retail users. - -### 👤 Social & Consumer (Move) - -- **The Idea**: A decentralized achievement system or a social tipping platform - for creators. -- **Key Integration**: Integrate Initia Usernames to let people send assets or - rewards to name.init instead of long hex addresses. -- **The Goal**: A user-friendly application that prioritizes onboarding and - human-readable identities. - ---- - -# Part 3: Power-Up with Native Features - -To qualify for the prize pool, you must implement at least **one** of these. - -### 1. Built-in Indexer (Rich Data) - -Query transaction history and NFT holdings via REST APIs. - -**Prompt:** - -```terminal wrap -Using the `initia-appchain-dev` skill, how do I query the built-in indexer to show my transaction history in my React frontend? -``` - -### 2. Connect Oracle (Skip/Slinky) - -Access fast, enshrined price data directly in your smart contracts. - -**Prompt:** - -```terminal wrap -Using the `initia-appchain-dev` skill, show me how to use the `initia_std::oracle` to get the current price of ETH in my Move module. -``` - -### 3. Auto-signing (Web2 UX) - -Enable frictionless, session-based signing for high-frequency interactions. - -**Prompt:** - -```terminal wrap -Using the `initia-appchain-dev` skill, modify my InterwovenKit frontend to enable auto-signing for 1 hour. -``` +# Part 2: Choose Your Blueprint Pattern + +To build a winning hackathon project, don't just write a contract—implement an +**Interwoven Blueprint**. These patterns leverage Initia's native features to +create experiences that are impossible on other chains. + + + + **The Goal:** A high-frequency application where the blockchain handles logic silently in the background. Users never see a wallet popup after the initial session start. + - **Native Feature:** [Auto-signing](/interwovenkit/features/autosign/introduction) + - **Best for:** Gaming, Social tipping, High-frequency trading. + - **Reference Implementation:** [BlockForge (Move)](/hackathon/examples/move-game) + + **AI Power-Up Prompt:** + ```terminal wrap + Using the `initia-appchain-dev` skill, please modify my InterwovenKit frontend to enable auto-signing for 1 hour so my users can interact with my contract without constant popups. + ``` + + + + **The Goal:** An application that makes decisions based on real-time, high-fidelity external data provided directly by the chain infrastructure. + - **Native Feature:** [Connect Oracle](/developers/developer-guides/tools/oracles/connect/introduction) or [Built-in Indexer](/developers/developer-guides/tools/indexers/indexer-introduction) + - **Best for:** DeFi Lending, Automated Agents, Analytics Dashboards. + - **Reference Implementation:** [MiniBank (EVM)](/hackathon/examples/evm-bank) + + **AI Power-Up Prompt:** + ```terminal wrap + Using the `initia-appchain-dev` skill, show me how to use the native Oracle precompile in my smart contract to fetch the live price of ETH/USD. + ``` + + + + **The Goal:** An application that prioritizes human-readable identities and seamless onboarding, making crypto feel like a standard Web2 app. + - **Native Feature:** [Initia Usernames](/home/core-applications/initia-usernames) + - **Best for:** Consumer Social, Peer-to-peer payments, DAO governance. + - **Reference Implementation:** [MemoBoard (Wasm)](/hackathon/examples/wasm-social) + + **AI Power-Up Prompt:** + ```terminal wrap + Using the `initia-appchain-dev` skill, modify my React frontend to use the `useUsernameQuery` hook so I can display the .init names of my users instead of their hex addresses. + ``` + + --- -# Part 4: Making It Demo-Ready +# Part 3: Making It Demo-Ready Judges want to see **On-chain Proof**. Use this checklist before submitting. diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx index 992925c..5be6fff 100644 --- a/hackathon/examples/evm-bank.mdx +++ b/hackathon/examples/evm-bank.mdx @@ -205,19 +205,15 @@ Using the `initia-appchain-dev` skill, please build and publish the MiniBank Sol --- -## Step 3: Fund your Browser Wallet +## Step 3: Fund your Browser Wallet (L1) -Ensure your personal wallet has tokens to interact with the bank. +To interact with your appchain, you first need testnet tokens on the Initia L1. In the next step, we will use the **Interwoven Bridge** to move these tokens to your appchain. -**1. Get your EVM Address:** Open your browser wallet (like Keplr or Leap) and copy your Ethereum-style address (it starts with `0x...`). +**1. Get your Address:** Open your browser wallet (like Keplr or Leap) and copy your address. -**2. Send Tokens from Gas Station:** Replace `` in the prompt below with the address you just copied. +**2. Use the Faucet:** Visit the **[Initia Testnet Faucet](https://app.testnet.initia.xyz/faucet)**, paste your address, and request testnet `INIT` tokens. -**Prompt:** - -```terminal wrap -Using the `initia-appchain-dev` skill, please fund my wallet address with 1 INIT on L1 and 100 of my appchain's native tokens on L2. -``` +**3. Verify Balance:** Ensure you see your `INIT` balance in your wallet on the `Initia Testnet` network. --- @@ -457,6 +453,7 @@ import { encodeFunctionData, parseEther, formatEther } from "viem"; import { AccAddress } from "@initia/initia.js"; const MINI_BANK_ADDRESS = "YOUR_CONTRACT_ADDRESS"; +const CHAIN_ID = "your-chain-id"; // Found in Step 2 const MINI_BANK_ABI = [ { name: "deposit", type: "function", stateMutability: "payable", inputs: [] }, { name: "withdraw", type: "function", inputs: [{ name: "amount", type: "uint256" }] }, @@ -468,7 +465,7 @@ const Bank = () => { const [amount, setAmount] = useState(''); const [balance, setBalance] = useState('0'); const [isPending, setIsPending] = useState(false); - const { address, initiaAddress, requestTxBlock } = useInterwovenKit(); + const { address, initiaAddress, requestTxBlock, openDeposit, openWithdraw } = useInterwovenKit(); const fetchBalance = async () => { if (!address) return; @@ -500,13 +497,27 @@ const Bank = () => { return () => clearInterval(interval); }, [address]); + const handleBridgeIn = () => { + openDeposit({ + denoms: ["uinit"], // Bridge L1 INIT + chainId: CHAIN_ID, // To our Appchain + }); + }; + + const handleBridgeOut = () => { + openWithdraw({ + denoms: ["uinit"], // Move L2 INIT + chainId: CHAIN_ID, // From our Appchain (to L1) + }); + }; + const handleDeposit = async () => { if (!amount || !initiaAddress) return; const data = encodeFunctionData({ abi: MINI_BANK_ABI, functionName: "deposit" }); setIsPending(true); try { await requestTxBlock({ - chainId: "your-chain-id", + chainId: CHAIN_ID, messages: [{ typeUrl: "/minievm.evm.v1.MsgCall", value: { @@ -541,7 +552,7 @@ const Bank = () => { setIsPending(true); try { await requestTxBlock({ - chainId: "your-chain-id", + chainId: CHAIN_ID, messages: [{ typeUrl: "/minievm.evm.v1.MsgCall", value: { @@ -566,14 +577,25 @@ const Bank = () => { } }; + const bridgeContainerStyle = { backgroundColor: '#fef3c7', padding: '20px', borderRadius: '16px', marginBottom: '20px', border: '1px solid #fde68a', textAlign: 'left' }; const balanceContainerStyle = { backgroundColor: '#f1f5f9', padding: '30px', borderRadius: '16px', marginBottom: '30px', border: '1px solid #e2e8f0' }; const balanceValueStyle = { fontSize: '42px', fontWeight: '800', color: '#2563eb', margin: '10px 0', fontFamily: 'monospace' }; const inputStyle = { width: '100%', padding: '14px', marginBottom: '20px', borderRadius: '10px', border: '2px solid #e2e8f0', fontSize: '16px', boxSizing: 'border-box' }; const buttonContainerStyle = { display: 'flex', gap: '15px' }; const actionButtonStyle = { flex: 1, padding: '14px', borderRadius: '10px', border: 'none', fontWeight: '700', fontSize: '16px', cursor: 'pointer', color: 'white' }; + const bridgeButtonStyle = { backgroundColor: '#d97706', color: 'white', border: 'none', padding: '8px 16px', borderRadius: '8px', cursor: 'pointer', fontSize: '14px', fontWeight: '600' }; return (
+
+
Interwoven Bridge
+

Move funds between Initia L1 and your Appchain.

+
+ + +
+
+
Your Savings Balance
{balance} GAS
@@ -674,6 +696,65 @@ minitiad tx evm call $DATA \ --- +# ⚡ Power-Up: Connect Oracle (Price Feeds) + +To make your MiniBank "Interwoven-native," you can use the **Connect Oracle** to +show users the real-time USD value of their savings. + +### 1. Update the Contract + +The oracle is a pre-deployed contract on your appchain. You can query it to get the +latest price of any asset (e.g., `INIT/USD`). + +**Example Prompt:** + +```terminal wrap +Using the `initia-appchain-dev` skill, please modify my MiniBank contract to use the `ConnectOracle` contract. Add a function `getSavingsInUSD()` that fetches the current price of INIT and returns the user's balance multiplied by that price. +``` + + +The `ConnectOracle` interface is built-in. Here is how your contract interacts +with it: + +```solidity wrap +interface IConnectOracle { + struct Price { + uint256 price; + uint256 timestamp; + uint64 height; + uint64 nonce; + uint64 decimal; + uint64 id; + } + function get_price(string memory pair_id) external view returns (Price memory); +} + +contract MiniBank { + // The oracle address can be queried from the chain RPC + // (minievm.evm.v1.Query/ConnectOracle) + IConnectOracle public oracle; + + constructor(address _oracle) { + oracle = IConnectOracle(_oracle); + } + + // ... existing balance logic ... + + function getSavingsInUSD() public view returns (uint256) { + IConnectOracle.Price memory priceData = oracle.get_price("INIT/USD"); + return (balances[msg.sender] * priceData.price) / (10**priceData.decimal); + } +} +``` + + + **Pro Tip:** You can find your appchain's Oracle address by asking your AI + assistant to run the `ConnectOracle` query against your local node. + + + +--- + ## Next Steps Now that you've mastered an EVM application, you're ready to build your own diff --git a/hackathon/examples/move-game.mdx b/hackathon/examples/move-game.mdx index e6d3a22..7169bb3 100644 --- a/hackathon/examples/move-game.mdx +++ b/hackathon/examples/move-game.mdx @@ -229,12 +229,33 @@ Using the `initia-appchain-dev` skill, please scaffold a new Vite + React applic ```terminal wrap Now, using the `initia-appchain-dev`, please modify the Game.jsx component in the `blockforge-frontend` directory to interact with our deployed blockforge smart contract on my appchain. -The Mint Shard button should call the mint_shard function, and the Craft Relic button should call the craft_relic function. Also, please display the player's current inventory of shards and relics. Finally, add a button to enable/disable the native auto-signing feature for a smoother game experience. +The Mint Shard button should call the mint_shard function, and the Craft Relic button should call the craft_relic function. Also, please display the player's current inventory of shards and relics. ``` + ### 1. Project Setup Refer to the [Interwoven Kit Documentation](../../interwovenkit/introduction) - for detailed snippets on connecting your frontend to an appchain. + for initial project scaffolding instructions. + + ### 2. Configure Providers + Wrap your application with `InterwovenKitProvider` to enable wallet + connectivity. + + ```tsx main.jsx + import { InterwovenKitProvider, TESTNET } from "@initia/interwovenkit-react"; + + // ... other imports + + ReactDOM.createRoot(document.getElementById("root")).render( + + + + + + + + ); + ``` --- @@ -283,6 +304,72 @@ minitiad query move view items view_inventory \ --- +# ⚡ Power-Up: Auto-signing (Session UX) + +To make your BlockForge game "Interwoven-native," you can enable **Auto-signing** +to create a frictionless experience where players don't see wallet popups for +every game action. + +### 1. How it Works + +When a user enables Auto-sign, InterwovenKit performs three steps: +1. **Ghost Wallet Derivation**: The user signs a one-time message + (`personal_sign`) to derive a unique, application-specific HD wallet. +2. **Authz Grant**: The user's primary wallet grants permission to this ghost + wallet to execute specific Move functions (`MsgExecute`) on their behalf. +3. **Feegrant**: The primary wallet authorizes the ghost wallet to use its + balance to pay for transaction fees. + +### 2. Update the Frontend + +You can enable session-based signing by modifying your provider configuration +and adding a toggle in your UI. + +**Example Prompt:** + +```terminal wrap +Using the `initia-appchain-dev` skill, please modify my InterwovenKit configuration in `main.jsx` to enable `enableAutoSign`. Then, update `Game.jsx` to include a button that toggles auto-signing on and off for the player using the `autoSign` methods from `useInterwovenKit`. +``` + + +First, enable the feature in your provider: + +```tsx main.jsx + + + +``` + +Then, use the `useInterwovenKit` hook in your component to manage the session: + +```tsx Game.jsx +const { autoSign } = useInterwovenKit(); +const chainId = "your-chain-id"; + +// Check if auto-sign is active for this chain +const isAutoSignEnabled = autoSign.isEnabledByChain[chainId]; + +return ( + +); +``` + + + **Pro Tip:** You can check the exact expiration of the current session using `autoSign.expiredAtByChain[chainId]`. + + + +--- + ## Next Steps Now that you've mastered a Move application, you're ready to build your own diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index f89ce23..141f455 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -70,12 +70,12 @@ use cosmwasm_std::{entry_point, to_json_binary, Binary, Deps, DepsMut, Env, Mess use cw_storage_plus::Item; #[cw_serde] -pub struct Message { +pub struct Memo { pub sender: Addr, pub message: String, } -pub const MESSAGES: Item> = Item::new("messages"); +pub const MESSAGES: Item> = Item::new("messages"); #[cw_serde] pub struct InstantiateMsg {} @@ -94,23 +94,22 @@ pub enum QueryMsg { #[cw_serde] pub struct AllMessagesResponse { - pub messages: Vec, + pub messages: Vec, } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate(deps: DepsMut, _env: Env, _info: MessageInfo, _msg: InstantiateMsg) -> StdResult { +pub fn instantiate(deps: DepsMut, _env: Env, _info: MessageInfo, _msg: InstantiateMsg) -> Result { MESSAGES.save(deps.storage, &vec![])?; Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute(deps: DepsMut, _env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { +pub fn execute(deps: DepsMut, _env: Env, info: MessageInfo, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::PostMessage { message } => { - MESSAGES.update(deps.storage, |mut messages| -> StdResult<_> { - messages.push(Message { sender: info.sender, message }); - Ok(messages) - })?; + let mut messages = MESSAGES.load(deps.storage)?; + messages.push(Memo { sender: info.sender, message }); + MESSAGES.save(deps.storage, &messages)?; Ok(Response::new().add_attribute("action", "post_message")) } } @@ -151,7 +150,7 @@ mod tests { let val: AllMessagesResponse = from_json(&res).unwrap(); assert_eq!(val.messages.len(), 1); assert_eq!(val.messages[0].message, "Hello!"); - assert_eq!(val.messages[0].sender, "user1"); + assert_eq!(val.messages[0].sender.as_str(), "user1"); } } ``` @@ -177,15 +176,19 @@ Using the `initia-appchain-dev` skill, please build and publish the MemoBoard Ru Standard `cargo build` binaries often fail validation on-chain. For WasmVM deployment, it is strongly recommended to use the **CosmWasm Optimizer**. -**Note for Apple Silicon (M1/M2/M3):** Use the `cosmwasm/optimizer-arm64:0.16.1` -image variant. +**Note for Apple Silicon (M1/M2/M3):** You **MUST** use the +`cosmwasm/optimizer-arm64:0.16.1` image variant or the build will be extremely +slow and may fail. ```bash wrap # Run from the root of your project +# Use 'optimizer' for x86_64 or 'optimizer-arm64' for Apple Silicon +OPTIMIZER_IMAGE="cosmwasm/optimizer-arm64:0.16.1" + docker run --rm -v "$(pwd)/memoboard":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/optimizer:0.16.1 + $OPTIMIZER_IMAGE ``` The optimized binary will be located in `./memoboard/artifacts/memoboard.wasm`. @@ -202,10 +205,11 @@ minitiad tx wasm store ./memoboard/artifacts/memoboard.wasm \ **2. Retrieve the Code ID and Instantiate:** -If the `code_id` is not returned directly, query the transaction hash: +If the `code_id` is not returned directly, wait for 5 seconds for indexing and then query the transaction hash: ```bash wrap -minitiad q tx +# Retrieve Code ID +minitiad q tx --output json | jq -r '.events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value' ``` Then, instantiate the contract: @@ -220,6 +224,15 @@ minitiad tx wasm instantiate '{}' \ --no-admin --yes ``` +**3. Retrieve the Contract Address:** + +Wait for 5 seconds for indexing and then query the transaction hash: + +```bash wrap +# Retrieve Contract Address +minitiad q tx --output json | jq -r '.events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value' +``` + --- @@ -416,6 +429,10 @@ ReactDOM.createRoot(document.getElementById('root')).render( font-size: 0.75rem; color: #999; } +.message-content { + margin-top: 8px; + font-size: 1.1rem; +} .input-group { display: flex; gap: 12px; @@ -455,44 +472,57 @@ const rest = new RESTClient('http://localhost:1317', { const Board = () => { const [messages, setMessages] = useState([]) const [content, setContent] = useState('') - const { initiaAddress, requestTxBlock, openWallet, openConnect } = + const { initiaAddress, requestTxBlock, openWallet, openConnect, username } = useInterwovenKit() + const truncate = (addr) => `${addr.slice(0, 10)}...${addr.slice(-6)}` + const fetchMessages = async () => { - // Encode query to base64 for the REST path - const queryData = btoa(JSON.stringify({ all_messages: {} })) - const res = await rest.wasm.smartContractState( - MEMO_BOARD_ADDRESS, - queryData, - ) - // Use optional chaining for resilience - setMessages((res?.messages || []).reverse()) + try { + // Wasm queries via REST MUST be base64 encoded + const queryData = Buffer.from(JSON.stringify({ all_messages: {} })).toString('base64') + const res = await rest.wasm.smartContractState(MEMO_BOARD_ADDRESS, queryData) + setMessages((res?.messages || []).reverse()) + } catch (e) { + console.error("Failed to fetch messages", e) + } } useEffect(() => { fetchMessages() + // Poll for new messages every 5 seconds + const interval = setInterval(fetchMessages, 5000) + return () => clearInterval(interval) }, []) const handlePostMessage = async () => { + if (!content) return + // Encode execute msg to Uint8Array (bytes) const msg = new TextEncoder().encode( JSON.stringify({ post_message: { message: content } }), ) - await requestTxBlock({ - chainId: 'your-chain-id', - messages: [ - { - typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', - value: { - sender: initiaAddress, - contract: MEMO_BOARD_ADDRESS, - msg, - funds: [], + try { + await requestTxBlock({ + chainId: 'your-chain-id', + messages: [ + { + typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract', + value: { + sender: initiaAddress, + contract: MEMO_BOARD_ADDRESS, + msg, + funds: [], + }, }, - }, - ], - }) + ], + }) + setContent('') + fetchMessages() + } catch (e) { + console.error("Transaction failed", e) + } } return ( @@ -508,7 +538,7 @@ const Board = () => {
- {initiaAddress.slice(0, 10)}...{initiaAddress.slice(-6)} + {truncate(initiaAddress)} +
@@ -624,7 +645,7 @@ minitiad query wasm contract-state smart '{"all_messages":{}} To make your MemoBoard "Interwoven-native," you can replace long, complex addresses with human-readable **Initia Usernames** (e.g., `vitalik.init`). -### Step 0: Register your .init Name +## Step 6: Register your .init Name Before updating your code, you should register a primary username for your wallet on the Initia testnet. @@ -637,7 +658,7 @@ on the Initia testnet. 4. Click **Register** and approve the transaction. Once resolved, your new `.init` name will appear in the top-right corner of the Initia App. -### 1. Update the Frontend +## Step 7: Update the Frontend Your AI assistant knows how to integrate Initia Usernames. Simply ask it to update your board. @@ -649,19 +670,30 @@ Using the `initia-appchain-dev` skill, please add Initia username support to my ``` -The `useInterwovenKit()` hook provides the `username` for the currently connected wallet. You can use it to personalize the UI: - -```tsx -const { initiaAddress, username } = useInterwovenKit(); +The `useInterwovenKit()` hook provides the `username` for the currently connected wallet. To implement this, update your `src/Board.jsx` to extract the `username` and update the render logic: + +```tsx wrap +// 1. Extract username from the hook +const { initiaAddress, username, openConnect, openWallet, requestTxSync } = useInterwovenKit(); + +// 2. Update the Header to show the username +
+ + +
-// In your render: +// 3. Update the Feed to show the username for the current user's posts
{m.sender === initiaAddress && username ? username : truncate(m.sender)}
``` - **Pro Tip:** For other addresses in the feed, continue using the truncated hex address until a public multi-address resolver is available. + **Pro Tip:** This pattern ensures that the connected user sees their identity reflected immediately in the application (in both the header and their own posts). For other participants in the feed, we continue to show the truncated address until a global resolver is implemented.
diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index 904914f..c242fdd 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -366,7 +366,7 @@ Initia L1 and your appchain, you need to start the **OPinit Executor** and the **IBC Relayer**. These bots handle the "interweaving" of your chain. - **Prerequisite:** Your appchain must be running before configuring these bots. Because `weave init` (and `weave rollup start`) runs your chain in the background, you can continue using the same terminal window. + **Prerequisite:** Your appchain must be running before configuring these bots. Because `weave init` runs your chain in the background, you can continue using the same terminal window. ### 6.1 Start the OPinit Executor From da878a2d112a27f75476d5c198f693946bae33fa Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Fri, 20 Feb 2026 09:08:20 +0700 Subject: [PATCH 13/17] docs: finalize example development workflow and formatting --- hackathon/builder-guide.mdx | 80 ++++++++--- hackathon/examples/evm-bank.mdx | 181 +++++++++++++------------ hackathon/examples/move-game.mdx | 188 ++++++++++++++++++-------- hackathon/examples/wasm-social.mdx | 68 ++++++---- hackathon/hackathon-landing.mdx | 18 ++- hackathon/submission-requirements.mdx | 12 +- 6 files changed, 350 insertions(+), 197 deletions(-) diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index 647558f..c8cf2cc 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -29,11 +29,11 @@ Before proceeding, ensure you have completed these milestones: Use these common commands and AI prompts to manage your project during the hackathon. -| Task | Command / AI Prompt | -| :------------------ | :------------------------------------------------------------------------------------------------------------------------------ | -| **Resume Appchain** | `weave start` | -| **Health Check** | _"Using the `initia-appchain-dev` skill, please verify that my appchain is producing blocks and show my gas-station balances."_ | -| **Key Import** | See the [Local Keyring Import](#key-import) section below. | +| Task | Command / AI Prompt | +| :------------------ | :---------------------------------------------------------------------------------------------------------------------------- | +| **Resume Appchain** | `weave start` | +| **Health Check** | _Using the `initia-appchain-dev` skill, please verify that my appchain is producing blocks and show my gas-station balances._ | +| **Key Import** | See the [Local Keyring Import](#key-import) section below. | ### Local Keyring Import @@ -106,12 +106,12 @@ Using the `initia-appchain-dev` skill, please fund my personal wallet - + **The Goal:** A high-frequency application where the blockchain handles logic silently in the background. Users never see a wallet popup after the initial session start. - **Native Feature:** [Auto-signing](/interwovenkit/features/autosign/introduction) - **Best for:** Gaming, Social tipping, High-frequency trading. @@ -123,19 +123,21 @@ create experiences that are impossible on other chains. ``` - - **The Goal:** An application that makes decisions based on real-time, high-fidelity external data provided directly by the chain infrastructure. - - **Native Feature:** [Connect Oracle](/developers/developer-guides/tools/oracles/connect/introduction) or [Built-in Indexer](/developers/developer-guides/tools/indexers/indexer-introduction) - - **Best for:** DeFi Lending, Automated Agents, Analytics Dashboards. - - **Reference Implementation:** [MiniBank (EVM)](/hackathon/examples/evm-bank) - - **AI Power-Up Prompt:** - ```terminal wrap - Using the `initia-appchain-dev` skill, show me how to use the native Oracle precompile in my smart contract to fetch the live price of ETH/USD. - ``` - - - + + **The Goal:** An application that makes decisions based on real-time, + high-fidelity external data provided directly by the chain infrastructure. - + **Native Feature:** [Connect + Oracle](/developers/developer-guides/tools/oracles/connect/introduction) or + [Built-in + Indexer](/developers/developer-guides/tools/indexers/indexer-introduction) - + **Best for:** DeFi Lending, Automated Agents, Analytics Dashboards. - + **Reference Implementation:** [MiniBank (EVM)](/hackathon/examples/evm-bank) + **AI Power-Up Prompt:** ```terminal wrap Using the `initia-appchain-dev` + skill, show me how to use the native Oracle precompile in my smart contract to + fetch the live price of ETH/USD. ``` + + + **The Goal:** An application that prioritizes human-readable identities and seamless onboarding, making crypto feel like a standard Web2 app. - **Native Feature:** [Initia Usernames](/home/core-applications/initia-usernames) - **Best for:** Consumer Social, Peer-to-peer payments, DAO governance. @@ -161,6 +163,44 @@ Judges want to see **On-chain Proof**. Use this checklist before submitting. - [ ] **Native Feature**: You've pointed to the code implementing an Initia-native feature. +--- + +# Part 4: Debugging & Troubleshooting + +Speed is everything in a hackathon, and debugging is where most time is lost. +Use these professional workflows to unblock yourself, even when following the +standard examples. + +### ⚡️ High-Signal AI Debugging + +Whether you are building from scratch or running a blueprint example, errors are +inevitable. + +1. **Open the Browser Console**: Press `F12` or `Cmd+Option+J` to see the exact + error logs. +2. **Context is King**: Ensure your AI agent (Cursor, Gemini) is **opened in + your project root**. This allows it to reference your `package.json`, your + `interwovenkit` initialization, and your specific chain configuration. +3. **The Perfect Debugging Prompt**: Provide the **console error** alongside + the **relevant file**. + > _Prompt Example: "I'm following the MiniBank example and getting this + > `RPC Error: ...` in the console. Here is my `App.tsx`. Why is my + > transaction failing?"_ + +### 📚 Deep Dives & Source Truth + +If your AI agent is stuck or you need to see the source of truth: + +- **Official Docs**: Visit [docs.initia.xyz](https://docs.initia.xyz/) for + architectural details and API references. +- **Initia Examples**: Reference the + [initia-labs/examples](https://github.com/initia-labs/examples) repository for + working code across all VMs (EVM, Move, Wasm). +- **Core Repositories**: Explore [initia-labs](https://github.com/initia-labs) + on GitHub to see the underlying implementation of the SDKs and CLI tools. + +--- + > **Mandatory:** Review the > **[Submission & Technical Requirements](/hackathon/submission-requirements)** > to ensure you are eligible for prizes. diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx index ee7c7c5..bc9064e 100644 --- a/hackathon/examples/evm-bank.mdx +++ b/hackathon/examples/evm-bank.mdx @@ -171,7 +171,8 @@ cd minibank forge build # Extract bytecode (requires jq) -jq -r '.bytecode.object' out/MiniBank.sol/MiniBank.json | sed 's/^0x//' | tr -d '\n' > minibank.bin +# Ensure NO '0x' prefix and NO trailing newlines +jq -r '.bytecode.object' out/MiniBank.sol/MiniBank.json | tr -d '\n' | sed 's/^0x//' > minibank.bin ``` Then deploy the binary. **Find your Chain ID first** if you don't know it: @@ -190,28 +191,32 @@ minitiad tx evm create minibank.bin \ --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ - --gas auto --gas-adjustment 1.4 --yes --output json + --gas auto --gas-adjustment 1.4 --yes --output json > deploy.json ``` **Retrieve your contract address:** The output will provide a `txhash`. Wait a few seconds for indexing, then find your contract address: ```bash wrap -sleep 5 -minitiad q tx --output json | jq -r '.events[] | select(.type=="contract_created") | .attributes[] | select(.key=="contract") | .value' +# Replace with the hash from deploy.json +minitiad q tx --output json | jq -r '.events[] | select(.type=="contract_created") | .attributes[] | select(.key=="contract") | .value' ``` --- -## Step 3: Fund your Browser Wallet (L1) +## Step 3: Fund your Browser Wallet -To interact with your appchain, you first need testnet tokens on the Initia L1. In the next step, we will use the **Interwoven Bridge** to move these tokens to your appchain. +Ensure your personal wallet has tokens to pay for the gas and initial deposits on your appchain. -**1. Get your Address:** Open your browser wallet (like Keplr or Leap) and copy your address. +**1. Get your Wallet Address:** Open your browser wallet and copy your address (it starts with `init1...`). -**2. Use the Faucet:** Visit the **[Initia Testnet Faucet](https://app.testnet.initia.xyz/faucet)**, paste your address, and request testnet `INIT` tokens. +**2. Send Tokens from Gas Station:** Replace `` in the prompt below with the address you just copied. -**3. Verify Balance:** Ensure you see your `INIT` balance in your wallet on the `Initia Testnet` network. +**Prompt:** + +```terminal wrap +Using the `initia-appchain-dev` skill, please fund my wallet address with 100 of my appchain's native tokens on L2. +``` --- @@ -334,7 +339,8 @@ const customChain = { }, metadata: { minitia: { type: "minievm" }, - is_evm: true + is_evm: true, + is_l1: false } }; @@ -442,6 +448,12 @@ export default App **5. Create the `Bank.jsx` Component:** Create `src/Bank.jsx` and add the contract interaction logic. +> **Pro Tip**: For a cleaner UI, hide the numeric "up/down" arrows in your CSS: +> ```css +> input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } +> input[type=number] { -moz-appearance: textfield; } +> ``` + > **Pro Tip**: For `view` functions that depend on `msg.sender` (like `getBalance`), you MUST provide a `from` address in your `eth_call` parameters so the appchain knows whose balance to check. ```javascript wrap @@ -463,7 +475,7 @@ const Bank = () => { const [amount, setAmount] = useState(''); const [balance, setBalance] = useState('0'); const [isPending, setIsPending] = useState(false); - const { address, initiaAddress, requestTxBlock, openDeposit, openWithdraw } = useInterwovenKit(); + const { address, initiaAddress, requestTxBlock } = useInterwovenKit(); const fetchBalance = async () => { if (!address) return; @@ -495,20 +507,6 @@ const Bank = () => { return () => clearInterval(interval); }, [address]); - const handleBridgeIn = () => { - openDeposit({ - denoms: ["uinit"], // Bridge L1 INIT - chainId: CHAIN_ID, // To our Appchain - }); - }; - - const handleBridgeOut = () => { - openWithdraw({ - denoms: ["uinit"], // Move L2 INIT - chainId: CHAIN_ID, // From our Appchain (to L1) - }); - }; - const handleDeposit = async () => { if (!amount || !initiaAddress) return; const data = encodeFunctionData({ abi: MINI_BANK_ABI, functionName: "deposit" }); @@ -516,7 +514,7 @@ const Bank = () => { try { await requestTxBlock({ chainId: CHAIN_ID, - messages: [{ + msgs: [{ typeUrl: "/minievm.evm.v1.MsgCall", value: { sender: initiaAddress, @@ -524,6 +522,7 @@ const Bank = () => { input: data, value: parseEther(amount).toString(), accessList: [], + authList: [], }, }], onSuccess: () => { @@ -551,7 +550,7 @@ const Bank = () => { try { await requestTxBlock({ chainId: CHAIN_ID, - messages: [{ + msgs: [{ typeUrl: "/minievm.evm.v1.MsgCall", value: { sender: initiaAddress, @@ -559,6 +558,7 @@ const Bank = () => { input: data, value: "0", accessList: [], + authList: [], }, }], onSuccess: () => { @@ -575,25 +575,14 @@ const Bank = () => { } }; - const bridgeContainerStyle = { backgroundColor: '#fef3c7', padding: '20px', borderRadius: '16px', marginBottom: '20px', border: '1px solid #fde68a', textAlign: 'left' }; const balanceContainerStyle = { backgroundColor: '#f1f5f9', padding: '30px', borderRadius: '16px', marginBottom: '30px', border: '1px solid #e2e8f0' }; const balanceValueStyle = { fontSize: '42px', fontWeight: '800', color: '#2563eb', margin: '10px 0', fontFamily: 'monospace' }; const inputStyle = { width: '100%', padding: '14px', marginBottom: '20px', borderRadius: '10px', border: '2px solid #e2e8f0', fontSize: '16px', boxSizing: 'border-box' }; const buttonContainerStyle = { display: 'flex', gap: '15px' }; const actionButtonStyle = { flex: 1, padding: '14px', borderRadius: '10px', border: 'none', fontWeight: '700', fontSize: '16px', cursor: 'pointer', color: 'white' }; - const bridgeButtonStyle = { backgroundColor: '#d97706', color: 'white', border: 'none', padding: '8px 16px', borderRadius: '8px', cursor: 'pointer', fontSize: '14px', fontWeight: '600' }; return (
-
-
Interwoven Bridge
-

Move funds between Initia L1 and your Appchain.

-
- - -
-
-
Your Savings Balance
{balance} GAS
@@ -669,16 +658,11 @@ minitiad tx evm call $SIG \ ``` **3. Query Balance:** -Querying a function that uses `msg.sender` requires a `from` address in the JSON-RPC call. +Querying a function that uses `msg.sender` requires a `from` address in the query call. ```bash wrap SIG=$(cast sig "getBalance()") -# Replace with the address from step 1 -HEX_RESULT=$(curl -s -X POST -H "Content-Type: application/json" \ - --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"from":"","to":"","data":"'$SIG'"},"latest"],"id":1}' \ - http://localhost:8545 | jq -r '.result') - -# Convert hex to decimal tokens -cast --from-wei $HEX_RESULT +# Replace and +minitiad q evm call 0x$SIG --output json ``` **4. Withdraw (0.5 tokens):** @@ -694,60 +678,91 @@ minitiad tx evm call $DATA \ --- -# ⚡ Power-Up: Connect Oracle (Price Feeds) +# ⚡ Power-Up: Interwoven Bridge -To make your MiniBank "Interwoven-native," you can use the **Connect Oracle** to -show users the real-time USD value of their savings. +Adding bridge support allows users to bring liquidity from the broader Initia +ecosystem into your rollup. This is essential for onboarding users from L1, +enabling exit liquidity, and ensuring your app is mainnet-ready. -### 1. Update the Contract + + **Local Dev Limitation:** The Interwoven UI requires a registered chain ID to + resolve assets. While it may appear empty for your local-only appchain, adding + this button prepares your app for its public launch. + -The oracle is a pre-deployed contract on your appchain. You can query it to get the -latest price of any asset (e.g., `INIT/USD`). +### Step 6: Update the Frontend + +The `useInterwovenKit()` hook provides `openDeposit` and `openWithdraw` +functions that open a specialized modal for bridging assets. **Example Prompt:** ```terminal wrap -Using the `initia-appchain-dev` skill, please modify my MiniBank contract to use the `ConnectOracle` contract. Add a function `getSavingsInUSD()` that fetches the current price of INIT and returns the user's balance multiplied by that price. +Using the `initia-appchain-dev` skill, please enable Interwoven Bridge support in my MiniBank so I can move funds between chains on Initia. ``` - -The `ConnectOracle` interface is built-in. Here is how your contract interacts -with it: + +To implement this, update your `src/Bank.jsx` to include the bridge logic and +UI: -```solidity wrap -interface IConnectOracle { - struct Price { - uint256 price; - uint256 timestamp; - uint64 height; - uint64 nonce; - uint64 decimal; - uint64 id; - } - function get_price(string memory pair_id) external view returns (Price memory); -} +```tsx wrap +// 1. Extract bridge functions from the hook +const { address, openBridge } = useInterwovenKit(); -contract MiniBank { - // The oracle address can be queried from the chain RPC - // (minievm.evm.v1.Query/ConnectOracle) - IConnectOracle public oracle; +// 2. Add bridge handler +const handleBridge = () => { + openBridge({ + srcChainId: 'initiation-2', // Public testnet ID + srcDenom: 'uinit' // Native INIT + }); +}; - constructor(address _oracle) { - oracle = IConnectOracle(_oracle); - } +// 3. Add the Bridge UI section to your render (conditionally) +const bridgeContainerStyle = { + marginTop: '2rem', + padding: '1.5rem', + backgroundColor: '#fffbeb', + borderRadius: '24px', + border: '1px solid #fef3c7', + textAlign: 'left' +}; - // ... existing balance logic ... +const bridgeButtonStyle = { + width: '100%', + padding: '0.85rem', + backgroundColor: '#d97706', + color: 'white', + border: 'none', + borderRadius: '14px', + fontSize: '13px', + fontWeight: '800', + cursor: 'pointer', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + gap: '0.5rem' +}; - function getSavingsInUSD() public view returns (uint256) { - IConnectOracle.Price memory priceData = oracle.get_price("INIT/USD"); - return (balances[msg.sender] * priceData.price) / (10**priceData.decimal); - } -} +// Inside return (showing it only when connected)... +{address && ( +
+
+ Interwoven Ecosystem +
+

+ Access the broader Initia network to move assets between chains. +

+ +
+)} ``` - **Pro Tip:** You can find your appchain's Oracle address by asking your AI - assistant to run the `ConnectOracle` query against your local node. + **Pro Tip:** This allows users to tap into L1 liquidity (like INIT from the + faucet) and bring it into your appchain's economy seamlessly while keeping + the landing page focused.
diff --git a/hackathon/examples/move-game.mdx b/hackathon/examples/move-game.mdx index 7169bb3..f796f4c 100644 --- a/hackathon/examples/move-game.mdx +++ b/hackathon/examples/move-game.mdx @@ -87,7 +87,7 @@ InitiaStdlib = { local = "deps/movevm/precompile/modules/initia_stdlib" } MoveStdlib = { local = "deps/movevm/precompile/modules/move_stdlib" } [addresses] -blockforge = "0x2" # Use a placeholder hex address for local builds +blockforge = "_" # Use a placeholder to be set during build std = "0x1" ``` @@ -97,13 +97,17 @@ Next, delete the default `blockforge.move` file and create a new file named ```move wrap module blockforge::items { use std::signer; + use std::vector; /// Error codes const E_INSUFFICIENT_SHARDS: u64 = 1; + struct Shard has key, store, copy, drop {} + struct Relic has key, store, copy, drop {} + struct Inventory has key { - shards: u64, - relics: u64, + shards: vector, + relics: vector, } /// Mint basic items called shards. @@ -111,11 +115,14 @@ module blockforge::items { public entry fun mint_shard(account: &signer) acquires Inventory { let addr = signer::address_of(account); if (!exists(addr)) { - move_to(account, Inventory { shards: 1, relics: 0 }); + move_to(account, Inventory { + shards: vector::singleton(Shard {}), + relics: vector::empty() + }); } else { let inventory = borrow_global_mut(addr); - inventory.shards = inventory.shards + 1; - } + vector::push_back(&mut inventory.shards, Shard {}); + }; } /// Craft a relic by burning 2 shards @@ -124,30 +131,32 @@ module blockforge::items { assert!(exists(addr), E_INSUFFICIENT_SHARDS); let inventory = borrow_global_mut(addr); - assert!(inventory.shards >= 2, E_INSUFFICIENT_SHARDS); + assert!(vector::length(&inventory.shards) >= 2, E_INSUFFICIENT_SHARDS); + + // Burn 2 shards + vector::pop_back(&mut inventory.shards); + vector::pop_back(&mut inventory.shards); - inventory.shards = inventory.shards - 2; - inventory.relics = inventory.relics + 1; + // Add 1 relic + vector::push_back(&mut inventory.relics, Relic {}); } - #[view] - /// View a player's inventory - public fun view_inventory(addr: address): (u64, u64) acquires Inventory { - if (exists(addr)) { - let inventory = borrow_global(addr); - (inventory.shards, inventory.relics) - } else { - (0, 0) - } + /// Returns (shards, relics) for the given address. + public fun get_inventory(addr: address): (u64, u64) acquires Inventory { + if (!exists(addr)) { + return (0, 0) + }; + let inventory = borrow_global(addr); + (vector::length(&inventory.shards), vector::length(&inventory.relics)) } } ``` Once the files are created, you can verify everything is correct by building the -project. +project. Replace `0xYOUR_HEX_ADDRESS` with your deployment address hex (0x...). ```bash wrap -minitiad move build --language-version=2.1 --named-addresses blockforge=0x2 +minitiad move build --named-addresses blockforge=0xYOUR_HEX_ADDRESS ``` If you see `BUILDING blockforge`, then **BlockForge was built successfully! 🛠️** @@ -171,23 +180,25 @@ Using the `initia-appchain-dev` skill, please build and publish the blockforge M First, get your gas station's hex address: ```bash wrap -minitiad keys show gas-station -a --keyring-backend test | xargs minitiad keys parse +# Use the to_hex.py script to convert bech32 to hex +python3 scripts/to_hex.py $(minitiad keys show gas-station -a --keyring-backend test) ``` -Then, build and publish the compiled module to your appchain, substituting +Then, build and publish the compiled module to your appchain. Substitute `0xYOUR_HEX_ADDRESS` with the value from the previous step: ```bash wrap cd blockforge -# Replace `your-chain-id` with your appchain's ID -minitiad move deploy \ +# 1. Build the module with the correct hex named address +minitiad move build --named-addresses blockforge=0xYOUR_HEX_ADDRESS + +# 2. Publish the compiled bytecode +minitiad tx move publish build/blockforge/bytecode_modules/items.mv \ --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ - --named-addresses blockforge=0xYOUR_HEX_ADDRESS \ - --gas auto --gas-adjustment 1.4 --yes \ - --build --force + --gas auto --gas-adjustment 1.4 --yes --upgrade-policy COMPATIBLE ```
@@ -237,25 +248,90 @@ The Mint Shard button should call the mint_shard function, and the Craft Relic b Refer to the [Interwoven Kit Documentation](../../interwovenkit/introduction) for initial project scaffolding instructions. - ### 2. Configure Providers - Wrap your application with `InterwovenKitProvider` to enable wallet - connectivity. +### 2. Configure Providers - ```tsx main.jsx - import { InterwovenKitProvider, TESTNET } from "@initia/interwovenkit-react"; +Wrap your application with `InterwovenKitProvider` to enable wallet +connectivity. Ensure the `customChain` includes `fee_tokens` and +`bech32_prefix`. - // ... other imports +```tsx main.jsx +import { Buffer } from 'buffer' +window.Buffer = Buffer +window.process = { env: { NODE_ENV: 'development' } } + +import React from 'react' +import ReactDOM from 'react-dom/client' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider, createConfig, http } from 'wagmi' +import { mainnet } from 'wagmi/chains' +import { + InterwovenKitProvider, + TESTNET, + injectStyles, +} from '@initia/interwovenkit-react' +import '@initia/interwovenkit-react/styles.css' +import InterwovenKitStyles from '@initia/interwovenkit-react/styles.js' +import App from './App.jsx' + +injectStyles(InterwovenKitStyles) + +const queryClient = new QueryClient() +const wagmiConfig = createConfig({ + chains: [mainnet], + transports: { + [mainnet.id]: http(), + }, +}) + +const customChain = { + chain_id: 'your-appchain-id', + chain_name: 'BlockForge Appchain', + bech32_prefix: 'init', + network_type: 'testnet', + apis: { + rpc: [{ address: 'http://localhost:26657' }], + rest: [{ address: 'http://localhost:1317' }], + indexer: [{ address: 'http://localhost:8080' }], + }, + fees: { + fee_tokens: [ + { + denom: 'umin', // Replace with your appchain's native denom + fixed_min_gas_price: 0.15, + }, + ], + }, + metadata: { + is_l1: false, + }, +} - ReactDOM.createRoot(document.getElementById("root")).render( - +ReactDOM.createRoot(document.getElementById('root')).render( + + - + - - ); - ``` + + , +) +``` + + + **Pro Tip: Move View Function Encoding:** Address arguments for `rest.move.view` MUST be 32-byte padded hex and Base64 encoded: + ```javascript + const b64Addr = Buffer.from( + AccAddress.toHex(address).replace('0x', '').padStart(64, '0'), + 'hex' + ).toString('base64'); + ``` + --- @@ -286,7 +362,8 @@ for i in {1..3}; do --from gas-station \ --keyring-backend test \ --chain-id your-chain-id \ - --gas auto --gas-adjustment 1.4 --yes + --gas auto --gas-adjustment 1.4 --yes \ + --args '[]' --type-args '[]' sleep 2 done ``` @@ -294,10 +371,8 @@ done **Check your inventory:** ```bash wrap -GAS_STATION_ADDRESS=$(minitiad keys show gas-station -a --keyring-backend test) - -minitiad query move view items view_inventory \ - --args "[\"address:${GAS_STATION_ADDRESS}\"]" +minitiad query move view items get_inventory \ + --args '["address:init1..."]' ``` @@ -306,13 +381,14 @@ minitiad query move view items view_inventory \ # ⚡ Power-Up: Auto-signing (Session UX) -To make your BlockForge game "Interwoven-native," you can enable **Auto-signing** -to create a frictionless experience where players don't see wallet popups for -every game action. +To make your BlockForge game natively integrated with the Initia stack, you can +enable **Auto-signing** to create a frictionless experience where players don't +see wallet popups for every game action. ### 1. How it Works When a user enables Auto-sign, InterwovenKit performs three steps: + 1. **Ghost Wallet Derivation**: The user signs a one-time message (`personal_sign`) to derive a unique, application-specific HD wallet. 2. **Authz Grant**: The user's primary wallet grants permission to this ghost @@ -338,7 +414,7 @@ First, enable the feature in your provider: @@ -347,20 +423,22 @@ First, enable the feature in your provider: Then, use the `useInterwovenKit` hook in your component to manage the session: ```tsx Game.jsx -const { autoSign } = useInterwovenKit(); -const chainId = "your-chain-id"; +const { autoSign } = useInterwovenKit() +const chainId = 'your-chain-id' // Check if auto-sign is active for this chain -const isAutoSignEnabled = autoSign.isEnabledByChain[chainId]; +const isAutoSignEnabled = autoSign.isEnabledByChain[chainId] return ( - -); +) ``` diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index c00caac..63620af 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -208,7 +208,8 @@ minitiad tx wasm store ./memoboard/artifacts/memoboard.wasm \ **2. Retrieve the Code ID and Instantiate:** -If the `code_id` is not returned directly, wait for 5 seconds for indexing and then query the transaction hash: +If the `code_id` is not returned directly, wait for 5 seconds for indexing and +then query the transaction hash: ```bash wrap # Retrieve Code ID @@ -355,20 +356,22 @@ const customChain = { indexer: [{ address: 'http://localhost:8080' }], // Placeholder REQUIRED for stability }, fees: { - fee_tokens: [{ - denom: 'umin', - fixed_min_gas_price: 0.15, - low_gas_price: 0.15, - average_gas_price: 0.15, - high_gas_price: 0.15 - }], + fee_tokens: [ + { + denom: 'umin', + fixed_min_gas_price: 0.15, + low_gas_price: 0.15, + average_gas_price: 0.15, + high_gas_price: 0.15, + }, + ], }, staking: { - staking_tokens: [{ denom: 'umin' }] + staking_tokens: [{ denom: 'umin' }], }, metadata: { minitia: { type: 'miniwasm' }, - is_l1: false // REQUIRED for local appchains + is_l1: false, // REQUIRED for local appchains }, } @@ -388,7 +391,8 @@ ReactDOM.createRoot(document.getElementById('root')).render( , ) ``` -``` + +```` **4. Create the `Board.jsx` Component:** Create `src/Board.jsx` and `src/Board.css` with the following content: @@ -469,7 +473,7 @@ ReactDOM.createRoot(document.getElementById('root')).render( font-weight: 600; cursor: pointer; } -``` +```` **src/Board.jsx:** @@ -498,11 +502,16 @@ const Board = () => { const fetchMessages = async () => { try { // Wasm queries via REST MUST be base64 encoded - const queryData = Buffer.from(JSON.stringify({ all_messages: {} })).toString('base64') - const res = await rest.wasm.smartContractState(MEMO_BOARD_ADDRESS, queryData) + const queryData = Buffer.from( + JSON.stringify({ all_messages: {} }), + ).toString('base64') + const res = await rest.wasm.smartContractState( + MEMO_BOARD_ADDRESS, + queryData, + ) setMessages((res?.messages || []).reverse()) } catch (e) { - console.error("Failed to fetch messages", e) + console.error('Failed to fetch messages', e) } } @@ -542,7 +551,7 @@ const Board = () => { // Small delay to allow block inclusion setTimeout(fetchMessages, 2000) } catch (e) { - console.error("Transaction failed", e) + console.error('Transaction failed', e) } } @@ -558,10 +567,17 @@ const Board = () => { ) : (
- -
@@ -587,9 +603,7 @@ const Board = () => {

Board Feed

{messages.map((m, i) => (
-
- {truncate(m.sender)} -
+
{truncate(m.sender)}
{m.message}
))} @@ -642,15 +656,17 @@ minitiad query wasm contract-state smart '{"all_messages":{}} # ⚡ Power-Up: Initia Usernames -To make your MemoBoard "Interwoven-native," you can replace long, complex -addresses with human-readable **Initia Usernames** (e.g., `vitalik.init`). +To make your MemoBoard natively integrated with the Initia stack, you can +replace long, complex addresses with human-readable **Initia Usernames** (e.g., +`vitalik.init`). ## Step 6: Register your .init Name -Before updating your code, you should register a primary username for your wallet -on the Initia testnet. +Before updating your code, you should register a primary username for your +wallet on the Initia testnet. -1. Navigate to [app.testnet.initia.xyz/usernames](https://app.testnet.initia.xyz/usernames) +1. Navigate to + [app.testnet.initia.xyz/usernames](https://app.testnet.initia.xyz/usernames) and connect your browser wallet (e.g., Leap or Keplr). 2. In the **Find a username** search box, enter your desired name. If it is available, you will see a green **Available** checkmark. diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index c242fdd..b881cff 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -2,11 +2,11 @@ title: 'Your First Appchain: A Step-by-Step Guide' --- -## Build a Sovereign Blockchain with Your AI Co-pilot +## Build an Appchain with Your AI Co-pilot -Welcome to the hackathon! This guide will walk you through building a sovereign -blockchain from scratch. You'll go from a simple idea to a functioning appchain -with a frontend in record time. +Welcome to the hackathon! This guide will walk you through building an appchain +from scratch. You'll go from a simple idea to a functioning appchain with a +frontend efficiently. --- @@ -33,7 +33,7 @@ your appchain, write smart contracts, and build your frontend. **Run the following command in your terminal:** ```bash wrap -npx skills add initia-labs/hackathon-skills +npx skills add initia-labs/agent-skills ``` --- @@ -322,6 +322,10 @@ Here's a guide on how to navigate the interactive setup: **Action:** Enter `1000000000000000000000000` (10^24). This ensures you have plenty of tokens for testing, especially if you are on the EVM track. + + If you are on the **Move track**, use `10000000000000000000` (10^19) instead, as Move balances are represented as `u64` and will overflow with larger values. + + ### Add Additional Genesis Accounts **Prompt:** ```terminal wrap @@ -363,7 +367,7 @@ Your appchain will now launch and start producing blocks! To enable the Optimistic bridge and cross-chain communication (IBC) between Initia L1 and your appchain, you need to start the **OPinit Executor** and the -**IBC Relayer**. These bots handle the "interweaving" of your chain. +**IBC Relayer**. These bots manage the cross-chain connectivity of your chain. **Prerequisite:** Your appchain must be running before configuring these bots. Because `weave init` runs your chain in the background, you can continue using the same terminal window. @@ -573,7 +577,7 @@ Congratulations! You have successfully launched your first appchain. Now it's time to build your unique hackathon entry. The fastest way to build a winning project is to start with a **Blueprint**. -These patterns provide a working "scaffold" (Contract + Frontend) that you can +These patterns provide a working scaffold (Contract + Frontend) that you can modify and expand. diff --git a/hackathon/submission-requirements.mdx b/hackathon/submission-requirements.mdx index ae8d779..4cfa4de 100644 --- a/hackathon/submission-requirements.mdx +++ b/hackathon/submission-requirements.mdx @@ -17,7 +17,7 @@ with the Initia stack. ### 🏗️ Pillar 1: Dedicated Rollup Architecture This hackathon is dedicated to the power of appchains. Your project should be -deployed as its own sovereign rollup. +deployed as its own appchain. - **Requirement:** Provide your rollup's **Chain ID** and a link to a transaction or contract deployment on your rollup. @@ -27,8 +27,8 @@ deployed as its own sovereign rollup. ### ⚛️ Pillar 2: Optimized Frontend Experience We encourage builders to use the flagship tooling designed for the Interwoven -ecosystem. This ensures your application is "Interwoven-ready" and provides a -seamless experience for users across Initia. +ecosystem. This ensures your application is fully integrated with the Initia +stack and provides a seamless experience for users. - **Requirement:** Utilize **InterwovenKit** (`@initia/interwovenkit-react`) for wallet connections and transaction handling. @@ -37,7 +37,7 @@ seamless experience for users across Initia. ### ⚡ Pillar 3: Showcasing Initia Native Features -High-value projects go beyond "Hello World" by leveraging Initia's native +High-value projects go beyond Hello World by leveraging Initia's native features. Your submission should implement at least **one** of the following: 1. **Auto-signing:** Create a frictionless UX for high-frequency interactions @@ -70,9 +70,9 @@ Access the official tools and documentation to build your project: - **Rollup Indexer (Rollytics):** [View Swagger](https://rollytics-api-echelon-1.anvil.asia-southeast.initia.xyz/swagger/index.html) - — Use this to query transactions and assets **on your appchain**. + (Use this to query transactions and assets **on your appchain**). - **L1 Indexer:** [View Swagger](https://indexer.initia.xyz/swagger/index.html) - — Use this to query global data like **Initia Usernames**. + (Use this to query global data like **Initia Usernames**). - **L1 Testnet RPC:** `https://rpc.testnet.initia.xyz` - **L1 Testnet LCD:** `https://lcd.testnet.initia.xyz` - **Faucets:** [faucet.testnet.initia.xyz](https://faucet.testnet.initia.xyz) From 5b8eef5ebea6b14c0dce71851740ef679c6080ca Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Fri, 20 Feb 2026 10:40:43 +0700 Subject: [PATCH 14/17] docs: fix outdated example references and formatting --- hackathon/builder-guide.mdx | 70 +++++++++++++-------------- hackathon/examples/evm-bank.mdx | 8 +-- hackathon/examples/move-game.mdx | 9 ++-- hackathon/examples/wasm-social.mdx | 6 +-- hackathon/hackathon-landing.mdx | 12 ++--- hackathon/submission-requirements.mdx | 35 +++++++------- 6 files changed, 69 insertions(+), 71 deletions(-) diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index c8cf2cc..2aa2125 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -37,8 +37,8 @@ hackathon. ### Local Keyring Import -The **Gas Station** account acts as your **Universal Developer Key**. Run these -commands in your terminal to import it into your local keychains so you can sign +The Gas Station account acts as your Universal Developer Key. Run these commands +in your terminal to import it into your local keychains so you can sign transactions via the CLI. ```bash wrap @@ -61,15 +61,15 @@ Master the **Describe → Build → Test** cycle. This is how you win the hackat ### 💰 Funding Your Personal Wallet Before you can interact with your appchain via a browser wallet (like Keplr, -Leap, or MetaMask), you need to fund your personal address from your **Gas -Station**. +Leap, or MetaMask), you need to fund your personal address from your Gas +Station. -**1. Copy your wallet address:** +1. Copy your wallet address: -- **Move / Wasm Track**: Copy your `init1...` address. -- **EVM Track**: Copy your `0x...` address. +- Move / Wasm Track: Copy your `init1...` address. +- EVM Track: Copy your `0x...` address. -**2. Ask your AI Assistant to fund you:** +2. Ask your AI Assistant to fund you: **Prompt:** @@ -99,16 +99,16 @@ Using the `initia-appchain-dev` skill, please fund my personal wallet - **Submission Receipt:** To qualify for the hackathon prizes, you must provide - the **Contract Address** of your primary logic and a **Transaction Hash** of a - user interacting with it. Save these as soon as you have a working version! + Submission Receipt: To qualify for the hackathon prizes, you must provide the + Contract Address of your primary logic and a Transaction Hash of a user + interacting with it. Save these as soon as you have a working version! # Part 2: Choose Your Blueprint Pattern To build a winning hackathon project, don't just write a contract, implement an -**Interwoven Blueprint**. These patterns leverage Initia's native features to -create experiences that are impossible on other chains. +Interwoven Blueprint. These patterns leverage Initia's native features to create +experiences that are impossible on other chains. @@ -123,31 +123,29 @@ create experiences that are impossible on other chains. ``` - - **The Goal:** An application that makes decisions based on real-time, - high-fidelity external data provided directly by the chain infrastructure. - - **Native Feature:** [Connect - Oracle](/developers/developer-guides/tools/oracles/connect/introduction) or - [Built-in - Indexer](/developers/developer-guides/tools/indexers/indexer-introduction) - - **Best for:** DeFi Lending, Automated Agents, Analytics Dashboards. - - **Reference Implementation:** [MiniBank (EVM)](/hackathon/examples/evm-bank) - **AI Power-Up Prompt:** ```terminal wrap Using the `initia-appchain-dev` - skill, show me how to use the native Oracle precompile in my smart contract to - fetch the live price of ETH/USD. ``` + + **The Goal:** An application that allows users to move assets between the + broader Initia L1 and your appchain without leaving your interface. - **Native + Feature:** [Interwoven Bridging](/interwovenkit/features/bridging) via + `openBridge` - **Best for:** DeFi Lending, Cross-chain storefronts, + Multi-chain games. - **Reference Implementation:** [MiniBank + (EVM)](/hackathon/examples/evm-bank) **AI Power-Up Prompt:** ```terminal wrap + Using the `initia-appchain-dev` skill, please add Interwoven Bridge support to + my app so I can move funds between Initia L1 and my appchain directly from my + UI. ``` - - **The Goal:** An application that prioritizes human-readable identities and seamless onboarding, making crypto feel like a standard Web2 app. - - **Native Feature:** [Initia Usernames](/home/core-applications/initia-usernames) - - **Best for:** Consumer Social, Peer-to-peer payments, DAO governance. - - **Reference Implementation:** [MemoBoard (Wasm)](/hackathon/examples/wasm-social) - - **AI Power-Up Prompt:** - ```terminal wrap - Using the `initia-appchain-dev` skill, modify my React frontend to use the `useUsernameQuery` hook so I can display the .init names of my users instead of their hex addresses. - ``` - + + **The Goal:** An application that prioritizes human-readable identities, replacing complex hex addresses with personal usernames. + - **Native Feature:** [Initia Usernames](/home/core-applications/initia-usernames) + - **Best for:** Consumer Social, Peer-to-peer payments, DAO governance. + - **Reference Implementation:** [MemoBoard (Wasm)](/hackathon/examples/wasm-social) + + **AI Power-Up Prompt:** + ```terminal wrap + Using the `initia-appchain-dev` skill, update my frontend to display the user's .init username in the header instead of their wallet address. + ``` + --- diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx index bc9064e..020216a 100644 --- a/hackathon/examples/evm-bank.mdx +++ b/hackathon/examples/evm-bank.mdx @@ -1,5 +1,5 @@ --- -title: 'EVM Tutorial: MiniBank' +title: 'EVM Tutorial: MiniBank (Interwoven Bridge)' --- **Prerequisite:** Before starting this tutorial, you should have completed the @@ -8,9 +8,9 @@ an EVM-compatible appchain running locally. --- -This tutorial will guide you through building a simple digital piggy bank on -your EVM appchain. Users can deposit tokens, withdraw them, and check their -savings balance. +This tutorial will guide you through building a liquidity-ready digital piggy bank on +your EVM appchain. Users can deposit tokens, withdraw them, and access the +broader Initia ecosystem via native bridging. By the end of this tutorial, you will have: diff --git a/hackathon/examples/move-game.mdx b/hackathon/examples/move-game.mdx index f796f4c..34bd423 100644 --- a/hackathon/examples/move-game.mdx +++ b/hackathon/examples/move-game.mdx @@ -1,5 +1,5 @@ --- -title: 'Move Tutorial: BlockForge Game' +title: 'Move Tutorial: BlockForge Game (Invisible UX)' --- **Prerequisite:** Before starting this tutorial, you should have completed the @@ -8,9 +8,10 @@ your own appchain running locally. --- -This tutorial will guide you through building a complete, functioning appchain -project on top of your existing appchain: **BlockForge**, a tiny on-chain game -engine where players can mint and craft items. +This tutorial will guide you through building a high-frequency on-chain game on +your Move appchain. BlockForge is a crafting engine that demonstrates Invisible +UX: allowing players to interact with the blockchain seamlessly without constant +wallet popups. By the end of this tutorial, you will have instructed your AI assistant to: diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index 63620af..8d778ad 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -1,5 +1,5 @@ --- -title: 'Wasm Tutorial: MemoBoard' +title: 'Wasm Tutorial: MemoBoard (Human Identity)' --- **Prerequisite:** Before starting this tutorial, you should have completed the @@ -9,8 +9,8 @@ Wasm-compatible appchain running locally. --- This tutorial will guide you through building a lightning-fast on-chain -guestbook called **MemoBoard**. Users can post short public messages (memos), -and anyone can read the board. +guestbook called **MemoBoard**. Users can post public messages, and the +application prioritizes human-readable identity by resolving `.init` usernames. By the end of this tutorial, you will have: diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index b881cff..d5f210f 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -586,21 +586,21 @@ modify and expand. icon="wand-magic-sparkles" href="/hackathon/examples/move-game" > - Frictionless games and high-frequency apps. + Frictionless games with Auto-signing. - Data-rich DeFi and automated agents. + Native liquidity and cross-chain bridging. - Consumer-centric apps with .init usernames. + Identity-first apps with .init usernames. diff --git a/hackathon/submission-requirements.mdx b/hackathon/submission-requirements.mdx index 4cfa4de..5091f7d 100644 --- a/hackathon/submission-requirements.mdx +++ b/hackathon/submission-requirements.mdx @@ -19,8 +19,8 @@ with the Initia stack. This hackathon is dedicated to the power of appchains. Your project should be deployed as its own appchain. -- **Requirement:** Provide your rollup's **Chain ID** and a link to a - transaction or contract deployment on your rollup. +- **Requirement:** Provide your rollup's Chain ID and a link to a transaction or + contract deployment on your rollup. - **Getting Started:** Use the `weave` CLI to launch and manage your environment. @@ -30,7 +30,7 @@ We encourage builders to use the flagship tooling designed for the Interwoven ecosystem. This ensures your application is fully integrated with the Initia stack and provides a seamless experience for users. -- **Requirement:** Utilize **InterwovenKit** (`@initia/interwovenkit-react`) for +- **Requirement:** Utilize InterwovenKit (`@initia/interwovenkit-react`) for wallet connections and transaction handling. - **Why:** This stack enables advanced Initia features like social logins via Privy and cross-chain visibility. @@ -38,15 +38,15 @@ stack and provides a seamless experience for users. ### ⚡ Pillar 3: Showcasing Initia Native Features High-value projects go beyond Hello World by leveraging Initia's native -features. Your submission should implement at least **one** of the following: +features. Your submission should implement at least one of the following: -1. **Auto-signing:** Create a frictionless UX for high-frequency interactions +1. Auto-signing: Create a frictionless UX for high-frequency interactions (e.g., games or trading). -2. **Built-in Indexer:** Query rich historical data or NFT holdings using the +2. Built-in Indexer: Query rich historical data or NFT holdings using the native REST APIs. -3. **Connect Oracle:** Integrate Skip's enshrined price feeds for DeFi or - economic logic. -4. **Initia Usernames:** Resolve and display `.init` names to improve user +3. Connect Oracle: Integrate Skip's enshrined price feeds for DeFi or economic + logic. +4. Initia Usernames: Resolve and display .init names to improve user onboarding. --- @@ -81,13 +81,12 @@ Access the official tools and documentation to build your project: # 3. Submission Summary (Add to your README) -To help our technical reviewers understand your project, please include this -summary in your project's `README.md`: +To assist our technical review process and ensure your project stands out, +please include this summary in your project's `README.md`: -| Feature | Details | -| :-------------------------- | :-------------------------------------------------- | -| **Rollup Chain ID** | (e.g., `my-game-1`) | -| **Contract/Module Address** | (The address of your deployed smart contract) | -| **L2 Interaction TX** | [Link to a transaction that *calls your contract*] | -| **Frontend Stack** | InterwovenKit | -| **Native Feature(s)** | (e.g., Auto-signing / Indexer / Oracle / Usernames) | +| Feature | Details / Links | Proof of Implementation (Short Note) | +| :-------------------- | :------------------- | :------------------------------------------------------------------------------------------ | +| **Rollup Chain ID** | e.g., my-game-1 | N/A | +| **Logic Delta** | [Link to Core Logic] | Briefly describe the primary custom logic you added or changed from the base templates. | +| **L2 Interaction TX** | [Hash/Link] | Explain the State Transition this TX represents (e.g., "Mints an NFT via the Move module"). | +| **Native Feature(s)** | e.g., Auto-signing | Why was this feature the right choice for your application's architecture? | From 34303e75ce071ecab7314c7efb7f1e0f943b8b3f Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Fri, 20 Feb 2026 11:41:41 +0700 Subject: [PATCH 15/17] fix: flow, formatting, styling --- .prettierignore | 1 + hackathon/builder-guide.mdx | 87 +++++++++------------------ hackathon/examples/evm-bank.mdx | 32 ++++++---- hackathon/examples/move-game.mdx | 12 ++-- hackathon/examples/wasm-social.mdx | 16 ++--- hackathon/hackathon-landing.mdx | 44 +++----------- hackathon/submission-requirements.mdx | 39 +++++++++--- 7 files changed, 105 insertions(+), 126 deletions(-) diff --git a/.prettierignore b/.prettierignore index e7d6834..9077da9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,3 +4,4 @@ developers/developer-guides/vm-specific-tutorials/movevm/your-first-module.mdx developers/developer-guides/integrating-initia-apps/initiadex.mdx hackathon/hackathon-landing.mdx hackathon/examples/evm-bank.mdx +hackathon/builder-guide.mdx diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index 2aa2125..bbb9364 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -29,28 +29,10 @@ Before proceeding, ensure you have completed these milestones: Use these common commands and AI prompts to manage your project during the hackathon. -| Task | Command / AI Prompt | -| :------------------ | :---------------------------------------------------------------------------------------------------------------------------- | -| **Resume Appchain** | `weave start` | -| **Health Check** | _Using the `initia-appchain-dev` skill, please verify that my appchain is producing blocks and show my gas-station balances._ | -| **Key Import** | See the [Local Keyring Import](#key-import) section below. | - -### Local Keyring Import - -The Gas Station account acts as your Universal Developer Key. Run these commands -in your terminal to import it into your local keychains so you can sign -transactions via the CLI. - -```bash wrap -# 1. Extract your mnemonic from the weave config -MNEMONIC=$(jq -r '.common.gas_station.mnemonic' ~/.weave/config.json) - -# 2. Import into initiad (L1) -initiad keys add gas-station --recover --keyring-backend test --coin-type 60 --key-type eth_secp256k1 --source <(echo -n "$MNEMONIC") - -# 3. Import into minitiad (L2) -minitiad keys add gas-station --recover --keyring-backend test --coin-type 60 --key-type eth_secp256k1 --source <(echo -n "$MNEMONIC") -``` +| Task | Command / AI Prompt | +| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Resume Appchain** | `weave start` | +| **Health Check** | _Using the `initia-appchain-dev` skill, please verify that my appchain, executor bot, and relayer are running and that my Gas Station account has a balance._ | --- @@ -99,8 +81,8 @@ Using the `initia-appchain-dev` skill, please fund my personal wallet - Submission Receipt: To qualify for the hackathon prizes, you must provide the - Contract Address of your primary logic and a Transaction Hash of a user + **Submission Receipt:** To qualify for the hackathon prizes, you must provide + the Contract Address of your primary logic and a Transaction Hash of a user interacting with it. Save these as soon as you have a working version! @@ -111,41 +93,25 @@ Interwoven Blueprint. These patterns leverage Initia's native features to create experiences that are impossible on other chains. - + **The Goal:** A high-frequency application where the blockchain handles logic silently in the background. Users never see a wallet popup after the initial session start. - **Native Feature:** [Auto-signing](/interwovenkit/features/autosign/introduction) - **Best for:** Gaming, Social tipping, High-frequency trading. - - **Reference Implementation:** [BlockForge (Move)](/hackathon/examples/move-game) - - **AI Power-Up Prompt:** - ```terminal wrap - Using the `initia-appchain-dev` skill, please modify my InterwovenKit frontend to enable auto-signing for 1 hour so my users can interact with my contract without constant popups. - ``` - - **The Goal:** An application that allows users to move assets between the - broader Initia L1 and your appchain without leaving your interface. - **Native - Feature:** [Interwoven Bridging](/interwovenkit/features/bridging) via - `openBridge` - **Best for:** DeFi Lending, Cross-chain storefronts, - Multi-chain games. - **Reference Implementation:** [MiniBank - (EVM)](/hackathon/examples/evm-bank) **AI Power-Up Prompt:** ```terminal wrap - Using the `initia-appchain-dev` skill, please add Interwoven Bridge support to - my app so I can move funds between Initia L1 and my appchain directly from my - UI. ``` - - - - **The Goal:** An application that prioritizes human-readable identities, replacing complex hex addresses with personal usernames. - - **Native Feature:** [Initia Usernames](/home/core-applications/initia-usernames) - - **Best for:** Consumer Social, Peer-to-peer payments, DAO governance. - - **Reference Implementation:** [MemoBoard (Wasm)](/hackathon/examples/wasm-social) - - **AI Power-Up Prompt:** - ```terminal wrap - Using the `initia-appchain-dev` skill, update my frontend to display the user's .init username in the header instead of their wallet address. - ``` - + + **The Goal:** An application that allows users to move assets between the + broader Initia L1 and your appchain without leaving your interface. + - **Native Feature:** [Interwoven Bridging](/interwovenkit/features/transfers/deposit-withdraw) + - **Best for:** DeFi Lending, Cross-chain storefronts, + Multi-chain games. + + + + **The Goal:** An application that prioritizes human-readable identities, replacing complex hex addresses with personal usernames. + - **Native Feature:** [Initia Usernames](/developers/developer-guides/integrating-initia-apps/usernames) + - **Best for:** Consumer Social, Peer-to-peer payments, DAO governance. + --- @@ -179,11 +145,14 @@ inevitable. 2. **Context is King**: Ensure your AI agent (Cursor, Gemini) is **opened in your project root**. This allows it to reference your `package.json`, your `interwovenkit` initialization, and your specific chain configuration. -3. **The Perfect Debugging Prompt**: Provide the **console error** alongside - the **relevant file**. - > _Prompt Example: "I'm following the MiniBank example and getting this - > `RPC Error: ...` in the console. Here is my `App.tsx`. Why is my - > transaction failing?"_ +3. The Perfect Debugging Prompt: Provide the console error and ask your + assistant to find the cause within your project. + + **Prompt:** + + ```terminal wrap + I'm getting this [INSERT_CONSOLE_ERROR] in the browser. Looking at my codebase, why is my transaction failing and how do I fix it? + ``` ### 📚 Deep Dives & Source Truth diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx index 020216a..2fc8994 100644 --- a/hackathon/examples/evm-bank.mdx +++ b/hackathon/examples/evm-bank.mdx @@ -2,9 +2,11 @@ title: 'EVM Tutorial: MiniBank (Interwoven Bridge)' --- -**Prerequisite:** Before starting this tutorial, you should have completed the -**[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have -an EVM-compatible appchain running locally. + + **Prerequisite:** Before starting this tutorial, you should have completed the + [Your First Appchain: A Step-by-Step Guide](../hackathon-landing) and have + an EVM-compatible appchain running locally. + --- @@ -99,7 +101,9 @@ contract MiniBank { ### Unit Testing with Foundry To verify your contract's logic, create a test file named `MiniBank.t.sol` in the `test` directory. -> **Pro Tip**: `testFail` is deprecated in newer versions of Foundry. Use `vm.expectRevert()` for failure testing. + + **Pro Tip**: `testFail` is deprecated in newer versions of Foundry. Use `vm.expectRevert()` for failure testing. + ```solidity wrap // SPDX-License-Identifier: MIT @@ -448,13 +452,17 @@ export default App **5. Create the `Bank.jsx` Component:** Create `src/Bank.jsx` and add the contract interaction logic. -> **Pro Tip**: For a cleaner UI, hide the numeric "up/down" arrows in your CSS: -> ```css -> input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } -> input[type=number] { -moz-appearance: textfield; } -> ``` + + **Pro Tip:** For a cleaner UI, hide the numeric "up/down" arrows in your CSS: + ```css + input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } + input[type=number] { -moz-appearance: textfield; } + ``` + -> **Pro Tip**: For `view` functions that depend on `msg.sender` (like `getBalance`), you MUST provide a `from` address in your `eth_call` parameters so the appchain knows whose balance to check. + + **Pro Tip**: For `view` functions that depend on `msg.sender` (like `getBalance`), you MUST provide a `from` address in your `eth_call` parameters so the appchain knows whose balance to check. + ```javascript wrap import React, { useState, useEffect } from 'react'; @@ -771,6 +779,6 @@ const bridgeButtonStyle = { ## Next Steps Now that you've mastered an EVM application, you're ready to build your own -idea! +idea! Ensure your project meets all the technical pillars before submitting. -**[→ Go to Builder Guide](../builder-guide)** +**[→ Review Submission Requirements](../submission-requirements)** diff --git a/hackathon/examples/move-game.mdx b/hackathon/examples/move-game.mdx index 34bd423..a0c4250 100644 --- a/hackathon/examples/move-game.mdx +++ b/hackathon/examples/move-game.mdx @@ -2,9 +2,11 @@ title: 'Move Tutorial: BlockForge Game (Invisible UX)' --- -**Prerequisite:** Before starting this tutorial, you should have completed the -**[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have -your own appchain running locally. + + **Prerequisite:** Before starting this tutorial, you should have completed the + [Your First Appchain: A Step-by-Step Guide](../hackathon-landing) and have a + Move-compatible appchain running locally. + --- @@ -452,6 +454,6 @@ return ( ## Next Steps Now that you've mastered a Move application, you're ready to build your own -idea! +idea! Ensure your project meets all the technical pillars before submitting. -**[→ Go to Builder Guide](../builder-guide)** +**[→ Review Submission Requirements](../submission-requirements)** diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index 8d778ad..778058f 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -2,9 +2,11 @@ title: 'Wasm Tutorial: MemoBoard (Human Identity)' --- -**Prerequisite:** Before starting this tutorial, you should have completed the -**[Your First Appchain: A Step-by-Step Guide](../hackathon-landing)** and have a -Wasm-compatible appchain running locally. + + **Prerequisite:** Before starting this tutorial, you should have completed the + [Your First Appchain: A Step-by-Step Guide](../hackathon-landing) and have a + Wasm-compatible appchain running locally. + --- @@ -392,8 +394,6 @@ ReactDOM.createRoot(document.getElementById('root')).render( ) ``` -```` - **4. Create the `Board.jsx` Component:** Create `src/Board.jsx` and `src/Board.css` with the following content: @@ -473,7 +473,7 @@ ReactDOM.createRoot(document.getElementById('root')).render( font-weight: 600; cursor: pointer; } -```` +``` **src/Board.jsx:** @@ -718,6 +718,6 @@ const { initiaAddress, username, openConnect, openWallet, requestTxSync } = useI ## Next Steps Now that you've mastered a Wasm application, you're ready to build your own -idea! +idea! Ensure your project meets all the technical pillars before submitting. -**[→ Go to Builder Guide](../builder-guide)** +**[→ Review Submission Requirements](../submission-requirements)** diff --git a/hackathon/hackathon-landing.mdx b/hackathon/hackathon-landing.mdx index d5f210f..6ed8ab1 100644 --- a/hackathon/hackathon-landing.mdx +++ b/hackathon/hackathon-landing.mdx @@ -571,40 +571,16 @@ Using the `initia-appchain-dev` skill, please verify that my appchain, executor --- -## Step 9: Next Steps: Choose Your Blueprint Pattern - -Congratulations! You have successfully launched your first appchain. Now it's -time to build your unique hackathon entry. - -The fastest way to build a winning project is to start with a **Blueprint**. -These patterns provide a working scaffold (Contract + Frontend) that you can -modify and expand. - - - - Frictionless games with Auto-signing. - - - Native liquidity and cross-chain bridging. - - - Identity-first apps with .init usernames. - - - -**[→ Go to the Builder Guide for Blueprints & AI Prompts](/hackathon/builder-guide#part-2-choose-your-blueprint-pattern)** +## Step 9: Next Steps: Master the Workflow + +Congratulations! You have successfully launched your first appchain. Before +diving into a specific blueprint, we recommend mastering the development +workflow. + +The **Builder Guide** will teach you the **Describe → Build → Test** loop using +your AI co-pilot, which is essential for building a winning hackathon entry. + +**[→ Go to the Builder Guide](/hackathon/builder-guide)** --- diff --git a/hackathon/submission-requirements.mdx b/hackathon/submission-requirements.mdx index 5091f7d..0552cca 100644 --- a/hackathon/submission-requirements.mdx +++ b/hackathon/submission-requirements.mdx @@ -82,11 +82,34 @@ Access the official tools and documentation to build your project: # 3. Submission Summary (Add to your README) To assist our technical review process and ensure your project stands out, -please include this summary in your project's `README.md`: - -| Feature | Details / Links | Proof of Implementation (Short Note) | -| :-------------------- | :------------------- | :------------------------------------------------------------------------------------------ | -| **Rollup Chain ID** | e.g., my-game-1 | N/A | -| **Logic Delta** | [Link to Core Logic] | Briefly describe the primary custom logic you added or changed from the base templates. | -| **L2 Interaction TX** | [Hash/Link] | Explain the State Transition this TX represents (e.g., "Mints an NFT via the Move module"). | -| **Native Feature(s)** | e.g., Auto-signing | Why was this feature the right choice for your application's architecture? | +please include the following block at the **top** of your project's `README.md`. + +### 📝 Copy-Paste README Template + +```markdown +## 🚀 Initia Hackathon Submission + +- **Project Name**: [Your Project Name] + +### 📖 Project Overview + +[Provide a 2-3 sentence description of your application. Why is it valuable and +what problem does it solve?] + +### 🛠 Technical Specification (Automated Verification) + +- **Rollup Chain ID**: [e.g. my-game-1] +- **Logic Delta URL**: [Link to the core smart contract or module] +- **L2 Interaction TX**: [Hash/Link to a primary functionality transaction] +- **Demo Video URL**: [2-minute walkthrough via Loom, YouTube, etc.] +- **Interwoven Feature**: [Auto-signing / Bridging / Usernames] + +### 🧬 Implementation Detail + +- **Logic Delta**: [Briefly describe the primary custom logic you added or + changed compared to the base templates.] +- **Transaction Purpose**: [Explain why the provided TX represents a core + functionality of your application.] +- **Feature Rationale**: [Why was your chosen Interwoven feature the right + choice for this application's architecture?] +``` From eeed9dbbbf0ef827ca8e19c06655cc85e2a5690f Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Tue, 24 Feb 2026 13:20:53 +0700 Subject: [PATCH 16/17] docs: add tip to evaluate frontend for tutorials --- hackathon/examples/evm-bank.mdx | 6 ++++++ hackathon/examples/move-game.mdx | 22 +++++++++++++++++----- hackathon/examples/wasm-social.mdx | 10 ++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx index 2fc8994..6e1bad7 100644 --- a/hackathon/examples/evm-bank.mdx +++ b/hackathon/examples/evm-bank.mdx @@ -627,6 +627,12 @@ export default Bank; + + **Open the Frontend:** After scaffolding, `cd` into the `minibank-frontend` directory and run `npm run dev` to start the application. Open the provided URL in your browser and connect your wallet extension. + + If the app doesn't appear as expected or you encounter issues, check the **browser console** (F12 or Right-click > Inspect > Console) for logs. You can share these logs with your AI assistant to help troubleshoot errors or further customize the UI and functionality to your liking. + + --- ## Step 5: On-Chain Verification diff --git a/hackathon/examples/move-game.mdx b/hackathon/examples/move-game.mdx index a0c4250..fdd1da0 100644 --- a/hackathon/examples/move-game.mdx +++ b/hackathon/examples/move-game.mdx @@ -306,6 +306,9 @@ const customChain = { }, metadata: { is_l1: false, + minitia: { + type: 'minimove', + }, }, } @@ -327,16 +330,25 @@ ReactDOM.createRoot(document.getElementById('root')).render( ``` - **Pro Tip: Move View Function Encoding:** Address arguments for `rest.move.view` MUST be 32-byte padded hex and Base64 encoded: + **Pro Tip: Move View Function Encoding:** Address arguments for `rest.move.view` MUST be 32-byte hex (padded to exactly 64 characters) and then Base64 encoded. ```javascript - const b64Addr = Buffer.from( - AccAddress.toHex(address).replace('0x', '').padStart(64, '0'), - 'hex' - ).toString('base64'); + const hexAddr = AccAddress.toHex(address).replace('0x', '').padStart(64, '0'); + const b64Addr = Buffer.from(hexAddr, 'hex').toString('base64'); ``` + Also, remember to include a small delay (e.g., `setTimeout(fetch, 2000)`) after transactions before refreshing the state to allow the indexer to catch up. + + **Open the Frontend:** After scaffolding, `cd` into the `blockforge-frontend` directory and run `npm run dev` to start the application. Open the provided URL in your browser and connect your wallet extension. + +If the app doesn't appear as expected or you encounter issues, check the +**browser console** (F12 or Right-click > Inspect > Console) for logs. You can +share these logs with your AI assistant to help troubleshoot errors or further +customize the UI and functionality to your liking. + + + --- ## Step 5: On-Chain Verification diff --git a/hackathon/examples/wasm-social.mdx b/hackathon/examples/wasm-social.mdx index 778058f..5cf6290 100644 --- a/hackathon/examples/wasm-social.mdx +++ b/hackathon/examples/wasm-social.mdx @@ -617,6 +617,16 @@ export default Board + + **Open the Frontend:** After scaffolding, `cd` into the `memoboard-frontend` directory and run `npm run dev` to start the application. Open the provided URL in your browser and connect your wallet extension. + +If the app doesn't appear as expected or you encounter issues, check the +**browser console** (F12 or Right-click > Inspect > Console) for logs. You can +share these logs with your AI assistant to help troubleshoot errors or further +customize the UI and functionality to your liking. + + + --- ## Step 5: On-Chain Verification From 7a6443f50e5ef1f4dc6eccac64e499d153ebc4bf Mon Sep 17 00:00:00 2001 From: Manuel Alessandro Collazo Date: Tue, 24 Feb 2026 14:59:32 +0700 Subject: [PATCH 17/17] docs: align hackathon pillars, terminology, and development flow --- hackathon/builder-guide.mdx | 37 ++++++++++++------- hackathon/examples/evm-bank.mdx | 2 +- hackathon/submission-requirements.mdx | 52 +++++++++++++++------------ 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/hackathon/builder-guide.mdx b/hackathon/builder-guide.mdx index bbb9364..6f1e6d5 100644 --- a/hackathon/builder-guide.mdx +++ b/hackathon/builder-guide.mdx @@ -31,7 +31,7 @@ hackathon. | Task | Command / AI Prompt | | :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| **Resume Appchain** | `weave start` | +| **Resume Appchain** | `weave rollup start -d && weave opinit start executor -d` (Restarts both your chain and the bridge bot) | | **Health Check** | _Using the `initia-appchain-dev` skill, please verify that my appchain, executor bot, and relayer are running and that my Gas Station account has a balance._ | --- @@ -86,29 +86,40 @@ Using the `initia-appchain-dev` skill, please fund my personal wallet -# Part 2: Choose Your Blueprint Pattern +# Part 2: Choose Your Blueprint (Satisfy Pillar 3) -To build a winning hackathon project, don't just write a contract, implement an -Interwoven Blueprint. These patterns leverage Initia's native features to create -experiences that are impossible on other chains. +To qualify for the hackathon prizes, your project must implement at least one +Initia Native Feature (defined as Pillar 3 in the submission +requirements). These Blueprints provide the foundation for meeting that +requirement. + + + **The Custom Implementation:** To win, don't just deploy these examples as-is. + Judges look for your Custom Implementation: the unique code and functionality you + added on top of these base patterns to solve a specific problem. + - - **The Goal:** A high-frequency application where the blockchain handles logic silently in the background. Users never see a wallet popup after the initial session start. + + **Pillar 3: Invisible UX.** A high-frequency application where the + blockchain handles logic silently in the background. Users never see a + wallet popup after the initial session start. - **Native Feature:** [Auto-signing](/interwovenkit/features/autosign/introduction) - **Best for:** Gaming, Social tipping, High-frequency trading. - **The Goal:** An application that allows users to move assets between the - broader Initia L1 and your appchain without leaving your interface. + **Pillar 3: Liquidity & Connectivity.** An application that allows users + to move assets between the broader Initia L1 and your appchain without + leaving your interface. - **Native Feature:** [Interwoven Bridging](/interwovenkit/features/transfers/deposit-withdraw) - - **Best for:** DeFi Lending, Cross-chain storefronts, - Multi-chain games. + - **Best for:** DeFi Lending, Cross-chain storefronts, Multi-chain games. - - **The Goal:** An application that prioritizes human-readable identities, replacing complex hex addresses with personal usernames. + + **Pillar 3: Human Identity.** An application that prioritizes + human-readable identities, replacing complex hex addresses with personal + usernames. - **Native Feature:** [Initia Usernames](/developers/developer-guides/integrating-initia-apps/usernames) - **Best for:** Consumer Social, Peer-to-peer payments, DAO governance. diff --git a/hackathon/examples/evm-bank.mdx b/hackathon/examples/evm-bank.mdx index 6e1bad7..9123227 100644 --- a/hackathon/examples/evm-bank.mdx +++ b/hackathon/examples/evm-bank.mdx @@ -1,5 +1,5 @@ --- -title: 'EVM Tutorial: MiniBank (Interwoven Bridge)' +title: 'EVM Tutorial: MiniBank (Liquidity & Connectivity)' --- diff --git a/hackathon/submission-requirements.mdx b/hackathon/submission-requirements.mdx index 0552cca..1533bcb 100644 --- a/hackathon/submission-requirements.mdx +++ b/hackathon/submission-requirements.mdx @@ -38,16 +38,17 @@ stack and provides a seamless experience for users. ### ⚡ Pillar 3: Showcasing Initia Native Features High-value projects go beyond Hello World by leveraging Initia's native -features. Your submission should implement at least one of the following: - -1. Auto-signing: Create a frictionless UX for high-frequency interactions - (e.g., games or trading). -2. Built-in Indexer: Query rich historical data or NFT holdings using the - native REST APIs. -3. Connect Oracle: Integrate Skip's enshrined price feeds for DeFi or economic - logic. -4. Initia Usernames: Resolve and display .init names to improve user - onboarding. +features. Your submission should implement at least one of the following +Interwoven Power-Ups: + +1. **Auto-signing (Invisible UX):** Create a frictionless experience where + players or users can interact with the blockchain seamlessly without + constant wallet popups (Session UX). +2. **Interwoven Bridge (Liquidity & Connectivity):** Enable the native bridge + interface to allow users to move assets between your appchain and the + broader Initia ecosystem. +3. **Initia Usernames (Human Identity):** Integrate human-readable `.init` + names to replace complex addresses and improve user onboarding. --- @@ -68,11 +69,10 @@ Access the official tools and documentation to build your project: ### APIs & Endpoints -- **Rollup Indexer (Rollytics):** - [View Swagger](https://rollytics-api-echelon-1.anvil.asia-southeast.initia.xyz/swagger/index.html) - (Use this to query transactions and assets **on your appchain**). +- **Local Rollup Indexer:** `http://localhost:8080` (Use this to query + transactions and assets **on your appchain**). - **L1 Indexer:** [View Swagger](https://indexer.initia.xyz/swagger/index.html) - (Use this to query global data like **Initia Usernames**). + (Use this as a reference for querying global data like L1 assets and staking). - **L1 Testnet RPC:** `https://rpc.testnet.initia.xyz` - **L1 Testnet LCD:** `https://lcd.testnet.initia.xyz` - **Faucets:** [faucet.testnet.initia.xyz](https://faucet.testnet.initia.xyz) @@ -99,17 +99,25 @@ what problem does it solve?] ### 🛠 Technical Specification (Automated Verification) - **Rollup Chain ID**: [e.g. my-game-1] -- **Logic Delta URL**: [Link to the core smart contract or module] +- **GitHub Repository**: [Link to public repo] +- **Custom Implementation (Core Logic)**: [Link to the specific smart contract + or module file] +- **Power-Up (Interwoven Feature)**: [Link to the specific frontend file + implementing the feature] - **L2 Interaction TX**: [Hash/Link to a primary functionality transaction] - **Demo Video URL**: [2-minute walkthrough via Loom, YouTube, etc.] -- **Interwoven Feature**: [Auto-signing / Bridging / Usernames] ### 🧬 Implementation Detail -- **Logic Delta**: [Briefly describe the primary custom logic you added or - changed compared to the base templates.] -- **Transaction Purpose**: [Explain why the provided TX represents a core - functionality of your application.] -- **Feature Rationale**: [Why was your chosen Interwoven feature the right - choice for this application's architecture?] +- **The Custom Implementation**: Briefly describe the unique logic you added. + What did you build that wasn't in the base template? +- **The Power-Up**: Which Interwoven feature did you use, and exactly how does + it improve the user experience? +- **The Value Add**: How does this application benefit the broader Initia + ecosystem? Why is it better as an appchain than a generic L1 dApp? + +### 🏃 How to Run Locally + +[Provide 3-4 clear steps for a judge to run your frontend and connect it to a +local environment if necessary.] ```