diff --git a/.changeset/dark-states-sell.md b/.changeset/dark-states-sell.md
new file mode 100644
index 000000000..e36e92189
--- /dev/null
+++ b/.changeset/dark-states-sell.md
@@ -0,0 +1,5 @@
+---
+"@sei-js/mcp-server": patch
+---
+
+Adds the ability to search the @sei-js docs when providing answers
diff --git a/.gitignore b/.gitignore
index 3ed30996a..86ca8e9ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,6 @@ tmp
/out-tsc
main
module
-docs
# dependencies
node_modules
diff --git a/.windsurf/rules/docs.md b/.windsurf/rules/docs.md
new file mode 100644
index 000000000..989a4acb0
--- /dev/null
+++ b/.windsurf/rules/docs.md
@@ -0,0 +1,368 @@
+---
+trigger: model_decision
+description: When writing any Mintlify docs for any package. These docs are located in the /docs folder
+---
+
+---
+description: Mintlify writing assistant guidelines
+type: always
+---
+# Mintlify technical writing assistant
+
+You are an AI writing assistant specialized in creating exceptional technical documentation using Mintlify components and following industry-leading technical writing practices.
+
+## Core writing principles
+
+### Language and style requirements
+- Use clear, direct language appropriate for technical audiences
+- Write in second person ("you") for instructions and procedures
+- Use active voice over passive voice
+- Employ present tense for current states, future tense for outcomes
+- Maintain consistent terminology throughout all documentation
+- Keep sentences concise while providing necessary context
+- Use parallel structure in lists, headings, and procedures
+
+### Content organization standards
+- Lead with the most important information (inverted pyramid structure)
+- Use progressive disclosure: basic concepts before advanced ones
+- Break complex procedures into numbered steps
+- Include prerequisites and context before instructions
+- Provide expected outcomes for each major step
+- End sections with next steps or related information
+- Use descriptive, keyword-rich headings for navigation and SEO
+
+### User-centered approach
+- Focus on user goals and outcomes rather than system features
+- Anticipate common questions and address them proactively
+- Include troubleshooting for likely failure points
+- Provide multiple pathways when appropriate (beginner vs advanced), but offer an opinionated path for people to follow to avoid overwhelming with options
+
+## Mintlify component reference
+
+### Callout components
+
+#### Note - Additional helpful information
+
+
+Supplementary information that supports the main content without interrupting flow
+
+
+#### Tip - Best practices and pro tips
+
+
+Expert advice, shortcuts, or best practices that enhance user success
+
+
+#### Warning - Important cautions
+
+
+Critical information about potential issues, breaking changes, or destructive actions
+
+
+#### Info - Neutral contextual information
+
+
+Background information, context, or neutral announcements
+
+
+#### Check - Success confirmations
+
+
+Positive confirmations, successful completions, or achievement indicators
+
+
+### Code components
+
+#### Single code block
+
+```javascript config.js
+const apiConfig = {
+baseURL: 'https://api.example.com',
+timeout: 5000,
+headers: {
+ 'Authorization': `Bearer ${process.env.API_TOKEN}`
+}
+};
+```
+
+#### Code group with multiple languages
+
+
+```javascript Node.js
+const response = await fetch('/api/endpoint', {
+ headers: { Authorization: `Bearer ${apiKey}` }
+});
+```
+
+```python Python
+import requests
+response = requests.get('/api/endpoint',
+ headers={'Authorization': f'Bearer {api_key}'})
+```
+
+```curl cURL
+curl -X GET '/api/endpoint' \
+ -H 'Authorization: Bearer YOUR_API_KEY'
+```
+
+
+#### Request/Response examples
+
+
+```bash cURL
+curl -X POST 'https://api.example.com/users' \
+ -H 'Content-Type: application/json' \
+ -d '{"name": "John Doe", "email": "john@example.com"}'
+```
+
+
+
+```json Success
+{
+ "id": "user_123",
+ "name": "John Doe",
+ "email": "john@example.com",
+ "created_at": "2024-01-15T10:30:00Z"
+}
+```
+
+
+### Structural components
+
+#### Steps for procedures
+
+
+
+ Run `npm install` to install required packages.
+
+
+ Verify installation by running `npm list`.
+
+
+
+
+ Create a `.env` file with your API credentials.
+
+ ```bash
+ API_KEY=your_api_key_here
+ ```
+
+
+ Never commit API keys to version control.
+
+
+
+
+#### Tabs for alternative content
+
+
+
+ ```bash
+ brew install node
+ npm install -g package-name
+ ```
+
+
+
+ ```powershell
+ choco install nodejs
+ npm install -g package-name
+ ```
+
+
+
+ ```bash
+ sudo apt install nodejs npm
+ npm install -g package-name
+ ```
+
+
+
+#### Accordions for collapsible content
+
+
+
+ - **Firewall blocking**: Ensure ports 80 and 443 are open
+ - **Proxy configuration**: Set HTTP_PROXY environment variable
+ - **DNS resolution**: Try using 8.8.8.8 as DNS server
+
+
+
+ ```javascript
+ const config = {
+ performance: { cache: true, timeout: 30000 },
+ security: { encryption: 'AES-256' }
+ };
+ ```
+
+
+
+### API documentation components
+
+#### Parameter fields
+
+
+Unique identifier for the user. Must be a valid UUID v4 format.
+
+
+
+User's email address. Must be valid and unique within the system.
+
+
+
+Maximum number of results to return. Range: 1-100.
+
+
+
+Bearer token for API authentication. Format: `Bearer YOUR_API_KEY`
+
+
+#### Response fields
+
+
+Unique identifier assigned to the newly created user.
+
+
+
+ISO 8601 formatted timestamp of when the user was created.
+
+
+
+List of permission strings assigned to this user.
+
+
+#### Expandable nested fields
+
+
+Complete user object with all associated data.
+
+
+
+ User profile information including personal details.
+
+
+
+ User's first name as entered during registration.
+
+
+
+ URL to user's profile picture. Returns null if no avatar is set.
+
+
+
+
+
+
+### Interactive components
+
+#### Cards for navigation
+
+
+Complete walkthrough from installation to your first API call in under 10 minutes.
+
+
+
+
+ Learn how to authenticate requests using API keys or JWT tokens.
+
+
+
+ Understand rate limits and best practices for high-volume usage.
+
+
+
+### Media and advanced components
+
+#### Frames for images
+
+Wrap all images in frames.
+
+
+
+
+
+
+
+
+
+#### Tooltips and updates
+
+
+API
+
+
+
+## New features
+- Added bulk user import functionality
+- Improved error messages with actionable suggestions
+
+## Bug fixes
+- Fixed pagination issue with large datasets
+- Resolved authentication timeout problems
+
+
+## Required page structure
+
+Every documentation page must begin with YAML frontmatter:
+
+```yaml
+---
+title: "Clear, specific, keyword-rich title"
+description: "Concise description explaining page purpose and value"
+---
+```
+
+## Content quality standards
+
+### Code examples requirements
+- Always include complete, runnable examples that users can copy and execute
+- Show proper error handling and edge case management
+- Use realistic data instead of placeholder values
+- Include expected outputs and results for verification
+- Test all code examples thoroughly before publishing
+- Specify language and include filename when relevant
+- Add explanatory comments for complex logic
+
+### API documentation requirements
+- Document all parameters including optional ones with clear descriptions
+- Show both success and error response examples with realistic data
+- Include rate limiting information with specific limits
+- Provide authentication examples showing proper format
+- Explain all HTTP status codes and error handling
+- Cover complete request/response cycles
+
+### Accessibility requirements
+- Include descriptive alt text for all images and diagrams
+- Use specific, actionable link text instead of "click here"
+- Ensure proper heading hierarchy starting with H2
+- Provide keyboard navigation considerations
+- Use sufficient color contrast in examples and visuals
+- Structure content for easy scanning with headers and lists
+
+## AI assistant instructions
+
+### Component selection logic
+- Use **Steps** for procedures, tutorials, setup guides, and sequential instructions
+- Use **Tabs** for platform-specific content or alternative approaches
+- Use **CodeGroup** when showing the same concept in multiple languages
+- Use **Accordions** for supplementary information that might interrupt flow
+- Use **Cards and CardGroup** for navigation, feature overviews, and related resources
+- Use **RequestExample/ResponseExample** specifically for API endpoint documentation
+- Use **ParamField** for API parameters, **ResponseField** for API responses
+- Use **Expandable** for nested object properties or hierarchical information
+
+### Quality assurance checklist
+- Verify all code examples are syntactically correct and executable
+- Test all links to ensure they are functional and lead to relevant content
+- Validate Mintlify component syntax with all required properties
+- Confirm proper heading hierarchy with H2 for main sections, H3 for subsections
+- Ensure content flows logically from basic concepts to advanced topics
+- Check for consistency in terminology, formatting, and component usage
+
+### Error prevention strategies
+- Always include realistic error handling in code examples
+- Provide dedicated troubleshooting sections for complex procedures
+- Explain prerequisites clearly before beginning instructions
+- Include verification and testing steps with expected outcomes
+- Add appropriate warnings for destructive or security-sensitive actions
+- Validate all technical information through testing before publication
\ No newline at end of file
diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz
index 79122477a..8e52d04b5 100644
Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ
diff --git a/biome.json b/biome.json
index 737ac0270..cd801888b 100644
--- a/biome.json
+++ b/biome.json
@@ -7,7 +7,7 @@
},
"files": {
"ignoreUnknown": false,
- "ignore": ["*/coverage/*"]
+ "ignore": ["*/coverage/*", "*/dist/*", "packages/create-sei/templates/**"]
},
"formatter": {
"enabled": true,
diff --git a/docs/contributing.mdx b/docs/contributing.mdx
new file mode 100644
index 000000000..ce80a809d
--- /dev/null
+++ b/docs/contributing.mdx
@@ -0,0 +1,165 @@
+---
+title: Contributing
+description: Contributing to @sei-js - Complete guide to local development setup, testing, and pull request process
+icon: "hand-heart"
+---
+
+## Getting Started
+
+Welcome to the @sei-js contributor community! This guide will help you set up your local development environment and contribute to the project.
+
+### Prerequisites
+
+Before you begin, ensure you have:
+
+- **nvm** (Node Version Manager)
+- **Yarn** (4.7.0)
+
+### Local Development Setup
+
+
+
+ 1. Fork the [@sei-js repository](https://github.com/sei-protocol/sei-js) on GitHub
+ 2. Clone your fork locally:
+
+ ```bash
+ git clone git@github.com:sei-protocol/sei-js.git
+ cd sei-js
+ ```
+
+
+ This creates your own copy of the repository that you can modify freely.
+
+
+
+
+ Switch to the project's required Node.js version:
+
+ ```bash
+ nvm use
+ ```
+
+
+ This will use Node.js v20 as specified in the project's `.nvmrc` file.
+
+
+
+ You should see a message confirming you're now using the correct Node.js version.
+
+
+
+
+ Install all dependencies and link packages:
+
+ ```bash
+ yarn install
+ ```
+
+
+ This installs dependencies for all packages in the monorepo and sets up workspace linking.
+
+
+
+
+ Build all packages in the correct order:
+
+ ```bash
+ yarn build:all
+ ```
+
+
+ This ensures all packages are built and ready for development.
+
+
+
+
+ Verify everything is working:
+
+ ```bash
+ # Run all tests
+ yarn test:all
+
+ # Run tests with coverage report
+ yarn test:coverage
+ ```
+
+
+ All tests should pass and you should see coverage reports for each package.
+
+
+
+ Coverage reports help ensure your changes don't reduce test coverage. Look for coverage percentages in the output.
+
+
+
+
+ Start the documentation server to verify everything is set up correctly:
+
+ ```bash
+ yarn docs
+ ```
+
+
+ This will start the documentation server at `http://localhost:3000`
+
+
+
+ The documentation should open in your browser and display without errors.
+
+
+
+
+## Project Structure
+
+Understanding the monorepo structure will help you navigate and contribute effectively:
+
+```
+sei-js/
+├── packages/
+│ ├── create-sei/ # CLI scaffolding tool
+│ ├── precompiles/ # EVM precompile contracts and integrations
+│ ├── ledger/ # Ledger hardware wallet support
+│ ├── registry/ # Chain and asset registry
+│ ├── sei-global-wallet/ # Global wallet provider
+│ └── mcp-server/ # MCP server for AI integration
+├── docs/ # Documentation site
+└── ...
+```
+
+## Development Workflow
+
+### Code Quality and Standards
+
+We use **Biome** for code formatting and linting. Configure your IDE to use Biome for the best development experience:
+
+```bash
+# Check your code
+yarn biome check
+
+# Auto-fix formatting and linting issues
+yarn biome check --apply
+```
+
+
+Configure your IDE to use the project's Biome configuration for automatic formatting and linting as you code.
+
+
+### Running Tests
+
+Run tests to ensure your changes work correctly:
+
+```bash
+# Run all tests
+yarn test:all
+
+# Run tests with coverage report
+yarn test:coverage
+```
+
+
+Always aim for **100% code coverage** in your contributions. Add comprehensive tests for any new functionality or bug fixes.
+
+
+## Making Changes
+
+That's it! You're ready to start contributing to @sei-js. Make your changes, test them thoroughly with the commands above, and submit your pull request when ready.
diff --git a/docs/create-sei/quick-start.mdx b/docs/create-sei/quick-start.mdx
new file mode 100644
index 000000000..c4d07e584
--- /dev/null
+++ b/docs/create-sei/quick-start.mdx
@@ -0,0 +1,106 @@
+---
+title: 'Quick Start'
+description: 'Get started with @sei-js/create-sei in minutes'
+icon: "play"
+---
+
+## Installation
+
+You don't need to install `@sei-js/create-sei` globally. Use it directly with npx or pnpm:
+
+
+
+```bash npx
+npx @sei-js/create-sei app
+```
+
+```bash pnpm
+pnpm create @sei-js/create-sei app
+```
+
+
+
+## Interactive Setup
+
+The CLI provides an interactive wizard to guide you through project setup:
+
+
+
+ Execute the create-sei command with your project name:
+ ```bash
+ npx @sei-js/create-sei app -n my-sei-app
+ ```
+
+
+
+ Select your preferred frontend framework:
+ - **Next.js** - Full-stack React framework with SSR/SSG
+ - **Vite** - Fast build tool with React
+
+
+
+ Choose your blockchain integration:
+ - **EVM** - Ethereum-compatible development (recommended)
+ - **Cosmos** - Native Cosmos SDK (deprecated per SIP-3)
+
+
+
+ For EVM ecosystem, choose your wallet library:
+ - **Wagmi** - Type-safe React hooks for Ethereum
+ - **Ethers.js** - Traditional Ethereum library
+
+
+
+ The CLI automatically configures:
+ - TypeScript configuration
+ - Tailwind CSS styling
+ - ESLint configuration
+ - Prettier formatting
+ - Git initialization
+
+
+
+## Manual CLI Usage
+
+Skip the interactive setup by specifying all options directly:
+
+
+
+```bash Next.js + Wagmi
+npx @sei-js/create-sei app -n my-app -f next -e evm -l wagmi
+```
+
+```bash Vite + Ethers.js
+npx @sei-js/create-sei app -n my-app -f vite -e evm
+```
+
+```bash Next.js + CosmJS (Deprecated)
+npx @sei-js/create-sei app -n my-app -f next -e cosmos
+```
+
+
+
+### CLI Options
+
+| Flag | Long Form | Description | Options |
+|------|-----------|-------------|---------|
+| `-n` | `--name` | Project name (must be valid package name) | Any valid npm package name |
+| `-f` | `--framework` | Frontend framework | `vite`, `next` |
+| `-e` | `--ecosystem` | Blockchain ecosystem | `evm`, `cosmos` |
+| `-l` | `--library` | EVM library (EVM ecosystem only) | `wagmi` |
+
+
+**Template Combinations**: The CLI creates different project templates based on your flag combinations. See all available combinations on the [Templates page](/create-sei/templates).
+
+
+## What Happens Next
+
+After running the CLI, you'll have a fully configured Sei dApp ready for development:
+
+- **Project Structure Created** - Organized file structure with components, hooks, and utilities properly scaffolded for your chosen framework and ecosystem.
+
+- **Wallet Integration Ready** - Pre-configured wallet connections for your chosen ecosystem (Wagmi/Ethers.js for EVM, CosmJS for Cosmos) with connection hooks ready to use.
+
+- **Development Tools Configured** - TypeScript, ESLint, Prettier, and Tailwind CSS automatically configured with sensible defaults and ready for immediate development.
+
+- **Sei Network Integration** - Built-in Sei network configuration and contract interaction examples to help you start building on Sei right away.
\ No newline at end of file
diff --git a/docs/create-sei/templates.mdx b/docs/create-sei/templates.mdx
new file mode 100644
index 000000000..e507ecbb2
--- /dev/null
+++ b/docs/create-sei/templates.mdx
@@ -0,0 +1,170 @@
+---
+title: "Templates"
+description: "Choose from a collection of templates to quickly scaffold your Sei dApps. Each template comes pre-configured with wallet connection, network setup, and essential development tools."
+icon: "grid-2"
+---
+
+
+**New to @sei-js/create-sei?** Check out our [Quick Start guide](/create-sei/quick-start) for step-by-step instructions on getting started. This page is a reference for all available template combinations.
+
+
+## Next.js Templates
+
+Choose from these Next.js-based templates for building production-ready frontend dApps with server-side rendering, SEO optimization, and full-stack capabilities. Each template includes pre-configured wallet connections and Sei blockchain integration.
+
+
+
+ Production-ready Next.js application with Wagmi for type-safe Ethereum wallet connections and blockchain interactions. Includes built-in support for MetaMask, WalletConnect, Coinbase Wallet, and other popular wallets. Best for full-stack dApps requiring server-side rendering, SEO optimization, and robust wallet integration.
+
+
+
+ **CLI Flags:** `-f next -e evm -l wagmi`
+
+
+
+ **Tech Stack:** `Next.js 14` `Wagmi v2` `Viem` `TanStack Query` `Tailwind CSS`
+
+ ```bash
+ npx @sei-js/create-sei app -n my-app -f next -e evm -l wagmi
+ ```
+
+
+
+ Next.js application using Ethers.js for blockchain interactions with custom React hooks for wallet management. Includes pre-configured Sei precompile contract integrations for native blockchain functionality like token operations, staking, and governance. Ideal for developers familiar with Ethers.js who need direct access to Sei's unique features.
+
+
+
+ **CLI Flags:** `-f next -e evm`
+
+
+
+ **Tech Stack:** `Next.js 14` `Ethers.js v6` `Custom Hooks` `Sei Precompiles` `Tailwind CSS`
+
+ ```bash
+ npx @sei-js/create-sei app -n my-app -f next -e evm
+ ```
+
+
+
+
+ **Deprecated**: CosmWasm and Cosmos functionality will be removed from Sei as part of [SIP-3](https://github.com/sei-protocol/sips/blob/main/sips/sip-3.md). Please use EVM templates for new projects.
+
+
+ Legacy Next.js application with CosmJS for Cosmos SDK interactions and Keplr wallet integration. Supports native Cosmos transaction signing and IBC transfers. Only recommended for maintaining existing Cosmos-based applications before migrating to EVM templates.
+
+
+
+ **CLI Flags:** `-f next -e cosmos`
+
+
+
+ **Tech Stack:** `Next.js 14` `CosmJS` `Keplr Wallet` `Cosmos SDK` `Tailwind CSS`
+
+ ```bash
+ npx @sei-js/create-sei app -n my-app -f next -e cosmos
+ ```
+
+
+
+---
+
+## Vite Templates
+
+Select from these Vite-based templates for rapid frontend dApp development with instant hot module replacement and lightning-fast build times. Perfect for prototyping, single-page applications, and development environments requiring quick iteration cycles.
+
+
+
+ Ultra-fast development environment with Vite's instant hot module replacement and Wagmi's type-safe wallet connections. Features automatic wallet detection, connection state management, and optimized bundle sizes. Perfect for rapid prototyping, development testing, and single-page applications requiring fast iteration cycles.
+
+
+
+ **CLI Flags:** `-f vite -e evm -l wagmi`
+
+
+
+ **Tech Stack:** `Vite` `React 18` `TypeScript` `Wagmi v2` `Viem` `TanStack Query`
+
+ ```bash
+ npx @sei-js/create-sei app -n my-app -f vite -e evm -l wagmi
+ ```
+
+
+
+ Lightweight Vite application with Ethers.js for direct blockchain interactions and custom wallet connection setup. Includes Sei precompile contract factories for accessing native functionality like bank operations, staking rewards, and oracle price feeds. Best for developers who prefer minimal abstractions and direct control over wallet connections.
+
+
+
+ **CLI Flags:** `-f vite -e evm`
+
+
+
+ **Tech Stack:** `Vite` `React 18` `TypeScript` `Ethers.js v6` `Sei Precompiles`
+
+ ```bash
+ npx @sei-js/create-sei app -n my-app -f vite -e evm
+ ```
+
+
+
+
+ **Deprecated**: CosmWasm and Cosmos functionality will be removed from Sei as part of [SIP-3](https://github.com/sei-protocol/sips/blob/main/sips/sip-3.md). Please use EVM templates for new projects.
+
+
+ Legacy Vite application with CosmJS for Cosmos SDK interactions, Keplr wallet integration, and native Cosmos transaction signing. Supports IBC transfers and CosmWasm contract interactions. Only use for maintaining existing Cosmos applications during the transition period to EVM-based architecture.
+
+
+
+ **CLI Flags:** `-f vite -e cosmos`
+
+
+
+ **Tech Stack:** `Vite` `React 18` `TypeScript` `CosmJS` `Keplr Wallet`
+
+ ```bash
+ npx @sei-js/create-sei app -n my-app -f vite -e cosmos
+ ```
+
+
+
+## What's Included
+
+Every template includes these essential features:
+
+
+
+ Ready-to-use wallet connection with support for MetaMask, WalletConnect, and other popular wallets
+
+
+ Pre-configured for Sei mainnet, Atlantic-2 testnet, and devnet environments
+
+
+ Full TypeScript support with proper type definitions for contracts and blockchain interactions
+
+
+ ESLint, Prettier, and modern development tools configured out of the box
+
+
+ Mobile-first responsive layouts with Tailwind CSS utility classes
+
+
+ Comprehensive error boundaries and user feedback for blockchain interactions
+
+
\ No newline at end of file
diff --git a/docs/create-sei/welcome.mdx b/docs/create-sei/welcome.mdx
new file mode 100644
index 000000000..75fc1e871
--- /dev/null
+++ b/docs/create-sei/welcome.mdx
@@ -0,0 +1,36 @@
+---
+title: 'Introduction'
+description: 'CLI tool for scaffolding Sei applications'
+icon: "hammer"
+---
+
+## Overview
+
+`@sei-js/create-sei` is a CLI tool that scaffolds production-ready Sei dApps in seconds. Choose from EVM or Cosmos templates with Next.js/Vite, modern wallet integration, and TypeScript support.
+
+```bash
+npx @sei-js/create-sei app -n my-sei-app
+```
+
+
+**Cosmos Deprecation**: Per [SIP-3](https://github.com/sei-protocol/sei-improvement-proposals/blob/main/SIPS/sip-3.md), Sei is transitioning to EVM only. Use EVM templates for new projects.
+
+
+
+
+ Modern Ethereum-compatible development with Wagmi/Viem or Ethers.js
+
+
+ Native Cosmos SDK integration (deprecated per SIP-3)
+
+
+ Next.js for full-stack apps, Vite for lightweight builds
+
+
+ TypeScript, Tailwind CSS, ESLint, wallet connections included
+
+
+
+## What's Included
+
+Every project includes wallet connections, contract interactions, TypeScript, Tailwind CSS, ESLint, and responsive layouts. No additional setup required.
\ No newline at end of file
diff --git a/docs/docs.json b/docs/docs.json
new file mode 100644
index 000000000..ffb2fdcb0
--- /dev/null
+++ b/docs/docs.json
@@ -0,0 +1,143 @@
+{
+ "$schema": "https://mintlify.com/docs.json",
+ "name": "SeiJS Documentation",
+ "theme": "mint",
+ "logo": {
+ "dark": "https://cdn.sei.io/sei.svg",
+ "light": "https://cdn.sei.io/sei.svg"
+ },
+ "description": "Official TypeScript SDK for building decentralized applications on Sei Network. Complete @sei-js toolkit for EVM development, wallet integration, and blockchain interactions.",
+ "favicon": "/favicon.ico",
+ "colors": {
+ "primary": "#9E1F19",
+ "light": "#B52A2A",
+ "dark": "#780000"
+ },
+ "contextual": {
+ "options": ["copy", "chatgpt", "claude"]
+ },
+ "navigation": {
+ "global": {
+ "anchors": [
+ {
+ "anchor": "Sei Documentation",
+ "icon": "book-open-cover",
+ "href": "https://docs.sei.io"
+ },
+ {
+ "anchor": "Sei App",
+ "icon": "grid-2",
+ "href": "https://app.sei.io"
+ },
+ {
+ "anchor": "GitHub",
+ "icon": "github",
+ "href": "https://github.com/sei-protocol/sei-js"
+ }
+ ]
+ },
+ "dropdowns": [
+ {
+ "dropdown": "Getting Started",
+ "icon": "rocket",
+ "pages": [
+ {
+ "group": "Introduction",
+ "pages": ["introduction", "overview"]
+ },
+ {
+ "group": "Local Development",
+ "pages": ["contributing"]
+ }
+ ]
+ },
+ {
+ "dropdown": "@sei-js/mcp-server",
+ "description": "Teach your LLM about Sei",
+ "icon": "robot",
+ "pages": [
+ {
+ "group": "Getting Started",
+ "pages": ["mcp-server/introduction", "mcp-server/setup"]
+ },
+ {
+ "group": "Implementation",
+ "pages": ["mcp-server/tools", "mcp-server/prompts", "mcp-server/context"]
+ }
+ ]
+ },
+ {
+ "dropdown": "@sei-js/create-sei",
+ "description": "Boilerplate frontend dApps",
+ "icon": "hammer",
+ "pages": [
+ {
+ "group": "Getting Started",
+ "pages": ["create-sei/welcome", "create-sei/quick-start", "create-sei/templates"]
+ }
+ ]
+ },
+ {
+ "dropdown": "@sei-js/sei-global-wallet",
+ "description": "User friendly wallet connect",
+ "icon": "wallet",
+ "pages": [
+ {
+ "group": "Getting Started",
+ "pages": ["sei-global-wallet/introduction", "sei-global-wallet/quickstart"]
+ },
+ {
+ "group": "Integrations",
+ "pages": [
+ "sei-global-wallet/rainbowkit",
+ "sei-global-wallet/connectkit",
+ "sei-global-wallet/web3-react",
+ "sei-global-wallet/wagmi-dynamic",
+ "sei-global-wallet/dynamic-nextjs"
+ ]
+ }
+ ]
+ },
+ {
+ "dropdown": "@sei-js/precompiles",
+ "description": "Native functions from the EVM",
+ "icon": "microchip",
+ "pages": [
+ {
+ "group": "Getting Started",
+ "pages": ["precompiles/introduction", "precompiles/quick-start"]
+ },
+ {
+ "group": "Precompiles",
+ "pages": [
+ "precompiles/precompiles/address",
+ "precompiles/precompiles/bank",
+ "precompiles/precompiles/distribution",
+ "precompiles/precompiles/governance",
+ "precompiles/precompiles/ibc",
+ "precompiles/precompiles/json",
+ "precompiles/precompiles/oracle",
+ "precompiles/precompiles/pointer",
+ "precompiles/precompiles/pointerview",
+ "precompiles/precompiles/staking",
+ "precompiles/precompiles/wasm"
+ ]
+ }
+ ]
+ },
+ {
+ "dropdown": "@sei-js/ledger",
+ "description": "Hardware wallet connection",
+ "icon": "shield",
+ "pages": ["ledger/introduction"]
+ }
+ ]
+ },
+ "footer": {
+ "socials": {
+ "x": "https://x.com/SeiNetwork",
+ "github": "https://github.com/sei-protocol/sei-js",
+ "linkedin": "https://www.linkedin.com/company/sei-protocol"
+ }
+ }
+}
diff --git a/docs/favicon.ico b/docs/favicon.ico
new file mode 100644
index 000000000..fd7dbaea2
Binary files /dev/null and b/docs/favicon.ico differ
diff --git a/docs/introduction.mdx b/docs/introduction.mdx
new file mode 100644
index 000000000..ed08e4f3e
--- /dev/null
+++ b/docs/introduction.mdx
@@ -0,0 +1,108 @@
+---
+title: Welcome to @sei-js
+description: A TypeScript SDK for building decentralized applications on Sei
+icon: "rocket"
+---
+
+## Build on Sei
+
+@sei-js is the complete TypeScript SDK for building applications on Sei Network. Whether you're creating DeFi protocols, NFT marketplaces, or blockchain games, @sei-js provides everything you need to ship faster.
+
+**Works with your favorite tools:** Sei is fully EVM-compatible, so you can use Viem, Ethers.js, Foundry, Hardhat, and all your existing Ethereum development tools without any changes. @sei-js extends these tools with Sei-specific features like precompiled contracts and optimized wallet connections.
+
+
+
+ Build your first Sei app in under 10 minutes
+
+
+ Help improve @sei-js and contribute to the project
+
+
+
+## Why @sei-js?
+
+
+
+ Full type safety for every function, contract interaction, and API response. Catch errors at compile time.
+
+
+ Battle-tested components used by major applications in the Sei ecosystem.
+
+
+ Take advantage of Sei's fast finality, low gas fees, and native order matching.
+
+
+
+## Package ecosystem
+
+
+
+ **Native blockchain function access**
+
+ Access Sei's precompiled contracts directly from your EVM applications.
+
+ ```bash
+ yarn add @sei-js/precompiles
+ ```
+
+
+
+ **Project scaffolding and templates**
+
+ Bootstrap new Sei projects with pre-configured templates and tooling.
+
+ ```bash
+ npx @sei-js/create-sei app
+ ```
+
+
+
+ **Universal wallet connections**
+
+ Connect to any Sei-compatible wallet using the EIP-6963 standard.
+
+ ```bash
+ yarn add @sei-js/sei-global-wallet
+ ```
+
+
+
+ **Hardware wallet integration**
+
+ Secure transaction signing with Ledger hardware wallets.
+
+ ```bash
+ yarn add @sei-js/ledger
+ ```
+
+
+
+ **LLM blockchain integration**
+
+ Teach Claude, ChatGPT, or any LLM to interact with the Sei blockchain.
+
+ ```bash
+ npm install -g @sei-js/mcp-server
+ ```
+
+
+
+
+🤖 **Teach Your LLM About Sei**
+
+Connect Claude, ChatGPT, or any LLM to the Sei blockchain with **@sei-js/mcp-server**. Your AI assistant can check balances, transfer tokens, deploy contracts, and guide users through the entire @sei-js ecosystem.
+
+[Get Started with MCP →](/mcp-server/introduction)
+
+
+## Community & Support
+
+- [GitHub Discussions](https://github.com/sei-protocol/sei-js/discussions) - Ask questions and discuss features
+- [Discord](https://discord.gg/sei) - Join the Sei developer community
+- [Official Documentation](https://docs.sei.io) - Complete Sei protocol documentation
+
+## Report Issues
+
+- [GitHub Issues](https://github.com/sei-protocol/sei-js/issues) - Report bugs and request features
+- Include reproduction steps and environment details
+- Check existing issues before creating new ones
diff --git a/docs/ledger/introduction.mdx b/docs/ledger/introduction.mdx
new file mode 100644
index 000000000..7e4f770e2
--- /dev/null
+++ b/docs/ledger/introduction.mdx
@@ -0,0 +1,200 @@
+---
+title: '@sei-js/ledger'
+description: 'TypeScript library for SEI Ledger app helper functions'
+icon: "shield"
+---
+
+## Overview
+
+The `@sei-js/ledger` package provides TypeScript helper functions for integrating with the SEI Ledger hardware wallet app. It enables secure transaction signing and address derivation for Sei blockchain applications using Ledger devices.
+
+## Installation
+
+
+```bash yarn
+yarn add @sei-js/ledger
+```
+
+```bash npm
+npm install @sei-js/ledger
+```
+
+```bash pnpm
+pnpm add @sei-js/ledger
+```
+
+
+## Core Functions
+
+### createTransportAndApp
+
+Creates a transport connection and app instance for communicating with the Ledger device.
+
+**Parameters:**
+- None
+
+**Returns:**
+- `Promise<{transport: Transport, app: SeiApp}>` - Object containing transport and app instances
+
+
+```typescript Basic Usage
+import { createTransportAndApp } from '@sei-js/ledger';
+
+const { transport, app } = await createTransportAndApp();
+console.log(transport, app);
+```
+
+
+### getAddresses
+
+Retrieves both EVM and Cosmos addresses from the Ledger device for a given derivation path.
+
+**Parameters:**
+- `app` (SeiApp) - An instance of the Ledger Sei app
+- `path` (string) - HD derivation path (e.g., "m/44'/60'/0'/0/0")
+
+**Returns:**
+- `Promise<{evmAddress: string, nativeAddress: string}>` - Object containing both address types
+
+
+```typescript Get Addresses
+import { getAddresses } from '@sei-js/ledger';
+
+const { evmAddress, nativeAddress } = await getAddresses(app, "m/44'/60'/0'/0/0");
+console.log(evmAddress, nativeAddress);
+```
+
+
+### SeiLedgerOfflineAminoSigner
+
+A signer class that enables offline amino signing with Ledger devices, compatible with CosmJS.
+
+#### Constructor
+
+```typescript
+new SeiLedgerOfflineAminoSigner(app: SeiApp, path: string)
+```
+
+**Parameters:**
+- `app` (SeiApp) - An instance of the Ledger Sei app
+- `path` (string) - HD derivation path (e.g., "m/44'/60'/0'/0/0")
+
+
+```typescript Create Signer
+import { SeiLedgerOfflineAminoSigner } from '@sei-js/ledger';
+
+const ledgerSigner = new SeiLedgerOfflineAminoSigner(app, "m/44'/60'/0'/0/0");
+```
+
+
+#### getAccounts
+
+Retrieves account information from the Ledger device.
+
+**Returns:**
+- `Promise` - Array of AccountData objects with address and public key
+
+
+```typescript Get Accounts
+const accounts = await ledgerSigner.getAccounts();
+console.log(accounts);
+// { address: 'sei1...', pubkey: { type: 'tendermint/PubKeySecp256k1', value: '...' } }
+```
+
+
+#### signAmino
+
+Signs a transaction document using the Ledger device.
+
+**Parameters:**
+- `_signerAddress` (string) - The address of the signer (unused)
+- `signDoc` (StdSignDoc) - The sign document to be signed
+
+**Returns:**
+- `Promise` - Object containing the signed document and signature
+
+
+```typescript Sign Transaction
+import { StdSignDoc } from '@cosmjs/amino';
+
+const signDoc: StdSignDoc = { /* your StdSignDoc object */ };
+const signResponse = await ledgerSigner.signAmino('sei123...', signDoc);
+console.log(signResponse.signed, signResponse.signature);
+```
+
+
+## Complete Example
+
+Here's a complete example showing how to use the ledger package to delegate tokens:
+
+
+```typescript Complete Delegation Example
+import { coins, SigningStargateClient, StdFee } from "@cosmjs/stargate";
+import { createTransportAndApp, getAddresses, SeiLedgerOfflineAminoSigner } from "@sei-js/ledger";
+
+const testApp = async () => {
+ const validatorAddress = "seivaloper1sq7x0r2mf3gvwr2l9amtlye0yd3c6dqa4th95v";
+ const rpcUrl = "https://rpc-testnet.sei-apis.com/";
+ const memo = "Delegation";
+ const path = "m/44'/60'/0'/0/0";
+
+ // Create connection to Ledger device
+ const { app } = await createTransportAndApp();
+
+ // Get addresses from Ledger
+ const { nativeAddress } = await getAddresses(app, path);
+
+ // Create signer instance
+ const ledgerSigner = new SeiLedgerOfflineAminoSigner(app, path);
+
+ // Connect to Sei network
+ const signingStargateClient = await SigningStargateClient.connectWithSigner(
+ rpcUrl,
+ ledgerSigner
+ );
+
+ // Create delegation message
+ const msgDelegate = {
+ typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
+ value: {
+ delegatorAddress: nativeAddress.address,
+ validatorAddress: validatorAddress,
+ amount: coins(500, "usei"),
+ },
+ };
+
+ // Set transaction fee
+ const fee: StdFee = {
+ amount: [{ denom: "usei", amount: "20000" }],
+ gas: "200000",
+ };
+
+ // Sign and broadcast transaction
+ const result = await signingStargateClient.signAndBroadcast(
+ nativeAddress.address,
+ [msgDelegate],
+ fee,
+ memo
+ );
+
+ console.log("Broadcast result:", result);
+};
+
+testApp();
+```
+
+
+## Security Notes
+
+
+- Ensure your Ledger device is genuine and purchased from official sources
+- Always verify transaction details on your Ledger device screen before confirming
+- Keep your Ledger device firmware updated
+- Store your recovery phrase securely and never share it
+
+
+## Hardware Requirements
+
+- Ledger Nano S Plus, Nano X, or compatible device
+- SEI app installed on the Ledger device
+- USB or Bluetooth connection to your computer
diff --git a/docs/llms-full.txt b/docs/llms-full.txt
new file mode 100644
index 000000000..e9ddeebc5
--- /dev/null
+++ b/docs/llms-full.txt
@@ -0,0 +1,196 @@
+# SeiJS Documentation
+
+Official JavaScript SDK for building decentralized applications on Sei Network. Includes tools for EVM integration, boilerplate applications, wallet connections, and precompile contract interfaces.
+
+## Overview
+
+SeiJS is a comprehensive JavaScript SDK for interacting with the Sei blockchain. It provides tools for both Cosmos SDK and EVM integration, allowing developers to build decentralized applications on Sei Network.
+
+## Getting Started
+
+### Installation
+
+```bash
+npm install @sei-js/precompiles @sei-js/cosmos
+```
+
+For specific functionality, install the relevant packages:
+
+## Key Packages
+
+### @sei-js/core
+Core functionality for Sei blockchain interactions. Provides the foundation for connecting to Sei networks and performing basic operations.
+
+### @sei-js/precompiles
+Native blockchain function integrations through precompile contracts. These contracts provide direct access to Sei's unique blockchain features from EVM smart contracts.
+
+### @sei-js/cosmos
+Cosmos SDK integration tools. Provides access to Sei's Cosmos SDK features, including staking, governance, and IBC transfers.
+
+### @sei-js/create-sei
+Boilerplate applications and templates. Quickly scaffold new Sei applications with pre-configured setups.
+
+### @sei-js/ledger
+Ledger hardware wallet integration. Securely connect to Ledger devices for signing transactions on Sei.
+
+### @sei-js/sei-global-wallet
+Wallet connection tools. Simplifies connecting to various wallet providers for Sei applications.
+
+## Precompile Contracts
+
+Sei offers unique precompile contracts for blockchain interactions:
+
+### Address (0x1004)
+Address association between EVM and Cosmos addresses. Allows mapping between the two address formats.
+
+### Bank (0x1001)
+Token operations including transfers, balances, and supply queries. Access Sei's native token functionality from EVM.
+
+### Confidential Transfers (0x1010)
+Privacy features for confidential transactions. Enables private transfers with selective disclosure.
+
+### Distribution (0x1007)
+Reward distribution for staking and governance. Access staking rewards and community pool funds.
+
+### Governance (0x1006)
+Voting and deposits for governance proposals. Participate in Sei governance from EVM contracts.
+
+### IBC (0x1009)
+Cross-chain transfers using the Inter-Blockchain Communication protocol. Send tokens to other Cosmos chains.
+
+### JSON (0x1003)
+JSON parsing utilities for smart contracts. Simplifies handling JSON data in EVM contracts.
+
+### Oracle (0x1002)
+Price feeds and TWAPs for DeFi applications. Access reliable price data for various assets.
+
+### Pointer (0x100B)
+Token pointer creation for cross-chain assets. Create and manage pointers to tokens on other chains.
+
+### Pointerview (0x100A)
+Token pointer queries for viewing pointer information. Query details about token pointers.
+
+### Staking (0x1005)
+Validator operations including delegation and unbonding. Participate in Sei's proof-of-stake system.
+
+### WASM (0x1002)
+Smart contract interaction with CosmWasm contracts. Call CosmWasm contracts from EVM contracts.
+
+## Ethers.js Integration
+
+SeiJS provides full integration with Ethers.js for EVM interactions:
+
+```javascript
+import { ethers } from 'ethers';
+import { getBankPrecompile } from '@sei-js/precompiles/ethers';
+
+// Connect to Sei EVM
+const provider = new ethers.JsonRpcProvider('https://evm-rpc.sei-apis.com');
+const signer = new ethers.Wallet(privateKey, provider);
+
+// Get Bank precompile contract
+const bankContract = getBankPrecompile(signer);
+
+// Transfer tokens
+await bankContract.send('sei1...', 'usei', '1000000');
+```
+
+## Viem Integration
+
+SeiJS also supports Viem for modern EVM interactions:
+
+```javascript
+import { createWalletClient, http } from 'viem';
+import { privateKeyToAccount } from 'viem/accounts';
+import { sei } from '@sei-js/precompiles/viem';
+import { bankAbi } from '@sei-js/precompiles/viem';
+
+// Connect to Sei EVM
+const account = privateKeyToAccount('0x...');
+const client = createWalletClient({
+ account,
+ chain: sei,
+ transport: http()
+});
+
+// Call Bank precompile
+const result = await client.writeContract({
+ address: '0x0000000000000000000000000000000000001001',
+ abi: bankAbi,
+ functionName: 'send',
+ args: ['sei1...', 'usei', 1000000n]
+});
+```
+
+## Wallet Integration
+
+Connect to various wallets using the Sei Global Wallet:
+
+```javascript
+import { SeiGlobalWallet } from '@sei-js/sei-global-wallet';
+
+// Initialize wallet
+const wallet = new SeiGlobalWallet();
+
+// Connect to wallet
+await wallet.connect();
+
+// Get accounts
+const accounts = await wallet.getAccounts();
+
+// Sign transaction
+const signedTx = await wallet.signTransaction(tx);
+```
+
+## Create-Sei Templates
+
+Quickly scaffold new applications:
+
+```bash
+npx @sei-js/create-sei app
+```
+
+Choose from various templates:
+- React + Viem
+- Next.js + Ethers
+- Vue + Viem
+- Vanilla JS
+
+## Advanced Features
+
+### Confidential Transfers
+
+```javascript
+import { getConfidentialTransfersPrecompile } from '@sei-js/precompiles/ethers';
+
+const ctContract = getConfidentialTransfersPrecompile(signer);
+
+// Initialize account
+await ctContract.initializeAccount();
+
+// Make private transfer
+await ctContract.transfer('recipient_public_key', 'usei', '1000000');
+```
+
+### CosmWasm Integration
+
+```javascript
+import { getWasmPrecompile } from '@sei-js/precompiles/ethers';
+
+const wasmContract = getWasmPrecompile(signer);
+
+// Query CosmWasm contract
+const result = await wasmContract.query('sei1...', '{"get_count":{}}');
+
+// Execute CosmWasm contract
+await wasmContract.execute('sei1...', '{"increment":{}}', []);
+```
+
+## Security Best Practices
+
+- Always use the latest version of SeiJS packages
+- Validate all user inputs before sending to the blockchain
+- Use hardware wallets for high-value operations
+- Test thoroughly on testnet before deploying to mainnet
+- Follow proper key management practices
+- Implement proper error handling for all blockchain operations
diff --git a/docs/llms.txt b/docs/llms.txt
new file mode 100644
index 000000000..a7ea6f19f
--- /dev/null
+++ b/docs/llms.txt
@@ -0,0 +1,33 @@
+# SeiJS Documentation
+
+Official JavaScript SDK for building decentralized applications on Sei Network. Includes tools for EVM integration, boilerplate applications, wallet connections, and precompile contract interfaces.
+
+## Overview
+
+SeiJS is a comprehensive JavaScript SDK for interacting with the Sei blockchain. It provides tools for both Cosmos SDK and EVM integration, allowing developers to build decentralized applications on Sei Network.
+
+## Key Packages
+
+- @sei-js/core - Core functionality for Sei blockchain interactions
+- @sei-js/precompiles - Native blockchain function integrations through precompile contracts
+- @sei-js/cosmos - Cosmos SDK integration tools
+- @sei-js/create-sei - Boilerplate applications and templates
+- @sei-js/ledger - Ledger hardware wallet integration
+- @sei-js/registry - Asset registry for tokens and networks
+- @sei-js/sei-global-wallet - Wallet connection tools
+
+## Precompile Contracts
+
+Sei offers unique precompile contracts for blockchain interactions:
+- Address (0x1004) - Address association
+- Bank (0x1001) - Token operations
+- Confidential Transfers (0x1010) - Privacy features
+- Distribution (0x1007) - Reward distribution
+- Governance (0x1006) - Voting and deposits
+- IBC (0x1009) - Cross-chain transfers
+- JSON (0x1003) - JSON parsing utilities
+- Oracle (0x1002) - Price feeds and TWAPs
+- Pointer (0x100B) - Token pointer creation
+- Pointerview (0x100A) - Token pointer queries
+- Staking (0x1005) - Validator operations
+- WASM (0x1002) - Smart contract interaction
diff --git a/docs/mcp-server/context.mdx b/docs/mcp-server/context.mdx
new file mode 100644
index 000000000..53a93b8bb
--- /dev/null
+++ b/docs/mcp-server/context.mdx
@@ -0,0 +1,18 @@
+---
+title: "Documentation Context"
+description: "How the MCP server reads @sei-js documentation to provide intelligent assistance"
+icon: "book-open"
+---
+
+The Sei MCP Server includes intelligent documentation search that reads the entire @sei-js ecosystem documentation to provide context-aware responses and code generation.
+
+## Documentation Access
+
+The MCP server can search and reference documentation for all @sei-js packages:
+
+- **@sei-js/precompiles** - Precompile contract reference and integration examples
+- **@sei-js/sei-global-wallet** - EIP-6963 wallet standard implementation
+- **@sei-js/mcp-server** - Model Context Protocol server for LLMs
+- **@sei-js/registry** - Network configuration and asset information
+- **@sei-js/create-sei** - Project scaffolding and templates
+- **@sei-js/ledger** - Hardware wallet integration
diff --git a/docs/mcp-server/introduction.mdx b/docs/mcp-server/introduction.mdx
new file mode 100644
index 000000000..e48a22bae
--- /dev/null
+++ b/docs/mcp-server/introduction.mdx
@@ -0,0 +1,117 @@
+---
+title: "Sei MCP Server"
+description: "Enable AI assistants to interact with Sei blockchain through natural language using the Model Context Protocol"
+icon: "robot"
+---
+
+
+
+ Connect AI assistants to Sei blockchain with natural language commands for token transfers, smart contract interactions and deployments, and more.
+
+
+ Developers, Vibe Coders, DeFi users, NFT collectors, and anyone wanting to interact with Sei through natural language interfaces.
+
+
+
+## Quick Start
+
+
+**Secure by Default**: The MCP server runs in **read-only mode** by default. Wallet tools are disabled until you explicitly configure a private key.
+
+
+### Basic Setup (Read-Only)
+
+Start with read-only blockchain data access:
+
+```json
+{
+ "mcpServers": {
+ "sei": {
+ "command": "npx",
+ "args": ["-y", "@sei-js/mcp-server"]
+ }
+ }
+}
+```
+
+### Full Setup (With Wallet)
+
+To enable transactions and wallet tools, add the wallet mode flag and private key:
+
+```json
+{
+ "mcpServers": {
+ "sei": {
+ "command": "npx",
+ "args": ["-y", "@sei-js/mcp-server"],
+ "env": {
+ "WALLET_MODE": "private-key",
+ "PRIVATE_KEY": "0x123..."
+ }
+ }
+ }
+}
+```
+
+
+ Follow our step-by-step installation guide for Claude Desktop, Cursor, Windsurf, and custom integrations.
+
+
+## What is MCP?
+
+The Model Context Protocol is an open standard that connects AI systems with custom prompts, tools and data sources (context). It enables:
+
+- **Real-time blockchain data access** - Get current balances, transaction history, and network status directly from Sei
+- **Secure by default** - Runs in read-only mode until you explicitly enable wallet tools
+- **Full execution and write operations** - Deploy contracts, execute transactions, and interact with smart contracts (with wallet configured)
+- **Up-to-date documentation access** - Search and understand the latest Sei documentation and guides
+- **Specialized blockchain capabilities** - Access Sei-specific features like precompiles and native token operations
+
+The Sei MCP Server leverages this protocol to bring comprehensive blockchain functionality directly to your AI assistant, enabling natural language interactions with the Sei network.
+
+## Why Use Sei MCP Server?
+
+
+
+ Interact with Sei blockchain using conversational commands like "What's my SEI balance?" or "Send 1 SEI to this address" instead of complex API calls.
+
+
+
+ Get intelligent insights about transactions, contracts, and market data with built-in analysis capabilities powered by your AI assistant.
+
+
+
+ Works seamlessly with Cursor IDE, Windsurf, Claude Desktop, and custom applications through standardized MCP integration.
+
+
+
+ Access 16+ blockchain tools covering token management, NFT operations, smart contract interactions, and network monitoring.
+
+
+
+## Example Queries
+
+```text
+"How do I query staking my delegations using Viem?"
+"Generate a wallet connection component using Sei Global Wallet"
+"Help me set up a new Sei project with the latest patterns"
+```
+
+## Code Generation
+
+The AI generates accurate, production-ready code using official @sei-js patterns:
+
+- Uses correct package imports and APIs
+- Follows documented best practices
+- Includes proper error handling
+- References current version patterns
+
+
+The Sei MCP Server is actively developed with new features added regularly. Current version supports core blockchain operations with advanced DeFi integrations planned.
+
\ No newline at end of file
diff --git a/docs/mcp-server/prompts.mdx b/docs/mcp-server/prompts.mdx
new file mode 100644
index 000000000..6a1870e2e
--- /dev/null
+++ b/docs/mcp-server/prompts.mdx
@@ -0,0 +1,50 @@
+---
+title: "AI Prompts"
+description: "Pre-configured prompts for common blockchain operations"
+icon: "comments"
+---
+
+The Sei MCP Server includes pre-configured AI prompts for common blockchain tasks. Use these for quick access to frequent operations.
+
+## Pre-configured Prompts
+
+| Prompt | Purpose | Usage |
+|--------|---------|-------|
+| `my_wallet_address` | Get your wallet address | "What's my wallet address?" |
+| `explore_block` | Analyze block data | "Explore the latest block" |
+| `analyze_transaction` | Transaction details | "Analyze transaction 0xabc..." |
+| `analyze_address` | Address analysis | "Analyze address 0x742d..." |
+
+## Common Usage Examples
+
+### Balance Queries
+```text
+"What's my SEI balance?"
+"What's my USDC balance?"
+"Show me all my token balances"
+```
+
+### Transfer Operations
+```text
+"Send 1 SEI to 0x742d35Cc6634C0532925a3b8D4C1C4e3153DC"
+"Send 100 USDC to 0x742d..."
+"Transfer NFT token 123 to 0x742d..."
+```
+
+### DeFi Operations
+```text
+"Approve 1000 USDC for Uniswap"
+"Get info for token 0x3894..."
+"Is 0x3894... a contract?"
+```
+
+### Blockchain Analysis
+```text
+"Show me Sei network information"
+"Get latest block details"
+"Analyze transaction 0xabc123..."
+```
+
+
+Ask your AI assistant using natural language - it understands conversational commands and will map them to the appropriate MCP tools.
+
diff --git a/docs/mcp-server/setup.mdx b/docs/mcp-server/setup.mdx
new file mode 100644
index 000000000..7c5bbabf3
--- /dev/null
+++ b/docs/mcp-server/setup.mdx
@@ -0,0 +1,230 @@
+---
+title: "Setup & Installation"
+description: "Configure Sei MCP Server with Cursor, Windsurf, Claude Desktop, or CLI"
+icon: "download"
+---
+
+
+
+
+
+
+ Navigate to Cursor → Settings → Cursor Settings → MCP
+
+ ```
+ Cursor → Settings → Cursor Settings → MCP
+ ```
+
+
+
+ Click "Add new Global MCP server" and add this configuration to mcp.json:
+
+
+ ```json
+ {
+ "mcpServers": {
+ "sei": {
+ "command": "npx",
+ "args": ["-y", "@sei-js/mcp-server"],
+ "env": {
+ "WALLET_MODE": "private-key",
+ "PRIVATE_KEY": "0x123..."
+ }
+ }
+ }
+ }
+ ```
+
+
+
+
+ Restart Cursor to activate the MCP server. You'll see a notification when it's ready.
+
+
+
+
+
+
+
+
+
+ Navigate to Windsurf → Settings → Windsurf Settings → Cascade
+
+ ```
+ Windsurf → Settings → Windsurf Settings → Cascade
+ ```
+
+
+
+ Add the Sei MCP Server to your configuration:
+
+
+ ```json
+ {
+ "mcpServers": {
+ "sei": {
+ "command": "npx",
+ "args": ["-y", "@sei-js/mcp-server"],
+ "env": {
+ "WALLET_MODE": "private-key",
+ "PRIVATE_KEY": "0x123..."
+ }
+ }
+ }
+ }
+ ```
+
+
+
+
+ Save and restart Windsurf. The server loads automatically.
+
+
+
+
+
+
+
+
+
+ Download [Claude Desktop](https://claude.ai/download) from Anthropic.
+
+
+
+ Open Settings → Developer → Edit Config and add:
+
+
+ ```json
+ {
+ "mcpServers": {
+ "sei": {
+ "command": "npx",
+ "args": ["-y", "@sei-js/mcp-server"],
+ "env": {
+ "WALLET_MODE": "private-key",
+ "PRIVATE_KEY": "0x123..."
+ }
+ }
+ }
+ }
+ ```
+
+
+
+
+ Save and restart Claude Desktop to enable Sei tools.
+
+
+
+
+
+
+
+
+
+ ```bash
+ npm install -g @anthropic-ai/claude-code
+ ```
+
+
+
+ ```bash
+ # Read-only mode (default)
+ claude mcp add sei-mcp-server npx @sei-js/mcp-server
+
+ # Wallet-enabled mode
+ claude mcp add sei-mcp-server-wallet npx @sei-js/mcp-server --env WALLET_MODE=private-key PRIVATE_KEY=0x123...
+ ```
+
+
+
+ ```bash
+ claude
+ ```
+
+ The Sei MCP Server activates automatically in your session.
+
+
+
+
+
+
+## Wallet Connection
+
+
+**Wallet Tools Disabled by Default**
+
+For security, the MCP server runs in **read-only mode** by default. Only blockchain data tools are available without wallet configuration.
+
+
+### Default Behavior (Read-Only)
+
+Without wallet configuration, you can:
+- ✅ Check balances and account data
+- ✅ Read smart contract data
+- ✅ Get network and block information
+- ✅ Search documentation
+- ❌ Send transactions or transfer tokens
+- ❌ Deploy or write to contracts
+- ❌ Approve token spending
+
+### Enabling Wallet Tools
+
+To unlock transaction capabilities, add your private key to the configuration:
+
+
+Use a dedicated test wallet with minimal funds. Never use your main wallet's private key.
+
+
+
+
+ Export your private key from your wallet:
+ - Look for "Export Private Key" or "Show Private Key" in wallet settings
+ - Ensure the key starts with `0x`
+ - Fund the wallet with small amounts for testing
+
+
+
+ Add the `PRIVATE_KEY` environment variable to your MCP configuration:
+
+ ```json
+ {
+ "mcpServers": {
+ "sei": {
+ "command": "npx",
+ "args": ["-y", "@sei-js/mcp-server"],
+ "env": {
+ "WALLET_MODE": "private-key",
+ "PRIVATE_KEY": "0x123...."
+ }
+ }
+ }
+ }
+ ```
+
+
+
+ Restart your AI assistant and verify wallet tools are available:
+
+ **Ask your AI:** "What's my wallet address?"
+
+ If configured correctly, you'll get your wallet address. If not, you'll see an error message.
+
+
+
+### Security Best Practices
+
+
+
+ Use a dedicated wallet for testing, not your main holdings
+
+
+ Keep only small amounts needed for testing transactions
+
+
+ Never commit private keys to version control
+
+
+ Rotate test wallet keys periodically
+
+
\ No newline at end of file
diff --git a/docs/mcp-server/tools.mdx b/docs/mcp-server/tools.mdx
new file mode 100644
index 000000000..2eb4d9b94
--- /dev/null
+++ b/docs/mcp-server/tools.mdx
@@ -0,0 +1,157 @@
+---
+title: "Available Tools"
+description: "Complete reference of 28 MCP tools for blockchain operations"
+icon: "wrench"
+---
+
+The Sei MCP Server provides 28 tools for blockchain operations. **By default, wallet tools are disabled** and only read-only tools are available. [Enable wallet tools](/mcp-server/setup#wallet-connection) to unlock transaction capabilities.
+
+
+**Wallet Tools Disabled by Default**
+
+For security, wallet-dependent tools require explicit configuration. Only read-only blockchain data tools are available by default.
+
+
+## Read-Only Tools (Always Available)
+
+These tools work without wallet connection and are available by default:
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `get_balance` | Check SEI balance | "What's my SEI balance?" |
+| `is_contract` | Check if address is contract | "Is 0x3894... a contract?" |
+| `estimate_gas` | Estimate transaction gas cost | "How much gas for this transaction?" |
+
+## Wallet Tools (Require Configuration) 🔐
+
+
+These tools require [wallet configuration](/mcp-server/setup#wallet-connection) and are **disabled by default** for security.
+
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `get_address_from_private_key` | Get wallet address | "What's my wallet address?" |
+| `transfer_sei` | Send SEI tokens | "Send 1 SEI to 0x742d..." |
+
+## Network & Blockchain Data
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `get_chain_info` | Get network information | "Show me Sei network info" |
+| `get_supported_networks` | List supported networks | "What networks are supported?" |
+| `get_latest_block` | Get latest block | "Get latest block" |
+| `get_block_by_number` | Get specific block | "Get block 12345" |
+| `get_transaction` | Get transaction details | "Analyze transaction 0xabc..." |
+| `get_transaction_receipt` | Get transaction receipt | "Get receipt for 0xabc..." |
+
+## Token Management
+
+### Read-Only Token Tools
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `get_token_info` | Get ERC-20 token details | "Get info for token 0x3894..." |
+| `get_token_balance` | Check token balance | "What's my USDC balance?" |
+| `get_erc20_balance` | Check ERC-20 balance | "Check ERC20 balance for 0x742d..." |
+| `get_token_balance_erc20` | Get ERC-20 token balance | "Get token balance for address" |
+
+### Wallet-Required Token Tools 🔐
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `transfer_token` | Send ERC-20 tokens | "Send 100 USDC to 0x742d..." |
+| `transfer_erc20` | Transfer ERC-20 tokens | "Transfer tokens to address" |
+| `approve_token_spending` | Approve token spending | "Approve 1000 USDC for 0xDEX..." |
+
+## NFT Operations (ERC-721)
+
+### Read-Only NFT Tools
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `get_nft_info` | Get NFT details | "Get info for NFT token 123" |
+| `check_nft_ownership` | Verify NFT ownership | "Do I own NFT token 123?" |
+| `get_nft_balance` | Count NFTs owned | "How many NFTs do I own?" |
+
+### Wallet-Required NFT Tools 🔐
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `transfer_nft` | Transfer NFT | "Transfer NFT token 123 to 0x742d..." |
+
+## Multi-Token Operations (ERC-1155)
+
+### Read-Only ERC-1155 Tools
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `get_erc1155_balance` | Get ERC-1155 token balance | "Check my ERC1155 token balance" |
+| `get_erc1155_token_uri` | Get ERC-1155 metadata URI | "Get metadata for token ID 123" |
+
+### Wallet-Required ERC-1155 Tools 🔐
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `transfer_erc1155` | Transfer ERC-1155 tokens | "Transfer ERC1155 token to address" |
+
+## Smart Contract Operations
+
+### Read-Only Contract Tools
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `read_contract` | Read contract data | "Read balanceOf from contract 0x3894..." |
+
+### Wallet-Required Contract Tools 🔐
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `write_contract` | Execute contract function | "Call contract function with params" |
+| `deploy_contract` | Deploy new smart contract | "Deploy my token contract" |
+
+## Documentation
+
+| Tool | Purpose | Example Usage |
+|------|---------|---------------|
+| `search_sei_js_docs` | Search Sei-JS documentation | "How do I use precompiles with Viem?" |
+
+## Enabling Wallet Tools
+
+To use wallet-required tools (🔐), you must configure a wallet connection:
+
+
+
+ Add your private key to the MCP server configuration:
+
+ ```json
+ {
+ "mcpServers": {
+ "sei": {
+ "command": "npx",
+ "args": ["-y", "@sei-js/mcp-server"],
+ "env": {
+ "WALLET_MODE": "private-key",
+ "PRIVATE_KEY": "0x123..."
+ }
+ }
+ }
+ }
+ ```
+
+
+
+ Restart your AI assistant (Claude Desktop, Cursor, etc.) to activate wallet tools.
+
+
+
+[See full setup guide →](/mcp-server/setup#wallet-connection)
+
+## Security Notes
+
+
+**Wallet tools require a private key for transaction signing. Ensure this key is:**
+- Kept secure and never shared
+- Only used with funds you can afford to lose
+- Properly backed up before use
+- From a dedicated wallet, not your main holdings
+
\ No newline at end of file
diff --git a/docs/overview.mdx b/docs/overview.mdx
new file mode 100644
index 000000000..ebd14c05b
--- /dev/null
+++ b/docs/overview.mdx
@@ -0,0 +1,140 @@
+---
+title: Quick Start Guide
+description: Build your first Sei application in under 10 minutes with @sei-js
+icon: "bolt"
+---
+
+## Prerequisites
+
+Before you begin, ensure you have the following installed:
+
+
+
+ **Required for running @sei-js applications:**
+ - **Node.js** (v18 or higher) - Required for npx and package management
+ - **nvm** (Node Version Manager) - Recommended for managing Node.js versions
+
+
+ Verify your installation: `node --version` should output v18.0.0 or higher
+
+
+
+
+ **Traditional Editors:**
+ - **VS Code** - Popular, lightweight with excellent TypeScript support
+ - **WebStorm** - Full-featured IDE with advanced debugging and refactoring
+
+ **AI-Powered Editors:**
+ - **Cursor** - VS Code fork with built-in AI coding assistance
+ - **Windsurf** - AI-first development environment with intelligent code generation
+
+
+ All editors work great with @sei-js projects. Choose based on your preference for AI assistance and feature requirements.
+
+
+
+
+## Create your first Sei application
+
+
+
+ Generate a new Sei application using our CLI tool:
+
+
+ ```bash npx
+ npx @sei-js/create-sei app
+ ```
+
+ ```bash pnpm
+ pnpm create @sei-js/create-sei app
+ ```
+
+
+
+ **Expected outcome:** A new project directory with TypeScript configuration, testing setup, and example code.
+
+
+
+ The CLI will ask you to choose a template. Select "React + Wagmi" for a full-featured web application, or "Node.js" for backend/script development.
+
+
+
+
+ Move into your project directory and install dependencies:
+
+
+ ```bash npm
+ cd app
+ npm install
+ ```
+
+ ```bash yarn
+ cd app
+ yarn install
+ ```
+
+ ```bash pnpm
+ cd app
+ pnpm install
+ ```
+
+
+
+ **Expected outcome:** All dependencies installed successfully without errors.
+
+
+
+ **Common issues and solutions:**
+
+ - **Node version conflicts:** Use `nvm use` to switch to the correct Node.js version
+ - **Permission errors:** Avoid using `sudo` with npm. Use `nvm` or fix npm permissions
+ - **Network timeouts:** Try switching to a different registry: `npm config set registry https://registry.npmjs.org/`
+
+
+
+
+ Launch your application in development mode:
+
+
+ ```bash npm
+ npm run dev
+ ```
+
+ ```bash yarn
+ yarn dev
+ ```
+
+ ```bash pnpm
+ pnpm dev
+ ```
+
+
+
+ **Expected outcome:** Development server running at `http://localhost:3000` with hot reload enabled.
+
+
+ Your browser should automatically open to show your new Sei application with:
+ - Wallet connection button
+ - Network status display
+ - Example interactions ready to test
+
+
+
+## What you can build
+
+Your new Sei application comes with examples and patterns for common blockchain interactions:
+
+
+
+ Connect to any Sei-compatible wallet including MetaMask, Compass, and more using the built-in wallet integration
+
+
+ Fetch and display wallet balances for SEI and other tokens with real-time updates
+
+
+ Access blockchain information like total SEI supply using precompile contracts
+
+
+ Deploy and interact with smart contracts including simple examples like counters and token transfers
+
+
diff --git a/docs/precompiles/introduction.mdx b/docs/precompiles/introduction.mdx
new file mode 100644
index 000000000..e22cf4b21
--- /dev/null
+++ b/docs/precompiles/introduction.mdx
@@ -0,0 +1,34 @@
+---
+title: 'Introduction'
+description: '@sei-js/precompiles is a TypeScript library for interacting with Sei precompile contracts'
+icon: "microchip"
+---
+
+## Overview
+
+The `@sei-js/precompiles` package provides TypeScript utilities and helpers for interacting with Sei's precompile contracts. It offers seamless integration with popular Ethereum development tools like Viem and Ethers.js, providing typed interfaces, contract factories, and utilities specifically designed for Sei's precompile ecosystem.
+
+## Key Features
+
+- **Precompile-First Design**: Purpose-built for Sei's precompile contract ecosystem
+- **Type Safety**: Fully typed interfaces and contract factories for both Viem and Ethers.js
+- **Contract Helpers**: Utilities and helpers specifically for precompile interactions
+- **Production Ready**: Battle-tested precompile integrations used across the Sei ecosystem
+
+## Installation
+
+
+
+```bash npm
+npm install @sei-js/precompiles
+```
+
+```bash yarn
+yarn add @sei-js/precompiles
+```
+
+```bash pnpm
+pnpm add @sei-js/precompiles
+```
+
+
\ No newline at end of file
diff --git a/docs/precompiles/precompiles/address.mdx b/docs/precompiles/precompiles/address.mdx
new file mode 100644
index 000000000..8f3dc7dc0
--- /dev/null
+++ b/docs/precompiles/precompiles/address.mdx
@@ -0,0 +1,459 @@
+---
+title: 'Address Precompile'
+description: 'Manage address associations between Sei and EVM addresses through the Address precompile contract'
+icon: "address-card"
+---
+
+## Overview
+
+The Address precompile enables bidirectional address mapping between Sei's native Cosmos addresses (bech32 format) and EVM addresses (hex format). This is essential for cross-chain functionality and allows users to associate their Cosmos and EVM identities.
+
+**Contract Address:** `0x0000000000000000000000000000000000001004`
+
+## Key Features
+
+- **Address Translation**: Convert between Sei and EVM address formats
+- **Address Association**: Link Cosmos and EVM addresses for the same account
+- **Cross-Chain Identity**: Enable seamless interaction between EVM and Cosmos ecosystems
+- **Public Key Association**: Associate addresses using public key cryptography
+
+## Available Functions
+
+### View Functions
+
+
+
+ Get the associated Sei (Cosmos) address for an EVM address.
+
+ **Parameters:**
+ - `addr` (address): The EVM address to lookup
+
+ **Returns:** Associated Sei address in bech32 format
+
+ ```typescript
+ const seiAddress = await addressContract.getSeiAddr(
+ "0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A"
+ );
+ // Returns: "sei1wsltdx4m9k8dafl92nkwmywd6k7jdlpz5h3j3q"
+ ```
+
+
+
+ Get the associated EVM address for a Sei (Cosmos) address.
+
+ **Parameters:**
+ - `addr` (string): The Sei address to lookup (bech32 format)
+
+ **Returns:** Associated EVM address in hex format
+
+ ```typescript
+ const evmAddress = await addressContract.getEvmAddr(
+ "sei1wsltdx4m9k8dafl92nkwmywd6k7jdlpz5h3j3q"
+ );
+ // Returns: "0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A"
+ ```
+
+
+
+### State-Changing Functions
+
+
+
+ Associate addresses using signature verification.
+
+ **Parameters:**
+ - `v` (string): Recovery ID from signature
+ - `r` (string): R component of signature
+ - `s` (string): S component of signature
+ - `customMessage` (string): Custom message that was signed
+
+ **Returns:** Tuple of (seiAddr, evmAddr)
+
+ ```typescript
+ const [seiAddr, evmAddr] = await addressContract.associate(
+ "27", // v
+ "0x1234...", // r
+ "0x5678...", // s
+ "Associate my addresses" // customMessage
+ );
+ ```
+
+
+
+ Associate addresses using a public key.
+
+ **Parameters:**
+ - `pubKeyHex` (string): Public key in hexadecimal format
+
+ **Returns:** Tuple of (seiAddr, evmAddr)
+
+ ```typescript
+ const [seiAddr, evmAddr] = await addressContract.associatePubKey(
+ "0x04a1b2c3d4e5f6..." // Uncompressed public key
+ );
+ ```
+
+
+
+## Usage Examples
+
+
+
+ ```typescript
+ import { createPublicClient, createWalletClient, http } from 'viem';
+ import { privateKeyToAccount } from 'viem/accounts';
+ import {
+ seiTestnet,
+ ADDRESS_PRECOMPILE_ABI,
+ ADDRESS_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles/viem';
+
+ const publicClient = createPublicClient({
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ const account = privateKeyToAccount('0x...');
+ const walletClient = createWalletClient({
+ account,
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ // Get Sei address for EVM address
+ async function getSeiAddress(evmAddress: string) {
+ try {
+ const seiAddress = await publicClient.readContract({
+ address: ADDRESS_PRECOMPILE_ADDRESS,
+ abi: ADDRESS_PRECOMPILE_ABI,
+ functionName: 'getSeiAddr',
+ args: [evmAddress]
+ });
+
+ return seiAddress;
+ } catch (error) {
+ console.log('No association found for', evmAddress);
+ return null;
+ }
+ }
+
+ // Get EVM address for Sei address
+ async function getEvmAddress(seiAddress: string) {
+ try {
+ const evmAddress = await publicClient.readContract({
+ address: ADDRESS_PRECOMPILE_ADDRESS,
+ abi: ADDRESS_PRECOMPILE_ABI,
+ functionName: 'getEvmAddr',
+ args: [seiAddress]
+ });
+
+ return evmAddress;
+ } catch (error) {
+ console.log('No association found for', seiAddress);
+ return null;
+ }
+ }
+
+ // Associate addresses using public key
+ async function associateAddresses(publicKey: string) {
+ const hash = await walletClient.writeContract({
+ address: ADDRESS_PRECOMPILE_ADDRESS,
+ abi: ADDRESS_PRECOMPILE_ABI,
+ functionName: 'associatePubKey',
+ args: [publicKey]
+ });
+
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
+
+ // Parse the return values from logs or events
+ return receipt;
+ }
+
+ // Check if addresses are associated
+ async function checkAssociation(evmAddress: string, seiAddress: string) {
+ const [associatedSei, associatedEvm] = await Promise.all([
+ getSeiAddress(evmAddress),
+ getEvmAddress(seiAddress)
+ ]);
+
+ return {
+ isAssociated: associatedSei === seiAddress && associatedEvm === evmAddress,
+ evmToSei: associatedSei,
+ seiToEvm: associatedEvm
+ };
+ }
+
+ // Batch lookup multiple addresses
+ async function batchLookupAddresses(addresses: string[]) {
+ const lookupPromises = addresses.map(async (addr) => {
+ if (addr.startsWith('0x')) {
+ // EVM address
+ const seiAddr = await getSeiAddress(addr);
+ return { evmAddr: addr, seiAddr, type: 'evm' };
+ } else if (addr.startsWith('sei1')) {
+ // Sei address
+ const evmAddr = await getEvmAddress(addr);
+ return { seiAddr: addr, evmAddr, type: 'sei' };
+ }
+ return { error: 'Invalid address format', address: addr };
+ });
+
+ return await Promise.all(lookupPromises);
+ }
+ ```
+
+
+
+ ```typescript
+ import { ethers } from 'ethers';
+ import { getAddressPrecompileEthersContract } from '@sei-js/precompiles/ethers';
+
+ const provider = new ethers.JsonRpcProvider('https://evm-rpc-testnet.sei-apis.com');
+ const signer = new ethers.Wallet('0x...', provider);
+ const addressContract = getAddressPrecompileEthersContract(provider);
+
+ // Get Sei address for EVM address
+ async function getSeiAddress(evmAddress: string) {
+ try {
+ return await addressContract.getSeiAddr(evmAddress);
+ } catch (error) {
+ console.log('No association found for', evmAddress);
+ return null;
+ }
+ }
+
+ // Get EVM address for Sei address
+ async function getEvmAddress(seiAddress: string) {
+ try {
+ return await addressContract.getEvmAddr(seiAddress);
+ } catch (error) {
+ console.log('No association found for', seiAddress);
+ return null;
+ }
+ }
+
+ // Associate addresses using public key
+ async function associateAddresses(publicKey: string) {
+ const addressWithSigner = addressContract.connect(signer);
+
+ const tx = await addressWithSigner.associatePubKey(publicKey);
+ const receipt = await tx.wait();
+
+ // Extract return values from transaction logs
+ return receipt;
+ }
+
+ // Create address mapping utility
+ class AddressMapper {
+ private contract: ethers.Contract;
+
+ constructor(provider: ethers.Provider) {
+ this.contract = getAddressPrecompileEthersContract(provider);
+ }
+
+ async mapEvmToSei(evmAddress: string): Promise {
+ try {
+ return await this.contract.getSeiAddr(evmAddress);
+ } catch {
+ return null;
+ }
+ }
+
+ async mapSeiToEvm(seiAddress: string): Promise {
+ try {
+ return await this.contract.getEvmAddr(seiAddress);
+ } catch {
+ return null;
+ }
+ }
+
+ async isAssociated(evmAddress: string, seiAddress: string): Promise {
+ const [mappedSei, mappedEvm] = await Promise.all([
+ this.mapEvmToSei(evmAddress),
+ this.mapSeiToEvm(seiAddress)
+ ]);
+
+ return mappedSei === seiAddress && mappedEvm === evmAddress;
+ }
+ }
+
+ // Usage
+ const mapper = new AddressMapper(provider);
+ const isLinked = await mapper.isAssociated(
+ '0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A',
+ 'sei1wsltdx4m9k8dafl92nkwmywd6k7jdlpz5h3j3q'
+ );
+ ```
+
+
+
+ ```typescript
+ import {
+ ADDRESS_PRECOMPILE_ABI,
+ ADDRESS_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles';
+
+ // Using with web3.js
+ import Web3 from 'web3';
+
+ const web3 = new Web3('https://evm-rpc-testnet.sei-apis.com');
+ const addressContract = new web3.eth.Contract(
+ ADDRESS_PRECOMPILE_ABI,
+ ADDRESS_PRECOMPILE_ADDRESS
+ );
+
+ // Get Sei address for EVM address
+ const seiAddress = await addressContract.methods
+ .getSeiAddr('0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A')
+ .call();
+
+ // Get EVM address for Sei address
+ const evmAddress = await addressContract.methods
+ .getEvmAddr('sei1wsltdx4m9k8dafl92nkwmywd6k7jdlpz5h3j3q')
+ .call();
+
+ // Associate addresses using public key
+ const account = web3.eth.accounts.privateKeyToAccount('0x...');
+ web3.eth.accounts.wallet.add(account);
+
+ const tx = await addressContract.methods
+ .associatePubKey('0x04a1b2c3d4e5f6...')
+ .send({
+ from: account.address,
+ gas: 100000
+ });
+ ```
+
+
+
+## Common Use Cases
+
+### Cross-Chain Applications
+- **Unified Identity**: Link user identities across EVM and Cosmos ecosystems
+- **Asset Bridging**: Map assets between different address formats
+- **Multi-Chain Wallets**: Support both EVM and Cosmos transactions
+
+### DeFi Integration
+- **Liquidity Provision**: Use associated addresses for cross-chain liquidity
+- **Yield Farming**: Participate in farming across both ecosystems
+- **Governance**: Vote with associated addresses in different governance systems
+
+### Wallet Applications
+- **Address Book**: Display both address formats for contacts
+- **Transaction History**: Track transactions across both address types
+- **Portfolio Management**: Aggregate holdings across associated addresses
+
+## Address Association Process
+
+### Using Public Key (Recommended)
+```typescript
+// 1. Get user's public key from wallet
+const publicKey = await getPublicKeyFromWallet();
+
+// 2. Associate addresses
+const [seiAddr, evmAddr] = await addressContract.associatePubKey(publicKey);
+
+// 3. Verify association
+const isAssociated = await checkAssociation(evmAddr, seiAddr);
+```
+
+### Using Signature Verification
+```typescript
+// 1. Create custom message
+const message = "Associate my Sei and EVM addresses";
+
+// 2. Sign message with private key
+const signature = await signMessage(message, privateKey);
+
+// 3. Extract signature components
+const { v, r, s } = parseSignature(signature);
+
+// 4. Associate addresses
+const [seiAddr, evmAddr] = await addressContract.associate(v, r, s, message);
+```
+
+## Address Format Validation
+
+```typescript
+// Validate EVM address format
+function isValidEvmAddress(address: string): boolean {
+ return /^0x[a-fA-F0-9]{40}$/.test(address);
+}
+
+// Validate Sei address format
+function isValidSeiAddress(address: string): boolean {
+ return /^sei1[a-z0-9]{38}$/.test(address);
+}
+
+// Address format converter utility
+class AddressUtils {
+ static isEvm(address: string): boolean {
+ return address.startsWith('0x') && address.length === 42;
+ }
+
+ static isSei(address: string): boolean {
+ return address.startsWith('sei1') && address.length === 43;
+ }
+
+ static getAddressType(address: string): 'evm' | 'sei' | 'unknown' {
+ if (this.isEvm(address)) return 'evm';
+ if (this.isSei(address)) return 'sei';
+ return 'unknown';
+ }
+}
+```
+
+## Error Handling
+
+Common errors when using the Address precompile:
+
+- **No association found**: Addresses haven't been linked yet
+- **Invalid address format**: Malformed EVM or Sei addresses
+- **Association already exists**: Trying to associate already linked addresses
+- **Invalid signature**: Signature verification failed during association
+
+```typescript
+async function safeGetAssociation(address: string) {
+ try {
+ const addressType = AddressUtils.getAddressType(address);
+
+ if (addressType === 'evm') {
+ return await addressContract.getSeiAddr(address);
+ } else if (addressType === 'sei') {
+ return await addressContract.getEvmAddr(address);
+ } else {
+ throw new Error('Invalid address format');
+ }
+ } catch (error) {
+ if (error.message.includes('no association')) {
+ return null; // No association exists
+ } else if (error.message.includes('invalid address')) {
+ throw new Error('Invalid address format');
+ } else {
+ throw error; // Re-throw unexpected errors
+ }
+ }
+}
+```
+
+## Security Considerations
+
+- **Public Key Security**: Ensure public keys are handled securely
+- **Signature Verification**: Validate signatures before association
+- **Address Ownership**: Verify ownership before creating associations
+- **Association Permanence**: Address associations are typically permanent
+
+```typescript
+// Verify address ownership before association
+async function verifyAddressOwnership(address: string, signature: string) {
+ const message = "I own this address";
+ const recoveredAddress = recoverAddressFromSignature(message, signature);
+ return recoveredAddress.toLowerCase() === address.toLowerCase();
+}
+```
+
+## Related Precompiles
+
+- **[Bank](/precompiles/precompiles/bank)**: Transfer tokens between associated addresses
+- **[IBC](/precompiles/precompiles/ibc)**: Cross-chain transfers using address mapping
+- **[Staking](/precompiles/precompiles/staking)**: Delegate from associated addresses
diff --git a/docs/precompiles/precompiles/bank.mdx b/docs/precompiles/precompiles/bank.mdx
new file mode 100644
index 000000000..1bac2ec8e
--- /dev/null
+++ b/docs/precompiles/precompiles/bank.mdx
@@ -0,0 +1,347 @@
+---
+title: 'Bank Precompile'
+description: 'Interact with Sei native tokens and balances through the Bank precompile contract'
+icon: "building-columns"
+---
+
+## Overview
+
+The Bank precompile provides access to Sei's native token operations, allowing you to query balances, transfer tokens, and retrieve token metadata directly from EVM contracts. This precompile bridges EVM and Cosmos SDK bank module functionality.
+
+**Contract Address:** `0x0000000000000000000000000000000000001001`
+
+## Key Features
+
+- **Balance Queries**: Check token balances for any address and denomination
+- **Token Transfers**: Send native tokens between addresses
+- **Token Metadata**: Get token name, symbol, decimals, and total supply
+- **Multi-Denomination Support**: Work with any native token denomination
+
+## Available Functions
+
+### View Functions
+
+
+
+ Get the balance of a specific token denomination for an address.
+
+ **Parameters:**
+ - `acc` (address): The account address to query
+ - `denom` (string): The token denomination (e.g., "usei")
+
+ **Returns:** Token balance as uint256
+
+ ```typescript
+ const balance = await bankContract.balance(
+ "0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A",
+ "usei"
+ );
+ ```
+
+
+
+ Get all token balances for an address across all denominations.
+
+ **Parameters:**
+ - `acc` (address): The account address to query
+
+ **Returns:** Array of Coin structs with amount and denomination
+
+ ```typescript
+ const balances = await bankContract.all_balances(
+ "0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A"
+ );
+ // Returns: [{ amount: 1000000n, denom: "usei" }, ...]
+ ```
+
+
+
+ Get the display name for a token denomination.
+
+ **Parameters:**
+ - `denom` (string): The token denomination
+
+ **Returns:** Human-readable token name
+
+ ```typescript
+ const name = await bankContract.name("usei");
+ // Returns: "Sei"
+ ```
+
+
+
+ Get the symbol for a token denomination.
+
+ **Parameters:**
+ - `denom` (string): The token denomination
+
+ **Returns:** Token symbol
+
+ ```typescript
+ const symbol = await bankContract.symbol("usei");
+ // Returns: "SEI"
+ ```
+
+
+
+ Get the number of decimals for a token denomination.
+
+ **Parameters:**
+ - `denom` (string): The token denomination
+
+ **Returns:** Number of decimal places
+
+ ```typescript
+ const decimals = await bankContract.decimals("usei");
+ // Returns: 6
+ ```
+
+
+
+ Get the total supply of a token denomination.
+
+ **Parameters:**
+ - `denom` (string): The token denomination
+
+ **Returns:** Total token supply
+
+ ```typescript
+ const supply = await bankContract.supply("usei");
+ ```
+
+
+
+### State-Changing Functions
+
+
+
+ Transfer tokens between addresses.
+
+ **Parameters:**
+ - `fromAddress` (address): Source address
+ - `toAddress` (address): Destination address
+ - `denom` (string): Token denomination
+ - `amount` (uint256): Amount to transfer
+
+ **Returns:** Success boolean
+
+ ```typescript
+ const success = await bankContract.send(
+ "0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A",
+ "0x8ba1f109551bD432803012645Hac136c",
+ "usei",
+ 1000000n
+ );
+ ```
+
+
+
+ Send native SEI tokens to a Cosmos address.
+
+ **Parameters:**
+ - `toNativeAddress` (string): Destination Cosmos address
+
+ **Returns:** Success boolean
+
+ **Note:** This function is payable - send SEI with the transaction
+
+ ```typescript
+ const success = await bankContract.sendNative(
+ "sei1...",
+ { value: parseEther("1.0") }
+ );
+ ```
+
+
+
+## Usage Examples
+
+
+
+ ```typescript
+ import { createPublicClient, http, formatEther } from 'viem';
+ import {
+ seiTestnet,
+ BANK_PRECOMPILE_ABI,
+ BANK_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles/viem';
+
+ const client = createPublicClient({
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ // Get SEI balance
+ async function getSeiBalance(address: string) {
+ const balance = await client.readContract({
+ address: BANK_PRECOMPILE_ADDRESS,
+ abi: BANK_PRECOMPILE_ABI,
+ functionName: 'balance',
+ args: [address, 'usei']
+ });
+
+ return formatEther(balance);
+ }
+
+ // Get all balances
+ async function getAllBalances(address: string) {
+ const balances = await client.readContract({
+ address: BANK_PRECOMPILE_ADDRESS,
+ abi: BANK_PRECOMPILE_ABI,
+ functionName: 'all_balances',
+ args: [address]
+ });
+
+ return balances.map(coin => ({
+ denom: coin.denom,
+ amount: formatEther(coin.amount)
+ }));
+ }
+
+ // Get token metadata
+ async function getTokenInfo(denom: string) {
+ const [name, symbol, decimals] = await Promise.all([
+ client.readContract({
+ address: BANK_PRECOMPILE_ADDRESS,
+ abi: BANK_PRECOMPILE_ABI,
+ functionName: 'name',
+ args: [denom]
+ }),
+ client.readContract({
+ address: BANK_PRECOMPILE_ADDRESS,
+ abi: BANK_PRECOMPILE_ABI,
+ functionName: 'symbol',
+ args: [denom]
+ }),
+ client.readContract({
+ address: BANK_PRECOMPILE_ADDRESS,
+ abi: BANK_PRECOMPILE_ABI,
+ functionName: 'decimals',
+ args: [denom]
+ })
+ ]);
+
+ return { name, symbol, decimals };
+ }
+ ```
+
+
+
+ ```typescript
+ import { ethers } from 'ethers';
+ import { getBankPrecompileEthersContract } from '@sei-js/precompiles/ethers';
+
+ const provider = new ethers.JsonRpcProvider('https://evm-rpc-testnet.sei-apis.com');
+ const bankContract = getBankPrecompileEthersContract(provider);
+
+ // Get SEI balance
+ async function getSeiBalance(address: string) {
+ const balance = await bankContract.balance(address, 'usei');
+ return ethers.formatEther(balance);
+ }
+
+ // Get all balances
+ async function getAllBalances(address: string) {
+ const balances = await bankContract.all_balances(address);
+ return balances.map(coin => ({
+ denom: coin.denom,
+ amount: ethers.formatEther(coin.amount)
+ }));
+ }
+
+ // Transfer tokens
+ async function transferTokens(
+ signer: ethers.Signer,
+ to: string,
+ amount: string
+ ) {
+ const bankWithSigner = bankContract.connect(signer);
+ const fromAddress = await signer.getAddress();
+
+ const tx = await bankWithSigner.send(
+ fromAddress,
+ to,
+ 'usei',
+ ethers.parseEther(amount)
+ );
+
+ return await tx.wait();
+ }
+ ```
+
+
+
+ ```typescript
+ import {
+ BANK_PRECOMPILE_ABI,
+ BANK_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles';
+
+ // Using with web3.js
+ import Web3 from 'web3';
+
+ const web3 = new Web3('https://evm-rpc-testnet.sei-apis.com');
+ const bankContract = new web3.eth.Contract(
+ BANK_PRECOMPILE_ABI,
+ BANK_PRECOMPILE_ADDRESS
+ );
+
+ // Get balance
+ const balance = await bankContract.methods
+ .balance('0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A', 'usei')
+ .call();
+
+ // Get all balances
+ const allBalances = await bankContract.methods
+ .all_balances('0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A')
+ .call();
+ ```
+
+
+
+## Common Use Cases
+
+### DeFi Integration
+- Query user token balances before swaps
+- Check available liquidity across denominations
+- Validate token transfers in smart contracts
+
+### Wallet Applications
+- Display user portfolio across all native tokens
+- Enable native token transfers
+- Show token metadata and formatting
+
+### Cross-Chain Applications
+- Bridge native tokens to other chains
+- Query token supplies for economic analysis
+- Handle multi-denomination transactions
+
+## Error Handling
+
+Common errors when using the Bank precompile:
+
+- **Invalid address format**: Ensure addresses are valid EVM addresses
+- **Unknown denomination**: Verify the token denomination exists
+- **Insufficient balance**: Check balance before attempting transfers
+- **Invalid amount**: Ensure transfer amounts are positive and within limits
+
+```typescript
+try {
+ const balance = await bankContract.balance(address, 'usei');
+ console.log('Balance:', formatEther(balance));
+} catch (error) {
+ if (error.message.includes('invalid address')) {
+ console.error('Invalid address format');
+ } else if (error.message.includes('unknown denomination')) {
+ console.error('Token denomination not found');
+ } else {
+ console.error('Unexpected error:', error);
+ }
+}
+```
+
+## Related Precompiles
+
+- **[Distribution](/precompiles/precompiles/distribution)**: Claim staking rewards
+- **[Staking](/precompiles/precompiles/staking)**: Delegate tokens to validators
+- **[IBC](/precompiles/precompiles/ibc)**: Transfer tokens cross-chain
diff --git a/docs/precompiles/precompiles/distribution.mdx b/docs/precompiles/precompiles/distribution.mdx
new file mode 100644
index 000000000..a52b5156a
--- /dev/null
+++ b/docs/precompiles/precompiles/distribution.mdx
@@ -0,0 +1,625 @@
+---
+title: 'Distribution Precompile'
+description: 'Claim staking rewards and manage reward distribution through the Distribution precompile contract'
+icon: "gift"
+---
+
+## Overview
+
+The Distribution precompile provides access to Sei's staking reward distribution system, allowing you to claim delegation rewards, set withdrawal addresses, and query pending rewards directly from EVM contracts. This bridges EVM functionality with Cosmos SDK distribution module.
+
+**Contract Address:** `0x0000000000000000000000000000000000001007`
+
+## Key Features
+
+- **Reward Claiming**: Withdraw staking rewards from validator delegations
+- **Batch Operations**: Claim rewards from multiple validators in a single transaction
+- **Reward Queries**: Check pending rewards before claiming
+- **Withdrawal Management**: Set custom withdrawal addresses for rewards
+
+## Available Functions
+
+### State-Changing Functions
+
+
+
+ Withdraw staking rewards from a specific validator.
+
+ **Parameters:**
+ - `validator` (string): The validator's operator address
+
+ **Returns:** Success boolean
+
+ ```typescript
+ const success = await distributionContract.withdrawDelegationRewards(
+ "seivaloper1..."
+ );
+ ```
+
+
+
+ Withdraw staking rewards from multiple validators in a single transaction.
+
+ **Parameters:**
+ - `validators` (string[]): Array of validator operator addresses
+
+ **Returns:** Success boolean
+
+ ```typescript
+ const validators = [
+ "seivaloper1...",
+ "seivaloper2...",
+ "seivaloper3..."
+ ];
+
+ const success = await distributionContract.withdrawMultipleDelegationRewards(
+ validators
+ );
+ ```
+
+
+
+ Set a custom address to receive withdrawn rewards.
+
+ **Parameters:**
+ - `withdrawAddr` (address): The EVM address to receive rewards
+
+ **Returns:** Success boolean
+
+ ```typescript
+ const success = await distributionContract.setWithdrawAddress(
+ "0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A"
+ );
+ ```
+
+
+
+### View Functions
+
+
+
+ Query pending staking rewards for a delegator.
+
+ **Parameters:**
+ - `delegatorAddress` (address): The delegator's EVM address
+
+ **Returns:** Rewards struct with detailed breakdown
+
+ **Return Structure:**
+ ```typescript
+ interface Rewards {
+ rewards: Array<{
+ coins: Array<{
+ amount: bigint;
+ decimals: bigint;
+ denom: string;
+ }>;
+ validator_address: string;
+ }>;
+ total: Array<{
+ amount: bigint;
+ decimals: bigint;
+ denom: string;
+ }>;
+ }
+ ```
+
+ ```typescript
+ const rewards = await distributionContract.rewards(
+ "0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A"
+ );
+
+ // Access total rewards
+ console.log('Total SEI rewards:', formatEther(rewards.total[0].amount));
+
+ // Access per-validator rewards
+ rewards.rewards.forEach(reward => {
+ console.log(`Validator ${reward.validator_address}:`);
+ reward.coins.forEach(coin => {
+ console.log(` ${coin.denom}: ${formatEther(coin.amount)}`);
+ });
+ });
+ ```
+
+
+
+## Usage Examples
+
+
+
+ ```typescript
+ import { createPublicClient, createWalletClient, http, formatEther } from 'viem';
+ import { privateKeyToAccount } from 'viem/accounts';
+ import {
+ seiTestnet,
+ DISTRIBUTION_PRECOMPILE_ABI,
+ DISTRIBUTION_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles/viem';
+
+ const publicClient = createPublicClient({
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ const account = privateKeyToAccount('0x...');
+ const walletClient = createWalletClient({
+ account,
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ // Query pending rewards
+ async function getPendingRewards(delegatorAddress: string) {
+ const rewards = await publicClient.readContract({
+ address: DISTRIBUTION_PRECOMPILE_ADDRESS,
+ abi: DISTRIBUTION_PRECOMPILE_ABI,
+ functionName: 'rewards',
+ args: [delegatorAddress]
+ });
+
+ return {
+ totalRewards: rewards.total.map(coin => ({
+ denom: coin.denom,
+ amount: formatEther(coin.amount),
+ decimals: Number(coin.decimals)
+ })),
+ validatorRewards: rewards.rewards.map(reward => ({
+ validator: reward.validator_address,
+ coins: reward.coins.map(coin => ({
+ denom: coin.denom,
+ amount: formatEther(coin.amount),
+ decimals: Number(coin.decimals)
+ }))
+ }))
+ };
+ }
+
+ // Claim rewards from a single validator
+ async function claimRewardsFromValidator(validatorAddress: string) {
+ const hash = await walletClient.writeContract({
+ address: DISTRIBUTION_PRECOMPILE_ADDRESS,
+ abi: DISTRIBUTION_PRECOMPILE_ABI,
+ functionName: 'withdrawDelegationRewards',
+ args: [validatorAddress]
+ });
+
+ return await publicClient.waitForTransactionReceipt({ hash });
+ }
+
+ // Claim rewards from multiple validators
+ async function claimAllRewards(validatorAddresses: string[]) {
+ const hash = await walletClient.writeContract({
+ address: DISTRIBUTION_PRECOMPILE_ADDRESS,
+ abi: DISTRIBUTION_PRECOMPILE_ABI,
+ functionName: 'withdrawMultipleDelegationRewards',
+ args: [validatorAddresses]
+ });
+
+ return await publicClient.waitForTransactionReceipt({ hash });
+ }
+
+ // Set withdrawal address
+ async function setRewardWithdrawalAddress(withdrawAddress: string) {
+ const hash = await walletClient.writeContract({
+ address: DISTRIBUTION_PRECOMPILE_ADDRESS,
+ abi: DISTRIBUTION_PRECOMPILE_ABI,
+ functionName: 'setWithdrawAddress',
+ args: [withdrawAddress]
+ });
+
+ return await publicClient.waitForTransactionReceipt({ hash });
+ }
+
+ // Comprehensive reward management
+ async function manageRewards(delegatorAddress: string) {
+ // 1. Check pending rewards
+ const pendingRewards = await getPendingRewards(delegatorAddress);
+
+ console.log('Pending rewards:');
+ pendingRewards.totalRewards.forEach(reward => {
+ console.log(` ${reward.denom}: ${reward.amount}`);
+ });
+
+ // 2. Get validators with rewards
+ const validatorsWithRewards = pendingRewards.validatorRewards
+ .filter(reward => reward.coins.some(coin => parseFloat(coin.amount) > 0))
+ .map(reward => reward.validator);
+
+ if (validatorsWithRewards.length === 0) {
+ console.log('No rewards to claim');
+ return;
+ }
+
+ // 3. Claim all rewards efficiently
+ if (validatorsWithRewards.length === 1) {
+ console.log('Claiming rewards from single validator');
+ return await claimRewardsFromValidator(validatorsWithRewards[0]);
+ } else {
+ console.log(`Claiming rewards from ${validatorsWithRewards.length} validators`);
+ return await claimAllRewards(validatorsWithRewards);
+ }
+ }
+
+ // Auto-compound rewards (claim and re-delegate)
+ async function autoCompoundRewards(
+ delegatorAddress: string,
+ preferredValidator: string
+ ) {
+ // This would require integration with staking precompile
+ const rewards = await getPendingRewards(delegatorAddress);
+ const totalSeiRewards = rewards.totalRewards.find(r => r.denom === 'usei');
+
+ if (totalSeiRewards && parseFloat(totalSeiRewards.amount) > 0) {
+ console.log(`Auto-compounding ${totalSeiRewards.amount} SEI`);
+
+ // 1. Claim rewards
+ const validatorsWithRewards = rewards.validatorRewards
+ .filter(r => r.coins.some(c => c.denom === 'usei' && parseFloat(c.amount) > 0))
+ .map(r => r.validator);
+
+ await claimAllRewards(validatorsWithRewards);
+
+ // 2. Re-delegate (would need staking precompile integration)
+ console.log(`Would re-delegate to ${preferredValidator}`);
+ }
+ }
+ ```
+
+
+
+ ```typescript
+ import { ethers } from 'ethers';
+ import { getDistributionPrecompileEthersContract } from '@sei-js/precompiles/ethers';
+
+ const provider = new ethers.JsonRpcProvider('https://evm-rpc-testnet.sei-apis.com');
+ const signer = new ethers.Wallet('0x...', provider);
+ const distributionContract = getDistributionPrecompileEthersContract(provider);
+
+ // Query pending rewards
+ async function getPendingRewards(delegatorAddress: string) {
+ const rewards = await distributionContract.rewards(delegatorAddress);
+
+ return {
+ totalRewards: rewards.total.map(coin => ({
+ denom: coin.denom,
+ amount: ethers.formatEther(coin.amount),
+ decimals: Number(coin.decimals)
+ })),
+ validatorRewards: rewards.rewards.map(reward => ({
+ validator: reward.validator_address,
+ coins: reward.coins.map(coin => ({
+ denom: coin.denom,
+ amount: ethers.formatEther(coin.amount),
+ decimals: Number(coin.decimals)
+ }))
+ }))
+ };
+ }
+
+ // Claim rewards from single validator
+ async function claimRewardsFromValidator(validatorAddress: string) {
+ const distributionWithSigner = distributionContract.connect(signer);
+
+ const tx = await distributionWithSigner.withdrawDelegationRewards(validatorAddress);
+ return await tx.wait();
+ }
+
+ // Claim rewards from multiple validators
+ async function claimAllRewards(validatorAddresses: string[]) {
+ const distributionWithSigner = distributionContract.connect(signer);
+
+ const tx = await distributionWithSigner.withdrawMultipleDelegationRewards(validatorAddresses);
+ return await tx.wait();
+ }
+
+ // Reward management class
+ class RewardManager {
+ private contract: ethers.Contract;
+ private signer: ethers.Signer;
+
+ constructor(provider: ethers.Provider, signer: ethers.Signer) {
+ this.contract = getDistributionPrecompileEthersContract(provider);
+ this.signer = signer;
+ }
+
+ async getPendingRewards(delegatorAddress: string) {
+ const rewards = await this.contract.rewards(delegatorAddress);
+
+ return {
+ totalRewards: rewards.total.map(coin => ({
+ denom: coin.denom,
+ amount: ethers.formatEther(coin.amount),
+ decimals: Number(coin.decimals)
+ })),
+ validatorRewards: rewards.rewards.map(reward => ({
+ validator: reward.validator_address,
+ coins: reward.coins.map(coin => ({
+ denom: coin.denom,
+ amount: ethers.formatEther(coin.amount),
+ decimals: Number(coin.decimals)
+ }))
+ }))
+ };
+ }
+
+ async claimAllAvailableRewards(delegatorAddress: string) {
+ const rewards = await this.getPendingRewards(delegatorAddress);
+
+ const validatorsWithRewards = rewards.validatorRewards
+ .filter(reward => reward.coins.some(coin => parseFloat(coin.amount) > 0))
+ .map(reward => reward.validator);
+
+ if (validatorsWithRewards.length === 0) {
+ throw new Error('No rewards available to claim');
+ }
+
+ const contractWithSigner = this.contract.connect(this.signer);
+
+ if (validatorsWithRewards.length === 1) {
+ const tx = await contractWithSigner.withdrawDelegationRewards(validatorsWithRewards[0]);
+ return await tx.wait();
+ } else {
+ const tx = await contractWithSigner.withdrawMultipleDelegationRewards(validatorsWithRewards);
+ return await tx.wait();
+ }
+ }
+
+ async setWithdrawAddress(withdrawAddress: string) {
+ const contractWithSigner = this.contract.connect(this.signer);
+ const tx = await contractWithSigner.setWithdrawAddress(withdrawAddress);
+ return await tx.wait();
+ }
+ }
+
+ // Usage
+ const rewardManager = new RewardManager(provider, signer);
+
+ // Check and claim all rewards
+ const delegatorAddress = await signer.getAddress();
+ await rewardManager.claimAllAvailableRewards(delegatorAddress);
+ ```
+
+
+
+ ```typescript
+ import {
+ DISTRIBUTION_PRECOMPILE_ABI,
+ DISTRIBUTION_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles';
+
+ // Using with web3.js
+ import Web3 from 'web3';
+
+ const web3 = new Web3('https://evm-rpc-testnet.sei-apis.com');
+ const distributionContract = new web3.eth.Contract(
+ DISTRIBUTION_PRECOMPILE_ABI,
+ DISTRIBUTION_PRECOMPILE_ADDRESS
+ );
+
+ // Query pending rewards
+ const rewards = await distributionContract.methods
+ .rewards('0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A')
+ .call();
+
+ // Setup account for transactions
+ const account = web3.eth.accounts.privateKeyToAccount('0x...');
+ web3.eth.accounts.wallet.add(account);
+
+ // Claim rewards from single validator
+ const claimTx = await distributionContract.methods
+ .withdrawDelegationRewards('seivaloper1...')
+ .send({
+ from: account.address,
+ gas: 200000
+ });
+
+ // Claim rewards from multiple validators
+ const validators = ['seivaloper1...', 'seivaloper2...'];
+ const claimAllTx = await distributionContract.methods
+ .withdrawMultipleDelegationRewards(validators)
+ .send({
+ from: account.address,
+ gas: 300000
+ });
+ ```
+
+
+
+## Common Use Cases
+
+### Automated Reward Claiming
+- **DeFi Protocols**: Automatically claim and reinvest staking rewards
+- **Yield Optimization**: Compound rewards to maximize returns
+- **Portfolio Management**: Regular reward harvesting across multiple validators
+
+### Liquid Staking Protocols
+- **Reward Distribution**: Distribute claimed rewards to token holders
+- **Fee Collection**: Set withdrawal addresses to protocol treasury
+- **Automated Compounding**: Reinvest rewards to increase staking positions
+
+### Staking-as-a-Service
+- **Client Management**: Claim rewards on behalf of clients
+- **Fee Deduction**: Set withdrawal addresses for fee collection
+- **Performance Tracking**: Monitor reward generation across validators
+
+## Reward Optimization Strategies
+
+### Timing Optimization
+```typescript
+// Check if rewards are worth claiming (considering gas costs)
+async function shouldClaimRewards(
+ delegatorAddress: string,
+ minRewardThreshold: string = "1" // 1 SEI minimum
+) {
+ const rewards = await getPendingRewards(delegatorAddress);
+ const totalSeiRewards = rewards.totalRewards.find(r => r.denom === 'usei');
+
+ if (!totalSeiRewards) return false;
+
+ const rewardAmount = parseFloat(totalSeiRewards.amount);
+ const threshold = parseFloat(minRewardThreshold);
+
+ return rewardAmount >= threshold;
+}
+```
+
+### Validator Selection for Claiming
+```typescript
+// Prioritize validators with highest rewards
+async function getOptimalClaimingOrder(delegatorAddress: string) {
+ const rewards = await getPendingRewards(delegatorAddress);
+
+ return rewards.validatorRewards
+ .filter(reward => reward.coins.some(coin => parseFloat(coin.amount) > 0))
+ .sort((a, b) => {
+ const aSeiReward = a.coins.find(c => c.denom === 'usei');
+ const bSeiReward = b.coins.find(c => c.denom === 'usei');
+
+ const aAmount = aSeiReward ? parseFloat(aSeiReward.amount) : 0;
+ const bAmount = bSeiReward ? parseFloat(bSeiReward.amount) : 0;
+
+ return bAmount - aAmount; // Descending order
+ })
+ .map(reward => reward.validator);
+}
+```
+
+### Batch Claiming Strategy
+```typescript
+// Determine optimal batching strategy
+async function getOptimalClaimingStrategy(
+ delegatorAddress: string,
+ maxValidatorsPerTx: number = 10
+) {
+ const validatorsWithRewards = await getOptimalClaimingOrder(delegatorAddress);
+
+ if (validatorsWithRewards.length <= maxValidatorsPerTx) {
+ return {
+ strategy: 'single_batch',
+ batches: [validatorsWithRewards]
+ };
+ } else {
+ const batches = [];
+ for (let i = 0; i < validatorsWithRewards.length; i += maxValidatorsPerTx) {
+ batches.push(validatorsWithRewards.slice(i, i + maxValidatorsPerTx));
+ }
+
+ return {
+ strategy: 'multiple_batches',
+ batches
+ };
+ }
+}
+```
+
+## Reward Tracking and Analytics
+
+```typescript
+// Reward tracking utility
+class RewardTracker {
+ private claimedRewards: Array<{
+ timestamp: number;
+ validators: string[];
+ amount: string;
+ txHash: string;
+ }> = [];
+
+ recordClaim(validators: string[], amount: string, txHash: string) {
+ this.claimedRewards.push({
+ timestamp: Date.now(),
+ validators,
+ amount,
+ txHash
+ });
+ }
+
+ getTotalClaimed(): string {
+ return this.claimedRewards
+ .reduce((total, claim) => total + parseFloat(claim.amount), 0)
+ .toString();
+ }
+
+ getClaimFrequency(): number {
+ if (this.claimedRewards.length < 2) return 0;
+
+ const timeSpan = this.claimedRewards[this.claimedRewards.length - 1].timestamp -
+ this.claimedRewards[0].timestamp;
+
+ return timeSpan / (this.claimedRewards.length - 1); // Average time between claims
+ }
+
+ getMostRewardingValidators(): string[] {
+ const validatorRewards = new Map();
+
+ this.claimedRewards.forEach(claim => {
+ const rewardPerValidator = parseFloat(claim.amount) / claim.validators.length;
+ claim.validators.forEach(validator => {
+ validatorRewards.set(
+ validator,
+ (validatorRewards.get(validator) || 0) + rewardPerValidator
+ );
+ });
+ });
+
+ return Array.from(validatorRewards.entries())
+ .sort((a, b) => b[1] - a[1])
+ .map(entry => entry[0]);
+ }
+}
+```
+
+## Error Handling
+
+Common errors when using the Distribution precompile:
+
+- **No rewards available**: No pending rewards to claim
+- **Invalid validator**: Validator address doesn't exist
+- **Withdrawal address error**: Invalid withdrawal address format
+- **Insufficient gas**: Complex multi-validator claims need more gas
+
+```typescript
+async function safeClaimRewards(validatorAddresses: string[]) {
+ try {
+ // Validate inputs
+ if (validatorAddresses.length === 0) {
+ throw new Error('No validators specified');
+ }
+
+ // Check for pending rewards first
+ const delegatorAddress = await signer.getAddress();
+ const rewards = await getPendingRewards(delegatorAddress);
+
+ const hasRewards = rewards.validatorRewards.some(reward =>
+ validatorAddresses.includes(reward.validator) &&
+ reward.coins.some(coin => parseFloat(coin.amount) > 0)
+ );
+
+ if (!hasRewards) {
+ throw new Error('No rewards available for specified validators');
+ }
+
+ // Claim rewards
+ if (validatorAddresses.length === 1) {
+ return await claimRewardsFromValidator(validatorAddresses[0]);
+ } else {
+ return await claimAllRewards(validatorAddresses);
+ }
+ } catch (error) {
+ if (error.message.includes('no rewards')) {
+ throw new Error('No rewards available to claim');
+ } else if (error.message.includes('validator not found')) {
+ throw new Error('One or more validators not found');
+ } else if (error.message.includes('out of gas')) {
+ throw new Error('Insufficient gas - try claiming fewer validators at once');
+ } else {
+ throw error;
+ }
+ }
+}
+```
+
+## Related Precompiles
+
+- **[Staking](/precompiles/precompiles/staking)**: Delegate tokens to earn rewards
+- **[Bank](/precompiles/precompiles/bank)**: Check reward balances after claiming
+- **[Governance](/precompiles/precompiles/governance)**: Participate in governance with staked tokens
diff --git a/docs/precompiles/precompiles/governance.mdx b/docs/precompiles/precompiles/governance.mdx
new file mode 100644
index 000000000..196a925ab
--- /dev/null
+++ b/docs/precompiles/precompiles/governance.mdx
@@ -0,0 +1,470 @@
+---
+title: 'Governance Precompile'
+description: 'Participate in Sei network governance through voting and deposits via the Governance precompile contract'
+icon: "check-to-slot"
+---
+
+## Overview
+
+The Governance precompile enables participation in Sei's on-chain governance system directly from EVM contracts. Users can vote on proposals and make deposits to support governance proposals, bridging EVM functionality with Cosmos SDK governance.
+
+**Contract Address:** `0x0000000000000000000000000000000000001006`
+
+## Key Features
+
+- **Proposal Voting**: Cast votes on governance proposals with different options
+- **Proposal Deposits**: Deposit tokens to support governance proposals
+- **Democratic Participation**: Enable EVM contracts to participate in network governance
+- **Transparent Governance**: All governance actions are recorded on-chain
+
+## Available Functions
+
+### State-Changing Functions
+
+
+
+ Cast a vote on a governance proposal.
+
+ **Parameters:**
+ - `proposalID` (uint64): The ID of the proposal to vote on
+ - `option` (int32): The vote option (1=Yes, 2=Abstain, 3=No, 4=NoWithVeto)
+
+ **Returns:** Success boolean
+
+ **Vote Options:**
+ - `1` - **Yes**: Support the proposal
+ - `2` - **Abstain**: Neutral vote (counts toward quorum)
+ - `3` - **No**: Oppose the proposal
+ - `4` - **NoWithVeto**: Strong opposition (can cause proposal failure)
+
+ ```typescript
+ // Vote "Yes" on proposal #42
+ const success = await governanceContract.vote(42n, 1);
+
+ // Vote "No" on proposal #43
+ const success = await governanceContract.vote(43n, 3);
+ ```
+
+
+
+ Make a deposit to support a governance proposal.
+
+ **Parameters:**
+ - `proposalID` (uint64): The ID of the proposal to deposit to
+
+ **Returns:** Success boolean
+
+ **Note:** This function is payable - send SEI with the transaction as deposit
+
+ ```typescript
+ // Deposit 100 SEI to proposal #42
+ const success = await governanceContract.deposit(42n, {
+ value: parseEther("100")
+ });
+ ```
+
+
+
+## Usage Examples
+
+
+
+ ```typescript
+ import { createPublicClient, createWalletClient, http, parseEther } from 'viem';
+ import { privateKeyToAccount } from 'viem/accounts';
+ import {
+ seiTestnet,
+ GOVERNANCE_PRECOMPILE_ABI,
+ GOVERNANCE_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles/viem';
+
+ const publicClient = createPublicClient({
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ const account = privateKeyToAccount('0x...');
+ const walletClient = createWalletClient({
+ account,
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ // Vote options enum for clarity
+ enum VoteOption {
+ YES = 1,
+ ABSTAIN = 2,
+ NO = 3,
+ NO_WITH_VETO = 4
+ }
+
+ // Cast a vote on a proposal
+ async function voteOnProposal(proposalId: bigint, option: VoteOption) {
+ const hash = await walletClient.writeContract({
+ address: GOVERNANCE_PRECOMPILE_ADDRESS,
+ abi: GOVERNANCE_PRECOMPILE_ABI,
+ functionName: 'vote',
+ args: [proposalId, option]
+ });
+
+ return await publicClient.waitForTransactionReceipt({ hash });
+ }
+
+ // Make a deposit to a proposal
+ async function depositToProposal(proposalId: bigint, amount: string) {
+ const hash = await walletClient.writeContract({
+ address: GOVERNANCE_PRECOMPILE_ADDRESS,
+ abi: GOVERNANCE_PRECOMPILE_ABI,
+ functionName: 'deposit',
+ args: [proposalId],
+ value: parseEther(amount)
+ });
+
+ return await publicClient.waitForTransactionReceipt({ hash });
+ }
+
+ // Governance participation helper
+ async function participateInGovernance(
+ proposalId: bigint,
+ vote: VoteOption,
+ depositAmount?: string
+ ) {
+ const actions = [];
+
+ // Make deposit if specified
+ if (depositAmount) {
+ console.log(`Depositing ${depositAmount} SEI to proposal ${proposalId}`);
+ const depositTx = await depositToProposal(proposalId, depositAmount);
+ actions.push({ type: 'deposit', tx: depositTx });
+ }
+
+ // Cast vote
+ console.log(`Voting ${VoteOption[vote]} on proposal ${proposalId}`);
+ const voteTx = await voteOnProposal(proposalId, vote);
+ actions.push({ type: 'vote', tx: voteTx });
+
+ return actions;
+ }
+
+ // Batch voting on multiple proposals
+ async function batchVote(votes: Array<{ proposalId: bigint; option: VoteOption }>) {
+ const votePromises = votes.map(({ proposalId, option }) =>
+ voteOnProposal(proposalId, option)
+ );
+
+ return await Promise.all(votePromises);
+ }
+
+ // Example usage
+ await participateInGovernance(42n, VoteOption.YES, "100");
+ await batchVote([
+ { proposalId: 43n, option: VoteOption.NO },
+ { proposalId: 44n, option: VoteOption.ABSTAIN }
+ ]);
+ ```
+
+
+
+ ```typescript
+ import { ethers } from 'ethers';
+ import { getGovernancePrecompileEthersContract } from '@sei-js/precompiles/ethers';
+
+ const provider = new ethers.JsonRpcProvider('https://evm-rpc-testnet.sei-apis.com');
+ const signer = new ethers.Wallet('0x...', provider);
+ const governanceContract = getGovernancePrecompileEthersContract(provider);
+
+ // Vote options enum
+ enum VoteOption {
+ YES = 1,
+ ABSTAIN = 2,
+ NO = 3,
+ NO_WITH_VETO = 4
+ }
+
+ // Cast a vote on a proposal
+ async function voteOnProposal(proposalId: number, option: VoteOption) {
+ const governanceWithSigner = governanceContract.connect(signer);
+
+ const tx = await governanceWithSigner.vote(proposalId, option);
+ return await tx.wait();
+ }
+
+ // Make a deposit to a proposal
+ async function depositToProposal(proposalId: number, amount: string) {
+ const governanceWithSigner = governanceContract.connect(signer);
+
+ const tx = await governanceWithSigner.deposit(proposalId, {
+ value: ethers.parseEther(amount)
+ });
+
+ return await tx.wait();
+ }
+
+ // Governance manager class
+ class GovernanceManager {
+ private contract: ethers.Contract;
+ private signer: ethers.Signer;
+
+ constructor(provider: ethers.Provider, signer: ethers.Signer) {
+ this.contract = getGovernancePrecompileEthersContract(provider);
+ this.signer = signer;
+ }
+
+ async vote(proposalId: number, option: VoteOption): Promise {
+ const contractWithSigner = this.contract.connect(this.signer);
+ const tx = await contractWithSigner.vote(proposalId, option);
+ return await tx.wait();
+ }
+
+ async deposit(proposalId: number, amount: string): Promise {
+ const contractWithSigner = this.contract.connect(this.signer);
+ const tx = await contractWithSigner.deposit(proposalId, {
+ value: ethers.parseEther(amount)
+ });
+ return await tx.wait();
+ }
+
+ async voteWithDeposit(
+ proposalId: number,
+ option: VoteOption,
+ depositAmount: string
+ ): Promise<{ depositTx: ethers.TransactionReceipt; voteTx: ethers.TransactionReceipt }> {
+ const depositTx = await this.deposit(proposalId, depositAmount);
+ const voteTx = await this.vote(proposalId, option);
+
+ return { depositTx, voteTx };
+ }
+ }
+
+ // Usage
+ const governance = new GovernanceManager(provider, signer);
+
+ // Vote on a proposal
+ await governance.vote(42, VoteOption.YES);
+
+ // Deposit and vote
+ await governance.voteWithDeposit(43, VoteOption.NO, "50");
+ ```
+
+
+
+ ```typescript
+ import {
+ GOVERNANCE_PRECOMPILE_ABI,
+ GOVERNANCE_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles';
+
+ // Using with web3.js
+ import Web3 from 'web3';
+
+ const web3 = new Web3('https://evm-rpc-testnet.sei-apis.com');
+ const governanceContract = new web3.eth.Contract(
+ GOVERNANCE_PRECOMPILE_ABI,
+ GOVERNANCE_PRECOMPILE_ADDRESS
+ );
+
+ // Setup account
+ const account = web3.eth.accounts.privateKeyToAccount('0x...');
+ web3.eth.accounts.wallet.add(account);
+
+ // Vote on proposal
+ const voteTx = await governanceContract.methods
+ .vote(42, 1) // Vote "Yes" on proposal 42
+ .send({
+ from: account.address,
+ gas: 100000
+ });
+
+ // Deposit to proposal
+ const depositTx = await governanceContract.methods
+ .deposit(42)
+ .send({
+ from: account.address,
+ value: web3.utils.toWei('100', 'ether'), // 100 SEI
+ gas: 100000
+ });
+ ```
+
+
+
+## Vote Options Explained
+
+### 1. Yes (Option 1)
+- **Purpose**: Support the proposal
+- **Effect**: Counts toward proposal approval
+- **When to use**: When you agree with the proposal
+
+### 2. Abstain (Option 2)
+- **Purpose**: Neutral stance but participate in quorum
+- **Effect**: Counts toward quorum but not for/against
+- **When to use**: When you want to participate but have no strong opinion
+
+### 3. No (Option 3)
+- **Purpose**: Oppose the proposal
+- **Effect**: Counts against proposal approval
+- **When to use**: When you disagree with the proposal
+
+### 4. NoWithVeto (Option 4)
+- **Purpose**: Strong opposition with penalty implications
+- **Effect**: Can cause proposal failure and deposit forfeiture
+- **When to use**: When you believe the proposal is harmful or spam
+
+```typescript
+// Helper function to get vote option description
+function getVoteDescription(option: number): string {
+ switch (option) {
+ case 1: return "Yes - Support the proposal";
+ case 2: return "Abstain - Neutral participation";
+ case 3: return "No - Oppose the proposal";
+ case 4: return "NoWithVeto - Strong opposition";
+ default: return "Invalid vote option";
+ }
+}
+```
+
+## Common Use Cases
+
+### DAO Integration
+- **Automated Voting**: Smart contracts can vote based on predetermined logic
+- **Delegation Systems**: Allow token holders to delegate voting power
+- **Proposal Support**: Automatically deposit to proposals meeting criteria
+
+### Community Governance
+- **Voting Campaigns**: Coordinate community voting efforts
+- **Proposal Funding**: Pool resources to support important proposals
+- **Governance Analytics**: Track voting patterns and participation
+
+### Protocol Governance
+- **Parameter Updates**: Vote on protocol parameter changes
+- **Upgrade Proposals**: Participate in network upgrade decisions
+- **Treasury Management**: Vote on treasury spending proposals
+
+## Governance Workflow
+
+### 1. Proposal Lifecycle
+```typescript
+// Typical governance proposal states:
+enum ProposalStatus {
+ DEPOSIT_PERIOD = "deposit_period", // Accepting deposits
+ VOTING_PERIOD = "voting_period", // Active voting
+ PASSED = "passed", // Proposal approved
+ REJECTED = "rejected", // Proposal failed
+ FAILED = "failed" // Proposal failed due to veto
+}
+```
+
+### 2. Participation Strategy
+```typescript
+async function smartGovernanceParticipation(
+ proposalId: bigint,
+ proposalType: string,
+ userPreferences: GovernancePreferences
+) {
+ // Analyze proposal type and user preferences
+ const decision = analyzeProposal(proposalType, userPreferences);
+
+ if (decision.shouldDeposit) {
+ await depositToProposal(proposalId, decision.depositAmount);
+ }
+
+ if (decision.shouldVote) {
+ await voteOnProposal(proposalId, decision.voteOption);
+ }
+
+ return decision;
+}
+```
+
+## Governance Best Practices
+
+### Research Before Voting
+- Read proposal details thoroughly
+- Understand the implications of changes
+- Consider long-term effects on the network
+
+### Deposit Considerations
+- Deposits help proposals reach voting stage
+- Failed proposals may result in deposit forfeiture
+- Consider the proposal's likelihood of success
+
+### Vote Timing
+- Vote early to signal community sentiment
+- Monitor voting progress and participation
+- Consider changing vote if new information emerges
+
+```typescript
+// Governance participation tracker
+class GovernanceTracker {
+ private votes: Map = new Map();
+ private deposits: Map = new Map();
+
+ recordVote(proposalId: bigint, option: VoteOption) {
+ this.votes.set(proposalId, option);
+ }
+
+ recordDeposit(proposalId: bigint, amount: string) {
+ this.deposits.set(proposalId, amount);
+ }
+
+ getParticipationSummary() {
+ return {
+ totalVotes: this.votes.size,
+ totalDeposits: this.deposits.size,
+ voteBreakdown: this.getVoteBreakdown(),
+ totalDepositAmount: this.getTotalDepositAmount()
+ };
+ }
+
+ private getVoteBreakdown() {
+ const breakdown = { yes: 0, no: 0, abstain: 0, noWithVeto: 0 };
+ for (const option of this.votes.values()) {
+ switch (option) {
+ case VoteOption.YES: breakdown.yes++; break;
+ case VoteOption.NO: breakdown.no++; break;
+ case VoteOption.ABSTAIN: breakdown.abstain++; break;
+ case VoteOption.NO_WITH_VETO: breakdown.noWithVeto++; break;
+ }
+ }
+ return breakdown;
+ }
+
+ private getTotalDepositAmount(): string {
+ return Array.from(this.deposits.values())
+ .reduce((total, amount) => total + parseFloat(amount), 0)
+ .toString();
+ }
+}
+```
+
+## Error Handling
+
+Common errors when using the Governance precompile:
+
+- **Invalid proposal ID**: Proposal doesn't exist
+- **Voting period ended**: Cannot vote after voting period closes
+- **Already voted**: Cannot change vote once cast
+- **Insufficient deposit**: Deposit amount too small
+
+```typescript
+async function safeVote(proposalId: bigint, option: VoteOption) {
+ try {
+ return await voteOnProposal(proposalId, option);
+ } catch (error) {
+ if (error.message.includes('proposal not found')) {
+ throw new Error(`Proposal ${proposalId} does not exist`);
+ } else if (error.message.includes('voting period ended')) {
+ throw new Error(`Voting period for proposal ${proposalId} has ended`);
+ } else if (error.message.includes('already voted')) {
+ throw new Error(`Already voted on proposal ${proposalId}`);
+ } else {
+ throw error;
+ }
+ }
+}
+```
+
+## Related Precompiles
+
+- **[Bank](/precompiles/precompiles/bank)**: Check SEI balance before making deposits
+- **[Staking](/precompiles/precompiles/staking)**: Voting power is based on staked tokens
+- **[Distribution](/precompiles/precompiles/distribution)**: Claim rewards from governance participation
diff --git a/docs/precompiles/precompiles/ibc.mdx b/docs/precompiles/precompiles/ibc.mdx
new file mode 100644
index 000000000..3b8b489f5
--- /dev/null
+++ b/docs/precompiles/precompiles/ibc.mdx
@@ -0,0 +1,708 @@
+---
+title: 'IBC Precompile'
+description: 'Transfer tokens across Cosmos chains using the Inter-Blockchain Communication (IBC) protocol through the IBC precompile contract'
+icon: "arrow-right-arrow-left"
+---
+
+## Overview
+
+The IBC precompile enables cross-chain token transfers using the Inter-Blockchain Communication (IBC) protocol directly from EVM contracts. This allows seamless integration between Sei and other Cosmos SDK chains, enabling multi-chain DeFi applications and cross-chain asset management.
+
+**Contract Address:** `0x0000000000000000000000000000000000001009`
+
+## Key Features
+
+- **Cross-Chain Transfers**: Send tokens to any IBC-enabled Cosmos chain
+- **Flexible Timeouts**: Set custom timeout parameters or use defaults
+- **Memo Support**: Include arbitrary data with transfers
+- **Multi-Asset Support**: Transfer any IBC-compatible token denomination
+
+## Available Functions
+
+### State-Changing Functions
+
+
+
+ Transfer tokens to another chain via IBC with custom timeout parameters.
+
+ **Parameters:**
+ - `toAddress` (string): Recipient address on destination chain
+ - `port` (string): IBC port identifier (usually "transfer")
+ - `channel` (string): IBC channel identifier (e.g., "channel-0")
+ - `denom` (string): Token denomination to transfer
+ - `amount` (uint256): Amount to transfer (in base units)
+ - `revisionNumber` (uint64): Timeout height revision number
+ - `revisionHeight` (uint64): Timeout height revision height
+ - `timeoutTimestamp` (uint64): Timeout timestamp (nanoseconds)
+ - `memo` (string): Optional memo data
+
+ **Returns:** Success boolean
+
+ ```typescript
+ const success = await ibcContract.transfer(
+ "cosmos1...", // Destination address
+ "transfer", // Port
+ "channel-0", // Channel
+ "usei", // Denomination
+ parseEther("100"), // Amount (100 SEI)
+ 1n, // Revision number
+ 1000000n, // Revision height
+ 0n, // Timeout timestamp (0 = no timeout)
+ "Cross-chain transfer" // Memo
+ );
+ ```
+
+
+
+ Transfer tokens to another chain via IBC using default timeout parameters.
+
+ **Parameters:**
+ - `toAddress` (string): Recipient address on destination chain
+ - `port` (string): IBC port identifier (usually "transfer")
+ - `channel` (string): IBC channel identifier
+ - `denom` (string): Token denomination to transfer
+ - `amount` (uint256): Amount to transfer (in base units)
+ - `memo` (string): Optional memo data
+
+ **Returns:** Success boolean
+
+ **Note:** Uses default timeout of 10 minutes from current time
+
+ ```typescript
+ const success = await ibcContract.transferWithDefaultTimeout(
+ "cosmos1...", // Destination address
+ "transfer", // Port
+ "channel-0", // Channel
+ "usei", // Denomination
+ parseEther("50"), // Amount (50 SEI)
+ "Simple transfer" // Memo
+ );
+ ```
+
+
+
+## Usage Examples
+
+
+
+ ```typescript
+ import { createPublicClient, createWalletClient, http, parseEther } from 'viem';
+ import { privateKeyToAccount } from 'viem/accounts';
+ import {
+ seiTestnet,
+ IBC_PRECOMPILE_ABI,
+ IBC_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles/viem';
+
+ const publicClient = createPublicClient({
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ const account = privateKeyToAccount('0x...');
+ const walletClient = createWalletClient({
+ account,
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ // Common IBC channels and their destinations
+ const IBC_CHANNELS = {
+ OSMOSIS: 'channel-0',
+ COSMOS_HUB: 'channel-1',
+ JUNO: 'channel-2',
+ STARGAZE: 'channel-3'
+ } as const;
+
+ // Transfer with default timeout (recommended for most use cases)
+ async function transferToChain(
+ destinationAddress: string,
+ channel: string,
+ denom: string,
+ amount: string,
+ memo: string = ""
+ ) {
+ const hash = await walletClient.writeContract({
+ address: IBC_PRECOMPILE_ADDRESS,
+ abi: IBC_PRECOMPILE_ABI,
+ functionName: 'transferWithDefaultTimeout',
+ args: [
+ destinationAddress,
+ "transfer",
+ channel,
+ denom,
+ parseEther(amount),
+ memo
+ ]
+ });
+
+ return await publicClient.waitForTransactionReceipt({ hash });
+ }
+
+ // Transfer with custom timeout
+ async function transferWithCustomTimeout(
+ destinationAddress: string,
+ channel: string,
+ denom: string,
+ amount: string,
+ timeoutMinutes: number = 10,
+ memo: string = ""
+ ) {
+ const currentTime = Math.floor(Date.now() / 1000);
+ const timeoutTimestamp = BigInt((currentTime + timeoutMinutes * 60) * 1_000_000_000); // Convert to nanoseconds
+
+ const hash = await walletClient.writeContract({
+ address: IBC_PRECOMPILE_ADDRESS,
+ abi: IBC_PRECOMPILE_ABI,
+ functionName: 'transfer',
+ args: [
+ destinationAddress,
+ "transfer",
+ channel,
+ denom,
+ parseEther(amount),
+ 1n, // Revision number
+ 0n, // Revision height (0 = no height timeout)
+ timeoutTimestamp,
+ memo
+ ]
+ });
+
+ return await publicClient.waitForTransactionReceipt({ hash });
+ }
+
+ // Cross-chain DeFi helper
+ async function crossChainSwap(
+ destinationChain: keyof typeof IBC_CHANNELS,
+ destinationAddress: string,
+ amount: string,
+ swapMemo: string
+ ) {
+ const channel = IBC_CHANNELS[destinationChain];
+
+ console.log(`Initiating cross-chain swap to ${destinationChain}`);
+ console.log(`Channel: ${channel}, Amount: ${amount} SEI`);
+
+ return await transferToChain(
+ destinationAddress,
+ channel,
+ "usei",
+ amount,
+ swapMemo
+ );
+ }
+
+ // Batch cross-chain transfers
+ async function batchTransfer(
+ transfers: Array<{
+ destinationAddress: string;
+ channel: string;
+ denom: string;
+ amount: string;
+ memo?: string;
+ }>
+ ) {
+ const transferPromises = transfers.map(transfer =>
+ transferToChain(
+ transfer.destinationAddress,
+ transfer.channel,
+ transfer.denom,
+ transfer.amount,
+ transfer.memo || ""
+ )
+ );
+
+ return await Promise.all(transferPromises);
+ }
+
+ // Multi-chain portfolio rebalancing
+ async function rebalancePortfolio(
+ rebalanceConfig: Array<{
+ chain: keyof typeof IBC_CHANNELS;
+ targetAddress: string;
+ percentage: number; // Percentage of total balance
+ }>,
+ totalAmount: string
+ ) {
+ const totalAmountBN = parseFloat(totalAmount);
+
+ const transfers = rebalanceConfig.map(config => ({
+ destinationAddress: config.targetAddress,
+ channel: IBC_CHANNELS[config.chain],
+ denom: "usei",
+ amount: (totalAmountBN * config.percentage / 100).toString(),
+ memo: `Portfolio rebalancing - ${config.percentage}% to ${config.chain}`
+ }));
+
+ return await batchTransfer(transfers);
+ }
+
+ // Example usage
+ await crossChainSwap(
+ "OSMOSIS",
+ "osmo1...",
+ "100",
+ "=swap:uosmo:osmo1..."
+ );
+
+ await rebalancePortfolio([
+ { chain: "OSMOSIS", targetAddress: "osmo1...", percentage: 40 },
+ { chain: "COSMOS_HUB", targetAddress: "cosmos1...", percentage: 30 },
+ { chain: "JUNO", targetAddress: "juno1...", percentage: 30 }
+ ], "1000");
+ ```
+
+
+
+ ```typescript
+ import { ethers } from 'ethers';
+ import { getIbcPrecompileEthersContract } from '@sei-js/precompiles/ethers';
+
+ const provider = new ethers.JsonRpcProvider('https://evm-rpc-testnet.sei-apis.com');
+ const signer = new ethers.Wallet('0x...', provider);
+ const ibcContract = getIbcPrecompileEthersContract(provider);
+
+ // Transfer with default timeout
+ async function transferToChain(
+ destinationAddress: string,
+ channel: string,
+ denom: string,
+ amount: string,
+ memo: string = ""
+ ) {
+ const ibcWithSigner = ibcContract.connect(signer);
+
+ const tx = await ibcWithSigner.transferWithDefaultTimeout(
+ destinationAddress,
+ "transfer",
+ channel,
+ denom,
+ ethers.parseEther(amount),
+ memo
+ );
+
+ return await tx.wait();
+ }
+
+ // IBC transfer manager class
+ class IBCTransferManager {
+ private contract: ethers.Contract;
+ private signer: ethers.Signer;
+
+ // Common chain configurations
+ private readonly CHAINS = {
+ OSMOSIS: { channel: 'channel-0', prefix: 'osmo' },
+ COSMOS_HUB: { channel: 'channel-1', prefix: 'cosmos' },
+ JUNO: { channel: 'channel-2', prefix: 'juno' },
+ STARGAZE: { channel: 'channel-3', prefix: 'stars' }
+ };
+
+ constructor(provider: ethers.Provider, signer: ethers.Signer) {
+ this.contract = getIbcPrecompileEthersContract(provider);
+ this.signer = signer;
+ }
+
+ async transferWithDefaults(
+ destinationAddress: string,
+ channel: string,
+ denom: string,
+ amount: string,
+ memo: string = ""
+ ): Promise {
+ const contractWithSigner = this.contract.connect(this.signer);
+
+ const tx = await contractWithSigner.transferWithDefaultTimeout(
+ destinationAddress,
+ "transfer",
+ channel,
+ denom,
+ ethers.parseEther(amount),
+ memo
+ );
+
+ return await tx.wait();
+ }
+
+ async transferWithCustomTimeout(
+ destinationAddress: string,
+ channel: string,
+ denom: string,
+ amount: string,
+ timeoutMinutes: number,
+ memo: string = ""
+ ): Promise {
+ const contractWithSigner = this.contract.connect(this.signer);
+
+ const currentTime = Math.floor(Date.now() / 1000);
+ const timeoutTimestamp = BigInt((currentTime + timeoutMinutes * 60) * 1_000_000_000);
+
+ const tx = await contractWithSigner.transfer(
+ destinationAddress,
+ "transfer",
+ channel,
+ denom,
+ ethers.parseEther(amount),
+ 1n, // Revision number
+ 0n, // Revision height
+ timeoutTimestamp,
+ memo
+ );
+
+ return await tx.wait();
+ }
+
+ async transferToKnownChain(
+ chainName: keyof typeof this.CHAINS,
+ destinationAddress: string,
+ amount: string,
+ memo: string = ""
+ ): Promise {
+ const chainConfig = this.CHAINS[chainName];
+ if (!chainConfig) {
+ throw new Error(`Unknown chain: ${chainName}`);
+ }
+
+ return await this.transferWithDefaults(
+ destinationAddress,
+ chainConfig.channel,
+ "usei",
+ amount,
+ memo
+ );
+ }
+
+ // Validate destination address format
+ validateDestinationAddress(address: string, chainPrefix: string): boolean {
+ return address.startsWith(chainPrefix) && address.length >= 39;
+ }
+
+ // Get estimated transfer time
+ getEstimatedTransferTime(chainName: keyof typeof this.CHAINS): string {
+ const times = {
+ OSMOSIS: "1-2 minutes",
+ COSMOS_HUB: "1-2 minutes",
+ JUNO: "1-2 minutes",
+ STARGAZE: "1-2 minutes"
+ };
+
+ return times[chainName] || "1-3 minutes";
+ }
+ }
+
+ // Usage
+ const ibcManager = new IBCTransferManager(provider, signer);
+
+ // Transfer to Osmosis
+ await ibcManager.transferToKnownChain(
+ "OSMOSIS",
+ "osmo1...",
+ "100",
+ "DeFi farming"
+ );
+ ```
+
+
+
+ ```typescript
+ import {
+ IBC_PRECOMPILE_ABI,
+ IBC_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles';
+
+ // Using with web3.js
+ import Web3 from 'web3';
+
+ const web3 = new Web3('https://evm-rpc-testnet.sei-apis.com');
+ const ibcContract = new web3.eth.Contract(
+ IBC_PRECOMPILE_ABI,
+ IBC_PRECOMPILE_ADDRESS
+ );
+
+ // Setup account
+ const account = web3.eth.accounts.privateKeyToAccount('0x...');
+ web3.eth.accounts.wallet.add(account);
+
+ // Transfer with default timeout
+ const transferTx = await ibcContract.methods
+ .transferWithDefaultTimeout(
+ 'cosmos1...', // Destination address
+ 'transfer', // Port
+ 'channel-0', // Channel
+ 'usei', // Denomination
+ web3.utils.toWei('100', 'ether'), // Amount
+ 'Cross-chain transfer' // Memo
+ )
+ .send({
+ from: account.address,
+ gas: 300000
+ });
+
+ // Transfer with custom timeout
+ const currentTime = Math.floor(Date.now() / 1000);
+ const timeoutTimestamp = (currentTime + 600) * 1_000_000_000; // 10 minutes
+
+ const customTransferTx = await ibcContract.methods
+ .transfer(
+ 'cosmos1...',
+ 'transfer',
+ 'channel-0',
+ 'usei',
+ web3.utils.toWei('50', 'ether'),
+ 1, // Revision number
+ 0, // Revision height
+ timeoutTimestamp,
+ 'Custom timeout transfer'
+ )
+ .send({
+ from: account.address,
+ gas: 300000
+ });
+ ```
+
+
+
+## IBC Channel Configuration
+
+### Common Sei IBC Channels
+
+| Chain | Channel ID | Destination Prefix | Transfer Time |
+|-------|------------|-------------------|---------------|
+| Osmosis | channel-0 | osmo | 1-2 minutes |
+| Cosmos Hub | channel-1 | cosmos | 1-2 minutes |
+| Juno | channel-2 | juno | 1-2 minutes |
+| Stargaze | channel-3 | stars | 1-2 minutes |
+
+### Channel Discovery
+```typescript
+// Helper to validate channel and destination
+function validateIBCTransfer(
+ channel: string,
+ destinationAddress: string,
+ expectedPrefix: string
+) {
+ // Validate channel format
+ if (!channel.startsWith('channel-')) {
+ throw new Error('Invalid channel format. Must start with "channel-"');
+ }
+
+ // Validate destination address
+ if (!destinationAddress.startsWith(expectedPrefix)) {
+ throw new Error(`Invalid destination address. Must start with "${expectedPrefix}"`);
+ }
+
+ // Validate address length (typical Cosmos address is 39-45 characters)
+ if (destinationAddress.length < 39 || destinationAddress.length > 45) {
+ throw new Error('Invalid destination address length');
+ }
+
+ return true;
+}
+```
+
+## Common Use Cases
+
+### Cross-Chain DeFi
+- **Yield Farming**: Transfer tokens to other chains for higher yields
+- **Arbitrage**: Move assets between chains to exploit price differences
+- **Liquidity Provision**: Provide liquidity on multiple DEXs across chains
+
+### Portfolio Management
+- **Diversification**: Spread assets across multiple chains
+- **Risk Management**: Move assets to safer chains during market volatility
+- **Rebalancing**: Maintain target allocations across chains
+
+### Multi-Chain Applications
+- **Cross-Chain Swaps**: Enable swaps between assets on different chains
+- **Unified Wallets**: Manage assets across multiple chains from one interface
+- **Cross-Chain Governance**: Participate in governance across multiple chains
+
+## Transfer Strategies
+
+### Timeout Management
+```typescript
+// Calculate appropriate timeout based on network conditions
+function calculateOptimalTimeout(
+ destinationChain: string,
+ amount: string,
+ networkCongestion: 'low' | 'medium' | 'high' = 'medium'
+): number {
+ const baseTimeout = 10; // 10 minutes base
+
+ const congestionMultiplier = {
+ low: 1,
+ medium: 1.5,
+ high: 2
+ };
+
+ const amountMultiplier = parseFloat(amount) > 1000 ? 1.2 : 1; // Extra time for large transfers
+
+ return Math.ceil(baseTimeout * congestionMultiplier[networkCongestion] * amountMultiplier);
+}
+```
+
+### Memo Optimization
+```typescript
+// Generate optimized memos for different use cases
+function generateTransferMemo(
+ purpose: 'swap' | 'farming' | 'arbitrage' | 'general',
+ additionalData?: Record
+): string {
+ const memos = {
+ swap: (data: any) => `=swap:${data.outputToken}:${data.recipient}`,
+ farming: (data: any) => `farm:${data.poolId}:${data.strategy}`,
+ arbitrage: (data: any) => `arb:${data.targetPrice}:${data.slippage}`,
+ general: (data: any) => data?.message || 'IBC transfer'
+ };
+
+ return memos[purpose](additionalData);
+}
+```
+
+### Batch Transfer Optimization
+```typescript
+// Optimize batch transfers for gas efficiency
+async function optimizedBatchTransfer(
+ transfers: Array<{
+ destinationAddress: string;
+ channel: string;
+ denom: string;
+ amount: string;
+ memo?: string;
+ }>,
+ maxConcurrent: number = 3
+) {
+ // Group transfers by channel for efficiency
+ const transfersByChannel = transfers.reduce((acc, transfer) => {
+ if (!acc[transfer.channel]) acc[transfer.channel] = [];
+ acc[transfer.channel].push(transfer);
+ return acc;
+ }, {} as Record);
+
+ // Process transfers in batches
+ const results = [];
+ for (const [channel, channelTransfers] of Object.entries(transfersByChannel)) {
+ for (let i = 0; i < channelTransfers.length; i += maxConcurrent) {
+ const batch = channelTransfers.slice(i, i + maxConcurrent);
+ const batchPromises = batch.map(transfer =>
+ transferToChain(
+ transfer.destinationAddress,
+ transfer.channel,
+ transfer.denom,
+ transfer.amount,
+ transfer.memo
+ )
+ );
+
+ const batchResults = await Promise.all(batchPromises);
+ results.push(...batchResults);
+ }
+ }
+
+ return results;
+}
+```
+
+## Error Handling
+
+Common errors when using the IBC precompile:
+
+- **Invalid channel**: Channel doesn't exist or is closed
+- **Timeout expired**: Transfer took too long to complete
+- **Insufficient balance**: Not enough tokens to transfer
+- **Invalid destination**: Malformed destination address
+
+```typescript
+async function safeIBCTransfer(
+ destinationAddress: string,
+ channel: string,
+ denom: string,
+ amount: string,
+ memo: string = ""
+) {
+ try {
+ // Validate inputs
+ if (!destinationAddress || !channel || !denom || !amount) {
+ throw new Error('Missing required parameters');
+ }
+
+ // Validate channel format
+ if (!channel.startsWith('channel-')) {
+ throw new Error('Invalid channel format');
+ }
+
+ // Validate amount
+ if (parseFloat(amount) <= 0) {
+ throw new Error('Amount must be greater than 0');
+ }
+
+ return await transferToChain(destinationAddress, channel, denom, amount, memo);
+ } catch (error) {
+ if (error.message.includes('channel not found')) {
+ throw new Error(`IBC channel ${channel} not found or inactive`);
+ } else if (error.message.includes('insufficient funds')) {
+ throw new Error(`Insufficient ${denom} balance for transfer`);
+ } else if (error.message.includes('timeout')) {
+ throw new Error('Transfer timeout - try again with longer timeout');
+ } else if (error.message.includes('invalid destination')) {
+ throw new Error('Invalid destination address format');
+ } else {
+ throw error;
+ }
+ }
+}
+```
+
+## Security Considerations
+
+### Address Validation
+- Always validate destination addresses match the expected chain prefix
+- Verify channel IDs are correct for the intended destination chain
+- Double-check amounts and denominations before transfer
+
+### Timeout Management
+- Use appropriate timeouts based on network conditions
+- Consider using default timeouts for most transfers
+- Monitor for failed transfers due to timeouts
+
+### Memo Security
+- Avoid including sensitive information in memos
+- Be cautious with automated memo generation
+- Validate memo content for cross-chain applications
+
+```typescript
+// Security validation helper
+function validateTransferSecurity(
+ destinationAddress: string,
+ channel: string,
+ amount: string,
+ memo: string
+): { valid: boolean; warnings: string[] } {
+ const warnings: string[] = [];
+
+ // Check for common address typos
+ if (destinationAddress.includes('0x')) {
+ warnings.push('Destination address contains 0x - this may be an Ethereum address');
+ }
+
+ // Check for large transfers
+ if (parseFloat(amount) > 10000) {
+ warnings.push('Large transfer amount - please double-check');
+ }
+
+ // Check memo for sensitive data
+ if (memo.includes('private') || memo.includes('secret') || memo.includes('key')) {
+ warnings.push('Memo may contain sensitive information');
+ }
+
+ return {
+ valid: warnings.length === 0,
+ warnings
+ };
+}
+```
+
+## Related Precompiles
+
+- **[Bank](/precompiles/precompiles/bank)**: Check token balances before IBC transfers
+- **[Address](/precompiles/precompiles/address)**: Convert between EVM and Cosmos addresses
+- **[Oracle](/precompiles/precompiles/oracle)**: Get exchange rates for cross-chain arbitrage
diff --git a/docs/precompiles/precompiles/json.mdx b/docs/precompiles/precompiles/json.mdx
new file mode 100644
index 000000000..bd82ff98b
--- /dev/null
+++ b/docs/precompiles/precompiles/json.mdx
@@ -0,0 +1,712 @@
+---
+title: 'JSON Precompile'
+description: 'Parse and extract data from JSON responses using the JSON precompile contract for efficient on-chain data processing'
+icon: "brackets-curly"
+---
+
+## Overview
+
+The JSON precompile provides efficient JSON parsing capabilities directly on-chain, allowing smart contracts to extract specific values from JSON data without complex string manipulation. This is particularly useful for processing API responses, oracle data, and structured data from external sources.
+
+**Contract Address:** `0x0000000000000000000000000000000000001003`
+
+## Key Features
+
+- **Efficient Parsing**: Gas-optimized JSON parsing on-chain
+- **Type-Safe Extraction**: Extract data as specific types (bytes, uint256, arrays)
+- **Key-Based Access**: Extract values using JSON key paths
+- **Oracle Integration**: Process structured data from external APIs
+
+## Available Functions
+
+### View Functions
+
+
+
+ Extract a value from JSON data as bytes.
+
+ **Parameters:**
+ - `input` (bytes): The JSON data as bytes
+ - `key` (string): The JSON key path to extract
+
+ **Returns:** The extracted value as bytes
+
+ ```typescript
+ const jsonData = '{"price": "100.50", "symbol": "SEI"}';
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+
+ const priceBytes = await jsonContract.extractAsBytes(
+ jsonBytes,
+ "price"
+ );
+
+ // Convert back to string
+ const price = ethers.toUtf8String(priceBytes);
+ console.log('Price:', price); // "100.50"
+ ```
+
+
+
+ Extract an array of values from JSON data as bytes array.
+
+ **Parameters:**
+ - `input` (bytes): The JSON data as bytes
+ - `key` (string): The JSON key path to extract (must point to an array)
+
+ **Returns:** Array of extracted values as bytes
+
+ ```typescript
+ const jsonData = '{"validators": ["seivaloper1...", "seivaloper2..."]}';
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+
+ const validatorBytes = await jsonContract.extractAsBytesList(
+ jsonBytes,
+ "validators"
+ );
+
+ // Convert bytes array to string array
+ const validators = validatorBytes.map(bytes => ethers.toUtf8String(bytes));
+ console.log('Validators:', validators);
+ ```
+
+
+
+ Extract a numeric value from JSON data as uint256.
+
+ **Parameters:**
+ - `input` (bytes): The JSON data as bytes
+ - `key` (string): The JSON key path to extract (must be numeric)
+
+ **Returns:** The extracted value as uint256
+
+ ```typescript
+ const jsonData = '{"balance": "1000000000000000000", "decimals": 18}';
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+
+ const balance = await jsonContract.extractAsUint256(
+ jsonBytes,
+ "balance"
+ );
+
+ const decimals = await jsonContract.extractAsUint256(
+ jsonBytes,
+ "decimals"
+ );
+
+ console.log('Balance:', formatEther(balance)); // "1.0"
+ console.log('Decimals:', decimals.toString()); // "18"
+ ```
+
+
+
+## Usage Examples
+
+
+
+ ```typescript
+ import { createPublicClient, http, formatEther, toHex } from 'viem';
+ import {
+ seiTestnet,
+ JSON_PRECOMPILE_ABI,
+ JSON_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles/viem';
+
+ const publicClient = createPublicClient({
+ chain: seiTestnet,
+ transport: http()
+ });
+
+ // Helper to convert string to bytes
+ function stringToBytes(str: string): `0x${string}` {
+ return toHex(new TextEncoder().encode(str));
+ }
+
+ // Helper to convert bytes to string
+ function bytesToString(bytes: `0x${string}`): string {
+ const uint8Array = new Uint8Array(
+ bytes.slice(2).match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []
+ );
+ return new TextDecoder().decode(uint8Array);
+ }
+
+ // Extract string value from JSON
+ async function extractStringValue(jsonData: string, key: string): Promise {
+ const jsonBytes = stringToBytes(jsonData);
+
+ const result = await publicClient.readContract({
+ address: JSON_PRECOMPILE_ADDRESS,
+ abi: JSON_PRECOMPILE_ABI,
+ functionName: 'extractAsBytes',
+ args: [jsonBytes, key]
+ });
+
+ return bytesToString(result);
+ }
+
+ // Extract numeric value from JSON
+ async function extractNumericValue(jsonData: string, key: string): Promise {
+ const jsonBytes = stringToBytes(jsonData);
+
+ return await publicClient.readContract({
+ address: JSON_PRECOMPILE_ADDRESS,
+ abi: JSON_PRECOMPILE_ABI,
+ functionName: 'extractAsUint256',
+ args: [jsonBytes, key]
+ });
+ }
+
+ // Extract array from JSON
+ async function extractArrayValue(jsonData: string, key: string): Promise {
+ const jsonBytes = stringToBytes(jsonData);
+
+ const result = await publicClient.readContract({
+ address: JSON_PRECOMPILE_ADDRESS,
+ abi: JSON_PRECOMPILE_ABI,
+ functionName: 'extractAsBytesList',
+ args: [jsonBytes, key]
+ });
+
+ return result.map(bytes => bytesToString(bytes));
+ }
+
+ // Oracle data processor
+ async function processOracleData(oracleResponse: string) {
+ // Example oracle response
+ const jsonData = `{
+ "prices": {
+ "SEI": {
+ "usd": "0.45",
+ "change_24h": "5.2"
+ },
+ "ATOM": {
+ "usd": "12.30",
+ "change_24h": "-2.1"
+ }
+ },
+ "timestamp": "1640995200",
+ "source": "coingecko"
+ }`;
+
+ // Extract individual values
+ const seiPrice = await extractStringValue(jsonData, "prices.SEI.usd");
+ const atomPrice = await extractStringValue(jsonData, "prices.ATOM.usd");
+ const timestamp = await extractNumericValue(jsonData, "timestamp");
+ const source = await extractStringValue(jsonData, "source");
+
+ return {
+ prices: {
+ SEI: parseFloat(seiPrice),
+ ATOM: parseFloat(atomPrice)
+ },
+ timestamp: Number(timestamp),
+ source
+ };
+ }
+
+ // DeFi price aggregator
+ async function aggregatePriceData(priceFeeds: string[]) {
+ const results = [];
+
+ for (const feed of priceFeeds) {
+ try {
+ // Each feed is a JSON string with price data
+ const symbol = await extractStringValue(feed, "symbol");
+ const price = await extractStringValue(feed, "price");
+ const volume = await extractNumericValue(feed, "volume");
+ const lastUpdate = await extractNumericValue(feed, "last_update");
+
+ results.push({
+ symbol,
+ price: parseFloat(price),
+ volume: Number(volume),
+ lastUpdate: Number(lastUpdate)
+ });
+ } catch (error) {
+ console.error('Failed to process price feed:', error);
+ }
+ }
+
+ return results;
+ }
+
+ // Multi-chain data processor
+ async function processMultiChainData(chainDataJson: string) {
+ // Extract chain information
+ const chainName = await extractStringValue(chainDataJson, "chain_name");
+ const blockHeight = await extractNumericValue(chainDataJson, "block_height");
+ const validators = await extractArrayValue(chainDataJson, "validators");
+ const totalSupply = await extractNumericValue(chainDataJson, "total_supply");
+
+ return {
+ chainName,
+ blockHeight: Number(blockHeight),
+ validators,
+ totalSupply: formatEther(totalSupply)
+ };
+ }
+
+ // Configuration parser
+ async function parseProtocolConfig(configJson: string) {
+ const protocolName = await extractStringValue(configJson, "protocol_name");
+ const version = await extractStringValue(configJson, "version");
+ const maxSupply = await extractNumericValue(configJson, "max_supply");
+ const features = await extractArrayValue(configJson, "features");
+ const feeRate = await extractNumericValue(configJson, "fee_rate");
+
+ return {
+ protocolName,
+ version,
+ maxSupply: formatEther(maxSupply),
+ features,
+ feeRate: Number(feeRate)
+ };
+ }
+
+ // Example usage
+ const oracleData = await processOracleData('oracle_response');
+ console.log('SEI Price:', oracleData.prices.SEI);
+
+ const chainData = `{
+ "chain_name": "Sei",
+ "block_height": "1000000",
+ "validators": ["seivaloper1...", "seivaloper2..."],
+ "total_supply": "1000000000000000000000000000"
+ }`;
+
+ const processedData = await processMultiChainData(chainData);
+ console.log('Chain data:', processedData);
+ ```
+
+
+
+ ```typescript
+ import { ethers } from 'ethers';
+ import { getJsonPrecompileEthersContract } from '@sei-js/precompiles/ethers';
+
+ const provider = new ethers.JsonRpcProvider('https://evm-rpc-testnet.sei-apis.com');
+ const jsonContract = getJsonPrecompileEthersContract(provider);
+
+ // Extract string value from JSON
+ async function extractStringValue(jsonData: string, key: string): Promise {
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+ const result = await jsonContract.extractAsBytes(jsonBytes, key);
+ return ethers.toUtf8String(result);
+ }
+
+ // Extract numeric value from JSON
+ async function extractNumericValue(jsonData: string, key: string): Promise {
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+ return await jsonContract.extractAsUint256(jsonBytes, key);
+ }
+
+ // Extract array from JSON
+ async function extractArrayValue(jsonData: string, key: string): Promise {
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+ const result = await jsonContract.extractAsBytesList(jsonBytes, key);
+ return result.map(bytes => ethers.toUtf8String(bytes));
+ }
+
+ // JSON data processor class
+ class JSONDataProcessor {
+ private contract: ethers.Contract;
+
+ constructor(provider: ethers.Provider) {
+ this.contract = getJsonPrecompileEthersContract(provider);
+ }
+
+ async extractString(jsonData: string, key: string): Promise {
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+ const result = await this.contract.extractAsBytes(jsonBytes, key);
+ return ethers.toUtf8String(result);
+ }
+
+ async extractNumber(jsonData: string, key: string): Promise {
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+ return await this.contract.extractAsUint256(jsonBytes, key);
+ }
+
+ async extractArray(jsonData: string, key: string): Promise {
+ const jsonBytes = ethers.toUtf8Bytes(jsonData);
+ const result = await this.contract.extractAsBytesList(jsonBytes, key);
+ return result.map(bytes => ethers.toUtf8String(bytes));
+ }
+
+ // Process complex nested JSON
+ async processNestedData(jsonData: string, schema: Record) {
+ const results: Record = {};
+
+ for (const [field, keyPath] of Object.entries(schema)) {
+ try {
+ // Try to extract as string first
+ const stringValue = await this.extractString(jsonData, keyPath);
+
+ // Check if it's a number
+ if (/^\d+(\.\d+)?$/.test(stringValue)) {
+ results[field] = parseFloat(stringValue);
+ } else {
+ results[field] = stringValue;
+ }
+ } catch {
+ try {
+ // Try to extract as number
+ const numberValue = await this.extractNumber(jsonData, keyPath);
+ results[field] = Number(numberValue);
+ } catch {
+ try {
+ // Try to extract as array
+ const arrayValue = await this.extractArray(jsonData, keyPath);
+ results[field] = arrayValue;
+ } catch (error) {
+ console.error(`Failed to extract ${field} from ${keyPath}:`, error);
+ results[field] = null;
+ }
+ }
+ }
+ }
+
+ return results;
+ }
+
+ // Validate JSON structure
+ async validateJsonStructure(
+ jsonData: string,
+ requiredFields: string[]
+ ): Promise<{ valid: boolean; missingFields: string[] }> {
+ const missingFields: string[] = [];
+
+ for (const field of requiredFields) {
+ try {
+ await this.extractString(jsonData, field);
+ } catch {
+ try {
+ await this.extractNumber(jsonData, field);
+ } catch {
+ try {
+ await this.extractArray(jsonData, field);
+ } catch {
+ missingFields.push(field);
+ }
+ }
+ }
+ }
+
+ return {
+ valid: missingFields.length === 0,
+ missingFields
+ };
+ }
+ }
+
+ // Usage
+ const processor = new JSONDataProcessor(provider);
+
+ const jsonData = `{
+ "token": {
+ "name": "Sei",
+ "symbol": "SEI",
+ "decimals": 18,
+ "total_supply": "1000000000000000000000000000"
+ },
+ "price_data": {
+ "current_price": "0.45",
+ "market_cap": "450000000"
+ }
+ }`;
+
+ // Extract token information
+ const tokenName = await processor.extractString(jsonData, "token.name");
+ const tokenSymbol = await processor.extractString(jsonData, "token.symbol");
+ const decimals = await processor.extractNumber(jsonData, "token.decimals");
+
+ console.log(`Token: ${tokenName} (${tokenSymbol}), Decimals: ${decimals}`);
+ ```
+
+
+
+ ```typescript
+ import {
+ JSON_PRECOMPILE_ABI,
+ JSON_PRECOMPILE_ADDRESS
+ } from '@sei-js/precompiles';
+
+ // Using with web3.js
+ import Web3 from 'web3';
+
+ const web3 = new Web3('https://evm-rpc-testnet.sei-apis.com');
+ const jsonContract = new web3.eth.Contract(
+ JSON_PRECOMPILE_ABI,
+ JSON_PRECOMPILE_ADDRESS
+ );
+
+ // Extract string value
+ const jsonData = '{"price": "100.50", "symbol": "SEI"}';
+ const jsonBytes = web3.utils.toHex(jsonData);
+
+ const priceBytes = await jsonContract.methods
+ .extractAsBytes(jsonBytes, 'price')
+ .call();
+
+ const price = web3.utils.hexToUtf8(priceBytes);
+ console.log('Price:', price);
+
+ // Extract numeric value
+ const balance = await jsonContract.methods
+ .extractAsUint256(jsonBytes, 'balance')
+ .call();
+
+ console.log('Balance:', balance);
+
+ // Extract array
+ const arrayData = '{"validators": ["val1", "val2", "val3"]}';
+ const arrayBytes = web3.utils.toHex(arrayData);
+
+ const validatorBytes = await jsonContract.methods
+ .extractAsBytesList(arrayBytes, 'validators')
+ .call();
+
+ const validators = validatorBytes.map(bytes => web3.utils.hexToUtf8(bytes));
+ console.log('Validators:', validators);
+ ```
+
+
+
+## JSON Key Path Syntax
+
+### Simple Keys
+```typescript
+// For JSON: {"name": "Sei", "price": "0.45"}
+const name = await extractStringValue(jsonData, "name");
+const price = await extractStringValue(jsonData, "price");
+```
+
+### Nested Objects
+```typescript
+// For JSON: {"token": {"name": "Sei", "decimals": 18}}
+const tokenName = await extractStringValue(jsonData, "token.name");
+const decimals = await extractNumericValue(jsonData, "token.decimals");
+```
+
+### Array Access
+```typescript
+// For JSON: {"prices": ["0.45", "0.46", "0.44"]}
+const allPrices = await extractArrayValue(jsonData, "prices");
+
+// For JSON: {"validators": [{"name": "val1"}, {"name": "val2"}]}
+const validatorNames = await extractArrayValue(jsonData, "validators.name");
+```
+
+## Common Use Cases
+
+### Oracle Data Processing
+- **Price Feeds**: Extract price data from oracle responses
+- **Market Data**: Process trading volume, market cap, and other metrics
+- **External APIs**: Parse responses from external data sources
+
+### DeFi Protocol Integration
+- **Token Metadata**: Extract token information from registry responses
+- **Pool Data**: Process liquidity pool information
+- **Yield Data**: Extract APY and reward information
+
+### Cross-Chain Data
+- **Chain State**: Process blockchain state information
+- **Validator Data**: Extract validator sets and staking information
+- **Transaction Data**: Parse complex transaction metadata
+
+## Data Processing Patterns
+
+### Type-Safe Extraction
+```typescript
+// Define data schema
+interface TokenData {
+ name: string;
+ symbol: string;
+ decimals: number;
+ totalSupply: bigint;
+ holders: string[];
+}
+
+async function extractTokenData(jsonData: string): Promise {
+ return {
+ name: await extractStringValue(jsonData, "name"),
+ symbol: await extractStringValue(jsonData, "symbol"),
+ decimals: Number(await extractNumericValue(jsonData, "decimals")),
+ totalSupply: await extractNumericValue(jsonData, "total_supply"),
+ holders: await extractArrayValue(jsonData, "holders")
+ };
+}
+```
+
+### Batch Processing
+```typescript
+// Process multiple JSON objects efficiently
+async function batchProcessJsonData(jsonDataArray: string[], keyPath: string) {
+ const extractPromises = jsonDataArray.map(jsonData =>
+ extractStringValue(jsonData, keyPath)
+ );
+
+ return await Promise.all(extractPromises);
+}
+```
+
+### Error-Resilient Parsing
+```typescript
+async function safeExtractValue(
+ jsonData: string,
+ key: string,
+ defaultValue: any = null
+): Promise {
+ try {
+ // Try string extraction first
+ return await extractStringValue(jsonData, key);
+ } catch {
+ try {
+ // Try numeric extraction
+ return await extractNumericValue(jsonData, key);
+ } catch {
+ try {
+ // Try array extraction
+ return await extractArrayValue(jsonData, key);
+ } catch {
+ return defaultValue;
+ }
+ }
+ }
+}
+```
+
+## Performance Optimization
+
+### Efficient Data Extraction
+```typescript
+// Cache frequently accessed data
+class JSONCache {
+ private cache = new Map();
+
+ async getCachedValue(jsonData: string, key: string, extractor: Function) {
+ const cacheKey = `${jsonData.slice(0, 100)}-${key}`;
+
+ if (this.cache.has(cacheKey)) {
+ return this.cache.get(cacheKey);
+ }
+
+ const value = await extractor(jsonData, key);
+ this.cache.set(cacheKey, value);
+
+ return value;
+ }
+}
+```
+
+### Batch Key Extraction
+```typescript
+// Extract multiple keys in parallel
+async function extractMultipleKeys(
+ jsonData: string,
+ keys: Array<{ key: string; type: 'string' | 'number' | 'array' }>
+) {
+ const extractPromises = keys.map(async ({ key, type }) => {
+ switch (type) {
+ case 'string':
+ return { key, value: await extractStringValue(jsonData, key) };
+ case 'number':
+ return { key, value: await extractNumericValue(jsonData, key) };
+ case 'array':
+ return { key, value: await extractArrayValue(jsonData, key) };
+ default:
+ throw new Error(`Unknown type: ${type}`);
+ }
+ });
+
+ const results = await Promise.all(extractPromises);
+
+ return results.reduce((acc, { key, value }) => {
+ acc[key] = value;
+ return acc;
+ }, {} as Record);
+}
+```
+
+## Error Handling
+
+Common errors when using the JSON precompile:
+
+- **Invalid JSON**: Malformed JSON data
+- **Key not found**: Specified key doesn't exist in JSON
+- **Type mismatch**: Trying to extract wrong data type
+- **Invalid key path**: Malformed key path syntax
+
+```typescript
+async function safeJsonExtraction(
+ jsonData: string,
+ key: string,
+ expectedType: 'string' | 'number' | 'array'
+) {
+ try {
+ // Validate JSON format first
+ JSON.parse(jsonData); // This will throw if invalid
+
+ switch (expectedType) {
+ case 'string':
+ return await extractStringValue(jsonData, key);
+ case 'number':
+ return await extractNumericValue(jsonData, key);
+ case 'array':
+ return await extractArrayValue(jsonData, key);
+ default:
+ throw new Error(`Unsupported type: ${expectedType}`);
+ }
+ } catch (error) {
+ if (error.message.includes('JSON')) {
+ throw new Error('Invalid JSON format');
+ } else if (error.message.includes('key not found')) {
+ throw new Error(`Key "${key}" not found in JSON data`);
+ } else if (error.message.includes('type mismatch')) {
+ throw new Error(`Type mismatch: expected ${expectedType} for key "${key}"`);
+ } else {
+ throw error;
+ }
+ }
+}
+```
+
+## Security Considerations
+
+### Input Validation
+- Always validate JSON data before processing
+- Sanitize key paths to prevent injection attacks
+- Limit JSON data size to prevent DoS attacks
+
+### Data Integrity
+- Verify data sources and authenticity
+- Implement checksums for critical data
+- Use multiple data sources for validation
+
+```typescript
+// Security validation helper
+function validateJsonInput(jsonData: string, maxSize: number = 10000): boolean {
+ // Check size limit
+ if (jsonData.length > maxSize) {
+ throw new Error('JSON data exceeds size limit');
+ }
+
+ // Validate JSON format
+ try {
+ JSON.parse(jsonData);
+ } catch {
+ throw new Error('Invalid JSON format');
+ }
+
+ // Check for potential security issues
+ if (jsonData.includes('