diff --git a/.github/workflows/update-trieve-dataset.yml b/.github/workflows/update-trieve-dataset.yml index 9edf2ea8..01cf7e7b 100644 --- a/.github/workflows/update-trieve-dataset.yml +++ b/.github/workflows/update-trieve-dataset.yml @@ -7,6 +7,7 @@ on: - 'content/**' - 'app/**' - 'scripts/**' + - 'knowledge-base/**' workflow_dispatch: jobs: diff --git a/knowledge-base/account-management/add-sei-network-to-metamask.md b/knowledge-base/account-management/add-sei-network-to-metamask.md new file mode 100644 index 00000000..d4b2434d --- /dev/null +++ b/knowledge-base/account-management/add-sei-network-to-metamask.md @@ -0,0 +1,40 @@ +--- +title: 'How Do I Add Sei Network to MetaMask?' +description: 'How Do I Add Sei Network to MetaMask?' +--- + +# How Do I Add Sei Network to MetaMask? + +### Steps + +- Open **MetaMask**. + +- Click the **network dropdown** menu (top-left, often says "Ethereum Mainnet"). + +- Click **"Add network"** at the bottom. + +- Click **"Add a network manually"** (if Sei isn't shown in the list). + +- Enter the following details **exactly**: + +Network Name: `Sei Network` + +- New RPC URL: `https://evm-rpc.sei-apis.com` + +- Chain ID: `1329` + +- Currency Symbol: `SEI` + +- Block Explorer URL (Optional): `https://seitrace.com` + +- Click **"Save"**. + +### Explanation & Tips + +- **Chain ID is Crucial:** The most common error is mistyping the Chain ID. It **must** be `1329` for Sei mainnet. + +- **"Incorrect Network" Error:** If MetaMask shows this after adding, double-check all entered details, especially the Chain ID. You might need to remove the network and add it again carefully. See Fixing "Incorrect Network" Error in MetaMask. + +- **Alternative Public RPC:** If you experience connection issues later, you can try editing the network settings to use an alternative RPC URL like `https://sei.drpc.org`. + +- **Testnet:** For Sei Testnet (Atlantic-2), use Chain ID `1328` and RPC `https://evm-rpc-testnet.sei-apis.com`. diff --git a/knowledge-base/account-management/how-do-transactions-work-on-sei-evm-and-how.md b/knowledge-base/account-management/how-do-transactions-work-on-sei-evm-and-how.md new file mode 100644 index 00000000..84d17f2b --- /dev/null +++ b/knowledge-base/account-management/how-do-transactions-work-on-sei-evm-and-how.md @@ -0,0 +1,336 @@ +--- +title: 'How do transactions work on Sei EVM, and how quickly can I consider them final?' +description: 'How do transactions work on Sei EVM, and how quickly can I consider them final?' +--- + +# How do transactions work on Sei EVM, and how quickly can I consider them final? + +Sei EVM's transaction processing differs from traditional Ethereum-based chains due to its parallel execution model and unique consensus mechanism. Understanding this lifecycle helps you build more performant and reliable applications. + +## Transaction Lifecycle Overview + +Here's the complete journey of a transaction on Sei EVM: + +- **Creation**: User initiates a transaction through wallet or dApp + +- **Submission**: Transaction is signed and broadcast to the Sei network + +- **Mempool**: Transaction enters the validator mempool + +- **Parallelization Analysis**: Sei groups transactions that can be processed simultaneously + +- **Execution**: Transactions are executed in parallel where possible + +- **Conflict Resolution**: Conflicts between parallel executions are detected and resolved + +- **Block Inclusion**: Successful transactions are included in a block + +- **Consensus**: Block reaches consensus through Sei's tendermint-based consensus + +- **Finality**: Transaction becomes final (irreversible) + +- **State Update**: The global state is updated to reflect transaction results + +## Key Differences from Ethereum + +### Parallel Execution + +On Ethereum, transactions within a block are processed sequentially, one after another. On Sei: + +- The blockchain analyzes which transactions can be safely processed in parallel + +- Multiple transactions can execute simultaneously if they don't access the same state + +- Transactions with state conflicts may be reordered or reprocessed to maintain consistency + +- The final block shows a deterministic execution order despite parallel processing + +### Consensus and Finality + +``` +┌─────────────────────────────────────────────────────────────┐ +│ │ +│ Ethereum │ Sei │ +│ │ │ +│ ┌───────────┐ ~12+ secs │ ┌───────────┐ 400ms │ +│ │Transaction│ ─────────────► │ │Transaction│ ──────────► │ +│ │ Submitted │ │ │ Submitted │ │ +│ └───────────┘ │ └───────────┘ │ +│ │ │ │ │ +│ ▼ │ ▼ │ +│ ┌───────────┐ │ ┌───────────┐ │ +│ │ Included │ │ │ Included │ │ +│ │ in Block │ │ │ in Block │ │ +│ └───────────┘ │ └───────────┘ │ +│ │ │ │ │ +│ ▼ │ ▼ │ +│ ┌───────────┐ minutes-hrs │ ┌───────────┐ 1 sec │ +│ │Probabilist│ ─────────────► │ │ Instant │ ──────────► │ +│ │ Finality │ │ │ Finality │ │ +│ └───────────┘ │ └───────────┘ │ +│ │ │ +└─────────────────────────────────────────────────────────────┘ + +``` + +- **Ethereum**: Uses probabilistic finality, becoming more "final" with more confirmations + +- **Sei**: Uses instant finality through Tendermint consensus + +Once a block is confirmed, it cannot be reverted + +- Finality occurs within seconds, not minutes + +## Transaction Timing Benchmarks + +Typical transaction timings on Sei EVM: + +| +Phase | +Ethereum | +Sei EVM | + +| +Block time | +~12-15 seconds | +~400 milliseconds | + +| +First confirmation | +~12-15 seconds | +~400 milliseconds | + +| +Practical finality | +~2-3 minutes | +~1 second | + +| +Full finality | +~6+ minutes | +~1 second | + +## Concurrency Control in Practice + +Sei uses an Optimistic Concurrency Control (OCC) mechanism: + +- **Read Phase**: During transaction execution, a "read set" of accessed state is recorded + +- **Validation Phase**: Sei checks if any other parallel transactions modified the same state + +- **Write Phase**: If no conflicts, changes are committed; if conflicts exist, transactions may be re-executed + +This approach allows Sei to deliver: + +- High throughput with thousands of transactions per second + +- Deterministic results despite parallel execution + +- Short confirmation times regardless of network load + +## Transaction Failures Specific to Parallel Execution + +Unique failure modes on Sei EVM: + +- **Conflict Aborts**: Transactions might fail if concurrent transactions modify the same state + +- **Optimistic Execution Reversions**: A transaction initially executing successfully may revert if conflicts are detected + +- **Resequencing**: Transactions may execute in a different order than they were submitted + +Best practices for handling these scenarios: + +``` +// Example client-side code handling resubmission +async function sendTransactionWithRetry(tx, maxAttempts = 3) { + let attempts = 0; + while (attempts try { + const response = await wallet.sendTransaction(tx); + const receipt = await response.wait(); + + if (receipt.status === 1) { + return receipt; // Success + } + + // Failed but not due to conflict - no retry needed + if (!receipt.logs.some(log => log.topics.includes(CONFLICT_TOPIC_ID))) { + throw new Error("Transaction failed - not a conflict issue"); + } + + // Brief delay before retry + await new Promise(resolve => setTimeout(resolve, 200 * attempts)); + attempts++; + } catch (error) { + if (error.message.includes("conflict") || error.message.includes("resequenced")) { + await new Promise(resolve => setTimeout(resolve, 200 * attempts)); + attempts++; + } else { + throw error; // Different error - propagate + } + } + } + throw new Error(`Transaction failed after ${maxAttempts} attempts`); +} + +``` + +## Practical Implications for Developers + +### Waiting for Confirmations + +With Sei's fast finality, application developers can: + +- **Show Immediate Feedback**: Once a transaction receipt is received, it's safe to update the UI + +- **Chain Transactions**: Subsequent transactions can be submitted immediately after confirmation + +- **Reduce Pending States**: Shorter "pending" transaction states improve user experience + +``` +// Example React hook for Sei transaction tracking +function useSeiTransactionStatus(txHash: string | null) { + const [status, setStatus] = useState(txHash ? 'pending' : 'idle'); + + useEffect(() => { + if (!txHash) { + setStatus('idle'); + return; + } + + setStatus('pending'); + + const checkReceipt = async () => { + try { + const receipt = await provider.getTransactionReceipt(txHash); + if (receipt) { + setStatus(receipt.status === 1 ? 'success' : 'failed'); + return true; + } + return false; + } catch (error) { + console.error("Error checking receipt:", error); + return false; + } + }; + + // Check immediately + checkReceipt(); + + // Poll briefly - with Sei's quick finality, should resolve in ~1 second + const interval = setInterval(async () => { + const received = await checkReceipt(); + if (received) clearInterval(interval); + }, 200); // 200ms polling is reasonable for Sei + + return () => clearInterval(interval); + }, [txHash]); + + return status; +} + +``` + +### Off-Chain Systems Integration + +When integrating with off-chain systems such as databases or APIs: + +``` +// Example: Safely update backend after Sei transaction confirmation +async function processPayment(paymentTx, userId) { + // Wait for transaction confirmation + const receipt = await provider.waitForTransaction(paymentTx.hash); + + // Only proceed if transaction succeeded + if (receipt.status === 1) { + // Safe to update database - transaction is final + await database.recordPayment({ + userId, + amount: paymentTx.value, + txHash: paymentTx.hash, + confirmed: true, + timestamp: Date.now() + }); + + // Safe to trigger external API calls + await notificationService.sendPaymentConfirmation(userId); + } else { + // Handle failed transaction + await database.recordPayment({ + userId, + amount: paymentTx.value, + txHash: paymentTx.hash, + confirmed: false, + timestamp: Date.now() + }); + } +} + +``` + +## When to Consider a Transaction Final? + +Given Sei's architecture, here are practical guidelines: + +- **UI Updates**: Update UI immediately after receiving transaction receipt + +- **Dependent Transactions**: Wait for receipt before submitting dependent transactions + +- **External System Integration**: Wait for 1 block confirmation (~400ms) + +- **High-Value Transactions**: Wait for 2-3 block confirmations (~1-1.2 seconds) + +- **Critical Financial Operations**: Wait for 3-5 block confirmations (~1.2-2 seconds) + +## Reorgs and Chain Reorganizations + +Unlike Ethereum, where chain reorganizations can occur when miners find competing chains: + +- **Sei uses Tendermint consensus**, which has instant finality + +- **Reorgs do not occur** after block finalization + +- Transactions cannot be "dropped" after confirmation + +- No need to wait for 6+ confirmations as with Ethereum + +## Common Troubleshooting Scenarios + +### Transaction Stuck Pending + +If a transaction appears stuck in pending status: + +- Check if the transaction has a receipt using the block explorer + +- If no receipt after 10+ seconds (unusual for Sei): + +The transaction may have been dropped from the mempool + +- Network conditions may be preventing propagation + +- There could be a client-side issue with your connection + +Resolution: Consider resubmitting with higher gas price or checking network status. + +### Transaction Confirmed but State Unchanged + +If a transaction is confirmed but expected state changes aren't visible: + +- Verify the transaction was successful (status = 1) in the explorer + +- Check if the contract emitted expected events + +- Verify you're querying the correct contract and network + +- Consider if another parallel transaction caused unexpected state changes + +### Multiple Parallel Transactions + +When submitting multiple transactions in rapid succession: + +- Submit transactions with appropriate nonce values + +- Be aware that transactions may be reordered during parallel execution + +- Design your application logic to be resilient to reordering + +- Consider using the `nonce` parameter to enforce strict ordering when necessary diff --git a/knowledge-base/account-management/move-sei-between-native-keplr-and-evm-metamask.md b/knowledge-base/account-management/move-sei-between-native-keplr-and-evm-metamask.md new file mode 100644 index 00000000..6ab0b5c8 --- /dev/null +++ b/knowledge-base/account-management/move-sei-between-native-keplr-and-evm-metamask.md @@ -0,0 +1,56 @@ +--- +title: 'How Do I Move SEI Between Native (Keplr) and EVM (MetaMask)?' +description: 'How Do I Move SEI Between Native (Keplr) and EVM (MetaMask)?' +--- + +# How Do I Move SEI Between Native (Keplr) and EVM (MetaMask)? + +### **The Problem** + +I need to transfer my liquid (non-staked) SEI tokens from my Native address (sei1..., managed by Keplr) to my EVM address (0x..., managed by MetaMask), or vice versa. + +### **Solution Steps** + +Use the official Sei Bridge: + +- Ensure you have **both wallets** installed/accessible (Keplr & MetaMask). + +- Ensure both addresses have a **small amount of SEI for gas fees** (Native SEI for Keplr, EVM SEI for MetaMask if bridging _from_ EVM). + +- Go to the [Sei Bridge website](https://bridge.sei.io/). + +- Click to **Connect** both your Keplr (Native) and MetaMask (EVM) wallets. + +- Select **SEI** as the asset to bridge. + +- Choose the **Source Chain** (where the tokens _are now_) and **Destination Chain** (where you want them _to go_). + +Native to EVM: Source = "Sei", Destination = "Sei (EVM)" + +- EVM to Native: Source = "Sei (EVM)", Destination = "Sei" + +- Enter the **Amount** to transfer. + +- Verify the details and click **Transfer** (or similar button). + +- Approve the transaction in your **Source Wallet** (the one you're sending _from_). + +- Wait 1-5 minutes for completion. + +### **Explanation and Tips** + +- **Cause:** Native and EVM environments are separate. The bridge locks tokens on the source and issues corresponding tokens on the destination. + +- **Supported Assets:** The bridge primarily supports native SEI but may support other specific tokens. Check the bridge interface for options. + +- **Transaction Time:** Can take longer during high network activity. + +- **Tokens Not Appearing?** + +Verify the source transaction succeeded on its respective explorer ([SeiScan](https://www.seiscan.app/) for Native, [SeiTrace](https://seitrace.com/) for EVM). + +- Check the destination address on its explorer for the incoming bridge transaction. + +- See [Bridged Assets Not Appearing in Wallet](https://markdowntohtml.com/10-bridged-assets-not-appearing.md). + +- **Stuck Transfer?** If pending for hours, check bridge status and potentially contact bridge support. See [Cross-Chain Transfer Stuck for Several Hours.](https://markdowntohtml.com/11-bridge-transfer-stuck.md) diff --git a/knowledge-base/account-management/what-token-standards-are-supported-on-sei-evm-and.md b/knowledge-base/account-management/what-token-standards-are-supported-on-sei-evm-and.md new file mode 100644 index 00000000..8eceefe7 --- /dev/null +++ b/knowledge-base/account-management/what-token-standards-are-supported-on-sei-evm-and.md @@ -0,0 +1,438 @@ +--- +title: 'What token standards are supported on Sei EVM and how do I implement them?' +description: 'What token standards are supported on Sei EVM and how do I implement them?' +--- + +# What token standards are supported on Sei EVM and how do I implement them? + +Sei EVM follows Ethereum's compatibility model, supporting all major token standards. This article guides you through implementing the most common token standards on Sei and highlights any Sei-specific considerations. + +## ERC-20 Fungible Tokens + +The ERC-20 standard is fully supported on Sei EVM and works identically to Ethereum. + +### Basic Implementation + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract SeiToken is ERC20, Ownable { + constructor(address initialOwner) + ERC20("Sei Token Example", "STKN") + Ownable(initialOwner) + { + // Mint 1 million tokens to the contract deployer + _mint(initialOwner, 1000000 * 10**decimals()); + } + + // Optional: Add additional minting functionality + function mint(address to, uint256 amount) public onlyOwner { + _mint(to, amount); + } +} + +``` + +### Installation and Deployment + +``` +# Install OpenZeppelin contracts +npm install @openzeppelin/contracts + +# Compile with Hardhat +npx hardhat compile + +# Deploy to Sei testnet +npx hardhat run scripts/deploy-erc20.ts --network sei-testnet + +``` + +### Sei-Specific Considerations + +- While deploying ERC-20 tokens on Sei works similarly to Ethereum, consider using the Bank precompile for interoperability with native Sei assets. + +- For tokens that will interact with native Sei modules, consider implementing pointer contracts. + +## ERC-721 Non-Fungible Tokens (NFTs) + +ERC-721 for NFTs works seamlessly on Sei EVM. + +### Basic Implementation + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; + +contract SeiNFT is ERC721URIStorage, Ownable { + using Counters for Counters.Counter; + Counters.Counter private _tokenIds; + + constructor(address initialOwner) + ERC721("Sei NFT Collection", "SNFT") + Ownable(initialOwner) + {} + + function mintNFT(address recipient, string memory tokenURI) + public + onlyOwner + returns (uint256) + { + _tokenIds.increment(); + uint256 newItemId = _tokenIds.current(); + + _mint(recipient, newItemId); + _setTokenURI(newItemId, tokenURI); + + return newItemId; + } +} + +``` + +### Handling NFT Metadata + +- **IPFS Storage**: Store metadata and images on IPFS for decentralization + +``` +// Example using NFT.Storage +const { NFTStorage, File } = require('nft.storage'); +const fs = require('fs'); + +const API_KEY = 'your-nft-storage-api-key'; +const client = new NFTStorage({ token: API_KEY }); + +async function storeNFT(imagePath, name, description) { + const image = fs.readFileSync(imagePath); + const imageFile = new File([image], 'nft.png', { type: 'image/png' }); + + const metadata = await client.store({ + name, + description, + image: imageFile + }); + + return metadata.url; // Returns ipfs://... URL +} + +``` + +- **On-Chain Storage**: For small metadata, consider on-chain storage for guaranteed availability + +### Optimizing for Sei's Performance + +With Sei's high throughput and parallel execution: + +- Batch minting becomes more efficient + +- Consider implementing advanced functions that would be too gas-intensive on Ethereum + +``` +// Example batch mint function +function batchMint(address[] memory recipients, string[] memory tokenURIs) + public + onlyOwner + returns (uint256[] memory) +{ + require(recipients.length == tokenURIs.length, "Arrays must have same length"); + + uint256[] memory ids = new uint256[](recipients.length); + + for (uint i = 0; i newItemId = _tokenIds.current(); + + _mint(recipients[i], newItemId); + _setTokenURI(newItemId, tokenURIs[i]); + + ids[i] = newItemId; + } + + return ids; +} + +``` + +## ERC-1155 Multi-Token Standard + +ERC-1155 combines functionality from ERC-20 and ERC-721, allowing a single contract to manage multiple token types. + +### Basic Implementation + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract SeiMultiToken is ERC1155, Ownable { + // Token type IDs + uint256 public constant FUNGIBLE = 0; + uint256 public constant COLLECTIBLE_1 = 1; + uint256 public constant COLLECTIBLE_2 = 2; + + constructor(address initialOwner) + ERC1155("https://game.example/api/item/{id}.json") + Ownable(initialOwner) + { + // Mint 1000 fungible tokens + _mint(initialOwner, FUNGIBLE, 1000, ""); + + // Mint one of each collectible + _mint(initialOwner, COLLECTIBLE_1, 1, ""); + _mint(initialOwner, COLLECTIBLE_2, 1, ""); + } + + function mint(address to, uint256 id, uint256 amount) public onlyOwner { + _mint(to, id, amount, ""); + } + + function mintBatch( + address to, + uint256[] memory ids, + uint256[] memory amounts + ) public onlyOwner { + _mintBatch(to, ids, amounts, ""); + } +} + +``` + +## Other Token Standards + +### ERC-4626 Tokenized Vaults + +Perfect for DeFi applications on Sei: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract SeiVault is ERC4626 { + constructor(IERC20 asset) + ERC4626(asset) + ERC20("Sei Vault Token", "seiVT") + {} + + // Override _decimals to match the asset's decimals + function decimals() public view virtual override returns (uint8) { + return ERC20(asset()).decimals(); + } +} + +``` + +### ERC-2981 NFT Royalty Standard + +Important for NFT marketplaces: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; +import "@openzeppelin/contracts/token/common/ERC2981.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; + +contract SeiRoyaltyNFT is ERC721URIStorage, ERC2981, Ownable { + using Counters for Counters.Counter; + Counters.Counter private _tokenIds; + + constructor(address initialOwner) + ERC721("Sei Royalty NFT", "SRNFT") + Ownable(initialOwner) + { + // Set default royalty to 5% (500 basis points) + _setDefaultRoyalty(initialOwner, 500); + } + + function mintNFT( + address recipient, + string memory tokenURI, + address royaltyReceiver, + uint96 royaltyFeeNumerator + ) public onlyOwner returns (uint256) { + _tokenIds.increment(); + uint256 newItemId = _tokenIds.current(); + + _mint(recipient, newItemId); + _setTokenURI(newItemId, tokenURI); + + // Set token-specific royalty if provided + if (royaltyReceiver != address(0) && royaltyFeeNumerator > 0) { + _setTokenRoyalty(newItemId, royaltyReceiver, royaltyFeeNumerator); + } + + return newItemId; + } + + // Override required by Solidity for proper inheritance + function supportsInterface(bytes4 interfaceId) + public + view + override(ERC721, ERC2981) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} + +``` + +## Bridging Standards to Native Sei + +To achieve interoperability between EVM tokens and native Sei environment: + +### Token Pointers + +Using Sei's precompiled pointer contracts: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "./interfaces/IPointerRegistry.sol"; + +contract SeiNativeTokenPointer is ERC20 { + IPointerRegistry constant pointerRegistry = + IPointerRegistry(0x000000000000000000000000000000000000100A); + address immutable pointerContract; + string public nativeDenom; + + constructor(string memory _nativeDenom, string memory name, string memory symbol) + ERC20(name, symbol) + { + nativeDenom = _nativeDenom; + + // Register this contract as a pointer + pointerContract = pointerRegistry.registerPointer(); + } + + // Override transfer functions to utilize native token transfers + function transfer(address to, uint256 amount) public override returns (bool) { + // Implement native transfer logic using bank precompile + // ... + + emit Transfer(msg.sender, to, amount); + return true; + } +} + +``` + +## Testing Token Standards on Sei + +- **Setup Test Environment**: + +``` +// test/SeiToken.test.js +const { expect } = require("chai"); + +describe("SeiToken", function () { + let token; + let owner; + let addr1; + let addr2; + + beforeEach(async function () { + const SeiToken = await ethers.getContractFactory("SeiToken"); + [owner, addr1, addr2] = await ethers.getSigners(); + token = await SeiToken.deploy(owner.address); + }); + + it("Should assign the total supply to the owner", async function () { + const ownerBalance = await token.balanceOf(owner.address); + expect(await token.totalSupply()).to.equal(ownerBalance); + }); + + // More tests... +}); + +``` + +- **Test with Sei-Specific Logic**: + +``` +it("Should work with Sei's parallel execution", async function () { + // Simulate multiple concurrent transactions + await Promise.all([ + token.transfer(addr1.address, 50), + token.transfer(addr2.address, 100), + token.connect(addr1).approve(addr2.address, 50), + ]); + + // Verify results + expect(await token.balanceOf(addr1.address)).to.equal(50); + expect(await token.balanceOf(addr2.address)).to.equal(100); + expect(await token.allowance(addr1.address, addr2.address)).to.equal(50); +}); + +``` + +## Best Practices for Sei Token Implementations + +- **Optimize for Parallel Execution**: + +Design tokens with minimal state conflicts + +- Use granular state like individual balances rather than shared counters + +- Consider batch operations for efficiency + +- **Security Considerations**: + +Follow ERC standards precisely to ensure compatibility with wallets and exchanges + +- Use established libraries like OpenZeppelin + +- Consider formal verification for high-value contracts + +- **Gas Efficiency**: + +Take advantage of Sei's lower gas costs for more complex functionality + +- Implement batch operations where appropriate + +- Use ERC-1155 for multiple token types to save on deployment costs + +- **Interoperability**: + +Consider implementing pointer contracts for EVM-native interoperability + +- Use precompiles where applicable + +## Verifying Token Contracts + +``` +# Verify ERC-20 contract +npx hardhat verify --network sei-testnet DEPLOYED_CONTRACT_ADDRESS "CONSTRUCTOR_ARGUMENT" + +# Example +npx hardhat verify --network sei-testnet 0x123...789 "0xabc...def" + +``` + +## Adding Tokens to MetaMask + +Guide users to add your token to their wallet: + +- Open MetaMask and ensure Sei Network is selected + +- Click "Import tokens" at the bottom of the assets list + +- Enter the token contract address + +- Token symbol and decimals should auto-populate + +- Click "Add Custom Token" diff --git a/knowledge-base/compatibility-differences-with-ethereum/are-sei-network-gas-fees-consistently-lower-than.md b/knowledge-base/compatibility-differences-with-ethereum/are-sei-network-gas-fees-consistently-lower-than.md new file mode 100644 index 00000000..a5bf5dc4 --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/are-sei-network-gas-fees-consistently-lower-than.md @@ -0,0 +1,110 @@ +--- +title: 'Are Sei Network gas fees consistently lower than Ethereum?' +description: 'Are Sei Network gas fees consistently lower than Ethereum?' +--- + +# Are Sei Network gas fees consistently lower than Ethereum? + +Yes, Sei Network gas fees are consistently lower than Ethereum's, typically by at least an order of magnitude. This difference stems from several key factors: + +### Why Sei Fees Are Lower: + +- **Higher Throughput**: + +Sei processes significantly more transactions per second than Ethereum + +- More block space means less competition for inclusion + +- **Parallel Execution**: + +Sei's Optimistic Concurrency Control enables parallel transaction processing + +- More efficient execution means resources are used more effectively + +- **Different Tokenomics**: + +SEI token has a different valuation model than ETH + +- Fee market designs prioritize usability over scarcity + +- **Network Design Choices**: + +Sei was built from the ground up for high performance + +- Transaction processing optimized for efficiency + +### Quantitative Comparison: + +| +Transaction Type | +Ethereum Cost (USD) | +Sei Cost (USD) | +Savings | + +| +Simple Transfer | +$1-5 | +$0.01-0.05 | +99%+ | + +| +Token Swap | +$5-30 | +$0.05-0.30 | +99%+ | + +| +NFT Mint | +$10-100 | +$0.10-1.00 | +99%+ | + +| +Complex DeFi | +$20-200 | +$0.20-2.00 | +99%+ | + +_Note: Actual costs vary based on network conditions and token prices_ + +### Example Gas Usage: + +``` +// Ethereum typical gas prices (variable) +const ethGasPrice = ethers.utils.parseUnits("30", "gwei"); // 30 gwei is often considered "average" + +// Sei typical gas prices +const seiGasPrice = ethers.utils.parseUnits("0.5", "gwei"); // Much lower than Ethereum + +// Cost comparison for a simple transfer (21,000 gas) +const ethCost = ethGasPrice.mul(21000); // ~0.00063 ETH +const seiCost = seiGasPrice.mul(21000); // ~0.0000105 SEI + +console.log("ETH cost:", ethers.utils.formatEther(ethCost), "ETH"); +console.log("SEI cost:", ethers.utils.formatEther(seiCost), "SEI"); + +``` + +### Consistency Factors: + +- **Network Congestion**: + +Ethereum fees spike dramatically during high demand + +- Sei's higher capacity means congestion is less frequent + +- Even during peak usage, Sei maintains relatively low fees + +- **Gas Price Stability**: + +Sei gas prices remain more stable over time + +- Less dramatic fee fluctuations than Ethereum + +- **Long-Term Trend**: + +Ethereum's fee dynamics change with scaling solutions (L2s, etc.) + +- Sei's fundamental architecture ensures sustained fee advantages + +For developers and users, Sei's consistently lower fees enable applications that would be economically unfeasible on Ethereum, such as high-frequency trading, micro-transactions, and gas-intensive operations. diff --git a/knowledge-base/compatibility-differences-with-ethereum/can-standard-ethereum-contracts-be-deployed-to.md b/knowledge-base/compatibility-differences-with-ethereum/can-standard-ethereum-contracts-be-deployed-to.md new file mode 100644 index 00000000..36f91c4c --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/can-standard-ethereum-contracts-be-deployed-to.md @@ -0,0 +1,57 @@ +--- +title: 'Can Standard Ethereum Contracts Be Deployed to Sei EVM?' +description: 'Can Standard Ethereum Contracts Be Deployed to Sei EVM?' +--- + +# Can Standard Ethereum Contracts Be Deployed to Sei EVM? + +Yes, in most cases, **standard Solidity smart contracts written for Ethereum can be deployed directly to Sei's EVM environment without requiring code modifications.** + +**High Compatibility:** + +Sei's EVM is designed for high compatibility with the Ethereum Virtual Machine, specifically supporting Ethereum Improvement Proposals (EIPs) up to and including the **Cancun** hard fork level. This ensures that contracts utilizing standard EVM opcodes, interfaces (like ERC20, ERC721, ERC1155), and common development patterns will function as expected on Sei. + +**Easy Migration for dApps:** + +This high compatibility makes migrating existing Ethereum dApps significantly easier: + +- **Smart Contracts:** Your core Solidity contracts likely do not need changes. + +- **Deployment Tooling:** You can use standard Ethereum development tools like Hardhat or Foundry. Simply configure them with Sei's network details (RPC URL, Chain ID) to deploy your contracts to Sei Mainnet or Testnet. + +- **Frontend Integration:** Update your dApp's frontend (e.g., JavaScript using libraries like ethers.js or viem) to point to Sei's RPC endpoint and use the correct Chain ID (`1329` for Mainnet, `1328` for Testnet). + +**Example Hardhat Configuration (`hardhat.config.js`):** + +``` +require("@nomicfoundation/hardhat-toolbox"); +require('dotenv').config(); // To load private key from .env file + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: "0.8.20", // Use your contract's Solidity version + networks: { + sei_mainnet: { + url: process.env.SEI_MAINNET_RPC_URL || "https://evm-rpc.sei-apis.com", + chainId: 1329, + accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + }, + sei_testnet: { + url: process.env.SEI_TESTNET_RPC_URL || "https://evm-rpc-atlantic-2.sei-apis.com", + chainId: 1328, + accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + }, + }, +}; + +``` + +**Key Considerations During Migration:** + +- **Block Time:** Sei's much faster block time (~600ms vs. Ethereum's ~12s) requires adjusting frontend logic that relies on block progression (e.g., reducing polling intervals, updating UI feedback for faster confirmations). + +- **Gas Costs:** While generally lower, specific opcode costs might differ slightly. Test gas usage on Sei Testnet. *(See: [Troubleshooting "Out of Gas" Errors on Sei](https://markdowntohtml.com/link-to-out-of-gas-article))* + +- **Leveraging Sei Features:** While direct migration is possible, consider leveraging Sei's unique features (faster finality, parallelization, custom precompiles) for enhanced performance or functionality post-migration. + +_Overall, Sei offers a familiar EVM environment that streamlines the process of deploying existing Ethereum contracts and migrating dApps to allow developers to benefit from Sei's performance improvements with minimal friction._ diff --git a/knowledge-base/compatibility-differences-with-ethereum/convert-between-sei-native-and-evm-addresses.md b/knowledge-base/compatibility-differences-with-ethereum/convert-between-sei-native-and-evm-addresses.md new file mode 100644 index 00000000..8a52e59e --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/convert-between-sei-native-and-evm-addresses.md @@ -0,0 +1,62 @@ +--- +title: 'How Do I Convert Between Sei Native and EVM Addresses?' +description: 'How Do I Convert Between Sei Native and EVM Addresses?' +--- + +# How Do I Convert Between Sei Native and EVM Addresses? + +### The Problem + +I have a Sei native address (`sei1...`) and need to find its corresponding EVM address (`0x...`), or vice versa, for use in different wallets, explorers, or development tasks. + +### Solution Steps + +- **Use Block Explorer (Easiest for Users):** + +Go to [SeiScan (Native Explorer)](https://www.seiscan.app/pacific-1). + +- Search for your **Native (`sei1...`) address**. + +- The corresponding **EVM (`0x...`) address** is usually displayed on the address details page. *(Vice-versa lookup on EVM explorers like SeiTrace is less consistently available)*. + +- **Use Wallets Supporting Both (e.g., Compass Wallet):** + +Import your seed phrase into a wallet that displays both address types (like Compass). + +- The wallet interface will typically show both the `sei1...` and `0x...` formats for your account. + +- **Use `@sei-js/js` Library (For Developers):** + +Install: `npm install @sei-js/js` + +- Convert Native to EVM: + +``` +const { getEvmAddress } = require('@sei-js/js'); +const evmAddress = getEvmAddress('YOUR_SEI1_ADDRESS'); +console.log(evmAddress); + +``` + +- Convert EVM to Native: + +``` +const { getSeiAddress } = require('@sei-js/js'); +const seiAddress = getSeiAddress('YOUR_0x_ADDRESS'); +console.log(seiAddress); + +``` + +### Explanation and Tips + +- **⚠️ Important:** Converting address formats does **NOT** move funds between the Native and EVM environments. See Why Don't I See My Tokens After Converting My Address? + +- **Consistency:** The conversion is deterministic. A specific `sei1...` address will always map to the same `0x...` address and vice versa, as they derive from the same underlying private key. + +- **Finding Your Own Addresses:** If you only have Keplr (Native) and MetaMask (EVM) set up with the *same seed phrase*, you can use the `@sei-js/js` library or SeiScan with your known `sei1...` address to find your linked `0x...` address for MetaMask. + +### Related Guides + +- Why Don't I See My Tokens After Converting My Address? + +- How to Move Tokens Between Native Sei and EVM diff --git a/knowledge-base/compatibility-differences-with-ethereum/how-do-the-consensus-mechanism-and-finality-in.md b/knowledge-base/compatibility-differences-with-ethereum/how-do-the-consensus-mechanism-and-finality-in.md new file mode 100644 index 00000000..2ce80ef6 --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/how-do-the-consensus-mechanism-and-finality-in.md @@ -0,0 +1,242 @@ +--- +title: 'How do the consensus mechanism and finality in Sei differ from Ethereum?' +description: 'How do the consensus mechanism and finality in Sei differ from Ethereum?' +--- + +# How do the consensus mechanism and finality in Sei differ from Ethereum? + +## Consensus Mechanisms: Different Approaches + +The consensus mechanism is the protocol that determines how agreement is reached on the state of a blockchain. Sei and Ethereum take fundamentally different approaches to consensus, resulting in significant differences in performance and user experience. + +## Ethereum's Consensus Model + +After "The Merge" in September 2022, Ethereum moved to a Proof of Stake (PoS) system: + +- **Proof of Stake (PoS)**: Validators are selected to propose blocks based on their staked ETH + +- **Leader Election**: Slot leaders are chosen pseudo-randomly based on stake + +- **Block Time**: ~12-15 seconds between blocks + +- **Beacon Chain**: Coordinates validator activity and block finalization + +- **Fork Choice Rule**: LMD GHOST (Latest Message Driven Greedy Heaviest Observed SubTree) + +- **Probabilistic Finality**: Transactions become "more final" with each confirmation block + +Ethereum's finality is probabilistic, meaning transactions gain a higher probability of being final as more blocks are added on top of them. Practical finality typically requires 2-3 minutes (multiple block confirmations). + +## Sei's Consensus Model + +Sei uses a Tendermint-based Proof of Stake consensus: + +- **Tendermint BFT**: Byzantine Fault Tolerant consensus algorithm + +- **Instant Finality**: Blocks are final immediately after confirmation + +- **Block Time**: ~400 milliseconds + +- **Two-Phase Commit**: Pre-vote and pre-commit phases before finalization + +- **No Forking**: Blocks are never reorganized once committed + +- **Deterministic Validator Set**: Known validators for each block height + +Tendermint consensus provides instant finality, meaning once a block is confirmed, it can never be reversed or reorganized. This eliminates the need to wait for multiple confirmations. + +## Finality Time Comparison + +| +Network | +Block Time | +Time to First Confirmation | +Practical Finality | + +| +Ethereum | +12-15 seconds | +12-15 seconds | +2-3 minutes (12+ blocks) | + +| +Sei | +~400 milliseconds | +~400 milliseconds | +~400 milliseconds (instant) | + +## Technical Implementation Differences + +### Ethereum: + +- Uses slot-based block production + +- Requires attestations from validators + +- Relies on a "fork choice rule" to resolve competing chains + +- Can experience temporary chain reorganizations ("reorgs") + +- Requires economic assumptions about validator behavior + +### Sei: + +- Uses round-based block production + +- Requires >2/3 validator signatures for finality + +- Never creates competing chains at the same height + +- Cannot experience reorgs after block confirmation + +- Provides stronger consistency guarantees + +## Developer Implications + +The differences in consensus and finality have significant implications for dApp developers: + +### 1. Transaction Confirmation UX + +For Ethereum dApps: + +``` +// Ethereum dApp - wait for multiple confirmations for safety +async function waitForTransaction(txHash) { + // Wait for transaction to be mined + const receipt = await provider.waitForTransaction(txHash); + + // Wait for additional confirmations (typically 2-3 minutes) + await provider.waitForTransaction(txHash, 12); // 12 confirmations + + return receipt; +} + +``` + +For Sei dApps: + +``` +// Sei dApp - single confirmation is sufficient +async function waitForTransaction(txHash) { + // Wait for transaction to be mined (typically ~400ms) + const receipt = await provider.waitForTransaction(txHash); + + // No need to wait for additional confirmations + return receipt; +} + +``` + +### 2. User Interface Design + +The consensus differences affect how you should design your application's user experience: + +**Ethereum UIs typically:** + +- Show "pending" status for transactions + +- Display "confirming" status for 1-12 blocks + +- Recommend waiting for multiple confirmations for high-value transactions + +- Include reorg protection logic + +**Sei UIs can:** + +- Move directly from "pending" to "confirmed" + +- Consider transactions final after a single confirmation + +- Skip intermediate confirmation states + +- Provide more responsive feedback to users + +### 3. Transaction Safety + +In practical terms: + +**On Ethereum:** + +- High-value transactions should wait for multiple confirmations + +- Financial applications typically wait for 12+ confirmations + +- Applications must handle potential chain reorganizations + +- Frontends should implement optimistic UI with fallbacks + +**On Sei:** + +- Single confirmation provides complete finality + +- No need to wait for additional confirmations + +- No possibility of reorganization after confirmation + +- Frontends can treat confirmed transactions as permanently settled + +## Example: Transaction Monitoring Service + +How the consensus differences affect a transaction monitoring service: + +``` +// Ethereum implementation +class EthereumTransactionMonitor { + constructor(provider) { + this.provider = provider; + this.confirmedTxs = new Map(); // txHash -> confirmations + } + + async monitorTransaction(txHash) { + // Initial receipt + const receipt = await this.provider.waitForTransaction(txHash); + + // Consider "soft confirmed" but keep monitoring + this.confirmedTxs.set(txHash, 1); + this.emit('soft_confirmed', txHash); + + // Monitor for 12+ blocks to ensure finality + const blockNumber = receipt.blockNumber; + const subscription = this.provider.on('block', async (newBlockNumber) => { + const confirmations = newBlockNumber - blockNumber; + this.confirmedTxs.set(txHash, confirmations); + + if (confirmations >= 12) { + // Now consider fully confirmed + this.emit('confirmed', txHash); + this.provider.removeListener('block', subscription); + } + + // Check for chain reorganizations + const currentReceipt = await this.provider.getTransactionReceipt(txHash); + if (!currentReceipt || currentReceipt.blockHash !== receipt.blockHash) { + // Handle reorg! + this.emit('reorg', txHash); + // Restart monitoring + this.monitorTransaction(txHash); + } + }); + } +} + +// Sei implementation - much simpler! +class SeiTransactionMonitor { + constructor(provider) { + this.provider = provider; + } + + async monitorTransaction(txHash) { + // Wait for receipt + const receipt = await this.provider.waitForTransaction(txHash); + + // Transaction is final, no further monitoring needed + this.emit('confirmed', txHash); + + // No need to check for reorgs - impossible after confirmation + return receipt; + } +} + +``` + +These consensus differences allow Sei dApps to provide more responsive user experiences and simpler backend implementations, while maintaining the compatibility and familiarity of the EVM environment. For developers, this means applications with both the programmability of Ethereum and the rapid finality of high-performance blockchains. diff --git a/knowledge-base/compatibility-differences-with-ethereum/migrate-an-ethereum-dapp-to-sei-network.md b/knowledge-base/compatibility-differences-with-ethereum/migrate-an-ethereum-dapp-to-sei-network.md new file mode 100644 index 00000000..415d3dbf --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/migrate-an-ethereum-dapp-to-sei-network.md @@ -0,0 +1,239 @@ +--- +title: 'How to Migrate an Ethereum dApp to Sei Network' +description: 'How to Migrate an Ethereum dApp to Sei Network' +--- + +# How to Migrate an Ethereum dApp to Sei Network + +Sei's EVM environment provides strong compatibility with Ethereum, making migration relatively straightforward. This guide covers the key steps to port your dApp with minimal code changes. + +#### **Step 1: Update Network Configuration** + +First, add Sei Network to your development environment: + +**Hardhat Example:** + +``` +// hardhat.config.js +module.exports = { + networks: { + // ... existing networks + sei_testnet: { + url: "https://evm-rpc-atlantic-2.sei-apis.com", + chainId: 713715, + accounts: [process.env.PRIVATE_KEY] + }, + sei_mainnet: { + url: "https://evm-rpc.sei-apis.com", + chainId: 1329, + accounts: [process.env.PRIVATE_KEY] + } + }, + // ... rest of your config +}; + +``` + +**Truffle Example:** + +``` +// truffle-config.js +module.exports = { + networks: { + // ... existing networks + sei_testnet: { + provider: () => new HDWalletProvider(process.env.MNEMONIC, "https://evm-rpc-atlantic-2.sei-apis.com"), + network_id: 713715, + confirmations: 2, + timeoutBlocks: 200, + skipDryRun: true + }, + sei_mainnet: { + provider: () => new HDWalletProvider(process.env.MNEMONIC, "https://evm-rpc.sei-apis.com"), + network_id: 1329, + confirmations: 2, + timeoutBlocks: 200, + skipDryRun: true + } + } +}; + +``` + +**Foundry Example:** + +``` +# foundry.toml +[profile.default] +src = "src" +out = "out" + +[rpc_endpoints] +sei_testnet = "https://evm-rpc-atlantic-2.sei-apis.com" +sei_mainnet = "https://evm-rpc.sei-apis.com" + +``` + +#### **Step 2: Deploy Contracts to Sei** + +Deploy your contracts to Sei Testnet first to verify everything works: + +**Hardhat:** + +``` +npx hardhat run --network sei_testnet scripts/deploy.js + +``` + +**Truffle:** + +``` +truffle migrate --network sei_testnet + +``` + +**Foundry:** + +``` +forge create --rpc-url sei_testnet --private-key $PRIVATE_KEY src/MyContract.sol:MyContract + +``` + +#### **Step 3: Update Frontend Configuration** + +Update your frontend to connect to Sei Network: + +**ethers.js Example:** + +``` +// Add Sei network configuration +const networks = { + sei: { + chainId: "0x531", // 1329 in hex + chainName: "Sei Network", + nativeCurrency: { + name: "SEI", + symbol: "SEI", + decimals: 18 + }, + rpcUrls: ["https://evm-rpc.sei-apis.com"], + blockExplorerUrls: ["https://seitrace.com"] + } +}; + +// Add network switch function +async function switchToSei() { + try { + // Try to switch to Sei + await window.ethereum.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: networks.sei.chainId }], + }); + } catch (switchError) { + // If the network isn't added yet, add it + if (switchError.code === 4902) { + try { + await window.ethereum.request({ + method: 'wallet_addEthereumChain', + params: [networks.sei], + }); + } catch (addError) { + console.error('Failed to add Sei network:', addError); + } + } else { + console.error('Failed to switch to Sei network:', switchError); + } + } +} + +``` + +**web3.js Example:** + +``` +// Initialize provider +const web3 = new Web3("https://evm-rpc.sei-apis.com"); + +// Check if connected to Sei +async function checkNetwork() { + const chainId = await web3.eth.getChainId(); + if (chainId !== 1329) { + alert("Please switch to Sei Network in your wallet"); + } +} + +``` + +#### **Step 4: Adjust for Sei-Specific Features** + +While most Ethereum code works as-is, consider these adjustments: + +- **Block Time**: Sei has ~600ms blocks vs Ethereum's ~12s + +Reduce polling intervals (500ms recommended) + +- Adjust block-based timing mechanisms + +- **Gas Parameters**: + +Gas estimation may differ slightly + +- Include slightly higher gas limits initially + +- **Parallel Execution**: + +No code changes needed, but see [optimization guide](https://markdowntohtml.com/03-evm-development-best-practices.md) + +#### **Step 5: Test Thoroughly on Testnet** + +- Test all features on Sei Testnet (Atlantic-2) + +- Pay special attention to: + +Time-sensitive operations + +- Gas-intensive functions + +- External contract interactions + +#### Advanced Considerations + +- **Block Explorer Verification**: + +Use [SeiTrace](https://seitrace.com/) to verify contracts + +- Ensure compiler version and settings match deployment exactly + +- **Oracle Integration**: + +If your dApp uses Chainlink or other oracles, verify they have Sei Network support + +- **Interoperability**: + +Consider leveraging Sei's native chain for additional functionality + +### Common Migration Issues + +#### "Out of Gas" Errors + +- Some operations may have different gas costs on Sei + +- Solution: Increase gas limits, especially for contract deployment + +- See: [Fixing "Out of Gas" Errors](https://markdowntohtml.com/Transactions/05-out-of-gas-errors.md) + +#### Timing Differences + +- Time-dependent logic might behave differently with 600ms blocks + +- Solution: Use timestamps instead of block numbers for timing + +- Example: `require(block.timestamp > deadline)` instead of `require(block.number > deadlineBlock)` + +#### RPC Connection Issues + +- Some public RPC endpoints might have rate limits + +- Solution: Use alternative RPC endpoints or run your own node + +- See: [Public RPC Endpoints](https://markdowntohtml.com/04-public-rpc-endpoints.md) diff --git a/knowledge-base/compatibility-differences-with-ethereum/sei-fully-compatible-with-ethereum-smart-contract.md b/knowledge-base/compatibility-differences-with-ethereum/sei-fully-compatible-with-ethereum-smart-contract.md new file mode 100644 index 00000000..e16303b5 --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/sei-fully-compatible-with-ethereum-smart-contract.md @@ -0,0 +1,143 @@ +--- +title: 'Is Sei fully compatible with Ethereum smart contract standards such as ERC-20, ERC-721, ERC-1155?' +description: 'Is Sei fully compatible with Ethereum smart contract standards such as ERC-20, ERC-721, ERC-1155?' +--- + +# Is Sei fully compatible with Ethereum smart contract standards such as ERC-20, ERC-721, ERC-1155? + +Yes, Sei Network is fully compatible with standard Ethereum smart contract standards including ERC-20, ERC-721, and ERC-1155. Sei's EVM environment implements the Ethereum Virtual Machine specification up through the Cancun upgrade, ensuring that token standards work exactly as they do on Ethereum. + +### ERC-20 Compatibility + +Standard ERC-20 tokens deploy and function identically to Ethereum: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract MyToken is ERC20 { + constructor(uint256 initialSupply) ERC20("My Token", "MTK") { + _mint(msg.sender, initialSupply); + } +} + +``` + +You can use familiar tools like OpenZeppelin contracts without modification. All standard ERC-20 functions like `transfer`, `balanceOf`, `approve`, and `transferFrom` work as expected. + +### ERC-721 (NFTs) Compatibility + +Sei fully supports non-fungible token standards: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; + +contract MyNFT is ERC721URIStorage { + uint256 private _tokenIds; + + constructor() ERC721("My NFT Collection", "MYNFT") {} + + function mintNFT(address recipient, string memory tokenURI) + public + returns (uint256) + { + uint256 newItemId = _tokenIds++; + _mint(recipient, newItemId); + _setTokenURI(newItemId, tokenURI); + return newItemId; + } +} + +``` + +NFT marketplaces, collections, and other NFT infrastructure built for Ethereum can be deployed to Sei with minimal changes. + +### ERC-1155 (Multi-Token) Compatibility + +Multi-token standard is also fully supported: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; + +contract MyMultiToken is ERC1155 { + constructor() ERC1155("https://myapi.com/token/{id}.json") {} + + function mint(address account, uint256 id, uint256 amount, bytes memory data) + public + { + _mint(account, id, amount, data); + } + + function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) + public + { + _mintBatch(to, ids, amounts, data); + } +} + +``` + +### Marketplace and Infrastructure Support + +Common infrastructure also works without modification: + +``` +// Example of standard marketplace contract +interface IERC721 { + function transferFrom(address from, address to, uint256 tokenId) external; +} + +contract SimplifiedMarketplace { + struct Listing { + address seller; + uint256 price; + } + + mapping(address => mapping(uint256 => Listing)) public listings; + + function listItem(address nftContract, uint256 tokenId, uint256 price) external { + IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId); + listings[nftContract][tokenId] = Listing(msg.sender, price); + } + + function buyItem(address nftContract, uint256 tokenId) external payable { + Listing memory listing = listings[nftContract][tokenId]; + require(listing.price > 0, "Not for sale"); + require(msg.value >= listing.price, "Insufficient payment"); + + delete listings[nftContract][tokenId]; + IERC721(nftContract).transferFrom(address(this), msg.sender, tokenId); + payable(listing.seller).transfer(listing.price); + } +} + +``` + +### Testing Compatibility + +While standards are compatible, testing on Sei's testnet is always recommended: + +``` +# Configure Hardhat for Sei testnet +# In hardhat.config.js +module.exports = { + networks: { + seiTestnet: { + url: "https://evm-rpc.testnet.sei.io", + chainId: 1328, + accounts: [process.env.PRIVATE_KEY] + } + } +} + +# Deploy and test standard contracts +npx hardhat run scripts/deploy.js --network seiTestnet +``` diff --git a/knowledge-base/compatibility-differences-with-ethereum/sei-implement-eip-1559-fee-burning-or-is-its-gas.md b/knowledge-base/compatibility-differences-with-ethereum/sei-implement-eip-1559-fee-burning-or-is-its-gas.md new file mode 100644 index 00000000..7dee7649 --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/sei-implement-eip-1559-fee-burning-or-is-its-gas.md @@ -0,0 +1,95 @@ +--- +title: 'Does Sei implement EIP-1559 fee burning, or is its gas model different?' +description: 'Does Sei implement EIP-1559 fee burning, or is its gas model different?' +--- + +# Does Sei implement EIP-1559 fee burning, or is its gas model different? + +Sei does not implement Ethereum's EIP-1559 fee burning mechanism. Instead, it uses a modified fee model that combines aspects of Ethereum's gas system with Cosmos SDK fee structures: + +### Sei's Gas Model: + +- **Base Fee Structure**: + +Uses a standard gas price model similar to pre-EIP-1559 Ethereum + +- No automatic base fee adjustment or fee burning mechanism + +- Gas prices tend to be more stable than on Ethereum + +- **Fee Distribution**: + +Transaction fees go to validators rather than being burned + +- This aligns with Cosmos SDK's approach where validators receive fees for processing transactions + +- **Gas Pricing**: + +Gas prices are typically much lower than Ethereum + +- Gas units measure computational resources similar to Ethereum + +- Fees are paid in SEI tokens + +- **Example Transaction**: + +``` +// Standard EVM transaction on Sei +const tx = await signer.sendTransaction({ + to: recipient, + value: ethers.utils.parseEther("1.0"), + gasPrice: ethers.utils.parseUnits("0.5", "gwei"), // Much lower than ETH + gasLimit: 21000 +}); + +``` + +### Comparison with EIP-1559: + +| +Feature | +Ethereum (EIP-1559) | +Sei Network | + +| +Base Fee | +Dynamic, adjusted each block | +Static or gradually adjusted | + +| +Fee Burning | +Burns base fee portion | +No fee burning | + +| +Priority Fee | +Tip to validators | +Entire fee to validators | + +| +Fee Volatility | +Can change rapidly | +More stable | + +| +Block Space Auction | +Less competitive | +Standard gas price auction | + +### Implications: + +- **Tokenomics**: Without fee burning, SEI doesn't have the deflationary mechanism that ETH has + +- **User Experience**: Generally more predictable fees on Sei + +- **Fee Market**: Less competition for block space due to Sei's higher throughput + +- **Value Accrual**: Fees accrue to validators rather than reducing token supply + +For developers, this means: + +- Gas price estimation is simpler than on Ethereum + +- Fee spikes during network congestion are less severe + +- Gas strategies can be less complex than on Ethereum diff --git a/knowledge-base/compatibility-differences-with-ethereum/seis-execution-model-differ-from-ethereum.md b/knowledge-base/compatibility-differences-with-ethereum/seis-execution-model-differ-from-ethereum.md new file mode 100644 index 00000000..04766f2a --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/seis-execution-model-differ-from-ethereum.md @@ -0,0 +1,174 @@ +--- +title: "How does Sei's execution model differ from Ethereum?" +description: "How does Sei's execution model differ from Ethereum?" +--- + +# How does Sei's execution model differ from Ethereum? + +## Understanding Execution Models + +The execution model defines how a blockchain processes transactions. This is one of the most fundamental differences between Sei and Ethereum. + +## Ethereum's Sequential Execution + +Ethereum employs a strictly sequential transaction execution model: + +- **Single-Threaded Processing**: Only one transaction executes at a time + +- **Sequential Block Processing**: Transactions within a block run in strict order + +- **Global State Access**: Each transaction has access to the entire blockchain state + +- **Single CPU Utilization**: Regardless of the hardware's capabilities, only one CPU core handles execution + +- **Deterministic Ordering**: Transaction order is determined by gas price and nonce + +This approach ensures simplicity and determinism but creates a throughput bottleneck that limits Ethereum to approximately 15-30 transactions per second. + +## Sei's Parallel Execution with OCC + +Sei implements Optimistic Concurrency Control (OCC) to enable parallel transaction execution: + +- **Multi-Threaded Processing**: Multiple transactions execute simultaneously + +- **State Access Analysis**: The system automatically identifies which transactions can run in parallel + +- **Conflict Detection**: Transactions touching the same state are identified + +- **Optimistic Execution**: Transactions execute in parallel assuming no conflicts + +- **Conflict Resolution**: If conflicts occur, affected transactions are re-executed sequentially + +This approach significantly increases throughput while maintaining deterministic outcomes identical to sequential processing. + +## How Sei's OCC + +Sei's parallel execution follows several structured phases: + +### 1. Transaction Analysis + +Before execution, Sei: + +- Maps each transaction to its potential state accesses + +- Identifies read/write operations on contract storage + +- Detects account balance modifications + +- Groups non-conflicting transactions for parallel execution + +### 2. Optimistic Parallel Execution + +During execution: + +- Multiple CPU cores process transaction groups simultaneously + +- Each transaction maintains its own "read set" and "write set" + +- Temporary state changes are created but not immediately committed + +- Resource usage is distributed across hardware cores + +### 3. Conflict Detection + +After initial execution: + +- The system detects any state access conflicts between transactions + +- Three types of conflicts are possible: + +**Read-After-Write (RAW)**: Transaction B reads data modified by Transaction A + +- **Write-After-Read (WAR)**: Transaction B modifies data read by Transaction A + +- **Write-After-Write (WAW)**: Multiple transactions modify the same data + +### 4. Conflict Resolution + +If conflicts are detected: + +- Conflicting transactions are grouped together + +- Their temporary state changes are discarded + +- They are re-executed in sequential order + +- The final state is equivalent to what would have occurred under sequential execution + +## Performance Comparison + +The execution model difference creates substantial performance gaps: + +| +Metric | +Ethereum | +Sei | + +| +Transaction throughput | +15-30 TPS | +Thousands of TPS | + +| +CPU utilization | +Single core | +Multiple cores | + +| +Processing efficiency | +Limited by single thread | +Scales with hardware | + +| +Re-org possibility | +Yes (probabilistic finality) | +No (instant finality) | + +## Developer Implications + +For developers, Sei's parallel execution offers substantial benefits: + +- **Higher Performance**: Applications can handle much larger user bases + +- **Lower Gas Costs**: Less competition for block space means lower fees + +- **Faster User Experience**: Transactions confirm in milliseconds instead of seconds/minutes + +- **No Code Changes Required**: Standard Solidity contracts work without modification + +However, for optimal performance, developers should consider: + +``` +// Optimized contract pattern for Sei's parallel execution +contract ParallelOptimized { + // Avoid global counters that create contention points + // Instead use sharded data structures + mapping(address => uint256) public userValues; + + function increment() external { + // Each user updates their own shard, allowing parallel execution + userValues[msg.sender]++; + } + + // Only aggregate when needed + function getTotal(address[] calldata users) external view returns (uint256) { + uint256 total = 0; + for (uint i = 0; i return total; + } +} + +``` + +## SeiDB: The Storage Layer for Parallel Access + +Sei's custom storage layer (SeiDB) provides critical features that enable its parallel execution: + +- **Multi-Version Concurrency Control (MVCC)**: Maintains multiple versions of state + +- **Snapshot Isolation**: Ensures each transaction sees a consistent state view + +- **Lock-Free Operations**: Prevents thread blocking during concurrent access + +- **Efficient Rollback**: Allows rapid discarding of conflicting states + +For developers, Sei's execution model means better performance without requiring code changes, though optimized contract design can further enhance performance by reducing state contention. diff --git a/knowledge-base/compatibility-differences-with-ethereum/seis-gas-model-and-fee-structure-differ-from.md b/knowledge-base/compatibility-differences-with-ethereum/seis-gas-model-and-fee-structure-differ-from.md new file mode 100644 index 00000000..e54c44e8 --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/seis-gas-model-and-fee-structure-differ-from.md @@ -0,0 +1,309 @@ +--- +title: "How does Sei's gas model and fee structure differ from Ethereum?" +description: "How does Sei's gas model and fee structure differ from Ethereum?" +--- + +# How does Sei's gas model and fee structure differ from Ethereum? + +## Understanding Gas Models + +Gas is the unit of computational work in EVM blockchains. Both Sei and Ethereum use a gas-based pricing model, but with significant differences in implementation and economics. + +## Ethereum's Gas Model (Post-EIP-1559) + +Ethereum uses a complex dynamic fee market with a two-part fee structure: + +- **Base Fee**: Algorithmically determined, burned upon transaction execution + +- **Priority Fee** (Tip): Optional fee paid to validators for transaction prioritization + +- **Gas Limit**: Maximum computational work a transaction can perform + +- **Gas Units**: Measured in "gas" with different costs for various operations + +- **Gas Price**: Denominated in gwei (10^-9 ETH) + +The total transaction fee is calculated as: + +``` +Transaction Fee = Gas Used × (Base Fee + Priority Fee) + +``` + +Ethereum's base fee fluctuates based on network congestion, automatically adjusting up or down by up to 12.5% per block to target 50% full blocks. + +## Sei's Gas Model + +Sei employs a simpler and more predictable fee structure: + +- **Simplified Fee Model**: More stable gas prices without the complex EIP-1559 mechanics + +- **Gas Units**: Same concept as Ethereum, with potentially different costs per operation + +- **Gas Price**: Denominated in usei (10^-6 SEI) + +- **Gas Limit**: Maximum computational work a transaction can perform + +- **Parallel Execution**: Gas efficiency benefits from multi-threaded processing + +The fee calculation in Sei follows: + +``` +Transaction Fee = Gas Used × Gas Price + +``` + +Sei's gas prices typically remain more stable due to higher throughput capacity and less congestion. + +## Key Differences in Gas Units and Costs + +| +Operation | +Ethereum (gas) | +Sei (gas) | +Notes | + +| +Standard Transfer | +21,000 | +21,000 | +Same base cost | + +| +Contract Creation | +32,000+ | +32,000+ | +Similar base cost | + +| +SSTORE (cold) | +20,000 | +20,000 | +Similar storage costs | + +| +SLOAD (cold) | +2,100 | +2,100 | +Similar read costs | + +| +Precompile Calls | +Varies | +Varies | +Sei has additional precompiles | + +| +CALL | +2,600+ | +2,600+ | +Similar core operations | + +While the gas units are often similar, the actual ETH/SEI cost is typically lower on Sei due to: + +- Higher throughput reducing competition for block space + +- More stable gas prices + +- Gas efficiency from parallel execution + +## Fee Market Dynamics + +### Ethereum: + +- **High Volatility**: Gas prices can spike dramatically during peak usage + +- **Fee Burning**: ~70% of gas fees (base fee) are burned, reducing ETH supply + +- **MEV Competition**: Validators compete for profitable transaction ordering + +- **Congestion-Based Pricing**: Fees directly tied to network congestion + +### Sei: + +- **Lower Volatility**: More stable gas prices due to higher throughput + +- **No Fee Burning**: Fees go to validators as rewards + +- **Reduced MEV Impact**: Less profitable MEV due to faster blocks + +- **Capacity-Oriented**: Higher throughput means less competition for block space + +## Transaction Cost Comparison (Approximate) + +| +Transaction Type | +Ethereum Cost (USD)_ | +Sei Cost (USD)_ | +Ratio | + +| +Simple Transfer | +$0.50 - $5.00 | +$0.001 - $0.01 | +50-500x cheaper | + +| +Token Transfer | +$1.00 - $10.00 | +$0.002 - $0.02 | +50-500x cheaper | + +| +Basic Swap | +$5.00 - $50.00 | +$0.01 - $0.10 | +50-500x cheaper | + +| +NFT Mint | +$5.00 - $100.00 | +$0.01 - $0.20 | +50-500x cheaper | + +| +Complex Contract | +$10.00 - $200.00 | +$0.02 - $0.40 | +50-500x cheaper | + +\*Costs vary based on network conditions and token prices. Table shows typical ranges during moderate congestion. + +## Gas Estimation Considerations + +Ethereum and Sei both offer gas estimation, but with different characteristics: + +### Ethereum: + +``` +// Ethereum gas estimation with buffer +async function sendEthereumTransaction(contract, method, args) { + // Estimate gas + const estimatedGas = await contract.estimateGas[method](...args); + + // Add 20% buffer for safety + const gasLimit = Math.floor(estimatedGas.toNumber() * 1.2); + + // Send transaction + return contract[method](...args, { + gasLimit, + maxFeePerGas: ethers.utils.parseUnits('20', 'gwei'), + maxPriorityFeePerGas: ethers.utils.parseUnits('2', 'gwei') + }); +} + +``` + +### Sei: + +``` +// Sei gas estimation with larger buffer due to parallel execution +async function sendSeiTransaction(contract, method, args) { + // Estimate gas + const estimatedGas = await contract.estimateGas[method](...args); + + // Add 30% buffer for safety (accounting for parallel execution variability) + const gasLimit = Math.floor(estimatedGas.toNumber() * 1.3); + + // Send transaction with simple gas price + return contract[method](...args, { + gasLimit, + gasPrice: ethers.utils.parseUnits('0.1', 'gwei') // Much lower than Ethereum + }); +} + +``` + +Sei's gas estimation may sometimes be less precise due to the parallel execution model, so a slightly larger buffer is recommended. + +## Practical Impact for Developers + +The gas model differences have several implications for developers: + +### 1. Contract Optimization Priorities + +**Ethereum:** + +- Extreme focus on gas optimization + +- Complex techniques to reduce storage operations + +- Batching operations to amortize costs + +- Gas golf for minor optimizations + +**Sei:** + +- Less pressure for extreme gas optimization + +- Focus on reducing state contention for parallel execution + +- Simpler, more readable contracts can be economical + +- Gas optimization still beneficial but with different priorities + +### 2. Frontend Transaction Management + +**Ethereum:** + +``` +// Ethereum frontend transaction handling with fee estimates +async function createEthereumTransaction(provider, to, value) { + // Get fee data from network + const feeData = await provider.getFeeData(); + + // Prepare transaction with dynamic fees + return { + to, + value, + maxFeePerGas: feeData.maxFeePerGas, + maxPriorityFeePerGas: feeData.maxPriorityFeePerGas, + gasLimit: 21000 + }; +} + +``` + +**Sei:** + +``` +// Sei frontend transaction handling +async function createSeiTransaction(provider, to, value) { + // Simpler fee handling + return { + to, + value, + gasPrice: ethers.utils.parseUnits('0.1', 'gwei'), + gasLimit: 21000 + }; +} + +``` + +### 3. User Experience Considerations + +The fee differences affect how you design your application's UX: + +**For Ethereum dApps:** + +- Include prominent fee warnings and estimates + +- Build complex fee selection interfaces + +- Implement transaction timing mechanisms (speed up, cancel) + +- Educate users about gas price dynamics + +**For Sei dApps:** + +- Simplify fee UX with less focus on fee settings + +- Emphasize speed and reliability over fee optimization + +- Reduce or eliminate fee education requirements + +- Enable more frequent microtransactions + +_For developers, this means applications can use more frequent transactions, complex operations, and richer on-chain data without prohibitive costs. Users benefit from lower fees and more responsive applications._ + +_While the fundamental gas concept remains similar, Sei's implementation creates a more accessible and economical environment for EVM applications, removing one of the major barriers to blockchain adoption._ diff --git a/knowledge-base/compatibility-differences-with-ethereum/the-opcode-compatibility-differences-between-sei.md b/knowledge-base/compatibility-differences-with-ethereum/the-opcode-compatibility-differences-between-sei.md new file mode 100644 index 00000000..bd95ade2 --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/the-opcode-compatibility-differences-between-sei.md @@ -0,0 +1,388 @@ +--- +title: 'What are the opcode compatibility differences between Sei and Ethereum?' +description: 'What are the opcode compatibility differences between Sei and Ethereum?' +--- + +# What are the opcode compatibility differences between Sei and Ethereum? + +## Understanding EVM Opcode Compatibility + +The Ethereum Virtual Machine (EVM) uses opcodes as the foundational instruction set for smart contract execution. While Sei maintains high compatibility with Ethereum's opcodes, some differences exist that developers should understand. + +## Sei's EVM Opcode Support + +Sei's EVM implementation supports opcodes up to the Cancun hard fork, including: + +- Core computational opcodes + +- Stack manipulation + +- Memory operations + +- Storage operations + +- Control flow + +- Standard precompiles + +This compatibility allows most Ethereum contracts to run without modification on Sei. + +## Key Opcode Differences + +While most opcodes behave identically, some important differences exist: + +| +Opcode | +Ethereum Behavior | +Sei Behavior | +Migration Notes | + +| +SELFDESTRUCT | +Deprecated but functional | +Fully deprecated | +Need alternative approach | + +| +BLOCKHASH | +Access to 256 previous blocks | +Limited historical block access | +Use storage if needing more history | + +| +DIFFICULTY/PREVRANDAO | +Returns randomness from beacon chain | +Returns Tendermint consensus-based value | +Not suitable for randomness | + +| +CREATE2 | +Standard behavior | +Fully compatible but may have different gas costs | +Test thoroughly | + +| +EXTCODEHASH | +Standard behavior | +May have different gas cost | +Test thoroughly | + +| +TIMESTAMP | +~12s granularity | +~400ms granularity | +Time-sensitive logic may need adjustment | + +| +GAS | +Returns gas left | +Same behavior but different pricing model | +Gas estimation may differ | + +## SELFDESTRUCT Handling + +The `SELFDESTRUCT` opcode is fully deprecated in Sei. Contracts using it will need modifications: + +### Ethereum Pattern Using SELFDESTRUCT: + +``` +// Ethereum contract with SELFDESTRUCT +contract SelfdestructExample { + address payable owner; + + constructor() { + owner = payable(msg.sender); + } + + function close() external { + require(msg.sender == owner, "Not owner"); + selfdestruct(owner); // PROBLEMATIC ON SEI + } +} + +``` + +### Sei Compatible Alternative: + +``` +// Sei-compatible alternative +contract NoSelfdestructExample { + address payable owner; + bool public isActive = true; + + constructor() { + owner = payable(msg.sender); + } + + function close() external { + require(msg.sender == owner, "Not owner"); + require(isActive, "Already closed"); + + // Transfer all ETH balance + uint balance = address(this).balance; + if (balance > 0) { + owner.transfer(balance); + } + + // Mark contract as closed + isActive = false; + } + + // Add guard to all functions + modifier onlyActive() { + require(isActive, "Contract is closed"); + _; + } + + // Apply guard to all other functions + function exampleFunction() external onlyActive { + // Function logic here + } +} + +``` + +## BLOCKHASH Limitations + +The `BLOCKHASH` opcode may have limited historical access on Sei: + +### Ethereum Pattern: + +``` +// Ethereum contract accessing historical blocks +contract BlockHashExample { + function getOldBlockHash(uint256 blockNumber) external view returns (bytes32) { + require(block.number - blockNumber 256, "Too old"); + return blockhash(blockNumber); // Access to 256 previous blocks + } +} + +``` + +### Sei Compatible Alternative: + +``` +// Sei-compatible block hash storage +contract BlockHashStorageExample { + mapping(uint256 => bytes32) public storedHashes; + + // Store current block hash + function storeCurrentBlockHash() external { + storedHashes[block.number] = blockhash(block.number); + } + + // Retrieve stored hash or current hash if available + function getBlockHash(uint256 blockNumber) external view returns (bytes32) { + if (storedHashes[blockNumber] != bytes32(0)) { + return storedHashes[blockNumber]; + } + + // Only try blockhash if it's recent + if (block.number - blockNumber 10) { // Conservative limit + return blockhash(blockNumber); + } + + revert("Block hash not available"); + } +} + +``` + +## DIFFICULTY/PREVRANDAO Considerations + +The `DIFFICULTY`/`PREVRANDAO` opcode returns different values in Sei due to consensus differences: + +### Ethereum Pattern: + +``` +// Ethereum contract using PREVRANDAO for randomness +contract RandomnessExample { + function getPseudoRandom(address user, uint256 nonce) external view returns (uint256) { + return uint256(keccak256(abi.encodePacked( + block.prevrandao, // Different on Sei! + user, + nonce + ))); + } +} + +``` + +### Sei Compatible Alternative: + +``` +// Sei-compatible randomness approach +contract BetterRandomnessExample { + function getPseudoRandom(address user, uint256 nonce) external view returns (uint256) { + return uint256(keccak256(abi.encodePacked( + blockhash(block.number - 1), // Use block hash instead + block.timestamp, // More frequent updates on Sei + user, + nonce + ))); + } + + // For anything requiring true randomness, use an oracle + // Example with Chainlink VRF would be shown here +} + +``` + +## Gas-Related Opcodes + +Gas-related opcodes (`GAS`, `GASPRICE`) work the same way but may return different values due to Sei's different gas model: + +``` +// Function with gas-related operations +function checkGas() external view returns (uint256 gasLeft, uint256 gasPrice) { + gasLeft = gasleft(); // Works the same way but may differ in value + gasPrice = tx.gasprice; // Will be much lower on Sei +} + +``` + +## Timestamp Considerations + +Sei's faster block time (~400ms vs ~12s) means timestamp-based logic may need adjustments: + +``` +// Ethereum timing logic +function isDelayOver(uint256 startTime, uint256 delay) external view returns (bool) { + // On Ethereum, typical minimum practical delay might be 15-30 seconds + // On Sei, practical minimum could be under 1 second + return block.timestamp >= startTime + delay; +} + +``` + +## Testing for Opcode Compatibility + +To ensure your contracts work properly on Sei, follow these testing steps: + +### 1. Use Sei Testnet + +Deploy and test your contracts on Sei testnet (Chain ID 1328) to verify compatibility: + +``` +// hardhat.config.js +module.exports = { + networks: { + sei_testnet: { + url: "https://evm-rpc.testnet.sei.io", + chainId: 1328, + accounts: [process.env.PRIVATE_KEY] + } + } +}; + +``` + +### 2. Test Contract Bytecode + +For critical contracts, you can analyze the compiled bytecode to check for problematic opcodes: + +``` +// Script to check contract bytecode for incompatible opcodes +const { ethers } = require("ethers"); + +async function checkContractCompatibility(contractAddress, provider) { + // Get contract bytecode + const bytecode = await provider.getCode(contractAddress); + + // Check for selfdestruct opcode (0xff) + if (bytecode.includes("ff")) { + console.warn("Warning: Contract may contain SELFDESTRUCT opcode"); + } + + // Add other opcode checks as needed + + return bytecode; +} + +``` + +### 3. Gas Cost Testing + +Test gas costs on both Ethereum and Sei to understand any differences: + +``` +// Gas usage comparison test +async function compareGasUsage(contract, method, args) { + // Test on Ethereum + const ethEstimate = await ethProvider.estimateGas({ + to: contract.address, + data: contract.interface.encodeFunctionData(method, args) + }); + + // Test on Sei + const seiEstimate = await seiProvider.estimateGas({ + to: contract.address, + data: contract.interface.encodeFunctionData(method, args) + }); + + console.log(`Ethereum gas estimate: ${ethEstimate.toString()}`); + console.log(`Sei gas estimate: ${seiEstimate.toString()}`); + console.log(`Difference: ${ethEstimate.sub(seiEstimate).toString()}`); +} + +``` + +## Handling Precompiles + +Sei includes all standard Ethereum precompiles with identical addresses and behavior: + +| +Address | +Precompile | +Status on Sei | + +| +0x01 | +ecrecover | +Fully compatible | + +| +0x02 | +sha256 | +Fully compatible | + +| +0x03 | +ripemd160 | +Fully compatible | + +| +0x04 | +identity | +Fully compatible | + +| +0x05 | +modexp | +Fully compatible | + +| +0x06 | +ecAdd | +Fully compatible | + +| +0x07 | +ecMul | +Fully compatible | + +| +0x08 | +ecPairing | +Fully compatible | + +| +0x09 | +blake2f | +Fully compatible | + +Plus Sei's additional precompiles at addresses starting from `0x1001` to extend functionality. + +_For most contracts, no changes are needed to run on Sei. For those using the specific opcodes detailed above, modifications are straightforward. By testing thoroughly on Sei testnet, developers can ensure their contracts function correctly with Sei's EVM implementation._ + +_The high compatibility level means that the vast majority of Ethereum tooling, libraries, and smart contract patterns will work seamlessly on Sei, enabling developers to leverage existing code while benefiting from Sei's performance advantages._ diff --git a/knowledge-base/compatibility-differences-with-ethereum/the-sei-evm-environment.md b/knowledge-base/compatibility-differences-with-ethereum/the-sei-evm-environment.md new file mode 100644 index 00000000..13e4718f --- /dev/null +++ b/knowledge-base/compatibility-differences-with-ethereum/the-sei-evm-environment.md @@ -0,0 +1,30 @@ +--- +title: 'What is the Sei EVM Environment?' +description: 'What is the Sei EVM Environment?' +--- + +# What is the Sei EVM Environment? + +Sei Network provides a high-performance blockchain environment optimized for speed and throughput, making it particularly suitable for demanding applications like trading platforms and games. Within Sei, the **EVM (Ethereum Virtual Machine) environment** allows developers to deploy and run smart contracts written in languages like Solidity, using familiar Ethereum tools and standards. + +Think of the Sei EVM environment as a highly specialized execution layer for Ethereum-compatible smart contracts. + +**Key Differentiators (Compared to other EVM environments):** + +- **Optimized Performance:** + +**Fast Block Times:** Sei achieves significantly faster block finality compared to standard Ethereum, resulting in quicker transaction confirmations for users. + +- **Parallel Execution:** This is a core innovation. Sei's EVM can process multiple non-conflicting transactions *simultaneously* within a block. If two transactions don't attempt to modify the same contract state, they can run in parallel, drastically increasing the network's overall transaction throughput (TPS) beyond typical sequential execution limits. + +- **Enhanced Functionality via Precompiles:** + +Sei extends the standard EVM capabilities by providing **precompiled contracts**. These are built-in contracts at special addresses that offer efficient, low-gas access to core Sei chain features directly from Solidity. Examples include interacting with native staking, governance voting, token transfers, querying on-chain price oracles, and bridging to contracts. + +- **Native Token Integration:** + +The native `$SEI` token is used for gas fees within the EVM environment. + +- Precompiles facilitate interaction between EVM contracts and native Sei tokens (including $SEI itself and other tokens created on the Sei chain). + +_The Sei EVM environment aims to provide the compatibility and tooling familiarity of Ethereum while offering substantially higher performance and deeper integration with native chain features through parallelization and specialized precompiles._ diff --git a/knowledge-base/node-management/monitor-my-sei-evm-nodes-health.md b/knowledge-base/node-management/monitor-my-sei-evm-nodes-health.md new file mode 100644 index 00000000..a5f8c4d8 --- /dev/null +++ b/knowledge-base/node-management/monitor-my-sei-evm-nodes-health.md @@ -0,0 +1,126 @@ +--- +title: "How to monitor my Sei EVM node's health?" +description: "How to monitor my Sei EVM node's health?" +--- + +# How to monitor my Sei EVM node's health? + +To effectively monitor your Sei EVM node's health: + +### 1. Basic System Monitoring + +``` +# Check system resources +htop +df -h +free -m + +# Check node process +ps aux | grep seid + +``` + +### 2. Node-Specific Metrics + +``` +# Check sync status via RPC +curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ + http://localhost:8545 + +# Get current block height +curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ + http://localhost:8545 + +# Check peer count +curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":1}' \ + http://localhost:8545 + +``` + +### 3. Set Up Prometheus Monitoring + +``` +# Install Prometheus and Grafana + +# Configure Prometheus in /etc/prometheus/prometheus.yml +scrape_configs: + - job_name: 'sei_node' + scrape_interval: 15s + static_configs: + - targets: ['localhost:26660'] # Default Tendermint metrics port + +``` + +### 4. Create Alert Rules + +``` +# Example Prometheus alert rule +groups: +- name: sei-node-alerts + rules: + - alert: NodeBehind + expr: (max(sei_latest_block_height) - sei_latest_block_height) > 10 + for: 5m + labels: + severity: warning + annotations: + summary: "Node falling behind" + description: "Node is more than 10 blocks behind the network" + +``` + +### 5. Health Check Script + +``` +#!/bin/bash +# health_check.sh - Run periodically via cron + +# Check if node is syncing +SYNCING=$(curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ + http://localhost:8545 | jq '.result') + +# Check block height +BLOCK_HEIGHT=$(curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ + http://localhost:8545 | jq '.result') + +# Check peer count +PEER_COUNT=$(curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":1}' \ + http://localhost:8545 | jq '.result') + +# Send alerts if issues detected +if [ "$SYNCING" != "false" ]; then + echo "Node is still syncing" | mail -s "Sei Node Alert: Syncing" admin@example.com +fi + +if [ "$PEER_COUNT" -lt "3" ]; then + echo "Low peer count: $PEER_COUNT" | mail -s "Sei Node Alert: Low Peers" admin@example.com +fi + +# Log health status +echo "$(date) - Block: $BLOCK_HEIGHT, Peers: $PEER_COUNT, Syncing: $SYNCING" >> /var/log/sei_health.log + +``` + +### 6. Common Health Metrics to Monitor + +- **Block Height**: Compare against network block height + +- **Sync Status**: Whether node is fully synced + +- **Peer Count**: Should maintain healthy number of peers + +- **Request Latency**: Average response time for RPC requests + +- **Error Rate**: Percentage of RPC requests returning errors + +- **Disk Usage**: Blockchain data grows over time + +- **Memory Usage**: Watch for memory leaks + +- **CPU Usage**: Spikes during high transaction periods diff --git a/knowledge-base/node-management/the-public-rpc-endpoints-for-sei-evm.md b/knowledge-base/node-management/the-public-rpc-endpoints-for-sei-evm.md new file mode 100644 index 00000000..deda9d07 --- /dev/null +++ b/knowledge-base/node-management/the-public-rpc-endpoints-for-sei-evm.md @@ -0,0 +1,57 @@ +--- +title: 'What are the public RPC endpoints for Sei EVM?' +description: 'What are the public RPC endpoints for Sei EVM?' +--- + +# What are the public RPC endpoints for Sei EVM? + +Sei Network provides several public RPC endpoints for both mainnet and testnet: + +**Mainnet RPC Endpoints:** + +``` +Primary: https://evm-rpc.sei.io +Alternative: https://sei-mainnet-rpc.publicnode.com + +``` + +**Testnet RPC Endpoints:** + +``` +Primary: https://evm-rpc.testnet.sei.io +Alternative: https://sei-testnet-rpc.publicnode.com + +``` + +For production applications, consider: + +- Using a dedicated RPC provider for better reliability + +- Implementing failover between multiple endpoints + +- Running your own Sei node for critical applications + +Example of RPC failover implementation: + +``` +// RPC failover implementation +async function getReliableProvider() { + const rpcUrls = [ + "https://evm-rpc.sei.io", + "https://sei-mainnet-rpc.publicnode.com" + ]; + + for (const url of rpcUrls) { + try { + const provider = new ethers.providers.JsonRpcProvider(url); + await provider.getBlockNumber(); // Test connection + console.log(`Connected to ${url}`); + return provider; + } catch (error) { + console.warn(`Failed to connect to ${url}: ${error.message}`); + } + } + + throw new Error("All RPC endpoints failed"); +} +``` diff --git a/knowledge-base/nodes/debug-connection-refused-when-using-my-private-rpc.md b/knowledge-base/nodes/debug-connection-refused-when-using-my-private-rpc.md new file mode 100644 index 00000000..8ba4d331 --- /dev/null +++ b/knowledge-base/nodes/debug-connection-refused-when-using-my-private-rpc.md @@ -0,0 +1,69 @@ +--- +title: "How to debug "Connection Refused" when using my private RPC?" +description: "How to debug "Connection Refused" when using my private RPC?" +--- + +# How to debug "Connection Refused" when using my private RPC? + +If you're encountering "Connection Refused" errors when using your private Sei RPC: + +- **Check Network Connectivity**: + +``` +# Test basic network connectivity +ping your-rpc-host.com + +# Test TCP connectivity to the RPC port (usually 8545) +nc -vz your-rpc-host.com 8545 + +``` + +- **Verify Firewall Settings**: + +``` +# Check if firewall is blocking connections +sudo ufw status + +# Allow RPC port if using ufw +sudo ufw allow 8545/tcp + +``` + +- **Check RPC Configuration**: + +``` +# Ensure RPC is configured to accept external connections +# In your Sei node config, check: +# - RPC address should be 0.0.0.0:8545 (not 127.0.0.1) +# - CORS settings should allow your origin + +``` + +- **Verify RPC Service Status**: + +``` +# Check if the RPC service is running +sudo systemctl status seid + +# View logs for errors +sudo journalctl -u seid -n 100 + +``` + +- **Test Locally First**: + +``` +# Test RPC locally on the server +curl -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ + http://localhost:8545 + +``` + +If you're still experiencing issues after these steps: + +- Check for server resource limitations (CPU, memory, disk) + +- Ensure you're not exceeding request rate limits + +- Consider restarting your RPC node: `sudo systemctl restart seid` diff --git a/knowledge-base/nodes/why-are-my-json-rpc-calls-timing-out.md b/knowledge-base/nodes/why-are-my-json-rpc-calls-timing-out.md new file mode 100644 index 00000000..8c019ccc --- /dev/null +++ b/knowledge-base/nodes/why-are-my-json-rpc-calls-timing-out.md @@ -0,0 +1,88 @@ +--- +title: 'Why are my JSON-RPC calls timing out?' +description: 'Why are my JSON-RPC calls timing out?' +--- + +# Why are my JSON-RPC calls timing out? + +If your JSON-RPC calls to Sei Network are timing out, consider these common causes and solutions: + +- **RPC Node Overload**: + +Public RPCs may be experiencing high load + +- Solution: Use alternative RPCs or run your own node + +``` +// Try with longer timeout +const provider = new ethers.providers.JsonRpcProvider( +"https://evm-rpc.sei.io", +{ timeout: 60000 } // 60 seconds instead of default +); + +``` + +- **Network Congestion**: + +During periods of high activity, requests may timeout + +- Solution: Implement exponential backoff retry + +``` +async function callWithRetry(method, params, maxRetries = 5) { +let retries = 0; +while (retries try { + return await provider.send(method, params); + } catch (error) { + if (!error.message.includes("timeout") || retries === maxRetries - 1) { + throw error; + } + retries++; + const delay = Math.min(Math.pow(2, retries) * 1000, 10000); + console.log(`Retry ${retries} after ${delay}ms`); + await new Promise(r => setTimeout(r, delay)); + } +} +} + +``` + +- **Heavy Requests**: + +Complex queries (like fetching large state data) may timeout + +- Solution: Break into smaller requests ```javascript // Instead of fetching all events at once const events = await contract.queryFilter(filter, startBlock, endBlock); + +// Break into smaller chunks async function getEventsInChunks(filter, startBlock, endBlock, chunkSize = 1000) { let allEvents = []; for (let i = startBlock; i const end = Math.min(i + chunkSize - 1, endBlock); +const events = await contract.queryFilter(filter, i, end); +allEvents = [...allEvents, ...events]; + +```` + +} return allEvents; } ``` + +- +**Client-Side Network Issues**: + +Check your own network connectivity + +- Solution: Test from different networks or use VPN + +- +**RPC Method Support**: + +Some methods may not be supported or implemented efficiently + +- Solution: Check if method is supported or use alternatives +```` + +// Instead of eth_getLogs which can be heavy +// Use events from contract instance for more efficient queries +const contract = new ethers.Contract(address, abi, provider); +const filter = contract.filters.MyEvent(); +const events = await contract.queryFilter(filter, startBlock, endBlock); + +``` + +If timeouts persist, consider running a dedicated Sei node for reliable access. +``` diff --git a/knowledge-base/precompiles/how-can-my-evm-contract-look-up-associated.md b/knowledge-base/precompiles/how-can-my-evm-contract-look-up-associated.md new file mode 100644 index 00000000..9dbb2082 --- /dev/null +++ b/knowledge-base/precompiles/how-can-my-evm-contract-look-up-associated.md @@ -0,0 +1,74 @@ +--- +title: 'How can my EVM contract look up associated addresses or trigger address association?' +description: 'How can my EVM contract look up associated addresses or trigger address association?' +--- + +# How can my EVM contract look up associated addresses or trigger address association? + +Sei provides an **Address Precompile** at `0x0000000000000000000000000000000000001004` specifically for managing the link between Sei Native (`sei1...`) and EVM (`0x...`) addresses derived from the same private key. + +**Key Functions (Solidity Interface):** + +``` +interface ISeiAddressPrecompile { + // --- View Functions --- + + /** + * @notice Gets the associated Sei Bech32 address for a given EVM address. + * @param evmAddr The EVM address (`0x...`) to look up. + * @return seiAddr The associated Sei address string (`sei1...`). Reverts if not associated. + */ + function getSeiAddr(address evmAddr) external view returns (string memory seiAddr); + + /** + * @notice Gets the associated EVM address for a given Sei Bech32 address. + * @param seiAddr The Sei address string (`sei1...`) to look up. + * @return evmAddr The associated EVM address (`0x...`). Reverts if not associated. + */ + function getEvmAddr(string memory seiAddr) external view returns (address evmAddr); + + // --- State Changing Functions --- + + /** + * @notice Associates the EVM and Sei addresses derived from the signer of the provided message. + * @dev Requires a signature created off-chain over the customMessage. + * @param v The recovery ID (usually 27 or 28, potentially as hex string "0x1b" or "0x1c"). + * @param r The R component of the ECDSA signature (as hex string). + * @param s The S component of the ECDSA signature (as hex string). + * @param customMessage The exact message string that was signed. + * @return seiAddr The associated Sei address. + * @return evmAddr The associated EVM address. + */ + function associate(string memory v, string memory r, string memory s, string memory customMessage) external returns (string memory seiAddr, address evmAddr); + + /** + * @notice Associates the EVM and Sei addresses derived from a provided public key. + * @dev The public key must be in compressed format, represented as a hex string without the "0x" prefix. + * @param pubKeyHex The compressed public key hex string. + * @return seiAddr The associated Sei address. + * @return evmAddr The associated EVM address. + */ + function associatePubKey(string memory pubKeyHex) external returns (string memory seiAddr, address evmAddr); +} + +``` + +**How to Use:** + +- **Lookups (`getSeiAddr`, `getEvmAddr`):** Call these view functions directly from your contract to find an existing association. Handle potential reverts if no association exists (e.g., using `try/catch`). + +- **Association (`associate`, `associatePubKey`):** These functions *create* the on-chain link. They are typically **not called directly by end-users** from a generic contract. + +The `associate` function requires an off-chain signature generated by the user's wallet, making it suitable for integration into dApp frontends or dedicated association tools. + +- The `associatePubKey` function requires the user's compressed public key, which might be less common for users to handle directly. + +- These functions will fail if an association already exists for the derived addresses. + +**Important Considerations:** + +- **Association Requirement:** Many other Sei precompiles (like Staking, IBC, Bank `send`) require the `caller` to be associated before they can be used successfully. + +- **Gas Costs:** Lookup functions are cheap. Association functions (`associate`, `associatePubKey`) have a higher base gas cost (e.g., 50,000) due to cryptographic operations. + +- **Security:** Association proves ownership. The `associate` function relies on cryptographic signatures for security. diff --git a/knowledge-base/precompiles/how-can-my-evm-smart-contract-call-or-query-a.md b/knowledge-base/precompiles/how-can-my-evm-smart-contract-call-or-query-a.md new file mode 100644 index 00000000..3d6181af --- /dev/null +++ b/knowledge-base/precompiles/how-can-my-evm-smart-contract-call-or-query-a.md @@ -0,0 +1,97 @@ +--- +title: 'How can my EVM smart contract call or query a CosmWasm smart contract on Sei?' +description: 'How can my EVM smart contract call or query a CosmWasm smart contract on Sei?' +--- + +# How can my EVM smart contract call or query a CosmWasm smart contract on Sei? + +Sei provides a powerful **CosmWasm Interaction Precompile** at address `0x0000000000000000000000000000000000001002`. This allows EVM contracts to directly instantiate, execute messages on, and query CosmWasm contracts. + +**Key Functions (Solidity Interface):** + +``` +interface ISeiWasmdPrecompile { + // --- State Changing Functions --- + + /** + * @notice Instantiates a new CosmWasm contract from a code ID. + * @dev Caller's EVM address must be associated. msg.value must match usei amount in coins. + * @param codeID The code ID of the CosmWasm contract bytecode. + * @param admin Optional admin address (Sei bech32 format) for the new contract. + * @param msg The instantiation message (JSON as bytes). + * @param label A human-readable label for the contract instance. + * @param coins Funds to send to the contract upon instantiation (JSON sdk.Coins as bytes, e.g., '[{"denom":"usei","amount":"1000000"}]'). + * @return contractAddr The Bech32 address of the newly instantiated CosmWasm contract. + * @return data Any data returned by the CosmWasm instantiate response. + */ + function instantiate( + uint64 codeID, + string memory admin, + bytes memory msg, + string memory label, + bytes memory coins + ) external payable returns (string memory contractAddr, bytes memory data); + + /** + * @notice Executes a message on a CosmWasm contract. + * @dev Caller's EVM address must be associated. msg.value must match usei amount in coins. Can only be delegate called by the contract's registered Pointer contract. + * @param contractAddress The Bech32 address of the target CosmWasm contract. + * @param msg The execution message (JSON as bytes). + * @param coins Funds to send with the execution (JSON sdk.Coins as bytes). + * @return data Any data returned by the CosmWasm execution response. + */ + function execute( + string memory contractAddress, + bytes memory msg, + bytes memory coins + ) external payable returns (bytes memory data); + + /** + * @notice Executes a batch of messages on one or more CosmWasm contracts atomically. + * @dev Caller's EVM address must be associated. msg.value must match the sum of usei amounts in all coins fields. + * @param executeMsgs An array of execute messages. + * @return responses An array of data bytes returned by each CosmWasm execution response. + */ + function execute_batch(ExecuteMsg[] memory executeMsgs) + external payable returns (bytes[] memory responses); + + // --- View Function --- + + /** + * @notice Performs a smart query on a CosmWasm contract. + * @param contractAddress The Bech32 address of the target CosmWasm contract. + * @param req The query message (JSON as bytes). + * @return response The query response (JSON as bytes). + */ + function query(string memory contractAddress, bytes memory req) + external view returns (bytes memory response); + + // --- Helper Struct for execute_batch --- + struct ExecuteMsg { + string contractAddress; // Target CW contract bech32 address + bytes msg; // Execution message JSON bytes + bytes coins; // Funds JSON bytes (e.g., '[{"denom":"usei","amount":"0"}]') + } +} + +``` + +**How to Use:** + +- **Association:** The EVM address calling `instantiate`, `execute`, or `execute_batch` **must** be associated with a Sei native address. + +- **Interface & Instance:** Define/import `ISeiWasmdPrecompile` and get a reference: `ISeiWasmdPrecompile constant seiWasmd = ISeiWasmdPrecompile(0x0000000000000000000000000000000000001002);` + +- **Data Formatting:** Messages (`msg`, `req`) and funds (`coins`) must be provided as **bytes representing valid JSON**. For `coins`, use the `sdk.Coins` JSON format (e.g., `bytes('[{"denom":"usei","amount":"1000000"}]')` for 1 SEI). + +- **Value Matching:** For `instantiate`, `execute`, and `execute_batch`, the `msg.value` sent with the EVM call (in wei) **must exactly match** the total `usei` amount specified in the `coins` argument(s), converted to wei (1 usei = 10^12 wei). + +- **Responses:** Execution and query responses are returned as raw `bytes`, typically containing JSON data that needs to be decoded/parsed off-chain or potentially using the JSON precompile on-chain. + +**Important Considerations:** + +- **Delegate Call:** `instantiate` cannot be delegate called. `execute` can only be delegate called by the CW contract's registered Pointer contract, enabling seamless interaction via the pointer's EVM interface. + +- **Call Pattern:** Direct `CW -> EVM -> CW` write calls (instantiate/execute) are generally disallowed to prevent complex reentrancy scenarios. + +- **Gas:** Calls incur the base precompile gas cost plus the significant gas cost of the underlying CosmWasm execution (instantiation, message execution, or query processing). diff --git a/knowledge-base/precompiles/how-can-my-evm-smart-contract-get-on-chain-price.md b/knowledge-base/precompiles/how-can-my-evm-smart-contract-get-on-chain-price.md new file mode 100644 index 00000000..1c3b1cda --- /dev/null +++ b/knowledge-base/precompiles/how-can-my-evm-smart-contract-get-on-chain-price.md @@ -0,0 +1,103 @@ +--- +title: 'How can my EVM smart contract get on-chain price information for tokens?' +description: 'How can my EVM smart contract get on-chain price information for tokens?' +--- + +# How can my EVM smart contract get on-chain price information for tokens? + +# Using the Oracle Precompile (`0x...1008`) + +Sei provides an **Oracle Precompile** at address `0x0000000000000000000000000000000000001008` that allows EVM contracts to read price data directly from Sei's native oracle module. This is crucial for DeFi applications needing reliable price feeds. + +**Key Functions (Solidity Interface):** + +``` +interface ISeiOraclePrecompile { + // --- Return Struct Definitions --- + struct OracleExchangeRate { + string ExchangeRate; // The exchange rate, represented as a string decimal. + string LastUpdate; // Timestamp of the last successful update (as string). + int64 LastUpdateTimestamp; // Timestamp of the last successful update (as int64 epoch seconds). + } + + struct DenomOracleExchangeRatePair { + string Denom; // The denomination string (e.g., "usei", "uatom"). + OracleExchangeRate OracleExchangeRateVal; // The rate details. + } + + struct OracleTwap { + string Denom; // The denomination string. + string Twap; // The time-weighted average price (as string decimal). + int64 LookbackSeconds; // The lookback period used for calculation. + } + + // --- View Functions --- + + /** + * @notice Gets the latest exchange rates for all tracked denominations. + * @return rates An array of structs containing denom and rate information. + */ + function getExchangeRates() external view returns (DenomOracleExchangeRatePair[] memory rates); + + /** + * @notice Calculates and returns Time-Weighted Average Prices (TWAPs) for all tracked denominations. + * @param lookbackSeconds The duration (in seconds) over which to calculate the TWAP. + * @return twaps An array of structs containing denom and TWAP information. + */ + function getOracleTwaps(uint64 lookbackSeconds) external view returns (OracleTwap[] memory twaps); +} + +``` + +**How to Use:** + +- **Interface:** Define or import the `ISeiOraclePrecompile` interface in your contract. + +- **Instantiate:** Get a reference: `ISeiOraclePrecompile constant seiOracle = ISeiOraclePrecompile(0x0000000000000000000000000000000000001008);` + +- **Call Functions:** Invoke `getExchangeRates()` or `getOracleTwaps(lookback_seconds)`. + +**Important Considerations:** + +- **String Decimal Prices:** The most critical point is that `ExchangeRate` and `Twap` values are returned as **strings**, not `uint256`. These strings represent potentially high-precision decimal numbers. + +**Handling in Solidity:** You **cannot** directly cast these strings to `uint256` or use them in standard arithmetic operations if they contain decimals. You must either: + +Use a Solidity library designed for handling decimal strings or fixed-point arithmetic (e.g., ABDKMath64x64, PRBMath) to parse the string and convert it into a usable fixed-point representation. + +- Pass the string price off-chain for processing. + +- **Read-Only:** Both functions are view functions (read-only) and are non-payable (`msg.value` must be 0). + +- **Gas:** Gas costs are relatively low, primarily for reading oracle state. + +- **Available Denoms:** The functions return data for all denominations currently tracked by the Sei oracle module. + +**Example Usage (Conceptual - requires parsing library):** + +``` +// Assume FixedPoint library exists for string decimal parsing +import { FixedPoint } from "./FixedPoint.sol"; + +contract OracleUser { + ISeiOraclePrecompile constant seiOracle = ISeiOraclePrecompile(0x...); + + function checkSeiPriceAgainstThreshold(string memory priceThreshold) public view { + ISeiOraclePrecompile.DenomOracleExchangeRatePair[] memory rates = seiOracle.getExchangeRates(); + string memory currentPriceStr; + for (uint i = 0; i length; i++) { + if (keccak256(abi.encodePacked(rates[i].Denom)) == keccak256(abi.encodePacked("usei"))) { // Assuming "usei" price vs reference + currentPriceStr = rates[i].OracleExchangeRateVal.ExchangeRate; + break; + } + } + require(bytes(currentPriceStr).length > 0, "Price not found"); + + int256 currentPrice = FixedPoint.parseDecimal(currentPriceStr); + int256 thresholdPrice = FixedPoint.parseDecimal(priceThreshold); + + require(currentPrice >= thresholdPrice, "Price is below threshold"); + } +} + +``` diff --git a/knowledge-base/precompiles/how-can-my-evm-smart-contract-interact-with.md b/knowledge-base/precompiles/how-can-my-evm-smart-contract-interact-with.md new file mode 100644 index 00000000..1b3a4126 --- /dev/null +++ b/knowledge-base/precompiles/how-can-my-evm-smart-contract-interact-with.md @@ -0,0 +1,107 @@ +--- +title: 'How can my EVM smart contract interact with native Sei tokens (like $SEI or others)?' +description: 'How can my EVM smart contract interact with native Sei tokens (like $SEI or others)?' +--- + +# How can my EVM smart contract interact with native Sei tokens (like $SEI or others)? + +Sei provides a **Bank Precompile** contract at the special address `0x0000000000000000000000000000000000001001`. This precompile allows EVM contracts to directly interact with the native Sei token system (the `x/bank` module), enabling actions like sending native tokens and querying balances. + +**Key Functions (Solidity Interface):** + +``` +interface ISeiBankPrecompile { + // --- State Changing Functions --- + + /** + * @notice Sends native $SEI (usei/wei) attached as msg.value from the caller to a Sei address. + * @param recipientSeiAddr The recipient's Sei address (e.g., "sei1..."). + * @return success True if the transfer succeeded. + */ + function sendNative(string memory recipientSeiAddr) external payable returns (bool success); + + /** + * @notice Sends a specific native token (denom) from a sender to a recipient. + * @dev RESTRICTION: Can only be called by the registered ERC20 pointer contract for the specified denom. + * @param sender The sender's EVM address (must be associated). + * @param recipient The recipient's EVM address (or associated Sei address). + * @param denom The native token denomination string (e.g., "uatom"). + * @param amount The amount of the token to send (in its base unit). + * @return success True if the transfer succeeded. + */ + function send(address sender, address recipient, string memory denom, uint256 amount) external returns (bool success); + + // --- View Functions --- + + /** + * @notice Gets the balance of a specific native token for an account. + * @param account The EVM address of the account. + * @param denom The native token denomination string. + * @return balance The account's balance of the specified token. + */ + function balance(address account, string memory denom) external view returns (uint256 balance); + + /** + * @notice Gets all native token balances for an account. + * @param account The EVM address of the account. + * @return balances An array of all native balances held by the account. + */ + function all_balances(address account) external view returns (CoinBalance[] memory balances); + + /** + * @notice Gets the registered name for a native token denom. + * @param denom The native token denomination string. + * @return name The registered name. + */ + function name(string memory denom) external view returns (string memory name); + + /** + * @notice Gets the registered symbol for a native token denom. + * @param denom The native token denomination string. + * @return symbol The registered symbol. + */ + function symbol(string memory denom) external view returns (string memory symbol); + + /** + * @notice Gets the decimals for a native token denom. + * @dev IMPORTANT: Always returns 0 for native Sei tokens, as they are integer-based at the bank module level. + * @param denom The native token denomination string. + * @return decimals Always 0. + */ + function decimals(string memory denom) external view returns (uint8 decimals); + + /** + * @notice Gets the total supply of a specific native token denom. + * @param denom The native token denomination string. + * @return supply The total supply. + */ + function supply(string memory denom) external view returns (uint256 supply); + + // Helper struct for all_balances + struct CoinBalance { + uint256 Amount; + string Denom; + } +} + +``` + +**How to Use:** + +- **Import/Define Interface:** Include the `ISeiBankPrecompile` interface in your Solidity contract. + +- **Instantiate:** Create an instance pointing to the precompile address: `ISeiBankPrecompile constant seiBank = ISeiBankPrecompile(0x0000000000000000000000000000000000001001);` + +- **Call Functions:** Invoke the desired methods. + +**Important Considerations:** + +- **Sending $SEI:** Use `sendNative` and attach the amount of $SEI you want to send as `msg.value` in your call. The recipient address must be the *Sei native address* (`sei1...`) format. + +- **Sending Other Native Tokens:** Use the `send` function. This has a **major restriction**: it can generally only be called by the official **ERC20 Pointer Contract** associated with that specific `denom`. This prevents arbitrary EVM contracts from moving native assets they don't control via a pointer. + +- **Address Association:** For `send`, the `sender` address must be associated. For `sendNative`, the `msg.sender` (caller of the precompile) must be associated. + +- **Decimals:** Be aware that `decimals()` **always returns 0** for native tokens via this precompile. Native tokens on Sei are handled with integer amounts at the base layer. If you are creating an ERC20 pointer for a native token that *conceptually* has decimals (e.g., like USDC with 6 decimals), the pointer contract itself (not this bank precompile) implements the ERC20 `decimals()` function and handles the conversion logic. + +- **Gas:** View functions are cheap. `send` and `sendNative` incur gas costs related to the state changes in the bank module. diff --git a/knowledge-base/precompiles/how-can-my-evm-smart-contract-perform-staking.md b/knowledge-base/precompiles/how-can-my-evm-smart-contract-perform-staking.md new file mode 100644 index 00000000..7772ee59 --- /dev/null +++ b/knowledge-base/precompiles/how-can-my-evm-smart-contract-perform-staking.md @@ -0,0 +1,98 @@ +--- +title: 'How can my EVM smart contract perform staking actions like delegating $SEI?' +description: 'How can my EVM smart contract perform staking actions like delegating $SEI?' +--- + +# How can my EVM smart contract perform staking actions like delegating $SEI? + +Sei provides a **Staking Precompile** at address `0x0000000000000000000000000000000000001005` that allows EVM contracts to interact with Sei's native staking system. + +**Key Functions (Solidity Interface):** + +``` +interface ISeiStakingPrecompile { + // --- State Changing Functions --- + + /** + * @notice Delegates $SEI sent with the call (msg.value) from the caller to a validator. + * @dev Caller's EVM address must be associated with a Sei address. + * @param validatorBech32 The validator's address in Sei bech32 format (e.g., "seivaloper1..."). + * @return success True if delegation succeeded. + */ + function delegate(string memory validatorBech32) external payable returns (bool success); + + /** + * @notice Redelegates staked $SEI from a source validator to a destination validator. + * @dev Caller's EVM address must be associated. msg.value must be 0. + * @param srcValidatorBech32 The source validator's bech32 address. + * @param dstValidatorBech32 The destination validator's bech32 address. + * @param amount The amount of $SEI (in usei) to redelegate. + * @return success True if redelegation initiated successfully. + */ + function redelegate(string memory srcValidatorBech32, string memory dstValidatorBech32, uint256 amount) external returns (bool success); + + /** + * @notice Undelegates staked $SEI from a validator. + * @dev Caller's EVM address must be associated. msg.value must be 0. + * @param validatorBech32 The validator's bech32 address. + * @param amount The amount of $SEI (in usei) to undelegate. + * @return success True if undelegation initiated successfully. + */ + function undelegate(string memory validatorBech32, uint256 amount) external returns (bool success); + + // --- View Function --- + + /** + * @notice Queries the delegation information for a specific delegator and validator. + * @param delegator The delegator's EVM address (must be associated). + * @param validatorBech32 The validator's bech32 address. + * @return delegationInfo A struct containing delegation details. + */ + function delegation(address delegator, string memory validatorBech32) external view returns (Delegation memory delegationInfo); + + // --- Helper Structs for Return Value --- + struct Balance { + uint256 Amount; // Amount of tokens delegated (in usei) + string Denom; // Should always be "usei" + } + + struct DelegationDetails { + string DelegatorAddress; // Sei native address (sei1...) + uint256 Shares; // Number of validator shares owned + uint256 Decimals; // Precision of the Shares value (e.g., 10^18) + string ValidatorAddress; // Validator's bech32 address (seivaloper1...) + } + + struct Delegation { + Balance Balance; // The current token equivalent of the shares + DelegationDetails Delegation; // Details about the delegation shares + } +} + +``` + +**How to Use:** + +- **Association:** The EVM address calling `delegate`, `redelegate`, or `undelegate` **must** be associated with a Sei native address. The native address is the one that actually performs the staking operation. + +- **Interface:** Define or import the `ISeiStakingPrecompile` interface. + +- **Instantiate:** Get a reference: `ISeiStakingPrecompile constant seiStaking = ISeiStakingPrecompile(0x0000000000000000000000000000000000001005);` + +- **Call Functions:** + +**Delegate:** Call `delegate{value: amountToDelegateInWei}("validator_address")`. Note `value` is required. + +- **Redelegate/Undelegate:** Call `redelegate(...)` or `undelegate(...)` with `msg.value = 0`. The amount is specified as a function argument (in `usei`, the smallest unit of SEI). + +- **Query:** Call `delegation(...)` to get details. + +**Important Considerations:** + +- **Units:** When calling `redelegate` or `undelegate`, the `amount` argument is in `usei` (1 SEI = 1,000,000 usei). When calling `delegate`, the `msg.value` is in `wei` (the smallest EVM unit, 1 SEI = 10^18 wei). The precompile handles the conversion for delegation. + +- **No Delegate Call:** This precompile cannot be called using `delegatecall`. + +- **Staked Balance:** $SEI delegated via this precompile is managed by the associated native (`sei1...`) address. It will *not* appear in the EVM address balance in MetaMask. + +- **Gas:** Write operations incur higher base gas costs (50k-70k) plus the cost of the underlying staking module interaction. Querying is cheaper. diff --git a/knowledge-base/precompiles/how-can-my-evm-smart-contract-send-tokens-to.md b/knowledge-base/precompiles/how-can-my-evm-smart-contract-send-tokens-to.md new file mode 100644 index 00000000..606dde5a --- /dev/null +++ b/knowledge-base/precompiles/how-can-my-evm-smart-contract-send-tokens-to.md @@ -0,0 +1,91 @@ +--- +title: 'How can my EVM smart contract send tokens to other blockchains via IBC?' +description: 'How can my EVM smart contract send tokens to other blockchains via IBC?' +--- + +# How can my EVM smart contract send tokens to other blockchains via IBC? + +Sei provides an **IBC Precompile** at address `0x0000000000000000000000000000000000001009` that enables EVM smart contracts to initiate IBC (Inter-Blockchain Communication) token transfers. + +**Key Functions (Solidity Interface):** + +``` +interface ISeiIbcPrecompile { + /** + * @notice Initiates an IBC transfer with explicitly specified timeout parameters. + * @dev Caller's EVM address must be associated. msg.value must be 0. + * @param receiver The recipient address on the destination chain (string format). + * @param sourcePort The source port on Sei (e.g., "transfer"). + * @param sourceChannel The source channel ID on Sei (e.g., "channel-0"). + * @param denom The denomination of the token to send (e.g., "usei", "ibc/HASH..."). + * @param amount The amount of the token to send (in its base unit). + * @param revisionNumber The revision number part of the timeout height on the destination chain. + * @param revisionHeight The revision height part of the timeout height on the destination chain. + * @param timeoutTimestamp The absolute timestamp (in nanoseconds) after which the transfer times out. + * @param memo An optional memo string for the IBC transfer. + * @return success True if the IBC transfer message was successfully submitted. + */ + function transfer( + string memory receiver, + string memory sourcePort, + string memory sourceChannel, + string memory denom, + uint256 amount, + uint64 revisionNumber, + uint64 revisionHeight, + uint64 timeoutTimestamp, + string memory memo + ) external returns (bool success); + + /** + * @notice Initiates an IBC transfer using automatically calculated default timeout parameters. + * @dev Caller's EVM address must be associated. msg.value must be 0. + * @param receiver The recipient address on the destination chain (string format). + * @param sourcePort The source port on Sei (e.g., "transfer"). + * @param sourceChannel The source channel ID on Sei (e.g., "channel-0"). + * @param denom The denomination of the token to send (e.g., "usei", "ibc/HASH..."). + * @param amount The amount of the token to send (in its base unit). + * @param memo An optional memo string for the IBC transfer. + * @return success True if the IBC transfer message was successfully submitted. + */ + function transferWithDefaultTimeout( + string memory receiver, + string memory sourcePort, + string memory sourceChannel, + string memory denom, + uint256 amount, + string memory memo + ) external returns (bool success); +} + +``` + +**How to Use:** + +- **Association:** The EVM address (`msg.sender`) calling the precompile **must** be associated with a Sei native address. The native address is the actual sender of the IBC transfer. + +- **Interface:** Define or import the `ISeiIbcPrecompile` interface. + +- **Instantiate:** Get a reference: `ISeiIbcPrecompile constant seiIbc = ISeiIbcPrecompile(0x0000000000000000000000000000000000001009);` + +- **Call Functions:** + +Choose `transfer` if you need precise control over the timeout height and timestamp. + +- Choose `transferWithDefaultTimeout` for convenience, allowing Sei to calculate reasonable defaults based on the current block and client state. + +- **Parameters:** Provide the recipient address on the destination chain, the correct `sourcePort` and `sourceChannel` for the desired route, the `denom` of the token being sent (this can be native `usei` or an IBC voucher denomination like `ibc/HASH...`), the `amount` (in the token's smallest unit), and an optional `memo`. + +**Important Considerations:** + +- **Non-Payable:** These functions are non-payable (`msg.value` must be 0). The tokens being transferred are deducted from the associated Sei native address's balance. + +- **No Delegate Call:** This precompile cannot be called using `delegatecall`. + +- **Denominations:** You can send native Sei tokens (like `usei`) or tokens that have arrived on Sei via IBC (represented by their `ibc/...` denom). + +- **Timeout:** IBC transfers rely on timeouts. `transferWithDefaultTimeout` is generally recommended unless you have specific requirements for timeout calculation. + +- **IBC Knowledge:** Using this precompile requires understanding IBC concepts like ports, channels, and destination chain address formats. + +- **Gas:** While the precompile call itself has a base gas cost, the execution of the underlying IBC transfer involves interactions with multiple modules and relaying, which consumes Cosmos-level gas paid by the associated Sei native address. diff --git a/knowledge-base/precompiles/pointer-contracts-in-sei-how-do-the-pointer.md b/knowledge-base/precompiles/pointer-contracts-in-sei-how-do-the-pointer.md new file mode 100644 index 00000000..443f130a --- /dev/null +++ b/knowledge-base/precompiles/pointer-contracts-in-sei-how-do-the-pointer.md @@ -0,0 +1,129 @@ +--- +title: 'What are Pointer Contracts in Sei? How do the Pointer precompiles work?' +description: 'What are Pointer Contracts in Sei? How do the Pointer precompiles work?' +--- + +# What are Pointer Contracts in Sei? How do the Pointer precompiles work? + +Pointer contracts are a unique feature of Sei that bridge assets between Sei's native/CosmWasm environment and its EVM environment. They essentially create **standard ERC-compatible EVM interfaces** (like ERC20, ERC721, ERC1155) that "point" to an underlying native asset (like a bank token, CW20, CW721, or CW1155 contract). + +This allows EVM smart contracts, dApps, and wallets (like MetaMask) to interact with these bridged assets using familiar Ethereum standards. + +Sei provides two precompiles to manage these pointers: + +- **Pointer Precompile (`0x000000000000000000000000000000000000100b`):** Used to *create or update* pointer contracts. + +- **PointerView Precompile (`0x000000000000000000000000000000000000100A`):** Used to *query* information about existing pointer contracts. + +### Pointer Precompile (`0x...100b`) - Creating Pointers + +This precompile deploys a standard EVM wrapper contract that implements the relevant ERC interface and forwards calls to the underlying native/CW asset. + +**Key Functions (Solidity Interface):** + +``` +interface ISeiPointerPrecompile { + /** + * @notice Creates/updates an ERC20 pointer for a native bank token. + * @dev Denom must have metadata registered in the bank module. + * @param denom The native token denomination string. + * @return pointerAddr The EVM address of the ERC20 pointer contract. + */ + function addNativePointer(string memory denom) external returns (address pointerAddr); + + /** + * @notice Creates/updates an ERC20 pointer for a CW20 contract. + * @param cwAddress The Bech32 address of the CW20 contract. + * @return pointerAddr The EVM address of the ERC20 pointer contract. + */ + function addCW20Pointer(string memory cwAddress) external returns (address pointerAddr); + + /** + * @notice Creates/updates an ERC721 pointer for a CW721 contract. + * @param cwAddress The Bech32 address of the CW721 contract. + * @return pointerAddr The EVM address of the ERC721 pointer contract. + */ + function addCW721Pointer(string memory cwAddress) external returns (address pointerAddr); + + /** + * @notice Creates/updates an ERC1155 pointer for a CW1155 contract. + * @param cwAddress The Bech32 address of the CW1155 contract. + * @return pointerAddr The EVM address of the ERC1155 pointer contract. + */ + function addCW1155Pointer(string memory cwAddress) external returns (address pointerAddr); +} + +``` + +**Usage:** + +- Call the relevant `addPointer` function with the native denom or CW address. + +- The precompile deploys/updates the corresponding EVM wrapper contract and returns its `0x...` address. + +- This returned address can then be used with standard ERC20/721/1155 interfaces in other EVM contracts or dApps. + +- **Restrictions:** Cannot be delegate called, cannot be static called, non-payable (`msg.value` must be 0). For `addNativePointer`, the denom needs metadata registered. + +### PointerView Precompile (`0x...100A`) - Querying Pointers + +This precompile allows you to check if a pointer exists for a given asset and retrieve its details. + +**Key Functions (Solidity Interface):** + +``` +interface ISeiPointerViewPrecompile { + /** + * @notice Gets the pointer details for a native bank token denom. + * @param denom The native token denomination string. + * @return pointerAddr The EVM address of the pointer contract (address(0) if none). + * @return version The version ID of the deployed pointer contract code. + * @return exists True if a pointer exists for this denom. + */ + function getNativePointer(string memory denom) external view returns (address pointerAddr, uint16 version, bool exists); + + /** + * @notice Gets the pointer details for a CW20 contract address. + * @param cwAddress The Bech32 address of the CW20 contract. + * @return pointerAddr The EVM address of the pointer contract (address(0) if none). + * @return version The version ID of the deployed pointer contract code. + * @return exists True if a pointer exists for this contract. + */ + function getCW20Pointer(string memory cwAddress) external view returns (address pointerAddr, uint16 version, bool exists); + + /** + * @notice Gets the pointer details for a CW721 contract address. + * @param cwAddress The Bech32 address of the CW721 contract. + * @return pointerAddr The EVM address of the pointer contract (address(0) if none). + * @return version The version ID of the deployed pointer contract code. + * @return exists True if a pointer exists for this contract. + */ + function getCW721Pointer(string memory cwAddress) external view returns (address pointerAddr, uint16 version, bool exists); + + /** + * @notice Gets the pointer details for a CW1155 contract address. + * @param cwAddress The Bech32 address of the CW1155 contract. + * @return pointerAddr The EVM address of the pointer contract (address(0) if none). + * @return version The version ID of the deployed pointer contract code. + * @return exists True if a pointer exists for this contract. + */ + function getCW1155Pointer(string memory cwAddress) external view returns (address pointerAddr, uint16 version, bool exists); +} + +``` + +**Usage:** + +- Call the relevant `getPointer` function with the native denom or CW address. + +- Check the `exists` boolean. If true, `pointerAddr` contains the EVM address of the ERC-compatible contract. + +- **Restrictions:** View functions, non-payable. + +**Why Use Pointers?** + +- **EVM Compatibility:** Allows EVM dApps (DEXs, lending protocols, wallets) to interact with native/CW assets seamlessly using standard ERC interfaces. + +- **Unified Asset Representation:** Provides a consistent way to represent diverse Sei assets within the EVM environment. + +- **Bridging:** Facilitates interaction between EVM and CosmWasm contracts via these standardized interfaces. diff --git a/knowledge-base/seid/common-seid-cli-commands-for-everyday-use.md b/knowledge-base/seid/common-seid-cli-commands-for-everyday-use.md new file mode 100644 index 00000000..ca4f4370 --- /dev/null +++ b/knowledge-base/seid/common-seid-cli-commands-for-everyday-use.md @@ -0,0 +1,78 @@ +--- +title: 'What are common seid CLI commands for everyday use?' +description: 'What are common seid CLI commands for everyday use?' +--- + +# What are common seid CLI commands for everyday use? + +Here are some essential `seid` commands for everyday use: + +### Account Management + +``` +# Create new key/wallet +seid keys add mykey + +# Recover existing wallet +seid keys add mykey --recover + +# List all keys +seid keys list + +# Export key (for backup) +seid keys export mykey + +``` + +### Transaction Commands + +``` +# Send tokens +seid tx bank send mykey sei1recipient123... 1000000usei --chain-id pacific-1 + +# Delegate tokens to validator +seid tx staking delegate seivaloper1... 1000000usei --from mykey --chain-id pacific-1 + +# Withdraw all staking rewards +seid tx distribution withdraw-all-rewards --from mykey --chain-id pacific-1 + +# Vote on governance proposal +seid tx gov vote 1 yes --from mykey --chain-id pacific-1 + +``` + +### Query Commands + +``` +# Check account balance +seid query bank balances sei1myaddress... + +# Check transaction by hash +seid query tx AABBCCDDEEFF00112233 + +# Get validator list +seid query staking validators + +# Get governance proposals +seid query gov proposals + +# Check staking rewards +seid query distribution rewards sei1myaddress... + +``` + +### Node Management + +``` +# Check node status +seid status + +# Show node info +seid tendermint show-node-id + +# Export genesis file +seid export > genesis.json + +# Check validator consensus state +seid query tendermint-validator-set +``` diff --git a/knowledge-base/seid/configure-seid-for-different-networks.md b/knowledge-base/seid/configure-seid-for-different-networks.md new file mode 100644 index 00000000..105a2103 --- /dev/null +++ b/knowledge-base/seid/configure-seid-for-different-networks.md @@ -0,0 +1,53 @@ +--- +title: 'How do I configure seid for different networks?' +description: 'How do I configure seid for different networks?' +--- + +# How do I configure seid for different networks? + +You can configure `seid` to work with different networks (mainnet, testnet, local): + +### For Mainnet + +``` +# Set the configuration +seid config chain-id pacific-1 +seid config node https://sei-rpc.polkachu.com:443 + +# Test the connection +seid status + +``` + +### For Testnet (Atlantic) + +``` +# Set the configuration +seid config chain-id atlantic-2 +seid config node https://sei-testnet-rpc.polkachu.com:443 + +# Test the connection +seid status + +``` + +### For Local Development + +``` +# Set the configuration +seid config chain-id my-sei-chain +seid config node tcp://localhost:26657 +seid config keyring-backend test # For easier testing + +# Test the connection +seid status + +``` + +### Chain ID Reference + +- Mainnet: `pacific-1` + +- Current Testnet: `atlantic-2` + +- EVM Chain IDs: 1329 (mainnet), 1328 (testnet) diff --git a/knowledge-base/seid/initialize-a-local-sei-chain-for-development.md b/knowledge-base/seid/initialize-a-local-sei-chain-for-development.md new file mode 100644 index 00000000..b5c86296 --- /dev/null +++ b/knowledge-base/seid/initialize-a-local-sei-chain-for-development.md @@ -0,0 +1,66 @@ +--- +title: 'How do I initialize a local Sei chain for development?' +description: 'How do I initialize a local Sei chain for development?' +--- + +# How do I initialize a local Sei chain for development? + +To initialize a local Sei chain for development: + +### Method 1: Using the Initialize Script + +``` +# Clone the repository if you haven't already +git clone https://github.com/sei-protocol/sei-chain.git +cd sei-chain + +# Run the initialization script +./scripts/initialize_local_chain.sh + +# Start the chain +seid start + +``` + +### Method 2: Using the Python Node Runner + +``` +# Clone the repository +git clone https://github.com/sei-protocol/sei-chain.git +cd sei-chain + +# Run the node with Python +python3 ./scripts/run-node.py + +# If this fails, make sure you've installed requirements: +pip3 install -r scripts/requirements.txt + +``` + +### Method 3: Manual Initialization + +``` +# Initialize chain with custom chain-id +seid init my-node --chain-id my-sei-chain + +# Create a key for testing +seid keys add my-wallet + +# Add genesis account +seid add-genesis-account my-wallet 10000000000000usei + +# Generate genesis tx +seid gentx my-wallet 1000000usei --chain-id my-sei-chain + +# Collect genesis txs +seid collect-gentxs + +# Validate genesis +seid validate-genesis + +# Start the chain +seid start + +``` + +If you encounter "killed" errors during initialization on macOS, apply the codesign fix mentioned earlier. diff --git a/knowledge-base/seid/install-a-specific-version-of-seid.md b/knowledge-base/seid/install-a-specific-version-of-seid.md new file mode 100644 index 00000000..615d0799 --- /dev/null +++ b/knowledge-base/seid/install-a-specific-version-of-seid.md @@ -0,0 +1,151 @@ +--- +title: 'How do I install a specific version of seid?' +description: 'How do I install a specific version of seid?' +--- + +# How do I install a specific version of seid? + +To install a specific version of `seid`: + +### Method 1: Using Git Tags + +``` +# Clone the repository +git clone https://github.com/sei-protocol/sei-chain.git +cd sei-chain + +# List available tags/versions +git tag + +# Checkout specific version +git checkout v3.5.0 # Replace with your desired version + +# Build the binary +make install + +# Verify version +seid version + +``` + +### Method 2: Using Release Binaries + +``` +# For macOS (replace version as needed) +wget https://github.com/sei-protocol/sei-chain/releases/download/v3.5.0/sei-chain_3.5.0_Darwin_arm64.tar.gz +tar -xzf sei-chain_3.5.0_Darwin_arm64.tar.gz +sudo mv build/seid /usr/local/bin/ + +# For Linux +wget https://github.com/sei-protocol/sei-chain/releases/download/v3.5.0/sei-chain_3.5.0_Linux_amd64.tar.gz +tar -xzf sei-chain_3.5.0_Linux_amd64.tar.gz +sudo mv build/seid /usr/local/bin/ + +``` + +### Upgrading Between Versions + +``` +# Save your node key/config if needed +cp -r ~/.sei/config/priv_validator_key.json ~/backup/ +cp -r ~/.sei/config/node_key.json ~/backup/ + +# Install new version (using either method above) + +# Restore config if needed +cp ~/backup/priv_validator_key.json ~/.sei/config/ +cp ~/backup/node_key.json ~/.sei/config/ + +``` + +After installation, remember to apply the codesign fix on macOS if needed: + +``` +codesign --sign - --force $(which seid) + +``` + +## How do I debug Sei chain synchronization issues? + +If your node is having synchronization issues: + +### Check Sync Status + +``` +# Check if node is still catching up +seid status | grep catching_up + +# See current block height +seid status | grep latest_block_height + +# Compare with network block height (via public RPC) +curl -s https://sei-rpc.polkachu.com/status | jq '.result.sync_info.latest_block_height' + +``` + +### Diagnose Sync Problems + +``` +# Check logs for errors +tail -f ~/.sei/log/app.log + +# Get more detailed sync status +seid status + +# Check connected peers +curl -s http://localhost:26657/net_info | jq '.result.peers | length' + +``` + +### Solutions for Sync Issues + +- **Use State Sync for Quick Catch-up**: + +``` +# Stop node +pkill seid + +# Reset data (not config) +seid tendermint unsafe-reset-all + +# Configure state sync in ~/.sei/config/config.toml +# [statesync] +# enable = true +# rpc_servers = "https://sei-rpc.polkachu.com:443,https://sei-rpc.theamsolutions.info:443" +# trust_height = +# trust_hash = "" + +# Restart node +seid start + +``` + +- **Use Snapshot**: + +``` +# Stop node +pkill seid + +# Reset data +seid tendermint unsafe-reset-all + +# Download and extract snapshot +wget https://snapshots.polkachu.com/snapshots/sei/sei_latest.tar.lz4 +lz4 -dc sei_latest.tar.lz4 | tar -xf - -C ~/.sei + +# Restart node +seid start + +``` + +- **Update Configuration for Better Sync**: + +``` +# Edit ~/.sei/config/config.toml +# Set these values: +# [p2p] +# persistent_peers = "" +# seeds = "" +# max_num_inbound_peers = 50 +# max_num_outbound_peers = 50 +``` diff --git a/knowledge-base/seid/install-the-sei-cli-tools-on-different-operating.md b/knowledge-base/seid/install-the-sei-cli-tools-on-different-operating.md new file mode 100644 index 00000000..43032b86 --- /dev/null +++ b/knowledge-base/seid/install-the-sei-cli-tools-on-different-operating.md @@ -0,0 +1,84 @@ +--- +title: 'How do I install the Sei CLI tools on different operating systems?' +description: 'How do I install the Sei CLI tools on different operating systems?' +--- + +# How do I install the Sei CLI tools on different operating systems? + +### macOS Installation + +**Method 1: Using the Install Script** + +``` +# One-line installer (bash) +curl -sSL https://raw.githubusercontent.com/sei-protocol/sei-chain/main/scripts/quick_install.sh | bash + +# Verify installation +seid version + +``` + +**Method 2: Building from Source** + +``` +# Prerequisites: Install Go 1.21+ first +brew install go@1.21 + +# Clone the repository +git clone https://github.com/sei-protocol/sei-chain.git +cd sei-chain + +# Build the binary +make install + +# Verify installation +seid version + +``` + +### Linux Installation + +**Ubuntu/Debian** + +``` +# Update and install dependencies +sudo apt update +sudo apt install -y build-essential git curl wget jq + +# Install Go (if not installed) +wget -q -O - https://git.io/vQhTU | bash -s -- --version 1.21.0 +source ~/.profile + +# Clone and build +git clone https://github.com/sei-protocol/sei-chain.git +cd sei-chain +make install + +# Verify installation +seid version + +``` + +**CentOS/RHEL/Fedora** + +``` +# Install dependencies +sudo dnf install -y git curl wget make gcc + +# Install Go (if not installed) +wget -q -O - https://git.io/vQhTU | bash -s -- --version 1.21.0 +source ~/.profile + +# Clone and build +git clone https://github.com/sei-protocol/sei-chain.git +cd sei-chain +make install + +# Verify installation +seid version + +``` + +### Windows Installation + +The recommended approach for Windows users is to use WSL (Windows Subsystem for Linux) and follow the Linux installation instructions. diff --git a/knowledge-base/seid/my-seid-command-get-killed-immediately-on-macos.md b/knowledge-base/seid/my-seid-command-get-killed-immediately-on-macos.md new file mode 100644 index 00000000..c3b6a8bc --- /dev/null +++ b/knowledge-base/seid/my-seid-command-get-killed-immediately-on-macos.md @@ -0,0 +1,99 @@ +--- +title: 'Why does my seid command get killed immediately on macOS?' +description: 'Why does my seid command get killed immediately on macOS?' +--- + +# Why does my seid command get killed immediately on macOS? + +Many macOS users encounter an issue where the `seid` command is killed immediately after execution, often showing an error like `zsh: killed seid`. This typically happens because: + +- The binary isn't properly code-signed for macOS security + +- There may be memory limitations or conflicts + +- macOS security features (Gatekeeper) might be blocking execution + +### Solution: Re-sign the Binary + +The most effective solution is to re-sign the `seid` binary: + +``` +# Find the binary location (typically in ~/go/bin/) +which seid +# Output: /Users/yourusername/go/bin/seid + +# Re-sign the binary +codesign --sign - --force ~/go/bin/seid + +# Verify it works now +seid version + +``` + +This issue often occurs after macOS updates or when upgrading the binary. The codesigning process tells macOS the binary is safe to execute and prevents it from being terminated by security mechanisms. + +### Alternative Solutions + +If re-signing doesn't work: + +- **Check Memory Issues**: + +``` +# Run with verbose logging +GODEBUG=madvdontneed=1 seid start + +``` + +- **Reinstall from Source**: + +``` +cd sei-chain +git pull +make install + +``` + +- **Check for Conflicts**: + +``` +# See if process is being killed by system +log show --predicate 'eventMessage contains "seid"' --last 1h + +``` + +## How do I fix "seienv propose-upgrade" being killed immediately? + +If `seienv propose-upgrade` is being killed immediately (similar to the error shown below), it's usually due to the same code signing issues mentioned above: + +``` +seienv propose-upgrade v6.0.6 --seconds 300 +2 err | 08:27:19 AM +[1] 62560 killed seienv propose-upgrade v6.0.6 --seconds 300 + +``` + +### Solution: + +- **Re-sign the seienv binary**: + +``` +which seienv +# Output: /Users/yourusername/go/bin/seienv + +codesign --sign - --force ~/go/bin/seienv + +# Test it +seienv version + +``` + +- **If that doesn't work, rebuild from source**: + +``` +git clone https://github.com/sei-protocol/sei-chain.git +cd sei-chain/sei-env +make install + +``` + +This issue is common on macOS systems, especially after system updates. diff --git a/knowledge-base/seid/troubleshoot-performance-issues-with-the-sei-cli.md b/knowledge-base/seid/troubleshoot-performance-issues-with-the-sei-cli.md new file mode 100644 index 00000000..b617eb0c --- /dev/null +++ b/knowledge-base/seid/troubleshoot-performance-issues-with-the-sei-cli.md @@ -0,0 +1,69 @@ +--- +title: 'How can I troubleshoot performance issues with the Sei CLI tools?' +description: 'How can I troubleshoot performance issues with the Sei CLI tools?' +--- + +# How can I troubleshoot performance issues with the Sei CLI tools? + +If you're experiencing performance issues with Sei CLI tools: + +### 1. Check System Resources + +``` +# Check memory usage +free -m + +# Check disk space +df -h + +# Check CPU usage +top + +``` + +### 2. Enable Debug Logging + +``` +# Set log level to debug +RUST_LOG=debug seid start + +# For Go-based tools +GODEBUG=madvdontneed=1,gctrace=1 seid start + +``` + +### 3. Network Performance Issues + +``` +# Test network latency to RPC +ping -c 5 sei-rpc.polkachu.com + +# Use a closer RPC endpoint +seid config node https://sei-rpc.polkachu.com:443 + +``` + +### 4. Database Corruption + +If you suspect database corruption: + +``` +# Stop seid +pkill seid + +# Reset the database (warning: this deletes chain data) +seid tendermint unsafe-reset-all + +# Restart and sync from scratch (or from snapshot) +seid start + +``` + +### 5. Memory Optimization for macOS + +On macOS, memory handling can cause issues: + +``` +# Run with memory optimizations +GODEBUG=madvdontneed=1 seid start +``` diff --git a/knowledge-base/smart-contracts/optimize-my-smart-contracts-to-use-less-gas-on.md b/knowledge-base/smart-contracts/optimize-my-smart-contracts-to-use-less-gas-on.md new file mode 100644 index 00000000..696996b2 --- /dev/null +++ b/knowledge-base/smart-contracts/optimize-my-smart-contracts-to-use-less-gas-on.md @@ -0,0 +1,229 @@ +--- +title: 'How can I optimize my smart contracts to use less gas on Sei Network?' +description: 'How can I optimize my smart contracts to use less gas on Sei Network?' +--- + +# How can I optimize my smart contracts to use less gas on Sei Network? + +While Sei's parallel execution model already provides lower gas costs compared to many other EVM chains, optimizing your contracts can further reduce costs and improve performance. This guide covers Sei-specific and general EVM gas optimization techniques. + +## Sei-Specific Optimizations + +### Leverage Parallel Execution + +Sei's parallel execution model works best when: + +- **Minimize State Overlap**: Design contracts to reduce shared state access between unrelated transactions. + +- **Batch Related Operations**: Group related operations in single transactions where possible. + +- **Use Events Strategically**: Emit events for off-chain tracking instead of storing unnecessary data on-chain. + +### Use Sei Precompiles + +Sei's precompiled contracts are optimized implementations that cost less gas than equivalent Solidity code: + +- **Oracle Price Feeds** (`0x...1008`): Use the Oracle precompile instead of implementing your own oracle solution. + +- **Bank Operations** (`0x...1001`): Leverage native token transfers for better performance. + +- **Address Management** (`0x...1004`): Use for efficient address conversions and validation. + +- **IBC Transfers** (`0x...1009`): Enable cross-chain communication with minimal gas. + +## General EVM Optimizations + +### Storage Optimization + +Storage operations are among the most expensive EVM operations: + +``` +// ❌ Expensive: Uses multiple storage slots +uint8 public value1; +uint8 public value2; +uint8 public value3; + +// ✅ Efficient: Packs variables into a single storage slot +uint8 public value1; +uint8 public value2; +uint8 public value3; + +``` + +- **Variable Packing**: Group smaller variables together to fit in a single 32-byte storage slot. + +- **Use `bytes32` Instead of String**: When possible, use fixed-size bytes32 instead of dynamic strings. + +- **Consider Memory vs Storage**: Use memory for temporary data manipulation. + +### Computation Optimization + +- **Avoid Loops with Unknown Bounds**: They can consume unpredictable amounts of gas. + +- **Cache Array Length in Loops**: + +``` +// ❌ Expensive: Reads length on each iteration +for (uint i = 0; i length; i++) { ... } + +// ✅ Efficient: Reads length once +uint length = array.length; +for (uint i = 0; i length; i++) { ... } + +``` + +- **Short-circuit Evaluation**: Order conditions to evaluate cheaper checks first. + +``` +// ❌ Expensive if msg.sender check is usually false +function example(uint x) external { + if (complexCalculation(x) && msg.sender == owner) { ... } +} + +// ✅ Efficient: Checks cheaper condition first +function example(uint x) external { + if (msg.sender == owner && complexCalculation(x)) { ... } +} + +``` + +### Function Optimization + +- **Function Visibility**: Use the most restrictive visibility modifier appropriate: + +`external` is cheaper than `public` for functions called from outside + +- `internal` is cheaper than `private` for functions called within the contract + +- **View and Pure Functions**: Mark functions as `view` or `pure` when appropriate. + +- **Function Modifiers vs. Functions**: + +``` +// ❌ Less efficient for complex logic +modifier checkStuff() { + // Complex validation logic here + _; +} + +// ✅ More efficient for complex logic +function _checkStuff() internal view { + // Complex validation logic here +} + +function doSomething() external { + _checkStuff(); + // Function logic +} + +``` + +### Gas-Efficient Patterns + +- **Replace Expensive Operations**: + +Use bitwise operations instead of multiplication/division where possible + +- Use `unchecked` blocks for arithmetic when overflow is impossible + +``` +// ❌ Standard with overflow checks +function increment(uint x) external returns (uint) { + return x + 1; +} + +// ✅ Gas efficient for trusted inputs +function increment(uint x) external returns (uint) { + unchecked { return x + 1; } +} + +``` + +- **Gas-Efficient Libraries**: Use battle-tested libraries like OpenZeppelin's. + +## Testing Gas Efficiency + +To measure the impact of your optimizations: + +- **Use Hardhat's Gas Reporter**: + +``` +npm install --save-dev hardhat-gas-reporter + +``` + +In `hardhat.config.ts`: + +``` +import "hardhat-gas-reporter"; + +export default { + // ... other config + gasReporter: { + enabled: true, + currency: 'USD', + gasPrice: 10, // Adjust to Sei's typical gas price + } +}; + +``` + +- **Analyze Contract Size**: Use `npx hardhat size-contracts` to ensure you're not approaching the 24KB contract size limit. + +## Real-World Example + +Here's a before and after example of gas optimization: + +``` +// ❌ Before optimization +contract Expensive { + string[] private data; + + function addData(string calldata newData) external { + data.push(newData); + } + + function processData() external { + for (uint i = 0; i // Process each item + processItem(data[i]); + } + } + + function processItem(string memory item) internal { + // Process logic... + } +} + +// ✅ After optimization +contract Optimized { + bytes32[] private data; + + function addData(bytes32 newData) external { + data.push(newData); + } + + function processData() external { + uint length = data.length; + for (uint i = 0; i // Process each item + processItem(data[i]); + } + } + + function processItem(bytes32 item) internal pure { + // Process logic... + } +} + +``` + +## Benefits of Gas Optimization on Sei + +Gas optimization on Sei provides several advantages: + +- **Lower Transaction Costs**: Obvious benefit of reduced fees. + +- **Higher Transaction Throughput**: More efficient contracts enable more operations per transaction. + +- **Better User Experience**: Faster transactions with lower fees improve UX. + +- **Reduced Network Congestion**: Efficient contracts help the entire network perform better. diff --git a/knowledge-base/smart-contracts/seis-parallel-transaction-execution-work-and-how.md b/knowledge-base/smart-contracts/seis-parallel-transaction-execution-work-and-how.md new file mode 100644 index 00000000..c5cd1115 --- /dev/null +++ b/knowledge-base/smart-contracts/seis-parallel-transaction-execution-work-and-how.md @@ -0,0 +1,66 @@ +--- +title: "How does Sei's parallel transaction execution work and how does it benefit my dApps?" +description: "How does Sei's parallel transaction execution work and how does it benefit my dApps?" +--- + +# How does Sei's parallel transaction execution work and how does it benefit my dApps? + +Sei's EVM implementation features a powerful **Optimistic Concurrency Control (OCC)** mechanism that enables parallel transaction processing, which is an advancement over Ethereum's sequential execution model. + +## How Parallel Execution Works in Sei + +Sei uses a sophisticated transaction analysis and execution approach: + +- **Transaction Grouping**: The system automatically analyzes transactions to identify which ones can safely run in parallel based on state access patterns. + +- **Optimistic Execution**: Rather than forcing all transactions to execute one after another, Sei processes compatible transactions simultaneously across multiple threads. + +- **Conflict Detection**: The system tracks state read/write operations during execution to detect any conflicts between parallel transactions. + +- **Conflict Resolution**: If conflicts are detected, affected transactions are re-executed in a deterministic order to ensure consistency. + +- **Finalization**: Successfully executed transactions are committed to the blockchain in a deterministic order. + +## Benefits for Developers and Users + +This parallel execution model provides several key advantages: + +- **Higher Throughput**: Sei can process many more transactions per second than traditional sequential EVMs. + +- **Lower Fees**: Increased throughput leads to reduced congestion and lower gas costs during high-demand periods. + +- **Faster Finality**: Transactions confirm more quickly, improving user experience. + +- **No Code Changes Required**: Your existing Solidity contracts work without modification - the parallelization happens at the protocol level. + +## Technical Considerations + +When developing for Sei's EVM, keep these points in mind: + +- **Deterministic Results**: Despite parallel execution, results are always deterministic - the same transactions will always produce the same outcome. + +- **Contract Interactions**: The system automatically handles dependencies between contracts that interact with each other. + +- **Gas Model**: While execution happens in parallel, gas accounting remains consistent with the Ethereum model. + +- **Flash Loan Protection**: The parallel execution model has built-in protections against flash loan attacks that might exploit parallelism. + +## Performance Expectations + +In real-world conditions, Sei's EVM can achieve: + +- Throughput of thousands of transactions per second (multiple orders of magnitude higher than Ethereum) + +- Confirmation times of less than 1 second + +- Consistent performance even during high network activity + +## Best Practices + +To maximize the benefits of parallel execution: + +- Design contracts that minimize state overlap when possible + +- Consider batching multiple related operations in single transactions + +- Test throughput-sensitive applications under realistic load conditions diff --git a/knowledge-base/smart-contracts/set-up-a-local-development-environment-for.md b/knowledge-base/smart-contracts/set-up-a-local-development-environment-for.md new file mode 100644 index 00000000..085c4cd4 --- /dev/null +++ b/knowledge-base/smart-contracts/set-up-a-local-development-environment-for.md @@ -0,0 +1,265 @@ +--- +title: 'How do I set up a local development environment for building and testing Sei EVM smart contracts?' +description: 'How do I set up a local development environment for building and testing Sei EVM smart contracts?' +--- + +# How do I set up a local development environment for building and testing Sei EVM smart contracts? + +This guide walks you through setting up a complete development environment for building, testing, and deploying smart contracts on Sei's EVM. + +## Prerequisites + +- Node.js v16+ and npm/yarn + +- Git + +- Basic understanding of Solidity and Ethereum development + +## Step 1: Set Up a Sei EVM Project + +[Hardhat](https://hardhat.org/) is a popular development environment for Ethereum that works with Sei EVM. We'll use it for this guide. + +``` +# Create project directory +mkdir sei-evm-project +cd sei-evm-project + +# Initialize npm project +npm init -y + +# Install Hardhat and dependencies +npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-verify dotenv + +# Initialize Hardhat project +npx hardhat init +# Choose "Create a TypeScript project" for better developer experience + +``` + +## Step 2: Configure Hardhat for Sei EVM + +Create/edit `hardhat.config.ts` with Sei network configurations: + +``` +import { HardhatUserConfig } from "hardhat/config"; +import "@nomicfoundation/hardhat-toolbox"; +import "@nomicfoundation/hardhat-verify"; +import * as dotenv from "dotenv"; + +dotenv.config(); + +// Get private key from environment +const PRIVATE_KEY = process.env.PRIVATE_KEY || ""; + +const config: HardhatUserConfig = { + solidity: { + version: "0.8.19", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + networks: { + // Sei Testnet + "sei-testnet": { + url: "https://evm-rpc.testnet.sei.io", + chainId: 1328, + accounts: PRIVATE_KEY ? [PRIVATE_KEY] : [], + }, + // Sei Mainnet + "sei-mainnet": { + url: "https://evm-rpc.sei.io", + chainId: 1329, + accounts: PRIVATE_KEY ? [PRIVATE_KEY] : [], + }, + // Local development network + hardhat: { + chainId: 31337, + }, + }, + etherscan: { + apiKey: { + // Dummy API key - Sei explorer doesn't require a real key + "sei-testnet": "dummy", + "sei-mainnet": "dummy", + }, + customChains: [ + { + network: "sei-testnet", + chainId: 1328, + urls: { + apiURL: "https://testnet.seiexplorer.com/api", + browserURL: "https://testnet.seiexplorer.com", + }, + }, + { + network: "sei-mainnet", + chainId: 1329, + urls: { + apiURL: "https://seiexplorer.com/api", + browserURL: "https://seiexplorer.com", + }, + }, + ], + }, +}; + +export default config; + +``` + +Create a `.env` file to store your private key: + +``` +PRIVATE_KEY=your_private_key_here + +``` + +## Step 3: Create a Simple Smart Contract + +Create a sample contract in `contracts/SimpleStorage.sol`: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +contract SimpleStorage { + uint256 private value; + + event ValueChanged(uint256 newValue); + + function setValue(uint256 newValue) public { + value = newValue; + emit ValueChanged(newValue); + } + + function getValue() public view returns (uint256) { + return value; + } +} + +``` + +## Step 4: Create Deployment Script + +Create a deployment script in `scripts/deploy.ts`: + +``` +import { ethers } from "hardhat"; + +async function main() { + // Get the contract factory + const SimpleStorage = await ethers.getContractFactory("SimpleStorage"); + + // Deploy the contract + console.log("Deploying SimpleStorage..."); + const simpleStorage = await SimpleStorage.deploy(); + + // Wait for deployment to finish + await simpleStorage.deploymentTransaction()?.wait(); + + console.log(`SimpleStorage deployed to: ${await simpleStorage.getAddress()}`); +} + +// Execute deployment +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); + +``` + +## Step 5: Write Tests + +Create a test file in `test/SimpleStorage.ts`: + +``` +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { SimpleStorage } from "../typechain-types"; + +describe("SimpleStorage", function () { + let simpleStorage: SimpleStorage; + + beforeEach(async function () { + const SimpleStorage = await ethers.getContractFactory("SimpleStorage"); + simpleStorage = await SimpleStorage.deploy(); + }); + + it("Should return the initial value as 0", async function () { + expect(await simpleStorage.getValue()).to.equal(0); + }); + + it("Should set the value correctly", async function () { + const tx = await simpleStorage.setValue(42); + await tx.wait(); + expect(await simpleStorage.getValue()).to.equal(42); + }); + + it("Should emit an event when setting value", async function () { + await expect(simpleStorage.setValue(42)) + .to.emit(simpleStorage, "ValueChanged") + .withArgs(42); + }); +}); + +``` + +## Step 6: Compile, Test, and Deploy + +Compile your contracts: + +``` +npx hardhat compile + +``` + +Run tests: + +``` +npx hardhat test + +``` + +Deploy to Sei testnet: + +``` +npx hardhat run scripts/deploy.ts --network sei-testnet + +``` + +## Step 7: Verifying Contract on Sei Explorer + +Verify your deployed contract: + +``` +npx hardhat verify --network sei-testnet + +``` + +## Using Sei-Specific Features + +To interact with Sei's precompiles, you'll need to import the appropriate interface. For example, to use the Oracle precompile: + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +interface ISeiOraclePrecompile { + function getExchangeRate(string calldata denom) external view returns (uint256, uint256); +} + +contract PriceConsumer { + ISeiOraclePrecompile constant oraclePrecompile = + ISeiOraclePrecompile(0x0000000000000000000000000000000000001008); + + function getSeiPrice() external view returns (uint256 price, uint256 timestamp) { + return oraclePrecompile.getExchangeRate("usei"); + } +} + +``` diff --git a/knowledge-base/smart-contracts/use-sei-for-gas-fees-on-sei-evm-is-it-the-same.md b/knowledge-base/smart-contracts/use-sei-for-gas-fees-on-sei-evm-is-it-the-same.md new file mode 100644 index 00000000..125422d4 --- /dev/null +++ b/knowledge-base/smart-contracts/use-sei-for-gas-fees-on-sei-evm-is-it-the-same.md @@ -0,0 +1,36 @@ +--- +title: 'Can I use $SEI for gas fees on Sei EVM? Is it the same token used for native Sei functions?' +description: 'Can I use $SEI for gas fees on Sei EVM? Is it the same token used for native Sei functions?' +--- + +# Can I use $SEI for gas fees on Sei EVM? Is it the same token used for native Sei functions? + +Yes, the native token of the Sei Network, **$SEI**, is the **sole token used for paying gas fees** for all transactions within the Sei EVM environment. + +**Unified Gas Token:** + +Unlike some chains that might use different tokens for different virtual machines or layers, Sei uses $SEI consistently across its entire platform: + +- **EVM Transactions:** When you send a transaction to interact with a Solidity smart contract, deploy a contract, or even just transfer $SEI between EVM addresses (`0x...`), the gas cost is calculated and deducted from your EVM address's $SEI balance. + +- **Native Transactions:** Similarly, if you perform native actions like staking $SEI or voting on governance proposals using your native `sei1...` address, the gas fees for those transactions are also paid in $SEI, deducted from your native address's balance. + +**Important Distinction: Balances are Separate** + +While the *same* $SEI token is used, the balance held by your EVM (`0x...`) address is distinct from the balance held by your Native (`sei1...`) address. + +- To pay for EVM transaction gas, you need $SEI specifically in your **EVM address balance** (visible in MetaMask). + +- To pay for native transaction gas, you need $SEI in your **Native address balance**. + +If your EVM address balance is zero, you cannot send EVM transactions, even if you have $SEI in your associated native address. You must first transfer $SEI from your native address to your EVM address. + +**Fee Mechanism (EIP-1559):** + +Sei EVM implements a fee mechanism similar to Ethereum's EIP-1559, featuring: + +- A dynamic **Base Fee** (paid in $SEI per unit of gas) that adjusts based on network congestion. + +- A **Priority Fee** (or tip, paid in $SEI per unit of gas) that you can add to incentivize validators to include your transaction faster. + +The total EVM transaction fee is calculated as: `(Base Fee + Priority Fee) * Gas Used` (paid in $SEI). diff --git a/knowledge-base/smart-contracts/what-security-considerations-should-i-keep-in.md b/knowledge-base/smart-contracts/what-security-considerations-should-i-keep-in.md new file mode 100644 index 00000000..0cf86048 --- /dev/null +++ b/knowledge-base/smart-contracts/what-security-considerations-should-i-keep-in.md @@ -0,0 +1,243 @@ +--- +title: 'What security considerations should I keep in mind when developing smart contracts for Sei EVM?' +description: 'What security considerations should I keep in mind when developing smart contracts for Sei EVM?' +--- + +# What security considerations should I keep in mind when developing smart contracts for Sei EVM? + +While Sei's EVM implementation is compatible with Ethereum, there are Sei-specific security considerations alongside standard EVM security practices you should follow. This guide covers both to help you build secure dApps on Sei. + +## Sei-Specific Security Considerations + +### Parallel Execution Awareness + +Sei's parallel transaction processing can introduce potential edge cases: + +- **Transaction Ordering**: Don't assume transactions will be executed in a specific order, as parallel execution may reorder them within the same block. + +- **Block Information**: Be cautious with block-level information like `block.timestamp` and `block.number` in critical logic, as transactions executing in parallel access the same values. + +- **Flash Loan Protection**: Design your contracts to be resistant to flash loan attacks, which could exploit parallel execution to manipulate markets. + +### Precompile Security + +When using Sei's precompiled contracts: + +- **Input Validation**: Always validate inputs before passing them to precompiles. + +- **Address Association**: For precompiles requiring address association, verify association status before critical operations. + +- **Permission Control**: Implement proper access controls around precompile calls, especially those handling assets or performing sensitive operations. + +### Cross-Environment Considerations + +With Sei's dual native/EVM environment: + +- **Bridge Safety**: When using the native-to-EVM bridge, implement additional verification for high-value transfers. + +- **Address Format Validation**: Verify address formats when accepting native Sei addresses as inputs to avoid misdirected funds. + +## General EVM Security Best Practices + +### Access Control + +``` +// ❌ Insecure: No access control +function withdrawFunds() external { + payable(msg.sender).transfer(address(this).balance); +} + +// ✅ Secure: Proper access control +address public owner; + +constructor() { + owner = msg.sender; +} + +modifier onlyOwner() { + require(msg.sender == owner, "Not owner"); + _; +} + +function withdrawFunds() external onlyOwner { + payable(owner).transfer(address(this).balance); +} + +``` + +- **Role-Based Access**: Consider implementing role-based access using libraries like OpenZeppelin's AccessControl. + +- **Multi-Signature**: For high-value contracts, implement multi-signature requirements for critical operations. + +- **Time Locks**: Add time delays for sensitive operations, allowing monitoring and intervention if necessary. + +### Reentrancy Protection + +``` +// ❌ Vulnerable to reentrancy +function withdraw(uint amount) external { + require(balances[msg.sender] >= amount, "Insufficient balance"); + (bool success, ) = msg.sender.call{value: amount}(""); + require(success, "Transfer failed"); + balances[msg.sender] -= amount; // State change after external call +} + +// ✅ Protected against reentrancy +bool private locked; + +modifier nonReentrant() { + require(!locked, "Reentrant call"); + locked = true; + _; + locked = false; +} + +function withdraw(uint amount) external nonReentrant { + require(balances[msg.sender] >= amount, "Insufficient balance"); + balances[msg.sender] -= amount; // State change before external call + (bool success, ) = msg.sender.call{value: amount}(""); + require(success, "Transfer failed"); +} + +``` + +- **Check-Effects-Interactions Pattern**: Always apply state changes before making external calls. + +- **Reentrancy Guards**: Use nonReentrant modifiers from trusted libraries like OpenZeppelin. + +### Integer Overflow/Underflow + +``` +// ❌ Vulnerable to overflow/underflow (pre-Solidity 0.8.x) +function transfer(address to, uint256 amount) external { + require(balances[msg.sender] >= amount, "Insufficient balance"); + balances[msg.sender] -= amount; + balances[to] += amount; // Could overflow +} + +// ✅ Safe with Solidity 0.8.x built-in checks +// Or use SafeMath for earlier versions + +``` + +- **Use Recent Solidity Version**: Solidity 0.8.x includes built-in overflow/underflow checks. + +- **SafeMath**: For older Solidity versions, use SafeMath library. + +- **Unchecked Operations**: Only use `unchecked` blocks when you've verified overflow is impossible. + +### External Calls + +``` +// ❌ Unsafe external call +function unsafeCall(address target, bytes memory data) external { + (bool success, ) = target.call(data); + // Missing success check +} + +// ✅ Safe external call +function safeCall(address target, bytes memory data) external { + (bool success, bytes memory returnData) = target.call(data); + require(success, "External call failed"); + // Additionally validate returnData if needed +} + +``` + +- **Always Check Return Values**: Verify the success of external calls. + +- **Avoid Assuming Call Success**: Implement proper error handling for failed calls. + +- **Validate External Contract Addresses**: Verify addresses before making calls. + +### Front-Running Protection + +- **Commit-Reveal Schemes**: For operations sensitive to transaction ordering. + +- **Minimum/Maximum Acceptable Values**: Include parameters to specify acceptable slippage. + +- **Timeouts**: Implement expiration timestamps for pending operations. + +### Gas Considerations + +- **Avoid Unbounded Operations**: Functions shouldn't depend on unbounded data structures. + +- **Gas Limits**: Be aware of block gas limits when designing operations that might process large datasets. + +## Testing & Verification + +### Comprehensive Testing + +- **Unit Tests**: Test individual components with libraries like Hardhat's testing framework. + +- **Integration Tests**: Test contract interactions to ensure they work together properly. + +- **Fuzz Testing**: Use tools like Echidna to find edge cases through randomized inputs. + +### Security Audits + +- **Internal Reviews**: Have team members review each other's code. + +- **External Audits**: Consider professional audits for high-value contracts. + +- **Bug Bounties**: Implement bug bounty programs to incentivize security findings. + +## Deployment Practices + +### Upgradeability Considerations + +``` +// Example using OpenZeppelin's upgradeable contracts +contract MyUpgradeableContract is Initializable, UUPSUpgradeable { + function initialize() public initializer { + // Initialization code instead of constructor + } + + function _authorizeUpgrade(address) internal override onlyOwner {} +} + +``` + +- **Transparent vs UUPS**: Choose an upgradeability pattern appropriate for your needs. + +- **Initialization**: Ensure proper initialization of upgradeable contracts. + +- **Storage Layout**: Be cautious with storage layout changes in upgrades. + +### Emergency Preparedness + +- **Circuit Breakers**: Implement pause functionality for critical operations. + +- **Recovery Mechanisms**: Plan for potential security incidents. + +- **Key Management**: Use proper key management practices for admin/owner accounts. + +## Sei Testnet Usage + +- **Test Thoroughly on Testnet**: Always test on Sei testnet before mainnet deployment. + +- **Simulate Mainnet Conditions**: Test with realistic conditions similar to expected mainnet usage. + +- **Verify Precompile Behavior**: Ensure precompiles behave as expected in your specific use case. + +## Common Vulnerabilities Checklist + +- [ ] Reentrancy vulnerabilities + +- [ ] Access control issues + +- [ ] Integer overflows/underflows (pre-Solidity 0.8.x) + +- [ ] Unchecked external calls + +- [ ] Front-running vulnerabilities + +- [ ] Logic errors in business rules + +- [ ] Dependency vulnerabilities + +- [ ] Gas-related issues + +- [ ] Oracle manipulation vulnerabilities + +- [ ] Flash loan attack vectors diff --git a/knowledge-base/staking/choose-a-validator-for-staking.md b/knowledge-base/staking/choose-a-validator-for-staking.md new file mode 100644 index 00000000..087e9779 --- /dev/null +++ b/knowledge-base/staking/choose-a-validator-for-staking.md @@ -0,0 +1,118 @@ +--- +title: 'How To Choose a Validator for Staking' +description: 'How To Choose a Validator for Staking' +--- + +# How To Choose a Validator for Staking + +Choosing good validators is crucial for both your staking returns and the health of the Sei Network. Here are the key factors to consider when making your selection: + +#### **Key Validator Metrics to Evaluate** + +- **Commission Rate** + +This is the percentage of staking rewards the validator keeps + +- Lower commission rates mean more rewards for you + +- Typical range: 1-10% + +- Be cautious of 0% commissions as they may not be sustainable long-term + +- **Voting Power** + +The percentage of the network's total stake that this validator controls + +- For network health, consider delegating to validators with lower voting power + +- Spreading stake across many validators improves decentralization + +- **Uptime / Performance** + +Look for validators with 99%+ uptime + +- Check if they've been recently jailed for downtime + +- Consistent performance means better security and fewer missed rewards + +- **Security Practices** + +Research the validator's infrastructure setup + +- Established validators often share their security measures publicly + +- Look for mentions of redundancy, monitoring, and disaster recovery + +- **Governance Participation** + +Active participation in governance shows commitment to the network + +- Check their voting history on past proposals + +- Some validators publish their governance positions and reasoning + +- **Community Contributions** + +Does the validator contribute to Sei's ecosystem? + +- Contributions can include running infrastructure, developing tools, creating educational content + +- Active community members are more likely to remain committed long-term + +### How to Research Validators + +#### Using SeiScan + +- Visit [SeiScan](https://www.seiscan.app/) + +- Navigate to the "Validators" tab + +- Sort by various metrics (commission, voting power) + +- Click on individual validators to see detailed profiles + +#### Checking Validator Websites and Social Media + +- Many validators maintain websites explaining their operations + +- Check their Twitter/Discord for engagement with the community + +- Look for transparency in their communications + +### Risk Management Strategies + +#### Diversification + +- Consider spreading your stake across 3-5 validators + +- This reduces the impact if one validator faces issues + +- Also improves network decentralization + +#### Regular Review + +- Periodically check your validators' performance + +- Be prepared to redelegate if a validator changes commission or has performance issues + +#### Monitor for Changes + +- Commission rates can change (usually with notice) + +- Validators can become inactive or be slashed + +- Stay informed about your chosen validators + +### Common Questions + +**Q: Is it better to choose validators with higher or lower voting power?** +A: From a network health perspective, choosing validators with lower voting power helps improve decentralization. However, larger validators may have more resources for reliable infrastructure. + +**Q: How important is the commission rate?** +A: While important for your returns, it shouldn't be the only factor. A reliable validator with slightly higher commission might be better than an unreliable one with low commission. + +**Q: What happens if my validator gets slashed?** +A: A portion of your staked tokens (up to 5% depending on the infraction) could be slashed if your validator double-signs or commits other serious violations. + +**Q: Can I move my stake if I choose poorly?** +A: Yes, you can redelegate your stake to a different validator without waiting for the unbonding period. However, you can only redelegate from the same validator once every 7 days. diff --git a/knowledge-base/staking/claim-staking-rewards.md b/knowledge-base/staking/claim-staking-rewards.md new file mode 100644 index 00000000..f6176356 --- /dev/null +++ b/knowledge-base/staking/claim-staking-rewards.md @@ -0,0 +1,102 @@ +--- +title: 'How To Claim Staking Rewards' +description: 'How To Claim Staking Rewards' +--- + +# How To Claim Staking Rewards + +#### **Method 1: Using SeiScan** + +- Visit [SeiScan](https://www.seiscan.app/) + +- Connect your **Keplr wallet** or other Cosmos wallet + +- Navigate to the **"Staking"** tab + +- You'll see your delegations and accumulated rewards + +- Click **"Claim All Rewards"** to claim from all validators at once + +- Alternatively, find a specific validator and click **"Claim"** next to their entry + +- Review the transaction details and click **"Submit"** + +- Approve the transaction in your wallet + +#### **Method 2: Using Keplr Extension** + +- Open the **Keplr browser extension** + +- Select **"Sei"** from the network dropdown + +- Look for the **"Claim"** button in the Staking section + +- Click to claim all available rewards + +- Approve the transaction + +#### **Method 3: Using a Third-Party App (e.g., Restake)** + +- Visit [Restake.app/sei](https://restake.app/sei) + +- Connect your wallet + +- View your delegations and rewards + +- Click **"Claim All"** button + +- Confirm the transaction in your wallet + +### Explanation & Tips + +#### Reward Accumulation + +- Staking rewards accumulate **automatically** with each block + +- You don't need to claim frequently - rewards continue to grow whether claimed or not + +- Rewards are not automatically compounded (re-staked) unless you use auto-compound services + +#### Gas Fees Consideration + +- Claiming rewards requires a transaction fee + +- If you have small rewards across many validators, consider waiting until the rewards are larger + +- Claiming from multiple validators in one transaction is more gas-efficient than individual claims + +#### Auto-Compounding Options + +- Some validators offer **REStake** services, which automatically claim and re-stake your rewards + +- This requires granting permission to the validator + +- You can configure this on platforms that allow for it. + +#### After Claiming + +- Claimed rewards will be added to your **available balance** (not automatically re-staked) + +- You can then choose to: + +Stake these rewards again + +- Transfer them elsewhere + +- Bridge them to EVM + +- Hold them in your wallet + +### Common Questions + +**Q: How often should I claim my rewards?** +A: This depends on your staking amount. For smaller amounts (under 100 SEI), claiming monthly or quarterly is reasonable. For larger amounts, weekly claiming might make sense. + +**Q: Do rewards compound automatically?** +A: No, not by default. You need to manually claim and re-stake, or use an auto-compounding service. + +**Q: Are there tax implications for claiming rewards?** +A: In many jurisdictions, staking rewards may be considered income at the time they're claimed. Consult a tax professional for advice specific to your situation. + +**Q: What happens to unclaimed rewards if I unstake?** +A: When you initiate unbonding, any unclaimed rewards should be claimed first. Some interfaces automatically prompt you to claim rewards when unstaking. diff --git a/knowledge-base/staking/stake-sei-tokens-and-what-is-the-current-apr-or.md b/knowledge-base/staking/stake-sei-tokens-and-what-is-the-current-apr-or.md new file mode 100644 index 00000000..346a0f40 --- /dev/null +++ b/knowledge-base/staking/stake-sei-tokens-and-what-is-the-current-apr-or.md @@ -0,0 +1,101 @@ +--- +title: 'How do I stake SEI tokens, and what is the current APR or staking reward?' +description: 'How do I stake SEI tokens, and what is the current APR or staking reward?' +--- + +# How do I stake SEI tokens, and what is the current APR or staking reward? + +To stake SEI tokens and earn staking rewards: + +### Staking Process: + +**Using Native Wallet**: + +- Install a compatible wallet and add Sei Network + +- Deposit SEI tokens to your wallet + +- Navigate to the "Staking" section in the wallet + +- Browse the list of validators and their details + +- Select a validator and click "Delegate" + +- Enter the amount to stake and confirm + +**Using CLI**: + +``` +# Query validators +seid query staking validators + +# Delegate tokens (10 SEI) to a validator +seid tx staking delegate seivaloper1example... 10000000usei \ + --from mykey \ + --chain-id sei-chain-id \ + --gas auto \ + --fees 5000usei + +``` + +**Using Staking Precompile from EVM**: + +``` +// Staking precompile interface +const stakingContract = new ethers.Contract( + "0x0000000000000000000000000000000000001007", + stakingAbi, + signer +); + +// Get list of validators +const validators = await stakingContract.getValidators(); + +// Delegate tokens +const tx = await stakingContract.delegate( + validators[0], // First validator in the list + ethers.utils.parseUnits("10", 6) // 10 SEI (6 decimals in native) +); + +``` + +### Current Staking APR: + +The current APR for staking SEI tokens varies based on: + +- Total percentage of tokens staked + +- Validator commission rates (typically 5-10%) + +- Network inflation rate + +As of recent data: + +- The network-wide staking APR ranges from approximately 5-10% + +- This can change based on network parameters and staking participation + +To check current APR: + +- Visit [Sei Network explorers](https://www.seiscan.app/) or staking dashboards + +- Use CLI: `seid query mint inflation` + +- Calculate manually: + +``` +APR ≈ (Inflation Rate / Staked Ratio) * (1 - Community Tax) * (1 - Validator Commission) + +``` + +### Important Considerations: + +- **Validator Selection**: Consider reliability, uptime, commission rate, and voting participation + +- **Unbonding Period**: Staked SEI has a 21-day unbonding period during which tokens cannot be transferred and do not earn rewards + +- **Compounding**: To maximize returns, regularly claim and re-stake rewards + +- **Slashing Risk**: If a validator misbehaves, a portion of staked tokens may be slashed (penalized) + +For the most current APR information, check Sei Network's official resources or explorers. diff --git a/knowledge-base/staking/stake-sei-tokens.md b/knowledge-base/staking/stake-sei-tokens.md new file mode 100644 index 00000000..9d2bbfc1 --- /dev/null +++ b/knowledge-base/staking/stake-sei-tokens.md @@ -0,0 +1,108 @@ +--- +title: 'How To Stake SEI Tokens' +description: 'How To Stake SEI Tokens' +--- + +# How To Stake SEI Tokens + +#### **Prerequisites:** + +- You need SEI tokens in a **native Sei wallet** (not EVM) + +- If your tokens are on the EVM side, [bridge them first](https://markdowntohtml.com/Bridging/01-native-evm-bridge.md) + +#### **Method 1: Using SeiScan** + +- Visit [SeiScan](https://www.seiscan.app/) + +- Connect your **Keplr wallet** or other Cosmos wallet + +- Navigate to the **"Staking"** tab + +- Browse the validator list and click on a validator you want to delegate to + +- Click **"Delegate"** + +- Enter the **amount** of SEI you want to stake + +- Review transaction details and click **"Submit"** + +- Approve the transaction in your wallet + +#### **Method 2: Using Keplr Extension** + +- Open the **Keplr browser extension** + +- Select **"Sei"** from the network dropdown + +- Click on the **"Stake"** button + +- Select a validator from the list + +- Enter the **amount** to delegate + +- Click **"Delegate"** and approve the transaction + +#### **Method 3: Using Third-Party Staking Platforms** + +Several platforms offer user-friendly staking interfaces, such as: + +- [Restake.app](https://restake.app/sei) + +- [Cosmostation](https://wallet.cosmostation.io/) + +- [Leap Wallet](https://www.leapwallet.io/) + +Follow their respective interfaces to connect your wallet and stake SEI. + +### Explanation & Tips + +#### Staking Rewards + +- Current network reward rate is approximately **X%** annually (varies with network conditions) + +- Rewards are automatically accumulated and can be claimed manually + +- Staking rewards are subject to the validator's commission rate (typically 1-10%) + +#### Validator Selection Considerations + +- **Commission Rate**: Lower commission means more rewards for you + +- **Voting Power**: Prefer validators with lower voting power to improve network decentralization + +- **Uptime/Performance**: Check for validators with high uptime (99%+) + +- **Governance Participation**: Consider validators who actively participate in governance + +#### Unbonding Period + +- SEI has a **7-day unbonding period** + +- During unbonding, your tokens are **locked** (cannot be transferred or used) + +- You **do not earn rewards** during the unbonding period + +#### Claiming Rewards + +- Visit [SeiScan](https://www.seiscan.app/) or use Keplr + +- Navigate to the staking section + +- Look for "Claim Rewards" button + +- You can claim from all validators at once or individually + +### Common Questions + +**Q: Can I stake from my EVM wallet (MetaMask)?** +A: No, staking is only available on the native Sei chain. You must first bridge your tokens from EVM to native Sei. + +**Q: Is there a minimum amount required for staking?** +A: While there is no enforced minimum, very small amounts may result in transaction fees outweighing rewards. Consider staking at least 10 SEI. + +**Q: What happens if my chosen validator gets slashed?** +A: A portion of your staked tokens (currently up to 5%) could be slashed if your validator misbehaves. This is why validator selection is important. + +**Q: Can I move my stake between validators?** +A: Yes, you can redelegate your stake to a different validator without waiting for the unbonding period. However, you can only redelegate from the same validator once every 7 days. diff --git a/knowledge-base/transactions/fix-invalid-sender-errors-on-sei-evm.md b/knowledge-base/transactions/fix-invalid-sender-errors-on-sei-evm.md new file mode 100644 index 00000000..e031266d --- /dev/null +++ b/knowledge-base/transactions/fix-invalid-sender-errors-on-sei-evm.md @@ -0,0 +1,36 @@ +--- +title: "How Do I Fix "Invalid Sender" Errors on Sei EVM?" +description: "How Do I Fix "Invalid Sender" Errors on Sei EVM?" +--- + +# How Do I Fix "Invalid Sender" Errors on Sei EVM? + +### The Problem + +When trying to send a transaction or interact with a contract on Sei EVM using MetaMask or a script, the transaction fails quickly with an error like "Invalid Sender", "Sender account not found", "Nonce too low", "Nonce too high", or similar validation errors. + +### Solution Steps + +This usually means the transaction failed basic checks *before* contract execution. Common fixes: + +- **Check SEI Balance:** Ensure the sending EVM address (`0x...`) has enough liquid SEI on the Sei EVM network to cover the transaction's gas cost (Gas Limit \* Gas Price). + +- **Fix Nonce Issues (MetaMask):** + +Look for any other **pending transactions** in MetaMask's Activity tab. Try to **Cancel** or **Speed Up** the *oldest* pending transaction first. + +- If no pending tx visible or cancelling doesn't work, try **Reset Account**: Settings > Advanced > Reset Account. (This clears local nonce tracking; safe for funds but you may need to resubmit recent txs). + +- **Fix Nonce Issues (Code):** Ensure your script correctly fetches the *current* nonce before sending: `nonce = await provider.getTransactionCount(wallet.address, 'pending')`. Handle potential race conditions if sending rapidly. + +- **Check Wallet/Network:** Ensure you're using an EVM wallet (MetaMask) connected to the correct Sei EVM Network (Chain ID `1329`). + +### Explanation and Tips + +- **Cause:** The network validates sender balance, nonce sequence, and signature *before* executing the transaction. Failure here results in these errors. + +- **Nonce Explained:** Nonce is a transaction counter per address, starting at 0. Transactions must be mined in sequential nonce order (0, 1, 2...). "Nonce too low" means you tried to reuse a nonce. "Nonce too high" means a previous nonce is still pending. + +- **RPC Issues:** Rarely, the RPC node might be faulty. Try switching to an alternative public RPC endpoint in MetaMask settings (e.g., `https://sei-evm.publicnode.com`). + +- **Malformed Tx (Developers):** Double-check all transaction parameters (`to`, `value`, `data`, `chainId`, `gasLimit`, etc.) and the signing process in your code. diff --git a/knowledge-base/transactions/fix-out-of-gas-errors-on-sei-evm.md b/knowledge-base/transactions/fix-out-of-gas-errors-on-sei-evm.md new file mode 100644 index 00000000..9095014c --- /dev/null +++ b/knowledge-base/transactions/fix-out-of-gas-errors-on-sei-evm.md @@ -0,0 +1,40 @@ +--- +title: "How Do I Fix "Out of Gas" Errors on Sei EVM?" +description: "How Do I Fix "Out of Gas" Errors on Sei EVM?" +--- + +# How Do I Fix "Out of Gas" Errors on Sei EVM? + +### The Problem + +When sending a transaction or interacting with a smart contract on Sei EVM, it failed immediately with an "Out of Gas" error message. + +### Solution Steps + +This error means the transaction needed more computation than allowed by its **Gas Limit**. + +- **Retry the transaction**. + +- Before confirming in your wallet (e.g., MetaMask), find the **Gas Limit** setting (often under "Edit", "Advanced", or "Site Suggested" gas fees). + +- **Increase the Gas Limit** value. Try doubling the suggested limit or enter a significantly larger number (e.g., `1000000` or more for complex contract interactions). + +- Confirm and send the transaction again. + +### Explanation & Tips + +- **Gas Limit vs. Gas Price:** Do **not** confuse Gas Limit with Gas Price (or Max Fee/Priority Fee). "Out of Gas" relates *only* to the Gas **Limit**. Increasing the price won't fix it. + +- **Cause:** Every operation costs gas. The Gas Limit is your budget for computation. If the execution cost exceeds the budget, it fails. + +- **Why Increase?** Wallets sometimes underestimate the required limit, especially for contract interactions more complex than simple transfers. Sei's gas schedule might also differ slightly from other EVM chains. + +- **Developers:** + +If deploying/testing contracts, ensure your scripts (ethers.js, Hardhat) specify a sufficient `gasLimit` in transaction overrides: `contract.deploy({ gasLimit: 3000000 });` + +- Check your contract code for very gas-heavy operations (e.g., loops over large arrays, complex math, heavy storage writes). + +- Consider optimizing contract logic or splitting complex operations into multiple transactions. + +- **Balance Check:** While not directly causing the error, ensure you still have enough SEI to cover the *potential* cost (Gas Limit \* Gas Price). diff --git a/knowledge-base/transactions/fix-the-incorrect-network-error-in-metamask-for.md b/knowledge-base/transactions/fix-the-incorrect-network-error-in-metamask-for.md new file mode 100644 index 00000000..459f40cf --- /dev/null +++ b/knowledge-base/transactions/fix-the-incorrect-network-error-in-metamask-for.md @@ -0,0 +1,50 @@ +--- +title: "How Do I Fix the "Incorrect Network" Error in MetaMask for Sei?" +description: "How Do I Fix the "Incorrect Network" Error in MetaMask for Sei?" +--- + +# How Do I Fix the "Incorrect Network" Error in MetaMask for Sei? + +### The Problem + +After adding Sei Network to MetaMask, it displays an "Incorrect Network" message, or transactions fail immediately, suggesting MetaMask isn't properly connected to the Sei EVM chain. + +### Solution Steps + +This almost always means the network configuration details in MetaMask are wrong, especially the Chain ID. + +- Open **MetaMask**. + +- Click the **network dropdown** menu (top-left). + +- Find **Sei Network** in your list and click the settings/edit icon next to it (might need to go to Settings > Networks). + +- **Verify ALL details** meticulously against the official mainnet settings: + +Network Name: `Sei Network` (This is just a label, but good to be consistent) + +- New RPC URL: `https://evm-rpc.sei-apis.com` + +- **Chain ID:** `1329` (**This MUST be exact**) + +- Currency Symbol: `SEI` + +- Block Explorer URL: `https://seitrace.com` (Optional, but helpful) + +- Correct any discrepancies, especially the **Chain ID**. + +- Click **"Save"**. + +- Switch away from Sei Network and then back to it to ensure the connection refreshes. + +### Explanation & Tips + +- **Cause:** MetaMask uses the Chain ID to identify the network. If the ID doesn't match what the connected RPC endpoint reports (`eth_chainId`), MetaMask considers it the wrong network. + +- **Remove and Re-add:** If verifying/editing doesn't work, try removing the Sei Network configuration entirely from MetaMask (Settings > Networks > Select Sei > Delete/Remove Network) and then add it again carefully using the steps in How Do I Add Sei Network to MetaMask? + +- **RPC URL:** Ensure the RPC URL is also exactly correct. Typos matter. + +- **MetaMask Update:** Ensure your MetaMask extension/app is updated to the latest version. + +- **Browser Cache:** Try clearing your browser cache as a rare potential fix. diff --git a/knowledge-base/transactions/my-bridge-transfer-has-been-stuck-for-hours-what.md b/knowledge-base/transactions/my-bridge-transfer-has-been-stuck-for-hours-what.md new file mode 100644 index 00000000..1e3aa308 --- /dev/null +++ b/knowledge-base/transactions/my-bridge-transfer-has-been-stuck-for-hours-what.md @@ -0,0 +1,46 @@ +--- +title: 'My Bridge Transfer Has Been Stuck for Hours, What Now?' +description: 'My Bridge Transfer Has Been Stuck for Hours, What Now?' +--- + +# My Bridge Transfer Has Been Stuck for Hours, What Now? + +### The Problem + +I started a bridge transfer several hours ago. I've checked the explorers, and while the source transaction was successful, nothing has happened on the destination chain, or the process seems completely stalled. Typical troubleshooting steps haven't worked. + +### Solution Steps + +When a bridge transfer is stuck for an extended period (hours, not minutes) despite basic checks, it often requires intervention or investigation by the bridge provider. + +- **Check Bridge Provider Status:** Visit the official website, Discord, or Twitter for the **specific bridge** you used. Check *intensively* for any announcements about ongoing incidents, specific asset/chain delays, or required maintenance. + +- **Use Bridge-Specific Explorer (If available):** Some bridges (like Wormhole, LayerZero) have dedicated explorers where you can paste your *source* TxID to see the detailed status of the cross-chain messaging and execution steps. Check the bridge's documentation for this. + +- **Gather Information:** Collect the following details: + +Source Chain Transaction Hash (TxID). + +- Source Chain Name (e.g., Sei Native, Ethereum). + +- Destination Chain Name (e.g., Sei EVM, Arbitrum). + +- Your Source Address. + +- Your Destination Address. + +- Asset Name and Amount transferred. + +- Approximate Date and Time of the transfer. + +- **Contact Bridge Support:** Find the official support channel for the **bridge provider** (usually Discord, Telegram, or a support portal - **NOT** general Sei support unless using the native Sei Bridge for NativeEVM). Submit a support request with all the information gathered in step 3. + +### Explanation & Tips + +- **Patience is Key:** Investigating stuck cross-chain transactions can take time, even for support teams. Provide clear information and wait for their response. + +- **Potential Causes for Long Stalls:** Severe relayer issues (off-chain components are down/stuck), bridge contract bugs, issues requiring manual intervention by the bridge team, destination chain instability. + +- **Do NOT Send Duplicate Transactions:** Do not try to initiate the exact same bridge transfer again while the first one is potentially stuck mid-process, as this can complicate things. + +- **Security:** Be wary of scammers in support channels. Official support will *never* ask for your seed phrase or private keys. diff --git a/knowledge-base/transactions/my-evm-address-show-zero-balance-after-association.md b/knowledge-base/transactions/my-evm-address-show-zero-balance-after-association.md new file mode 100644 index 00000000..4ca1ddae --- /dev/null +++ b/knowledge-base/transactions/my-evm-address-show-zero-balance-after-association.md @@ -0,0 +1,32 @@ +--- +title: 'Why Does My EVM Address Show Zero Balance After Association?' +description: 'Why Does My EVM Address Show Zero Balance After Association?' +--- + +# Why Does My EVM Address Show Zero Balance After Association? + +It's a common point of confusion, but **address association does not automatically transfer funds** between your Sei Native address and your EVM address. + +Here's why: + +- **Separate Balance Environments:** Although both your `0x...` EVM address and your `sei1...` Native address are derived from the *same* private key, they represent distinct accounts within Sei's different execution layers. Think of them as two separate sub-accounts managed by the same key: + +The **Native (`sei1...`) address** holds $SEI tokens used for native functions like staking and governance, and interacts with native Sei assets. + +- The **EVM (`0x...`) address** holds $SEI tokens specifically formatted for use within the EVM environment – paying gas for EVM transactions and interacting with Solidity smart contracts. + +- **Association Links Identity, Not Funds:** The association process simply creates an on-chain link confirming that both addresses belong to you (i.e., are controlled by the same private key). It **does not** move any $SEI tokens from one address balance to the other. + +**How to Fund Your EVM Address:** + +To see and use $SEI in your EVM wallet (like MetaMask) after association, you need to explicitly send funds *from* your Native (`sei1...`) address *to* your EVM (`0x...`) address. + +This can typically be done through: + +- **Sei-Specific Wallets or Interfaces:** Wallets like Keplr, Leap, or dedicated Sei dashboards often provide functionality to send $SEI between your own native and EVM addresses. + +- **Programmatic Transfer (Advanced):** While less common for typical users, developers could potentially use native Sei transactions or specific bridge/transfer mechanisms if available. + +- *(Self-transfer Note: Standard EVM wallets like MetaMask cannot initiate transfers *from* your native `sei1...` address; the transfer must originate from the native side or a dedicated bridging interface.)* + +Once you transfer $SEI from your native address to your EVM address, it will appear in your MetaMask balance and be available for EVM gas fees and dApp interactions. diff --git a/knowledge-base/transactions/what-can-i-do-if-my-sei-transaction-is-stuck.md b/knowledge-base/transactions/what-can-i-do-if-my-sei-transaction-is-stuck.md new file mode 100644 index 00000000..5cf59097 --- /dev/null +++ b/knowledge-base/transactions/what-can-i-do-if-my-sei-transaction-is-stuck.md @@ -0,0 +1,50 @@ +--- +title: 'What Can I Do If My Sei Transaction is Stuck Pending?' +description: 'What Can I Do If My Sei Transaction is Stuck Pending?' +--- + +# What Can I Do If My Sei Transaction is Stuck Pending? + +### The Problem + +I sent a transaction using MetaMask (EVM) or Keplr (Native) on Sei, but it's been stuck in a "Pending" state for a long time and isn't confirming. + +### Solution Steps + +- **Check Explorer:** Get the Transaction Hash (TxID) from your wallet history. + +For EVM tx: Check [SeiTrace](https://seitrace.com/). + +- For Native tx: Check [SeiScan](https://www.seiscan.app/). + +- *Status Found?* If Failed, note the error and retry. If Success, the issue is elsewhere. If still Pending or Not Found, proceed below. + +- **MetaMask (EVM):** + +Go to the **Activity** tab. + +- Find the pending transaction. + +- Try **"Speed Up"** (resubmit with higher gas price - costs more). + +- If Speed Up fails or isn't desired, try **"Cancel"** (sends a 0 SEI tx with the same nonce - costs gas). + +- *Last Resort:* Settings > Advanced > **Reset Account** (clears local tx history/nonce, doesn't affect funds). Retry the original transaction after resetting. + +- **Keplr (Native):** + +Native transactions usually confirm/fail quickly. Wait at least 5 minutes. + +- If still not confirmed on [SeiScan](https://www.seiscan.app/), it likely never reached the network. + +- **Retry the transaction** ensuring you have enough native SEI for gas. + +### Explanation & Tips + +- **Possible Causes:** Network congestion, low gas price (EVM), incorrect nonce (EVM), RPC node issues. + +- **Nonce Issues (EVM):** Transactions *must* process in order. If an earlier transaction (nonce 5) is stuck, the next (nonce 6) won't confirm until 5 does. Speeding up or cancelling the *earliest* stuck transaction is key. + +- **Gas Price vs. Gas Limit (EVM):** "Speed Up" increases the *gas price* (priority). If the transaction fails with "Out of Gas", you need to increase the *gas limit*. + +- **Network/RPC Check:** Check [Sei Discord](https://discord.gg/sei) for network status. Try switching RPC endpoints in your wallet settings if problems persist. diff --git a/knowledge-base/transactions/why-havent-my-tokens-arrived-after-using-a-bridge.md b/knowledge-base/transactions/why-havent-my-tokens-arrived-after-using-a-bridge.md new file mode 100644 index 00000000..11cc6878 --- /dev/null +++ b/knowledge-base/transactions/why-havent-my-tokens-arrived-after-using-a-bridge.md @@ -0,0 +1,32 @@ +--- +title: "Why Haven't My Tokens Arrived After Using a Bridge?" +description: "Why Haven't My Tokens Arrived After Using a Bridge?" +--- + +# Why Haven't My Tokens Arrived After Using a Bridge? + +### The Problem + +I used the Sei Bridge (or another bridge) to send tokens. The transaction seemed successful on the sending chain, but the tokens haven't appeared in my destination wallet after waiting a reasonable time (e.g., 15-30 minutes, or longer for some bridges). + +### Solution Steps + +- **Confirm Source Tx Success:** Get the transaction hash (TxID) from your source wallet. Verify on the **source chain's explorer** ([SeiScan](https://www.seiscan.app/), [SeiTrace](https://seitrace.com/), Etherscan, etc.) that the transaction was definitely successful. + +- **Check Destination Explorer:** Find your **destination address** on the **destination chain's explorer**. Look for an incoming transaction from the bridge contract around the time you expected arrival. + +- **Allow More Time:** Cross-chain bridging takes time (locking, relaying, minting). Sei NativeEVM is usually fast (1-5 min), but external chains or network congestion can cause significant delays (30+ min is possible). + +- **Add Token Contract (EVM Wallets):** If bridging a non-native token *to* an EVM wallet (MetaMask), you MUST manually add the token's contract address on the **destination chain** (Sei EVM) to MetaMask for the balance to display. Find the correct address via bridge docs or the destination explorer. + +- **Check for Claim Step:** Does the specific bridge require a manual "Claim" transaction on the destination chain? Check the bridge UI or documentation. + +### Explanation & Tips + +- **Common Causes:** Network congestion (source or destination), relayer delays (off-chain parts of the bridge), failure to add token contract to wallet, bridge requiring a manual claim. + +- **Check Bridge Status:** Look for official announcements from the specific bridge provider (Twitter, Discord) about delays or maintenance. + +- **Correct Destination Address?** Double-check the destination address used in the bridge transaction details on the source explorer. + +- **Still Missing?** If hours pass and steps above don't reveal the tokens, contact support for the **specific bridge** you used, providing source TxID, addresses, asset, amount, and time. **See My Bridge Transfer Has Been Stuck for Hours, What Now?** diff --git a/scripts/upload-to-trieve.js b/scripts/upload-to-trieve.js index 0c39b7be..a7c61c7a 100644 --- a/scripts/upload-to-trieve.js +++ b/scripts/upload-to-trieve.js @@ -4,6 +4,7 @@ const path = require('path'); // Configuration const TRIEVE_API_BASE = 'https://api.trieve.ai/api'; const SCRAPED_DOCS_DIR = './public/_scraped-docs'; +const KNOWLEDGE_BASE_DIR = './knowledge-base'; const DELAY_BETWEEN_OPERATIONS = 500; async function uploadToTrieve() { @@ -116,11 +117,13 @@ async function getAllExistingFiles(apiKey, datasetId) { } async function loadScrapedFiles() { + const fileData = []; + + // Load scraped docs (.mdx files) try { const files = await fs.readdir(SCRAPED_DOCS_DIR); const mdxFiles = files.filter((file) => file.endsWith('.mdx')); - const fileData = []; for (const fileName of mdxFiles) { const filePath = path.join(SCRAPED_DOCS_DIR, fileName); const content = await fs.readFile(filePath, 'utf8'); @@ -131,11 +134,57 @@ async function loadScrapedFiles() { filePath }); } + console.log(` 📚 Loaded ${mdxFiles.length} files from scraped docs`); + } catch (error) { + console.warn(`⚠️ Could not load scraped docs: ${error.message}`); + } + + // Load knowledge base files (.md files, recursively) + try { + const kbFiles = await loadKnowledgeBaseFiles(KNOWLEDGE_BASE_DIR); + fileData.push(...kbFiles); + console.log(` 📚 Loaded ${kbFiles.length} files from knowledge base`); + } catch (error) { + console.warn(`⚠️ Could not load knowledge base: ${error.message}`); + } + + return fileData; +} - return fileData; +async function loadKnowledgeBaseFiles(dir, basePath = '') { + const fileData = []; + + try { + const entries = await fs.readdir(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + + if (entry.isDirectory()) { + // Recursively load subdirectories + const subPath = basePath ? `${basePath}/${entry.name}` : entry.name; + const subFiles = await loadKnowledgeBaseFiles(fullPath, subPath); + fileData.push(...subFiles); + } else if (entry.name.endsWith('.md')) { + const content = await fs.readFile(fullPath, 'utf8'); + // Use path-based naming for knowledge base files to avoid collisions + const fileName = basePath ? `kb-${basePath.replace(/\//g, '-')}-${entry.name}` : `kb-${entry.name}`; + + fileData.push({ + fileName, + content, + filePath: fullPath + }); + } + } } catch (error) { - throw new Error(`Failed to load scraped files: ${error.message}`); + // Directory might not exist, that's okay + if (error.code !== 'ENOENT') { + throw error; + } } + + return fileData; } async function compareFiles(existingFiles, scrapedFiles) {