diff --git a/skill/SKILL-CONTRACTS.md b/skill/SKILL-CONTRACTS.md index 99b24d4..fc846ae 100644 --- a/skill/SKILL-CONTRACTS.md +++ b/skill/SKILL-CONTRACTS.md @@ -50,9 +50,9 @@ Use this Skill when the user asks for: These facts must inform every answer involving Sei code or configuration: -1. **400ms block time, instant finality** — use `txResponse.wait(1)`; there is no "safe"/"finalized" distinction +1. **400ms block time, instant finality** — use `txResponse.wait(1)`; `safe`/`finalized`/`latest` all resolve to the same instantly-final block, so just query `latest` 2. **Parallel execution (OCC)** — minimize shared storage writes; partition state by user/asset/id; avoid hot globals -3. **SSTORE gas cost differs by network** — both mainnet (pacific-1) and testnet (atlantic-2) charge 72,000 gas per write (governance-adjustable) +3. **SSTORE gas is non-standard (and identical on both networks)** — mainnet (pacific-1) and testnet (atlantic-2) both charge 72,000 gas per write (governance [Proposal #109 (pacific-1)](https://www.mintscan.io/sei/proposals/109); testnet carries the same value with no separate proposal; governance-adjustable); a `forge --gas-report --fork-url` shows revm's ~22,100, not Sei's cost — use live `eth_estimateGas` 4. **Dual address system** — every account has both `sei1...` (bech32) and `0x...` (EVM); they must be **associated** before cross-VM token transfers 5. **PREVRANDAO is NOT random** — block-time-derived; always use Pyth VRF or Chainlink VRF for randomness 6. **COINBASE = fee collector** — global fee collector address, not the block proposer @@ -104,7 +104,7 @@ claude mcp add sei-mcp-server npx @sei-js/mcp-server ### 2. Apply Sei-specific correctness - **Network** (testnet 1328 vs mainnet 1329) -- **Gas price**: ≥ 50 gwei legacy `gasPrice` +- **Gas price**: legacy `gasPrice` at the governance-set, adjustable floor (currently ~50 gwei on mainnet — pacific-1 Proposal #112 / atlantic-2 #244; query `eth_gasPrice`) - **Address format** (bech32 vs EVM) and association if cross-VM - **SSTORE implications** for storage-heavy contracts - **Parallel execution implications** for shared mutable state diff --git a/skill/SKILL-ECOSYSTEM.md b/skill/SKILL-ECOSYSTEM.md index 76866cc..b08c7d8 100644 --- a/skill/SKILL-ECOSYSTEM.md +++ b/skill/SKILL-ECOSYSTEM.md @@ -3,8 +3,8 @@ name: sei-ecosystem description: > Use when user asks "what dApps are on Sei", "list Sei DEXes / lending / perps", "integrate with a Sei DEX or lending protocol", "what bridges work - with Sei", "how do I bridge tokens to Sei with LayerZero / Wormhole / Axelar - / IBC / CCTP", "find a Sei RPC endpoint", "RPC failover for Sei", "use Pyth / + with Sei", "how do I bridge tokens to Sei with LayerZero / Wormhole / CCTP", + "find a Sei RPC endpoint", "RPC failover for Sei", "use Pyth / Chainlink oracles on Sei", "set up The Graph / Goldsky subgraph for Sei", "set up a Sei full node", "how do I delegate SEI to a validator", "submit a governance proposal on Sei", "how do I become a Sei validator / RPC provider @@ -35,16 +35,17 @@ Use this Skill when the user asks for: - Sei dApps directory by category (DEX, lending, perps, RWA, NFT, gaming, infra, AI) - Integration patterns for DeFi protocols (DragonSwap, Yei, Takara, Saphyre) -- Bridges (LayerZero V2, Wormhole, Axelar, IBC, ThirdWeb, CCTP) +- Bridges (LayerZero V2, Circle CCTP v2; Wormhole legacy/verify-first); inbound IBC disabled (SIP-3, legacy/exit-only) - RPC endpoints — public, community, and paid providers + failover patterns -- Oracle integration (Chainlink, Pyth, API3, RedStone, native oracle precompile, VRF) +- Oracle integration (Chainlink, Pyth, API3, RedStone, VRF — the native oracle precompile is shut off) - Indexer setup (The Graph, Goldsky, Dune, Moralis, Goldrush) - Node operations (full node setup, state sync, snapshots, `seid` CLI) - Validator setup (key management, HSM, slashing, monitoring) - Staking, delegation, governance proposals - Participation roles (validator, RPC provider, indexer operator, oracle relayer, IBC relayer) - Grants and builder programs (Sei Foundation, Ecosystem Fund, Creator Fund) -- AI tooling (Sei MCP Server, Cambrian Agent Kit, x402) +- AI tooling (Sei MCP Server, Cambrian Agent Kit) +- Payments (USDC transfers, x402 HTTP-native micropayments) - Sei architecture context for ecosystem decisions (Twin Turbo, OCC, SeiDB, Sei Giga) ## Key architectural facts (always apply) @@ -53,19 +54,19 @@ These facts must inform every Sei ecosystem answer: 1. **400ms block time, instant finality** — block-level systems (relayers, bridges) should expect fast confirmation 2. **Parallel execution (OCC)** — high-throughput protocols must design for non-conflicting state -3. **SSTORE gas cost differs by network** — both mainnet and testnet: 72,000 gas per write (governance-adjustable) +3. **SSTORE gas is non-standard (and identical on both networks)** — mainnet and testnet both charge 72,000 gas per write (governance [Proposal #109 (pacific-1)](https://www.mintscan.io/sei/proposals/109); testnet carries the same value with no separate proposal; governance-adjustable) 4. **Dual address system** — every account has both `sei1...` and `0x...`; cross-VM transfers require association 5. **PREVRANDAO is NOT random** — use Pyth VRF or Chainlink VRF -6. **No base fee burn** — all fees go to validators; legacy `gasPrice` ≥ 50 gwei +6. **No base fee burn** — all fees go to validators; use legacy `gasPrice` at the governance-set, adjustable floor (currently ~50 gwei on mainnet — pacific-1 Proposal #112 / atlantic-2 #244; query `eth_gasPrice` for the live value) 7. **CosmWasm is deprecated** (SIP-3) — new ecosystem dApps should target EVM 8. **Chain IDs:** Mainnet `pacific-1` / EVM `1329`; Testnet `atlantic-2` / EVM `1328` 9. **Block gas limit:** 12.5M per block ## Default stack decisions -1. **Oracles**: Native oracle precompile for free SEI/USD price; Pyth (pull) for sub-second latency; Chainlink (push) for production DeFi defaults +1. **Oracles**: Pyth (pull) for sub-second latency; Chainlink (push) for production DeFi defaults; API3 / RedStone as alternatives. The native oracle precompile is **shut off (~July 2026)** — it returns no data; do not use it 2. **Indexers**: The Graph for custom query workloads; Goldsky for real-time CDC; Dune for analytics -3. **Bridges**: LayerZero V2 OFT for omnichain tokens; CCTP for native USDC; IBC for Cosmos ecosystem; Wormhole/Axelar for general-purpose +3. **Bridges**: LayerZero V2 OFT for omnichain tokens; CCTP for native USDC. Wormhole (NTT/WTT) is supported per Wormhole but **not documented by Sei** — verify first. Inbound IBC is disabled (SIP-3) — not a path for new transfers 4. **RPC**: Sei Foundation primary + community fallback for free; paid SaaS (QuickNode, Alchemy, dRPC) with multi-provider failover for production 5. **Networks**: Default to testnet (`atlantic-2`, chain ID 1328) unless explicitly mainnet 6. **Validators**: HSM-backed key management; uptime monitoring; participation in governance @@ -140,8 +141,8 @@ For agent-grade RPC patterns, see the 17 canonical skills in [ecosystem/rpc-agen ### Apps + integrations - **dApps directory by category:** [ecosystem/apps-directory.md](references/ecosystem/apps-directory.md) - **DeFi integration patterns (DEXes, lending):** [ecosystem/integration-defi.md](references/ecosystem/integration-defi.md) -- **Bridges (LayerZero, Wormhole, Axelar, IBC, CCTP):** [ecosystem/bridges.md](references/ecosystem/bridges.md) -- **IBC + legacy bridging deep dive:** [ecosystem/ibc-bridging.md](references/ecosystem/ibc-bridging.md) +- **Bridges (LayerZero V2, CCTP; Wormhole verify-first; IBC legacy/exit-only):** [ecosystem/bridges.md](references/ecosystem/bridges.md) +- **IBC (legacy / exit-only — inbound disabled, SIP-3):** [ecosystem/ibc-bridging.md](references/ecosystem/ibc-bridging.md) ### Infrastructure - **RPC endpoints — public, community, paid:** [ecosystem/rpc-providers.md](references/ecosystem/rpc-providers.md) @@ -155,6 +156,7 @@ For agent-grade RPC patterns, see the 17 canonical skills in [ecosystem/rpc-agen ### Participation - **Participation roles (validator / RPC / indexer / oracle / IBC / grants):** [ecosystem/participation-roles.md](references/ecosystem/participation-roles.md) - **AI tooling (Sei MCP Server, Cambrian, x402):** [ecosystem/ai-tooling.md](references/ecosystem/ai-tooling.md) +- **Payments (USDC + x402):** [ecosystem/payments.md](references/ecosystem/payments.md) ### Cross-domain references the ecosystem reaches for - Precompiles for on-chain integration: [precompiles/overview.md](references/precompiles/overview.md) diff --git a/skill/SKILL-FRONTEND.md b/skill/SKILL-FRONTEND.md index c805ba2..71723b8 100644 --- a/skill/SKILL-FRONTEND.md +++ b/skill/SKILL-FRONTEND.md @@ -6,7 +6,7 @@ description: > login", "display both EVM and Cosmos addresses", "RainbowKit / ConnectKit with Sei", "EIP-6963 wallet detection on Sei", "where on docs.sei.io is X", "where on sei.io is X", "contribute a page to docs.sei.io", "how do I author - Nextra MDX docs for Sei", "what's in the Sei brand kit", "where do I find + Mintlify MDX docs for Sei", "what's in the Sei brand kit", "where do I find Sei logos / press kit", or anything about Sei UIs, wallet UX, and the official web properties. Frontend-focused variant — UI stack, wallet UX, dual-address UX, and site/docs awareness. For deeper smart-contract or @@ -39,7 +39,7 @@ Use this Skill when the user asks for: - Network-add UX (`wallet_addEthereumChain` for Sei) - Fast-finality UX patterns (no multi-confirmation spinners) - Navigating sei.io and docs.sei.io to send users to the right page -- Authoring or contributing pages to docs.sei.io (Nextra + MDX + `_meta.js`) +- Authoring or contributing pages to docs.sei.io (Mintlify + MDX + `docs.json`) - Sei brand kit, logos, media assets, press contacts - Frontend-side reading from Sei precompiles (e.g., dual-address lookup via Addr precompile) @@ -48,7 +48,7 @@ Use this Skill when the user asks for: These facts must inform every Sei answer: 1. **400ms block time, instant finality** — use `tx.wait(1)` / `confirmations: 1`; no "safe"/"finalized" spinners -2. **Use legacy `gasPrice` ≥ 50 gwei** — Sei does not use EIP-1559 priority fees; min 50 gwei +2. **Use legacy `gasPrice`** — Sei does not use EIP-1559 priority fees; the minimum is governance-set and adjustable (currently ~50 gwei on mainnet — pacific-1 Proposal #112 / atlantic-2 #244; query `eth_gasPrice` for the live floor) 3. **Dual address system** — every user has both `sei1...` and `0x...`; surface both when needed 4. **Chain IDs:** Mainnet `pacific-1` / EVM `1329`; Testnet `atlantic-2` / EVM `1328` 5. **EIP-6963 is the default** for wallet detection; Wagmi `injected()` discovers all participants automatically @@ -59,7 +59,7 @@ These facts must inform every Sei answer: 1. **Library**: Wagmi + Viem for React; Ethers.js v6 for non-React or Node scripts 2. **Wallet (consumer)**: Sei Global Wallet (`@sei-js/sei-global-wallet`) — no install, social login, EIP-6963 3. **Wallet UX shell**: RainbowKit or ConnectKit for polished connect modal -4. **Chain config**: import `sei` / `seiTestnet` from `@sei-js/precompiles` +4. **Chain config**: import `sei` / `seiTestnet` from `wagmi/chains` (or `viem/chains`) — `@sei-js/precompiles` only ships the `seiLocal` dev chain, not `sei`/`seiTestnet` 5. **Always pin `chainId`** in writeContract calls 6. **Always use legacy `gasPrice ≥ 50 gwei`**, never EIP-1559 fields 7. **Default to testnet** in development; switch to mainnet only when explicitly requested @@ -129,7 +129,7 @@ Use it for: address lookup, balance checks, contract reads from a frontend testb ### Site awareness and contribution - **sei.io / docs.sei.io site map:** [frontend/sites-map.md](references/frontend/sites-map.md) -- **Contributing to docs.sei.io (Nextra + MDX + _meta.js):** [frontend/docs-contributing.md](references/frontend/docs-contributing.md) +- **Contributing to docs.sei.io (Mintlify + MDX + docs.json):** [frontend/docs-contributing.md](references/frontend/docs-contributing.md) - **Brand kit, logos, media:** [frontend/branding-media.md](references/frontend/branding-media.md) ### Cross-domain references frontends will reach for diff --git a/skill/SKILL.md b/skill/SKILL.md index 771327d..f58d1b8 100644 --- a/skill/SKILL.md +++ b/skill/SKILL.md @@ -59,15 +59,15 @@ This Skill covers three overlapping domains. Use it when the user asks for: - Wallet detection (EIP-6963), dual-address UX (`sei1...` ↔ `0x...`), fast-finality patterns - RainbowKit / ConnectKit integration - Navigating sei.io and docs.sei.io — pointing users to the right page -- Contributing pages to docs.sei.io (Nextra MDX, _meta.js, build flow) +- Contributing pages to docs.sei.io (Mintlify MDX, docs.json navigation, snippets) - Sei brand kit, logos, media assets, press contacts ### Ecosystem (apps + integration + participation) - Sei dApps directory by category (DEX, lending, perps, RWA, NFT, gaming, infra) - Integration patterns for DeFi protocols (DragonSwap, Yei, Takara, Saphyre) -- Bridges (LayerZero V2, Wormhole, Axelar, IBC, ThirdWeb, CCTP) +- Bridges (LayerZero V2, Circle CCTP v2 for native USDC; Wormhole legacy/verify-first); inbound IBC disabled (SIP-3) - RPC endpoints — public, community, and paid providers -- Oracle integration (Chainlink, Pyth, API3, RedStone, native precompile, VRF) +- Oracle integration (Chainlink, Pyth, API3, RedStone, VRF; native precompile is shut off) - Indexer setup (The Graph, Goldsky, Dune, Moralis, Goldrush) - Participation roles (validator, RPC provider, indexer operator, oracle relayer, IBC relayer) - Grants and builder programs (Sei Foundation, Ecosystem Fund, Creator Fund) @@ -80,9 +80,9 @@ This Skill covers three overlapping domains. Use it when the user asks for: These facts must inform every answer involving Sei code or configuration: -1. **400ms block time, instant finality** — use `txResponse.wait(1)` for confirmations; there is no "safe" or "finalized" block distinction +1. **400ms block time, instant finality** — use `txResponse.wait(1)` for confirmations; `safe`/`finalized`/`latest` all resolve to the same instantly-final block, so just query `latest` 2. **Parallel execution (OCC)** — minimize shared storage writes; partition state by user/asset/id; avoid hot globals written by many users -3. **SSTORE gas cost differs by network** — both mainnet (pacific-1) and testnet (atlantic-2) charge 72,000 gas per write (governance proposal #240); governance-adjustable — always verify with `forge test --gas-report` against the target network +3. **SSTORE gas cost is non-standard (and identical on both networks)** — mainnet (pacific-1) and testnet (atlantic-2) both charge 72,000 gas per write (set by governance [Proposal #109 (pacific-1)](https://www.mintscan.io/sei/proposals/109); testnet carries the same value with no separate proposal); governance-adjustable. A `forge --gas-report --fork-url` uses revm's standard EVM schedule and shows ~22,100, *not* Sei's cost — use a live `eth_estimateGas` against a Sei RPC for the real value 4. **Dual address system** — every account has both a `sei1...` bech32 address and a `0x...` EVM address derived from the same public key; they must be **associated** before cross-VM token transfers work 5. **PREVRANDAO is NOT random** — it returns a block-time-derived value; always use oracle VRF (Pyth VRF or Chainlink VRF) for on-chain randomness 6. **COINBASE = fee collector** — always returns the global fee collector address, not the block proposer; do not use it for proposer identity @@ -143,7 +143,7 @@ Once connected, use MCP tools for: wallet queries, balance checks, transaction d ### 2. Apply Sei-specific correctness Always be explicit about: - **Network** (testnet atlantic-2 vs mainnet pacific-1) and chain ID (1328 vs 1329) -- **Gas price**: minimum 50 gwei for legacy txs; use `gasPrice` not EIP-1559 fields +- **Gas price**: governance-set, adjustable minimum (currently ~50 gwei on mainnet — pacific-1 [Proposal #112](https://www.mintscan.io/sei/proposals/112) / atlantic-2 #244; it has changed before, 100→10→50) — query `eth_gasPrice` for the live floor; use legacy `gasPrice`, not EIP-1559 fields - **Address format** expected (bech32 `sei1...` vs EVM `0x...`) and whether association is required - **SSTORE implications** for contracts with many storage writes - **Parallel execution implications** for contracts with shared mutable state (hot globals) @@ -201,14 +201,15 @@ When implementing changes, provide: ### Frontend — UI stack and site awareness - **Frontend stack (Wagmi/Viem/sei-js, Sei Global Wallet, EIP-6963, dual-address UX):** [frontend/frontend-stack.md](references/frontend/frontend-stack.md) - **sei.io / docs.sei.io site map:** [frontend/sites-map.md](references/frontend/sites-map.md) -- **Contributing to docs.sei.io (Nextra, MDX, _meta.js):** [frontend/docs-contributing.md](references/frontend/docs-contributing.md) +- **Contributing to docs.sei.io (Mintlify, MDX, docs.json):** [frontend/docs-contributing.md](references/frontend/docs-contributing.md) - **Sei brand kit, logos, media:** [frontend/branding-media.md](references/frontend/branding-media.md) ### Ecosystem — apps, integration, participation - **dApps directory by category:** [ecosystem/apps-directory.md](references/ecosystem/apps-directory.md) - **DeFi integration patterns (DEXes, lending):** [ecosystem/integration-defi.md](references/ecosystem/integration-defi.md) -- **Bridges (LayerZero, Wormhole, Axelar, IBC, CCTP):** [ecosystem/bridges.md](references/ecosystem/bridges.md) -- **IBC & legacy bridging deep dive:** [ecosystem/ibc-bridging.md](references/ecosystem/ibc-bridging.md) +- **Bridges (LayerZero V2, CCTP; Wormhole verify-first; IBC legacy/exit-only):** [ecosystem/bridges.md](references/ecosystem/bridges.md) +- **IBC (legacy / exit-only — inbound disabled, SIP-3):** [ecosystem/ibc-bridging.md](references/ecosystem/ibc-bridging.md) +- **Payments (USDC + x402):** [ecosystem/payments.md](references/ecosystem/payments.md) - **RPC endpoints — public, community, paid:** [ecosystem/rpc-providers.md](references/ecosystem/rpc-providers.md) - **RPC agent skills (17 canonical patterns, retry, response shapes):** [ecosystem/rpc-agent-skills.md](references/ecosystem/rpc-agent-skills.md) - **Oracles:** [ecosystem/oracles.md](references/ecosystem/oracles.md) — Chainlink, Pyth, API3, RedStone, VRF diff --git a/skill/references/contracts/account-abstraction.md b/skill/references/contracts/account-abstraction.md index 60723e2..322698c 100644 --- a/skill/references/contracts/account-abstraction.md +++ b/skill/references/contracts/account-abstraction.md @@ -135,7 +135,7 @@ const txHash = await smartAccount.sendTransaction({ The paymaster pulls the equivalent USDC from the smart account to cover gas. The user holds zero SEI and still transacts. -> Verify the USDC contract address against [docs.sei.io USDC page](https://docs.sei.io/evm/reference/usdc) before deploying — addresses move during integration phases. +> Verify the USDC contract address against [docs.sei.io USDC page](https://docs.sei.io/evm/usdc-on-sei) before deploying — addresses move during integration phases. ## Sei Global Wallet (embedded AA) diff --git a/skill/references/contracts/common-errors.md b/skill/references/contracts/common-errors.md index 093d476..3e4ae58 100644 --- a/skill/references/contracts/common-errors.md +++ b/skill/references/contracts/common-errors.md @@ -155,7 +155,7 @@ curl http://localhost:26657/net_info | jq '.result.n_peers' ## Solidity / Contract Development ### SSTORE gas unexpectedly high -**Cause**: Sei charges 72,000 gas per cold write on both mainnet and testnet (governance proposal #240). Multiple storage writes in a function compound quickly. +**Cause**: Sei charges 72,000 gas per cold write on both mainnet and testnet (governance Proposal #109 on pacific-1; testnet carries the same value with no separate proposal). Multiple storage writes in a function compound quickly. **Fix**: Cache in memory, minimize storage writes. Use `forge test --gas-report` against the target network. ```solidity // Both networks: 3 × 72,000 = 216,000 gas just for storage diff --git a/skill/references/contracts/gas-optimization-sei.md b/skill/references/contracts/gas-optimization-sei.md index eb24fc5..2b23a94 100644 --- a/skill/references/contracts/gas-optimization-sei.md +++ b/skill/references/contracts/gas-optimization-sei.md @@ -13,16 +13,15 @@ Most Solidity gas advice transfers from Ethereum directly. This file covers only |---|---|---|---| | Block time | ~12s | **400ms** | 400ms | | Block gas limit | 30M | **12.5M** | 12.5M | -| Min gas price | dynamic (EIP-1559) | **50 gwei (fixed)** | 50 gwei | -| Cold SSTORE | 22,100 gas | 22,100 gas | 22,100 gas | -| Warm SSTORE (zero→nonzero) | 20,000 gas | **72,000 gas** | **72,000 gas** | +| Min gas price | dynamic (EIP-1559) | **~50 gwei (governance-set)** | ~50 gwei | +| SSTORE (zero→nonzero, first/cold write) | 22,100 gas | **72,000 gas** | **72,000 gas** | | EIP-1559 base fee burn | yes | **no — all to validators** | no | | `PREVRANDAO` | RANDAO output | **block-time-derived (NOT random)** | NOT random | | `COINBASE` | block proposer | **fee collector address** | fee collector | ## Rule 1: SSTORE costs 72,000 gas on Sei (both networks) -Both mainnet (pacific-1) and testnet (atlantic-2) charge **72,000 gas per zero→nonzero SSTORE** (governance proposal #240). This is governance-adjustable; verify against your target network before assuming. +Both mainnet (pacific-1) and testnet (atlantic-2) charge **72,000 gas per zero→nonzero SSTORE** (set by pacific-1 governance [Proposal #109](https://www.mintscan.io/sei/proposals/109); testnet carries the same value with no separate proposal). This is governance-adjustable; verify against your target network before assuming. **Implication:** a contract with many storage writes will cost significantly more on Sei than on Ethereum mainnet (20k). Measure with `forge test --gas-report` and minimise writes. @@ -37,9 +36,9 @@ forge test --gas-report --fork-url https://evm-rpc-testnet.sei-apis.com # testne - **Avoid setting then unsetting** — clearing a slot back to zero refunds gas (capped on Sei as on EIP-3529 Ethereum), but the round-trip rarely beats not writing at all. - **Use `transient` storage (EIP-1153)** for cross-call temporaries that don't need persistence — no SSTORE cost. Sei supports `tload`/`tstore` opcodes. -## Rule 2: 50 gwei minimum, no EIP-1559 +## Rule 2: ~50 gwei governance-set minimum, no EIP-1559 -Setting `gasPrice` below 50 gwei results in mempool eviction, not slow inclusion. +The EVM minimum gas price is governance-set and adjustable (currently ~50 gwei on mainnet — pacific-1 [Proposal #112](https://www.mintscan.io/sei/proposals/112) / atlantic-2 #244; it has changed before, 100→10→50). Query `eth_gasPrice` for the live floor. Setting `gasPrice` below it results in mempool eviction, not slow inclusion. ```ts // Viem diff --git a/skill/references/contracts/security.md b/skill/references/contracts/security.md index b5c7f11..94dcce3 100644 --- a/skill/references/contracts/security.md +++ b/skill/references/contracts/security.md @@ -67,6 +67,8 @@ interface IAddr { } function verifyCrossVMCaller(address evmAddr, string memory expectedSeiAddr) internal view { + // getSeiAddr REVERTS for an unassociated address (it does NOT return "") — + // so an unassociated caller fails closed here, which is the safe outcome. string memory actualSeiAddr = IAddr(ADDR_PRECOMPILE).getSeiAddr(evmAddr); require(keccak256(bytes(actualSeiAddr)) == keccak256(bytes(expectedSeiAddr)), "Address mismatch"); } @@ -82,13 +84,12 @@ function delegateForUser(string calldata validatorAddr, uint256 amount) external STAKING(STAKING_PRECOMPILE).delegate{value: amount}(validatorAddr); // No validation } -// ✅ Validate against allowlist or format-check -bytes memory addrBytes = bytes(validatorAddr); -require(addrBytes.length == 52, "Invalid validator address length"); -require( - addrBytes[0] == 's' && addrBytes[1] == 'e' && addrBytes[2] == 'i', - "Not a sei1valoper address" -); +// ✅ Validate against a known allowlist of operators you trust. +// Do NOT hardcode a bech32 length/prefix check: bech32 lengths are not a +// stable constant, and a "sei" prefix check also accepts a regular sei1... +// account address (validators use the seivaloper1... prefix). +mapping(bytes32 => bool) allowedValidators; // keccak256(validatorAddr) => allowed +require(allowedValidators[keccak256(bytes(validatorAddr))], "validator not allowlisted"); ``` ### 6. Staking Precompile Amount Units @@ -193,11 +194,11 @@ function swap(..., uint256 deadline) external { // ❌ Spot price from AMM — easily manipulated in same block uint256 price = pool.token0() / pool.token1(); -// ✅ Use a TWAP or external oracle (Pyth, Chainlink) +// ✅ Use a TWAP or external oracle (Pyth, Chainlink, API3, RedStone) PythStructs.Price memory price = pyth.getPriceNoOlderThan(priceId, 60); -// ✅ On Sei: native oracle precompile is free and safe -IOracle(0x1008).getOracleTwaps(3600); // 1-hour TWAP +// ❌ The native Oracle precompile (0x...1008) is SHUT OFF (~July 2026) — it +// returns no data (no-op). Use a third-party oracle (Pyth, Chainlink, API3, RedStone). ``` ### Signature Replay diff --git a/skill/references/contracts/tokens.md b/skill/references/contracts/tokens.md index c5f7607..6b89cd0 100644 --- a/skill/references/contracts/tokens.md +++ b/skill/references/contracts/tokens.md @@ -91,7 +91,7 @@ USDC on Sei is a native ERC20 — no pointer or bridging step needed. ## CW20 / CW721 — Legacy Status -> **Per SIP-3 (governance proposal 99)**: CosmWasm is deprecated on Sei. CW20 and CW721 are no longer the recommended token standards for new projects. +> **Per SIP-3** (initiated by mainnet Proposal 99; CosmWasm uploads disabled by mainnet #115 / testnet #246): CosmWasm is deprecated on Sei. CW20 and CW721 are no longer the recommended token standards for new projects. ### Migration Path diff --git a/skill/references/contracts/upgradeability.md b/skill/references/contracts/upgradeability.md index 32105ce..9b2db56 100644 --- a/skill/references/contracts/upgradeability.md +++ b/skill/references/contracts/upgradeability.md @@ -35,7 +35,7 @@ contract MyToken is Initializable, ERC20Upgradeable, OwnableUpgradeable, UUPSUpg function initialize(address owner) public initializer { __ERC20_init("MyToken", "MTK"); __Ownable_init(owner); - __UUPSUpgradeable_init(); + // OZ v5's UUPSUpgradeable is stateless — no __UUPSUpgradeable_init() call } function _authorizeUpgrade(address) internal override onlyOwner {} @@ -209,7 +209,7 @@ function _authorizeUpgrade(address) internal override onlyOwner { ## Sei-specific notes -- All standard OpenZeppelin upgrade tooling works unchanged. There's no Sei fork of `@openzeppelin/hardhat-upgrades` needed. +- No Sei fork of OpenZeppelin tooling is needed, but mind the toolchain version: the **stable** `@openzeppelin/hardhat-upgrades` targets **Hardhat 2** — Hardhat 3 support exists only as an alpha (`@openzeppelin/hardhat-upgrades@4.0.0-alpha`, ESM-only, new plugins/hooks API). On Hardhat 3 with the stable tooling, deploy an ERC1967 proxy directly and upgrade via UUPS `upgradeToAndCall`, validating storage layouts separately with `@openzeppelin/upgrades-core`. With OZ Contracts v5, `UUPSUpgradeable` is **stateless** — no `__UUPSUpgradeable_init()` call in your initializer (it's a no-op in v5.0.x and removed in v5.1+). - `evm_version = "cancun"` (or earlier) — newer EVM versions may not be enabled. - Proxy contracts work correctly with pointer contracts and precompiles. - OCC parallelism applies to upgrade-target contracts the same way: the upgrade itself is a single tx (serializing on the proxy slot for that one tx), but normal users hitting the proxy run in parallel. diff --git a/skill/references/ecosystem/ai-tooling.md b/skill/references/ecosystem/ai-tooling.md index 97b2ef5..33c2bfc 100644 --- a/skill/references/ecosystem/ai-tooling.md +++ b/skill/references/ecosystem/ai-tooling.md @@ -167,6 +167,12 @@ await kit.rebalancePortfolio({ --- +## Payments and x402 + +For agents that need to *pay* for resources or *charge* for them, Sei supports **x402** — HTTP-native micropayments settled in USDC. The `@sei-js/x402-*` packages wrap the 402 challenge/verify cycle for clients (`x402-fetch`, `x402-axios`) and servers (`x402-express`, `x402-hono`, `x402-next`). USDC on Sei is a standard ERC-20 with **6 decimals**. Full flow, addresses, and replay-protection requirements: [payments.md](payments.md). + +--- + ## Agent-Friendly Development Patterns ### Safety Guidelines for AI Agents Operating on Sei diff --git a/skill/references/ecosystem/apps-directory.md b/skill/references/ecosystem/apps-directory.md index aec7b4d..48a12af 100644 --- a/skill/references/ecosystem/apps-directory.md +++ b/skill/references/ecosystem/apps-directory.md @@ -48,7 +48,7 @@ Integration tip: see [integration-defi.md](integration-defi.md) for router/comet |---|---|---|---| | **Ondo Finance** | Tokenized US Treasuries (USDY) | https://ondo.finance | Largest tokenized Treasury by TVL | | **Agora** | Stablecoin / payments | https://agora.finance | RWA + payment rails | -| **Native USDC** | Stablecoin | (issued by Circle) | Verify current contract via [docs.sei.io USDC integration](https://docs.sei.io/evm/reference/usdc) | +| **Native USDC** | Stablecoin | (issued by Circle) | Verify current contract via [docs.sei.io USDC integration](https://docs.sei.io/evm/usdc-on-sei) | ## Liquid Staking (LSTs) @@ -110,10 +110,10 @@ See [addresses-wallets.md](../addresses-wallets.md) for setup and dual-address h | Bridge | Site | Notes | |---|---|---| -| **LayerZero V2** | https://layerzero.network | OFT standard; 50+ source chains | -| **Wormhole** | https://wormhole.com | Native + ERC-20 + NFT | -| **Axelar** | https://axelar.network | Cross-chain message passing | -| **IBC** | https://www.mintscan.io/sei/relayers | Cosmos-native; via Cosmos-side address | +| **LayerZero V2** | https://layerzero.network | OFT standard; Sei is a LayerZero V2 endpoint | +| **Wormhole** | https://wormhole.com | SeiEVM supported per Wormhole (NTT/WTT); not documented by Sei — verify. CosmWasm side legacy/exit-only | +| **Circle CCTP v2** | https://developers.circle.com/cctp | Native USDC, burn-and-mint | +| **IBC** | — | Legacy/exit-only — **inbound IBC disabled** (SIP-3, pacific-1 Prop 116 / atlantic-2 #247) | See [bridges.md](bridges.md) for integration details and addresses. @@ -147,5 +147,5 @@ These categories exist on other chains but have limited Sei presence as of this ## Sei-specific notes for integrators - Sei is **EVM-first as of SIP-3** — new dApps are EVM. Older CosmWasm-based protocols (Astroport, Kryptonite v1) may have EVM equivalents or pointer contracts. -- Treat all listed addresses as **placeholders until verified** against the project's docs or [docs.sei.io ecosystem contracts](https://docs.sei.io/evm/reference/ecosystem-contracts). -- Use [docs.sei.io/evm/reference/ecosystem-contracts](https://docs.sei.io/evm/reference/ecosystem-contracts) as the source of truth for canonical contract addresses (USDC, WETH, common bridge contracts). +- Treat all listed addresses as **placeholders until verified** against the project's docs or [docs.sei.io ecosystem contracts](https://docs.sei.io/evm/ecosystem-contracts). +- Use [docs.sei.io/evm/ecosystem-contracts](https://docs.sei.io/evm/ecosystem-contracts) as the source of truth for canonical contract addresses (USDC, WETH, common bridge contracts). diff --git a/skill/references/ecosystem/bridges.md b/skill/references/ecosystem/bridges.md index 006241f..1554ab8 100644 --- a/skill/references/ecosystem/bridges.md +++ b/skill/references/ecosystem/bridges.md @@ -1,218 +1,116 @@ --- title: Bridges to/from Sei -description: Bridges live on Sei — LayerZero V2 (OFT), Wormhole, Axelar, IBC, ThirdWeb. Supported assets, source chains, contract addresses, and integration patterns for each. +description: Bridges on Sei — LayerZero V2 (OFT) and Circle CCTP v2 (native USDC) are the documented EVM bridges, plus the official Sei bridge UI. Wormhole is verify-first (not Sei-documented); inbound IBC is disabled under SIP-3. --- # Bridges to/from Sei -How users and contracts move assets between Sei and other chains. Sei supports three EVM-style bridges (LayerZero, Wormhole, Axelar) plus IBC for the Cosmos ecosystem. +How users and contracts move assets and messages between Sei and other chains. The EVM bridges **Sei documents and recommends** are **LayerZero V2** (Sei is a full LayerZero V2 endpoint) and **Circle CCTP v2** (native USDC); the official UI is the **Sei bridge dashboard** / Thirdweb. Wormhole is supported at the protocol level but is **not documented by Sei** and its Sei CosmWasm side is legacy/exit-only — see the caveat below. Pick the bridge by the asset, not by habit. -> **Always verify bridge contract addresses** against the bridge's official docs before sending real value. Bridges are high-value targets and addresses change during version upgrades. +> **Inbound IBC is disabled under SIP-3** (pacific-1 [Proposal 116](https://www.mintscan.io/sei/proposals/116); atlantic-2 testnet **#247**). IBC assets from Cosmos chains can no longer arrive on Sei — treat IBC as legacy/exit-only and use an EVM bridge for new inbound transfers. See [ibc-bridging.md](ibc-bridging.md). -## Quick decision: which bridge? +> **Always verify bridge contract addresses, endpoint IDs, and CCTP domain IDs** against each bridge's official docs and on [Seiscan](https://seiscan.io) before sending real value. Bridges are high-value targets and addresses change across version upgrades — never hardcode them from memory. -| Bridge | Best for | Avoid when | -|---|---|---| -| **LayerZero V2** | OFT-style omnichain tokens; cross-chain dApp messaging | You need maximum decentralization (LZ uses a configurable DVN model) | -| **Wormhole** | Native asset transfers from Solana, Ethereum, Polygon | You want native LayerZero/CCTP routing | -| **Axelar** | Generalized message passing + asset transfers from Cosmos and EVM | Lowest-fee swaps (Axelar adds infra cost) | -| **IBC** | Cosmos ecosystem (Osmosis, Stride, Noble) | EVM source/dest chain | -| **ThirdWeb Bridge** | Embedded bridge UX in your dApp | You need direct contract integration | -| **Native USDC via CCTP** | USDC ↔ USDC across chains, no synthetic | Other assets | - -## LayerZero V2 +## Which bridge? (decision matrix) -Live on Sei mainnet and testnet. Sei is fully integrated as a LayerZero V2 endpoint. +| You have / want | Use | Mechanism | Why | +|---|---|---|---| +| A **new token** native on Sei + other chains | **LayerZero V2 OFT** | burn-and-mint, unified supply | You control both ends; no wrapped IOU, one canonical supply | +| **Native USDC** moved onto/off Sei | **Circle CCTP v2** | burn-and-mint native USDC | Canonical USDC, fewest trust assumptions, no synthetic | +| An **existing asset** only Wormhole covers (some Solana-native tokens) | **Wormhole** (WTT/NTT) — *verify first* | wrapped / native-token transfer | Supported per Wormhole's network list, but **not documented by Sei**; confirm current support and prefer LayerZero V2 / CCTP where they cover the asset | +| **Arbitrary cross-chain messages** / calls + transfers | **LayerZero** (OApp) | GMP messaging | Generalized message passing via Sei's LayerZero V2 endpoint | +| **End users** bridging in a UI, no integration | **Sei bridge dashboard** / Thirdweb | aggregated routing | Drop-in UX, no contract work | +| Assets coming **from a Cosmos chain via IBC** | **Not available inbound** | — | Inbound IBC disabled (pacific-1 Prop 116 / atlantic-2 #247, SIP-3) — bridge via an EVM route instead | -### Endpoints (mainnet) +## LayerZero V2 -| Component | Address | -|---|---| -| LayerZero Endpoint | `0x1a44076050125825900e736c501f859c50fE728c` | -| SendUln302 | `0xC39161c743D0307EB9BCc9FEF03eeb9Dc4802de7` | +Live on Sei mainnet and testnet — Sei is fully integrated as a LayerZero V2 endpoint. -> Verify against https://docs.layerzero.network/v2/deployments/sei before deploying. +> Sei LayerZero **Endpoint IDs (EIDs): mainnet `30280`, testnet `40455`.** Read the EndpointV2 address and all protocol contracts from https://docs.layerzero.network/v2/deployments/deployed-contracts?chains=sei — do not hardcode them from memory. ### OFT (Omnichain Fungible Token) pattern -Deploying a token that exists on Sei + Ethereum + Arbitrum simultaneously, with native cross-chain transfers: +A token that exists natively on Sei + other chains, with cross-chain sends that burn on the source and mint on the destination. Scaffold with `npx create-lz-oapp@latest` (choose the OFT example), deploy the same contract on each chain pointing at that chain's endpoint, then wire the peers. ```solidity -// MyOFT.sol -pragma solidity ^0.8.28; -import "@layerzerolabs/oft-evm/contracts/OFT.sol"; +// MyOFT.sol — same contract deploys on Sei and every other chain. +pragma solidity ^0.8.22; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { OFT } from "@layerzerolabs/oft-evm/contracts/OFT.sol"; contract MyOFT is OFT { - constructor(string memory name, string memory symbol, address lzEndpoint, address owner) - OFT(name, symbol, lzEndpoint, owner) - Ownable(owner) - {} + // `endpoint` is the LayerZero EndpointV2 address for the chain you deploy on + // (Sei mainnet EID 30280 / testnet EID 40455) — read it from the deployments page. + constructor(string memory name, string memory symbol, address endpoint, address owner) + OFT(name, symbol, endpoint, owner) Ownable(owner) {} } ``` -Deploy on each chain with the local LayerZero endpoint. Then wire the peers: +Wire peers, quote the fee, then send (the cross-chain fee is paid in native gas and must be quoted first): ```ts -// Set Sei as a peer of Ethereum's MyOFT -await ethOft.setPeer(SEI_EID, addressToBytes32(seiOftAddress)); -// And vice versa -await seiOft.setPeer(ETH_EID, addressToBytes32(ethOftAddress)); -``` - -Cross-chain send: +import { Options, addressToBytes32 } from "@layerzerolabs/lz-v2-utilities"; +import { parseUnits } from "ethers"; -```ts -import { Options } from "@layerzerolabs/lz-v2-utilities"; +// Tell Sei's OFT about the peer on the other chain (and vice versa on that chain). +await seiOft.setPeer(DST_EID, addressToBytes32(remoteOftAddress)); -const options = Options.newOptions().addExecutorLzReceiveOption(200_000n, 0n).toHex(); +const options = Options.newOptions().addExecutorLzReceiveOption(80_000n, 0n).toHex(); const sendParam = { - dstEid: SEI_EID, - to: addressToBytes32(recipient), - amountLD: parseEther("100"), - minAmountLD: parseEther("99"), + dstEid: DST_EID, + to: addressToBytes32(recipient0x), // 0x recipient on the destination chain + amountLD: parseUnits("100", 18), + minAmountLD: parseUnits("99", 18), // slippage floor extraOptions: options, composeMsg: "0x", oftCmd: "0x", }; -const { nativeFee } = await oft.read.quoteSend([sendParam, false]); -await oft.write.send([sendParam, { nativeFee, lzTokenFee: 0n }, refundAddr], { value: nativeFee }); -``` - -See https://docs.layerzero.network/v2/concepts/intro for full OFT walkthrough. - -### Sei Endpoint IDs - -| Network | EID | -|---|---| -| Sei mainnet | (verify via LZ docs — values change) | -| Sei testnet | (verify via LZ docs) | - -## Wormhole - -Live on Sei mainnet. Supports native token transfers, ERC-20 wrapping, NFT bridging, and generic messaging. - -### Use cases - -- Transfer USDC from Solana to Sei. -- Bridge ETH from Ethereum to Sei (becomes wrapped wETH). -- Cross-chain governance messages. - -### Integration - -Wormhole's TokenBridge contract on Sei has a fixed address — **verify via https://docs.wormhole.com/wormhole/reference/constants before integrating**. - -```ts -import { - wormhole, - Wormhole, - TokenId, - amount, -} from "@wormhole-foundation/sdk"; -import evm from "@wormhole-foundation/sdk/platforms/evm"; - -const wh = await wormhole("Mainnet", [evm]); -const sei = wh.getChain("Sei"); -const eth = wh.getChain("Ethereum"); - -const xfer = await wh.tokenTransfer( - Wormhole.tokenId("Ethereum", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), // USDC on ETH - amount.units(amount.parse("100", 6)), - Wormhole.chainAddress("Ethereum", senderEth), - Wormhole.chainAddress("Sei", recipientSei), - false, // not automatic -); - -const txids = await xfer.initiateTransfer(ethSigner); -// Wait, then: -const vaa = await xfer.fetchAttestation(); -const completeTxids = await xfer.completeTransfer(seiSigner); -``` - -## Axelar - -Live on Sei. Generalized message passing + asset transfers via the Axelar Network. - -```solidity -import "@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol"; - -contract MyAxelarApp is AxelarExecutable { - constructor(address gateway) AxelarExecutable(gateway) {} - - function sendMessage(string calldata destChain, string calldata destAddress, bytes calldata payload) external payable { - gateway.callContract(destChain, destAddress, payload); - } - - function _execute(string calldata sourceChain, string calldata sourceAddress, bytes calldata payload) internal override { - // Handle inbound message - } -} +const { nativeFee } = await seiOft.quoteSend(sendParam, false); // quote BEFORE sending +const tx = await seiOft.send(sendParam, { nativeFee, lzTokenFee: 0n }, refund0x, { value: nativeFee }); +await tx.wait(1); // one confirmation — Sei finalizes fast ``` -Sei Axelar gateway address: verify via https://docs.axelar.dev/dev/reference/mainnet-contract-addresses. +For an *already-deployed* ERC-20 you can't reissue, use an **OFT Adapter** (locks the existing token instead of minting) rather than `OFT`. Full walkthrough, EIDs, and deployed contracts: https://docs.sei.io/evm/bridging/layerzero and https://docs.layerzero.network/v2/concepts/intro. -## IBC (Cosmos ecosystem) +## Wormhole (verify first — not documented by Sei) -For asset transfers between Sei and Cosmos chains (Osmosis, Stride, Noble, etc.). IBC operates on the **Cosmos side** of Sei — uses `sei1...` addresses, not `0x...`. +Wormhole's [supported-networks list](https://wormhole.com/docs/products/reference/supported-networks/) shows a **SeiEVM** entry (chain id 1329) with NTT, WTT (wrapped token transfers), and CCTP routing on mainnet. **But Sei's own docs provide no Wormhole EVM integration guide — the documented, recommended EVM bridges are LayerZero V2 and Circle CCTP.** Treat Wormhole as verify-first: -To bridge an EVM-side asset (e.g., a pointer-wrapped ERC20) to a Cosmos chain via IBC: +- **The Wormhole *CosmWasm* side on Sei is legacy/exit-only.** Wrapped assets that arrived on the Cosmos side (e.g. `USDCso`, Wormhole-bridged `WETH`, `USDCet`) must be **bridged out** via the legacy [Portal Bridge](https://legacy.portalbridge.com) under SIP-3 — see https://docs.sei.io/learn/sip-03-migration. Do not route new inbound transfers through it. +- **For your own multichain token,** Wormhole **NTT** is the analogue of LayerZero's OFT; **WTT** is the lock/mint wrapped path. If you specifically need Wormhole (coverage LayerZero/CCTP lack), **verify the current SeiEVM contract addresses and the exact SDK chain handle** on https://wormhole.com/docs/products/reference/supported-networks/ before integrating — do not assume them from memory. -1. **Bridge EVM → Cosmos via the pointer/precompile bridge** — the asset becomes a Cosmos-side `ibc/...` denom. -2. **Send via `seid tx ibc-transfer transfer`** — standard IBC transfer to the destination chain. +When LayerZero V2 (OFT / messaging) or CCTP (USDC) cover your case, prefer them: they have first-class Sei documentation and deployed-contract tables. -```bash -seid tx ibc-transfer transfer \ - transfer channel-X \ - sei1recipient... \ - 100usei \ - --from mywallet \ - --node https://rpc.sei-apis.com \ - --chain-id pacific-1 -``` - -Channel IDs and counterparties: https://www.mintscan.io/sei/relayers. - -See [ibc-bridging.md](ibc-bridging.md) for full IBC mechanics. +## Native USDC via Circle CCTP v2 -## ThirdWeb Bridge - -ThirdWeb's bridge UI integrates as a drop-in widget for dApps. Supports Sei mainnet. +CCTP moves *native* USDC (no wrapper): burn on the source chain, Circle attests off-chain, mint on Sei. **USDC is 6 decimals on Sei** — convert with `parseUnits(value, 6)`. The recipient is passed as a 32-byte value (`mintRecipient` is the `0x...` Sei address left-padded to bytes32). ```ts -import { Bridge } from "@thirdweb-dev/react"; - - -``` - -See https://docs.sei.io/evm/bridging/thirdweb. - -## Native USDC via CCTP +import { parseUnits, pad } from "viem"; -Circle's Cross-Chain Transfer Protocol (CCTP) is the canonical way to move **native USDC** between supported chains, including Sei (verify support status at https://www.circle.com/cross-chain-transfer-protocol). CCTP burns USDC on the source chain and mints fresh USDC on Sei — no synthetic, no wrapped IOU. - -```ts -// Burn USDC on source chain (e.g., Ethereum) -await sourceUsdc.write.approve([CCTP_TOKEN_MESSENGER, amount]); -await ethCctp.write.depositForBurn([ +// 1) Approve + burn on the SOURCE chain. SEI_DOMAIN comes from Circle's CCTP +// supported-chains/domain table — verify, do not hardcode. +const amount = parseUnits("100", 6); // 100 USDC, 6 decimals +await sourceUsdc.write.approve([TOKEN_MESSENGER, amount]); +await sourceTokenMessenger.write.depositForBurn([ amount, - SEI_DOMAIN_ID, - addressToBytes32(seiRecipient), - USDC_ETH_ADDRESS, + SEI_DOMAIN, // Circle domain id for Sei + pad(seiRecipient0x, { size: 32 }), // mintRecipient as bytes32 + sourceUsdcAddress, ]); -// Wait for Circle attestation, then mint on Sei -await seiCctp.write.receiveMessage([message, attestation]); +// 2) Poll Circle's attestation API, then mint on Sei. +const tx = await seiMessageTransmitter.write.receiveMessage([message, attestation]); +await tx.wait(1); // mint confirms in ~one Sei block ``` -CCTP attestation is off-chain (Circle's API); typical end-to-end time is 15-30 minutes due to attestation finalization on the source chain (independent of Sei's 400ms finality). +End-to-end time is dominated by **source-chain** finality + Circle's attestation (often 15+ min), independent of Sei's sub-second finality. Get testnet USDC from the [Circle Faucet](https://faucet.circle.com). Addresses/domains: https://developers.circle.com/cctp. USDC on Sei: https://docs.sei.io/evm/usdc-on-sei. -## Bridging from EVM-side Sei to Cosmos-side Sei (cross-VM) +## End-user bridging UI -This is **not a bridge** but rather an in-chain pointer/association mechanism. See [pointers/overview.md](../pointers/overview.md) for ERC20↔CW20 routing within Sei itself. +For users (not contract integrations), point them at the official **[Sei bridge dashboard](https://dashboard.sei.io/bridge)** — it aggregates routes onto Sei. To embed bridging in your own dApp, use Thirdweb Payments (onramp/swap/bridge widget): https://docs.sei.io/evm/bridging/thirdweb. The dashboard's transfer tool also handles native↔EVM asset movement during SIP-3 migration: https://dashboard.sei.io/evm-upgrade. ## Comparison: time to finality @@ -220,27 +118,24 @@ This is **not a bridge** but rather an in-chain pointer/association mechanism. S |---|---|---| | LayerZero V2 | ~2-5 min | Depends on DVN config + source-chain finality | | Wormhole | ~10-15 min | Guardian set attestation + source finality | -| Axelar | ~5-15 min | Validator set attestation | | CCTP (native USDC) | ~15-30 min | Source-chain finality is the bottleneck | -| IBC | ~30-60s | Cosmos-to-Cosmos only | -Sei's instant finality on the **destination side** is fast; the bottleneck for cross-chain transfers is always the source chain's finality. +Sei's instant finality on the **destination side** is fast; the bottleneck for cross-chain transfers is always the source chain's finality + the bridge's attestation. ## Bridge security risks -- **DVN/oracle compromise** (LayerZero) — review the DVN set the bridge uses. -- **Guardian set compromise** (Wormhole) — historically targeted; check current guardian status. -- **Validator set compromise** (Axelar) — Axelar is a separate L1 with its own validator economic security. -- **Smart-contract risk** — every bridge has a contract that holds locked or burnable assets. Audit history matters. +- **DVN/oracle set** (LayerZero) — review the DVN set the pathway uses; if `quoteSend` reverts, the pathway/DVNs aren't wired. +- **Guardian set** (Wormhole) — historically targeted; check current guardian status. +- **Smart-contract risk** — every bridge holds locked or burnable value. Audit history matters. For high-value transfers, prefer: -1. CCTP for USDC (fewest trust assumptions). -2. Native LayerZero V2 OFT if you control both ends of the token. -3. Multiple-bridge redundancy for arbitrarily large value. +1. **CCTP** for USDC (fewest trust assumptions). +2. A self-controlled **LayerZero V2 OFT** if you control both ends of the token. ## Sei-specific notes -- **All EVM bridges accept `0x...` addresses on the Sei side.** Don't pass `sei1...` addresses to LayerZero/Wormhole/Axelar — they expect EVM format. -- **For IBC, use the user's `sei1...` address.** If the user only knows their `0x...`, derive the Cosmos-side via [addresses-wallets.md](../addresses-wallets.md). -- **Pointer contracts** let bridged assets exist as both ERC20 (for EVM dApps) and CW20/native denom (for Cosmos modules). See [pointers/overview.md](../pointers/overview.md). -- **Min gas price 50 gwei** applies to bridge claim/redemption transactions on Sei — under-priced redemptions just sit in mempool. +- **EVM bridges accept `0x...` addresses on the Sei side.** Don't pass `sei1...` addresses to LayerZero / CCTP — they expect EVM format. (Wormhole lists Sei twice — a CosmWasm `Sei` side and an EVM `SeiEVM` side; if you use it, confirm the exact SDK handle on Wormhole's docs.) +- **Use legacy `gasPrice` for Sei-side claim/redeem/mint transactions.** Sei has no EIP-1559 base-fee burn — set a single `gasPrice`, not `maxFeePerGas`/`maxPriorityFeePerGas`. The minimum gas price is governance-adjustable (currently ~50 gwei on mainnet — query `eth_gasPrice` for the live floor); an under-priced redemption just sits in the mempool. See https://docs.sei.io/evm/differences-with-ethereum. +- **Inbound IBC is disabled (SIP-3).** Don't route assets onto Sei via IBC; holders of legacy `ibc/...` assets must bridge *out* (e.g. swap USDC.n → native USDC via CCTP) before activation. See [ibc-bridging.md](ibc-bridging.md) and https://docs.sei.io/learn/sip-03-migration. +- **CosmWasm is deprecated for new development (SIP-3).** Deploy ERC-20 / OFT contracts directly; pointer contracts and the IBC precompile are legacy migration tooling. +- **Verify every contract address, EID, and CCTP domain ID** against the bridge's official docs and on Seiscan before deploying. diff --git a/skill/references/ecosystem/ibc-bridging.md b/skill/references/ecosystem/ibc-bridging.md index 5c139ff..4fd13f6 100644 --- a/skill/references/ecosystem/ibc-bridging.md +++ b/skill/references/ecosystem/ibc-bridging.md @@ -1,230 +1,68 @@ --- -title: IBC and Bridging on Sei -description: Inter-Blockchain Communication (IBC), LayerZero omnichain bridging, and ThirdWeb bridge integration on Sei. +title: IBC on Sei (legacy / exit-only) +description: Inter-Blockchain Communication (IBC) on Sei is legacy — inbound IBC is disabled under SIP-3. This covers IBC mechanics for exiting legacy ibc/... assets. For new bridging use the EVM bridges in bridges.md. --- -# IBC and Bridging on Sei +# IBC on Sei (legacy / exit-only) -## Inter-Blockchain Communication (IBC) +> **Inbound IBC is disabled under SIP-3.** On mainnet, pacific-1 [Proposal 116](https://www.mintscan.io/sei/proposals/116) disables inbound IBC transfers and [Proposal 115](https://www.mintscan.io/sei/proposals/115) freezes new CosmWasm; the atlantic-2 testnet equivalents are **#247** (Disable IBC Inbound) and **#246** (Disable CosmWasm Uploads). IBC assets from Cosmos chains can **no longer arrive** on Sei. Do **not** present IBC as a way to bring assets onto Sei. +> +> **For new inbound/outbound bridging, use the EVM bridges — LayerZero V2, Wormhole, or Circle CCTP for native USDC.** See [bridges.md](bridges.md). This file is retained for the one IBC action that still matters: **exiting** legacy `ibc/...` assets. -IBC is the native cross-chain messaging protocol for Cosmos chains. Sei supports IBC for transferring assets between Cosmos ecosystem chains (Cosmos Hub, Osmosis, Noble, Axelar, etc.). +## Why IBC is legacy on Sei -### How IBC Works +Sei is EVM-first as of SIP-3. IBC operated on the **Cosmos side** of Sei using `sei1...` addresses. With inbound IBC disabled, the only relevant flow is *exiting*: holders of legacy `ibc/...` assets (e.g. USDC.n bridged via Noble) must move them off the Cosmos side — swap to native USDC (bridge out via CCTP) or transfer out — before the upgrade fully activates. Migration routes and the affected-asset table are in https://docs.sei.io/learn/sip-03-migration. -1. User initiates an IBC transfer on the source chain -2. A relayer picks up the packet and relays it to the destination chain -3. The destination chain mints/unlocks the asset -4. The asset is represented as an IBC denom: `ibc//` +## IBC mechanics (for exit / historical context) -### IBC Transfer via seid CLI +An IBC transfer is relayed packet-by-packet; assets arrive as `ibc/` denoms. To send a Cosmos-side asset **out** of Sei to another Cosmos chain: ```bash -# Transfer tokens from Sei to another Cosmos chain +# Transfer tokens from Sei to another Cosmos chain (exit flow) seid tx ibc-transfer transfer \ transfer \ # port - channel-0 \ # channel (Sei→Osmosis, e.g.) - \ + channel-0 \ # channel (e.g. Sei→Osmosis) + \ 1000000usei \ # amount + denom --from \ --chain-id pacific-1 \ --node https://rpc.sei-apis.com \ --fees 20000usei \ - --timeout-height 0 \ --timeout-timestamp $(date -d "+1 hour" +%s)000000000 - -# Transfer IBC tokens from another chain to Sei -# (Run from the source chain's node) ``` -### Common IBC Channels (Sei Mainnet) - -| Destination | Channel | -|---|---| -| Osmosis | channel-0 | -| Cosmos Hub | channel-1 | -| Noble (USDC) | channel-36 | -| Axelar | channel-19 | - -> Check current channels at https://seiscan.io or https://www.mintscan.io/sei/relayers - -### IBC Denoms - -IBC assets arrive as `ibc/` denoms: +Resolve what an `ibc/...` denom represents: ```bash -# Query what an IBC denom represents -seid q ibc-transfer denom-trace \ - --node https://rpc.sei-apis.com - -# Example: ibc/FE2CD1E6828EC0FA5F0... might be USDC from Noble +seid q ibc-transfer denom-trace --node https://rpc.sei-apis.com ``` -### IBC from EVM Contract +Check current channels at https://www.mintscan.io/sei/relayers. + +## IBC precompile (legacy) -Use the IBC precompile (legacy, for CosmWasm-adjacent workflows): +The IBC precompile (`0x0000000000000000000000000000000000001009`) exposed IBC transfers to the EVM for CosmWasm-adjacent workflows. It is **legacy** — CosmWasm is deprecated (SIP-3) and inbound IBC is disabled, so it is not a path for new builds. The interface is documented for completeness only: ```solidity interface IIBC { function transfer( - string memory toAddress, - string memory port, - string memory channel, - string memory denom, - uint256 amount, - uint64 revisionNumber, - uint64 revisionHeight, - uint64 timeoutTimestamp, + string memory toAddress, string memory port, string memory channel, + string memory denom, uint256 amount, + uint64 revisionNumber, uint64 revisionHeight, uint64 timeoutTimestamp, string memory memo ) external payable returns (uint64 sequence); } - -contract IBCSender { - address constant IBC = 0x0000000000000000000000000000000000001009; - - function sendToOsmosis(string memory recipient, uint256 amount) external { - uint64 timeout = uint64(block.timestamp + 3600) * 1_000_000_000; // 1 hour - - IIBC(IBC).transfer( - recipient, // osmo1... - "transfer", // port - "channel-0", // Sei→Osmosis channel - "usei", // denom - amount, - 0, // revision number - 0, // revision height (use timeout timestamp instead) - timeout, - "" // memo - ); - } -} -``` - ---- - -## LayerZero - -LayerZero is an omnichain messaging protocol that enables asset bridging between EVM chains (Ethereum, Arbitrum, Avalanche, etc.) and Sei. - -### Omnichain Fungible Token (OFT) Standard - -LayerZero's OFT standard lets ERC20 tokens bridge between chains with a burn-and-mint mechanism: - -```solidity -pragma solidity ^0.8.28; - -import "@layerzerolabs/solidity-examples/contracts/token/oft/OFT.sol"; - -// Deploy this on Sei — token burns here when bridging out, mints when bridging in -contract MySeiToken is OFT { - constructor( - string memory name, - string memory symbol, - address lzEndpoint // LayerZero endpoint address for Sei - ) OFT(name, symbol, lzEndpoint) { - _mint(msg.sender, 1_000_000 * 10**18); - } -} ``` -### Initiating a Bridge Transfer - -```typescript -import { ethers } from 'ethers'; - -// OFT contract on Sei -const oftContract = new ethers.Contract(OFT_ADDRESS_ON_SEI, OFT_ABI, signer); - -// Bridge 100 tokens from Sei to Ethereum mainnet -const amount = ethers.parseEther("100"); -const toChainId = 101; // LayerZero chain ID for Ethereum - -// Estimate cross-chain fee -const [nativeFee, zroFee] = await oftContract.estimateSendFee( - toChainId, - ethers.zeroPadValue(recipientAddress, 32), - amount, - false, // use ZRO token for fee? no - "0x" // adapter params -); - -// Execute bridge -const tx = await oftContract.sendFrom( - await signer.getAddress(), - toChainId, - ethers.zeroPadValue(recipientAddress, 32), - amount, - await signer.getAddress(), // refund address - ethers.ZeroAddress, // ZRO payment address - "0x", // adapter params - { value: nativeFee } -); -await tx.wait(1); // instant finality on Sei -``` - -### LayerZero Endpoints on Sei - -| Network | Endpoint Address | LayerZero Chain ID | -|---|---|---| -| Mainnet | (see LayerZero docs for current address) | 46 | -| Testnet | (see LayerZero docs for current address) | 10045 | - ---- - -## ThirdWeb Bridge - -ThirdWeb provides a bridge interface and React components for cross-chain transfers. - -### ThirdWeb Universal Bridge - -```typescript -import { Bridge, NATIVE_TOKEN_ADDRESS } from "thirdweb/bridge"; -import { client } from "./client"; // your ThirdWeb client - -// Get quote for bridging SEI from Sei to Ethereum -const quote = await Bridge.Buy.quote({ - client, - originChainId: 1329, // Sei mainnet - originTokenAddress: NATIVE_TOKEN_ADDRESS, - destinationChainId: 1, // Ethereum mainnet - destinationTokenAddress: NATIVE_TOKEN_ADDRESS, - amount: parseEther("10"), -}); - -console.log("Bridge fee:", quote.fees); -console.log("Expected output:", quote.destinationAmount); -``` - -### ThirdWeb EIP-7702 + Bridge (Account Abstraction) - -ThirdWeb supports EIP-7702 smart account upgrades on Sei, enabling gasless bridge transactions: - -```typescript -import { inAppWallet } from "thirdweb/wallets"; -import { bridgeTokens } from "thirdweb/bridge"; - -// Create an in-app wallet (social login) -const wallet = inAppWallet(); -const account = await wallet.connect({ client, strategy: "google" }); - -// Execute bridge with EIP-7702 smart session -const bridgeTx = await bridgeTokens({ - client, - account, - originChain: sei, - destinationChain: ethereum, - amount: parseEther("5"), -}); -``` - ---- +## New bridging → use the EVM bridges -## Bridge Checklist +For omnichain tokens, wrapped assets, native USDC, or cross-chain messaging, use the EVM bridges. The canonical, Sei-documented patterns are **LayerZero V2 OFT** and **Circle CCTP v2** — addresses/EIDs live in [bridges.md](bridges.md) and on https://docs.sei.io/evm/bridging/layerzero. (Wormhole supports SeiEVM per its own network list but is not documented by Sei — verify first; see [bridges.md](bridges.md).) End users can bridge through the official [Sei bridge dashboard](https://dashboard.sei.io/bridge) or an embedded Thirdweb widget (https://docs.sei.io/evm/bridging/thirdweb). -Before integrating any bridge: +## Bridge checklist -- [ ] Verify the bridge is audited and has significant TVL (do not build on unaudited bridges) -- [ ] Test the full round trip on testnet first -- [ ] Handle failed IBC transfers (packets can timeout — implement a re-claim flow) -- [ ] Communicate to users that IBC transfers take 1-30 seconds; LayerZero takes 1-5 minutes -- [ ] Display the IBC denom correctly on the receiving chain (`ibc/...` format) -- [ ] For LayerZero: ensure your OFT contract is deployed and configured on both chains before launch +- [ ] Do **not** plan inbound IBC — it is disabled (SIP-3). Use an EVM bridge. +- [ ] For legacy `ibc/...` holdings, plan the **exit** before SIP-3 fully activates (CCTP for USDC). +- [ ] Verify any bridge is audited and has significant TVL before integrating. +- [ ] Test the full round trip on testnet (atlantic-2) first. +- [ ] For LayerZero: deploy + wire your OFT on both chains before launch; quote the native fee with `quoteSend`. +- [ ] Use legacy `gasPrice` for Sei-side claim/redeem transactions (no EIP-1559 base-fee burn). diff --git a/skill/references/ecosystem/integration-defi.md b/skill/references/ecosystem/integration-defi.md index ee1b3bd..1ba09d9 100644 --- a/skill/references/ecosystem/integration-defi.md +++ b/skill/references/ecosystem/integration-defi.md @@ -7,7 +7,7 @@ description: How to integrate with major DEXes, lending markets, and yield proto Patterns and code examples for calling DEX routers, lending markets, and other DeFi primitives on Sei. The protocol APIs themselves match their canonical EVM versions (Uniswap-V2/V3, Compound, Aave); this file calls out **only the Sei-specific deltas**. -> **Always verify contract addresses** against the protocol's official docs before sending real value. Addresses below are illustrative — the truth is in [docs.sei.io ecosystem contracts](https://docs.sei.io/evm/reference/ecosystem-contracts). +> **Always verify contract addresses** against the protocol's official docs before sending real value. Addresses below are illustrative — the truth is in [docs.sei.io ecosystem contracts](https://docs.sei.io/evm/ecosystem-contracts). ## Pre-flight checklist (every DeFi integration) @@ -181,7 +181,7 @@ See [oracles.md](oracles.md) for full Pyth/Chainlink integration patterns. ## Stablecoin handling: USDC on Sei -USDC on Sei mainnet is **native USDC issued by Circle**, not a bridged synthetic. Verify the current canonical address via [docs.sei.io USDC integration](https://docs.sei.io/evm/reference/usdc). +USDC on Sei mainnet is **native USDC issued by Circle**, not a bridged synthetic. Verify the current canonical address via [docs.sei.io USDC integration](https://docs.sei.io/evm/usdc-on-sei). ```ts const USDC_DECIMALS = 6; @@ -240,7 +240,7 @@ Pointer addresses are deterministic from the underlying CW20 denom. See [pointer ## Sei-specific notes -- **WSEI** (wrapped SEI) plays the role of WETH. Verify the canonical WSEI address via [docs.sei.io ecosystem contracts](https://docs.sei.io/evm/reference/ecosystem-contracts). +- **WSEI** (wrapped SEI) plays the role of WETH. Verify the canonical WSEI address via [docs.sei.io ecosystem contracts](https://docs.sei.io/evm/ecosystem-contracts). - **Native SEI** uses 18 decimals (not 6 like Cosmos-side `usei` micro-denom — that's a Cosmos-side concept; EVM sees 18 decimals). - **Atomic batching**: account abstraction (see [contracts/account-abstraction.md](../contracts/account-abstraction.md)) lets users do approve+swap in one user op without a separate approval tx. - **Liquidation latency**: 400ms blocks make liquidation MEV competitive; bots can react within 1-2 blocks. diff --git a/skill/references/ecosystem/node-operations.md b/skill/references/ecosystem/node-operations.md index 8d3de0b..4c93172 100644 --- a/skill/references/ecosystem/node-operations.md +++ b/skill/references/ecosystem/node-operations.md @@ -29,7 +29,7 @@ description: Running and maintaining Sei full nodes — node types, setup, state ```bash git clone https://github.com/sei-protocol/sei-chain.git cd sei-chain -git checkout # e.g. v5.9.0 +git checkout # pick the recommended tag from the Network Versions table on docs.sei.io make install # Verify @@ -39,14 +39,16 @@ seid version ### Initialize Node ```bash -# Initialize with your moniker +# Initialize with your moniker. genesis.json is written automatically for known +# networks (mainnet/testnets) — do NOT hand-download or overwrite it. seid init --chain-id pacific-1 -# Download genesis -curl -s https://raw.githubusercontent.com/sei-protocol/testnet/main/pacific-1/genesis.json \ - > $HOME/.sei/config/genesis.json +# For a validator (binds RPC/P2P to localhost), init in validator mode instead: +# seid init --chain-id pacific-1 --mode validator ``` +> **Never start from genesis on a live network** — it panics with `integer divide by zero`. Bootstrap via state sync (below) or a snapshot. + --- ## State Sync (Recommended for Fast Bootstrap) @@ -130,7 +132,7 @@ timeout-broadcast-tx-commit = "10s" ### app.toml (Database + API) ```toml -minimum-gas-prices = "0.01usei" +minimum-gas-prices = "0.02usei" # set at or above the mainnet-enforced floor; 0usei = local dev only [api] enable = true @@ -151,6 +153,32 @@ ss-prune-interval = 600 --- +## SeiDB storage, RocksDB, and Giga + +SeiDB has two layers: **State Commit (SC)** — a memiavl Merkle tree that holds Cosmos module state and computes the app hash — and **State Store (SS)** — versioned raw key/values for historical queries (`ss-enable = true` is required for any RPC node). + +- **RocksDB SS backend** (optional): faster for iteration-heavy work (`debug_trace*`, large archive queries). Build with `make build-rocksdb && make install-rocksdb`, then set `ss-backend = "rocksdb"`. RocksDB RPC nodes must state-sync on first start. +- **Giga SS Store** (optional, RPC nodes): splits the **State Store** so EVM state lives in its own SS DB. Controlled by a single bool — `evm-ss-split = true` (Sei v6.5+; older releases used per-key `evm-ss-write-mode`/`evm-ss-read-mode`). Requires a **fresh state sync** — flipping it on a node with existing data fails startup safety checks. **SC config is left untouched.** See the [Giga SS Store Migration Guide](https://docs.sei.io/node/giga-storage-migration). +- **Giga Storage (SC FlatKV routing)** is a *separate*, broader option that routes EVM **State Commit** data through FlatKV, controlled by the single `sc-write-mode` key: + + ```toml + [state-commit] + # Valid: memiavl_only (default), migrate_evm, evm_migrated, migrate_all_but_bank, + # all_migrated_but_bank, migrate_bank, flatkv_only. (test_only_dual_write is + # test-only — never in production.) There is NO sc-read-mode and NO + # sc-enable-lattice-hash key; the evm_lattice app-hash handling is internal. + sc-write-mode = "memiavl_only" + # Keys drained memiavl→FlatKV per block while migrating (migrate_* modes): + sc-keys-to-migrate-per-block = 1024 + ``` + + The migration is staged: `migrate_evm` drains EVM data in the background and settles at `evm_migrated`; later modes migrate the remaining modules. +- **Giga Executor** (`[giga_executor] enabled`) is a *separate* feature — an evmone-based EVM interpreter for throughput. Don't conflate it with Giga Storage. + +> Minimum gas price, block gas limit, and SSTORE/storage gas are governance-adjustable — confirm live values at https://docs.sei.io/evm/differences-with-ethereum, and set `minimum-gas-prices` at or above the mainnet floor (`0usei` is local-dev only). + +--- + ## Commonly Used Ports | Port | Protocol | Purpose | diff --git a/skill/references/ecosystem/oracles.md b/skill/references/ecosystem/oracles.md index 1f94ef9..0417fe2 100644 --- a/skill/references/ecosystem/oracles.md +++ b/skill/references/ecosystem/oracles.md @@ -13,45 +13,11 @@ description: Chainlink, Pyth Network, API3, and RedStone oracle integrations on | **Pyth Network** | Sub-second latency, NFTs, perps, high-frequency | Pull (user pushes update per tx) | | **API3** | First-party data, operational simplicity | Push (dAPI proxies) | | **RedStone** | On-demand, modular, custom feeds | Pull (wrap tx with price data) | -| **Native Oracle** | Simple on-chain access to Sei's oracle module | Precompile (always available) | +| **Native Oracle** (`0x…1008`) | ❌ **Shut off (~July 2026) — returns no data; do not use** | — | > **NEVER use `block.prevrandao` or `block.timestamp` for randomness** — use Pyth VRF or Chainlink VRF instead. ---- - -## Native Oracle Precompile - -**Address:** `0x0000000000000000000000000000000000001008` - -Sei has a built-in oracle module. Price data is submitted by validators each epoch. - -```solidity -pragma solidity ^0.8.28; - -interface IOracle { - struct OracleData { - int64 price; // price in micro-USD (divide by 1e6 to get USD) - uint64 denom; - uint64 timestamp; - } - - function getExchangeRates() external view returns (OracleData[] memory); - function getOracleTwaps(uint64 lookbackSeconds) external view returns (OracleData[] memory); -} - -contract PriceFeed { - address constant ORACLE = 0x0000000000000000000000000000000000001008; - - function getSeiPrice() external view returns (int64) { - IOracle.OracleData[] memory rates = IOracle(ORACLE).getExchangeRates(); - for (uint i = 0; i < rates.length; i++) { - // Find SEI/USD rate - return rates[i].price; // micro-USD - } - revert("SEI rate not found"); - } -} -``` +> **❌ The native Oracle precompile (`0x…1008`) is being shut off (~July 2026) and returns no usable data — treat it as a no-op.** It's gone, not merely deprecated: do not read prices from it. Use a third-party oracle (Chainlink, Pyth, API3, RedStone) for every feed — covered below. --- diff --git a/skill/references/ecosystem/participation-roles.md b/skill/references/ecosystem/participation-roles.md index c837c1f..bf733e5 100644 --- a/skill/references/ecosystem/participation-roles.md +++ b/skill/references/ecosystem/participation-roles.md @@ -69,8 +69,6 @@ Index Sei block data into a queryable form (subgraphs, SQL, REST APIs). Run alon Publish off-chain data (prices, randomness, weather, etc.) on-chain via an oracle network. -**Sei native oracle** (price feeds) — submitted by validators each epoch, no separate relayer role; price votes are part of consensus duty. - **Pyth Network** — operates a separate publisher/aggregator system; publishers are Pyth ecosystem participants, not Sei-specific. **Chainlink** — node operator on Chainlink, fulfilling jobs that touch Sei. Apply through Chainlink directly. diff --git a/skill/references/ecosystem/payments.md b/skill/references/ecosystem/payments.md new file mode 100644 index 0000000..e9056ae --- /dev/null +++ b/skill/references/ecosystem/payments.md @@ -0,0 +1,140 @@ +--- +title: Payments on Sei (USDC + x402) +description: Accept and send payments on Sei with USDC (ERC-20, 6 decimals) and x402 HTTP-native micropayments. Addresses, transfer flow, the 402 challenge/verify cycle, and replay protection. +--- + +# Payments on Sei (USDC + x402) + +Moving and accepting digital dollars on Sei: transferring **USDC** as a standard ERC-20, and gating HTTP endpoints behind per-request payments with the **x402** protocol so APIs, agents, and content can charge in stablecoins. USDC is the unit of account for both flows — x402 settles in USDC on Sei. + +## Critical facts + +- **USDC is a standard ERC-20 on Sei EVM.** Transfer with `transfer(to, amount)`, read balances with `balanceOf(account)`. No special precompile or bridge call for plain transfers. +- **USDC has 6 decimals** (not 18). `1 USDC = 1_000_000` base units. Convert with `parseUnits(value, 6)` / `formatUnits(value, 6)` — using 18 overpays by 10^12×. +- **USDC token addresses** (verify on [Seiscan](https://seiscan.io) before sending real value): + - Mainnet (pacific-1, 1329): `0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392` + - Testnet (atlantic-2, 1328): `0x4fCF1784B31630811181f670Aea7A7bEF803eaED` +- **Get testnet USDC** from the [Circle Faucet](https://faucet.circle.com), or bridge real USDC cross-chain with [Circle CCTP v2](https://developers.circle.com/cctp). You still need a little native SEI for fees. +- **~400ms blocks with fast finality make micropayments practical.** Confirm with one confirmation (`tx.wait(1)` / one block of polling), never `tx.wait(12)`. `safe`/`finalized`/`latest` resolve to the same instantly-final block — query `latest`. +- **Use legacy `gasPrice`.** No EIP-1559 base-fee burn (all fees go to validators). The minimum gas price is governance-adjustable (currently ~50 gwei on mainnet — query `eth_gasPrice` for the live floor). See https://docs.sei.io/evm/differences-with-ethereum. +- **x402 uses HTTP 402 ("Payment Required").** The server answers an unpaid request with `402` + a JSON payment challenge; the client pays on-chain, then retries with proof in a base64 `X-Payment` header. The challenge `x402Version` is `1`, scheme `exact`. + +## x402 packages (`@sei-js`) + +Pick by role rather than hand-rolling challenge/verify: +- Client (paying): [`@sei-js/x402-fetch`](https://www.npmjs.com/package/@sei-js/x402-fetch) or [`@sei-js/x402-axios`](https://www.npmjs.com/package/@sei-js/x402-axios). +- Server (charging): [`@sei-js/x402-express`](https://www.npmjs.com/package/@sei-js/x402-express), [`@sei-js/x402-hono`](https://www.npmjs.com/package/@sei-js/x402-hono), or [`@sei-js/x402-next`](https://www.npmjs.com/package/@sei-js/x402-next). +- Core protocol: [`@sei-js/x402`](https://www.npmjs.com/package/@sei-js/x402). + +## Send / accept USDC (viem) + +Minimal ERC-20 flow — check balance, then transfer. Default to testnet; switch to mainnet only on explicit confirmation. + +```js +import { createPublicClient, createWalletClient, http, formatUnits, parseUnits } from 'viem'; +import { sei, seiTestnet } from 'viem/chains'; +import { privateKeyToAccount } from 'viem/accounts'; + +const NETWORK = (process.env.SEI_NETWORK || 'testnet').toLowerCase(); +const chain = NETWORK === 'mainnet' ? sei : seiTestnet; + +// USDC: 6 decimals. Verify addresses on Seiscan before mainnet use. +const USDC_ADDRESS = NETWORK === 'mainnet' + ? '0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392' + : '0x4fCF1784B31630811181f670Aea7A7bEF803eaED'; +const USDC_ABI = [ + { name: 'balanceOf', type: 'function', stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], outputs: [{ type: 'uint256' }] }, + { name: 'transfer', type: 'function', stateMutability: 'nonpayable', + inputs: [{ name: 'to', type: 'address' }, { name: 'amount', type: 'uint256' }], + outputs: [{ type: 'bool' }] }, +]; + +const account = privateKeyToAccount(process.env.PRIVATE_KEY); +const publicClient = createPublicClient({ chain, transport: http() }); +const walletClient = createWalletClient({ account, chain, transport: http() }); + +const balance = await publicClient.readContract({ + address: USDC_ADDRESS, abi: USDC_ABI, functionName: 'balanceOf', args: [account.address], +}); +console.log('USDC balance:', formatUnits(balance, 6)); + +const amount = parseUnits('10', 6); // 10 USDC +if (balance < amount) throw new Error('Insufficient USDC balance'); + +const hash = await walletClient.writeContract({ + address: USDC_ADDRESS, abi: USDC_ABI, functionName: 'transfer', args: [process.env.RECIPIENT_ADDRESS, amount], +}); +await publicClient.waitForTransactionReceipt({ hash }); // one confirmation is enough on Sei +``` + +## Charge per request with x402 + +Five steps: (1) client requests a protected resource; (2) server returns `402` with a payment challenge; (3) client pays on-chain (a USDC transfer to `payTo`); (4) client retries with a base64 `X-Payment` proof; (5) server verifies on-chain and serves the resource. + +The challenge advertised on a `402` response: + +```json +{ + "x402Version": 1, + "accepts": [{ + "scheme": "exact", + "network": "sei-testnet", + "maxAmountRequired": "1000", + "resource": "/api/weather", + "payTo": "0x9dC2aA0038830c052253161B1EE49B9dD449bD66", + "asset": "0x4fCF1784B31630811181f670Aea7A7bEF803eaED", + "extra": { "name": "USDC", "version": "2", "reference": "sei-1234567890-abc123" } + }] +} +``` + +`maxAmountRequired` is in USDC base units — `"1000"` is `0.001` USDC. The `reference` is a per-challenge nonce used to prevent replay. Note `extra.version` (`"2"`) is the USDC contract's **EIP-712 domain version**, *not* the x402 protocol version (the top-level `x402Version`, `1`) — do not conflate them. + +Verification must check the receipt status, the recipient, the exact amount, **and** that the reference nonce has not been seen before: + +```typescript +async function verifyPayment(paymentHeader: string) { + const data = JSON.parse(Buffer.from(paymentHeader, 'base64').toString()); + const { x402Version, scheme, network, payload } = data; + if (x402Version !== 1 || scheme !== 'exact' || network !== 'sei-testnet') { + return { isValid: false, reason: 'Invalid payment format or network' }; + } + + const receipt = await publicClient.getTransactionReceipt({ hash: payload.txHash }); + if (receipt?.status !== 'success') { + return { isValid: false, reason: 'Transaction not found or reverted' }; + } + + // REQUIRED for a non-replayable paywall — do NOT ship without these. + // transferMatches decodes the USDC Transfer event from receipt.logs and confirms + // to === payTo and value >= maxAmountRequired; the reference helpers persist seen + // nonces so one valid payment can't be replayed. (The @sei-js/x402-* middleware does this.) + if (!transferMatches(receipt, payTo, maxAmountRequired) || !isReferenceUnused(payload.reference)) { + return { isValid: false, reason: 'Payment does not match challenge or was already used' }; + } + markReferenceUsed(payload.reference); + return { isValid: true, txHash: payload.txHash }; +} +``` + +For production, prefer the `@sei-js/x402-*` middleware (Express/Hono/Next) and client wrappers over hand-rolling challenge/verify. See the [sei-x402 repo](https://github.com/sei-protocol/sei-x402). + +## Common pitfalls + +- **Treating USDC as 18 decimals.** It is 6 decimals — `parseUnits('10', 6)`, not `parseEther('10')`. A wrong constant multiplies the amount by 10^12. +- **Waiting for 12 confirmations.** Sei finalizes in ~400ms — one confirmation; waiting 12 defeats the point of micropayments. +- **Sending EIP-1559 fee fields.** Use legacy `gasPrice`; query the live floor rather than hardcoding. +- **Forgetting native SEI for fees.** A USDC transfer still costs fees in native SEI. +- **Trusting `txHash` alone in x402.** Verify receipt status, recipient (`payTo`), exact amount, AND the unused `reference` nonce — otherwise a valid payment can be replayed. +- **Using testnet addresses on mainnet (or vice versa).** The USDC address differs per network — re-verify on Seiscan before moving real value. + +## Key links + +| Topic | Link | +|---|---| +| USDC on Sei (addresses, transfer guide) | https://docs.sei.io/evm/usdc-on-sei | +| x402 protocol on Sei | https://docs.sei.io/ai/x402 | +| sei-x402 repo (packages, quickstarts) | https://github.com/sei-protocol/sei-x402 | +| Circle CCTP v2 (bridge USDC in) | https://developers.circle.com/cctp | +| Circle testnet faucet | https://faucet.circle.com | diff --git a/skill/references/evm/best-practices.md b/skill/references/evm/best-practices.md index b19b929..ff6769f 100644 --- a/skill/references/evm/best-practices.md +++ b/skill/references/evm/best-practices.md @@ -89,7 +89,7 @@ function batchUpdate(address[] calldata users, uint256[] calldata scores) extern ## SSTORE Gas Awareness -Both mainnet (pacific-1) and testnet (atlantic-2) charge **72,000 gas per cold write** (governance proposal #240). This is governance-adjustable — always verify with `forge test --gas-report` targeting the correct network. +Both mainnet (pacific-1) and testnet (atlantic-2) charge **72,000 gas per cold write** (pacific-1 [Proposal #109](https://www.mintscan.io/sei/proposals/109); testnet carries the same value with no separate proposal). This is governance-adjustable. Note: a `forge test --gas-report --fork-url` report uses revm's standard EVM schedule and shows ~22,100, *not* Sei's cost — use a live `eth_estimateGas` against a Sei RPC for the real storage-write cost. **Testnet budget impact (72k):** - A simple 3-slot write transaction: 3 × 72k = 216k gas just for storage @@ -206,7 +206,7 @@ Sei precompiles are highly optimized native contracts — cheaper and more relia | Stake/unstake SEI | Staking | `0x1005` | | Claim rewards | Distribution | `0x1007` | | On-chain governance vote | Governance | `0x1006` | -| Oracle price feed | Oracle | `0x1008` | +| Oracle price feed — ❌ shut off (~July 2026), use a third-party oracle | Oracle | `0x1008` | | Address conversion | Addr | `0x1004` | | Native token send | Bank | `0x1001` | diff --git a/skill/references/evm/overview.md b/skill/references/evm/overview.md index a0ebb7e..7e95fc1 100644 --- a/skill/references/evm/overview.md +++ b/skill/references/evm/overview.md @@ -66,7 +66,7 @@ const tx = { ### SSTORE and Storage Writes ```solidity // SSTORE costs differ by network: -// - Both mainnet & testnet: 72,000 gas per cold write (governance proposal #240) +// - Both mainnet & testnet: 72,000 gas per cold write (pacific-1 Proposal #109; testnet same value, no separate proposal) // Always verify with `forge test --gas-report` against your target network. diff --git a/skill/references/frontend/docs-contributing.md b/skill/references/frontend/docs-contributing.md index e689a2b..339aa8d 100644 --- a/skill/references/frontend/docs-contributing.md +++ b/skill/references/frontend/docs-contributing.md @@ -1,61 +1,63 @@ --- title: Contributing to docs.sei.io -description: How to author or update pages on docs.sei.io. Repo layout, Nextra MDX conventions, _meta.js navigation config, frontmatter requirements, build commands, and PR workflow. +description: How to author or update pages on docs.sei.io. Mintlify repo layout, docs.json navigation, MDX frontmatter and components, snippets, local preview, CI checks, and PR workflow. --- # Contributing to docs.sei.io -The Sei docs are published from https://github.com/sei-protocol/sei-docs (despite the `-old` suffix in some tooling, this is the live source). Built with Nextra + Bun. This file is the contributor cheat sheet. +The Sei docs are published from https://github.com/sei-protocol/sei-docs and auto-deploy from `main`. The site is built with **Mintlify** (the repo was migrated off Nextra). This file is the contributor cheat sheet. ## Repo at a glance | Item | Value | |---|---| | Repo | https://github.com/sei-protocol/sei-docs | -| Framework | Nextra (Next.js docs theme) | -| Package manager / runtime | Bun | -| Page format | `.mdx` (Markdown + JSX) | -| Content root | `/content/` | -| Style guide | `/STYLE_GUIDE.mdx` | +| Platform | Mintlify (auto-deploys from `main`) | +| Config | `docs.json` (navigation, redirects, theme, search) | +| Page format | `.mdx` (Markdown + JSX components) | +| Content root | repo root — pages live in top-level section dirs (`evm/`, `learn/`, `node/`, `ai/`) | +| Reusable components | `/snippets/` (`.mdx` partials and `.jsx` custom React) | +| Style guide | `STYLE_GUIDE.md` (enforced by Vale) | +| Contributor rules | `AGENTS.md`, `CODEOWNERS`, PR template | + +There is **no `_meta.js`, no Bun, no `/content/` root** — those were the old Nextra setup. Navigation lives entirely in `docs.json`. ## Directory layout ``` -content/ -├── _meta.js # root nav config (top-level sections in display order) -├── index.mdx # docs.sei.io home -├── learn/ -│ ├── _meta.js # nav config for /learn -│ ├── index.mdx # /learn landing -│ └── ...mdx # individual pages -├── evm/ -│ ├── _meta.js +sei-docs/ +├── docs.json # navigation, redirects, theme — the single nav source of truth +├── index.mdx # docs.sei.io home +├── evm/ # EVM developer docs +│ ├── evm-general.mdx │ ├── precompiles/ -│ │ ├── _meta.js │ │ └── ...mdx -│ └── ... -├── cosmos-sdk/ # deprecated; new content goes elsewhere -├── node/ -│ └── ... -└── STYLE_GUIDE.mdx +│ └── sei-js/ +│ └── ...mdx +├── learn/ # concepts, accounts, architecture +├── node/ # node + validator operations +├── ai/ # AI tooling, skills, MCP, x402 +├── snippets/ # reusable .jsx custom components (Mintlify also supports .mdx partials) +├── images/ # static assets +├── skill.md # root agent-skill override (served at /.well-known/skills/) +└── STYLE_GUIDE.md ``` ## Authoring a page -1. **Pick the right section** — `learn/` for concepts, `evm/` for EVM dev, `node/` for node ops. Don't put new content in `cosmos-sdk/` (deprecated per SIP-03). +1. **Pick the right section** — `learn/` for concepts, `evm/` for EVM dev, `node/` for node ops, `ai/` for AI tooling. Don't add new Cosmos-SDK/CosmWasm content (deprecated per SIP-3). 2. **Filename**: kebab-case (`my-new-page.mdx`). 3. **MDX with frontmatter** at the top: ```mdx --- -title: "My Page Title" -description: "One-sentence description used for SEO and OG cards." -keywords: ["sei", "evm", "..."] +title: 'My Page Title' +sidebarTitle: 'Short Nav Title' +description: 'One-sentence description used for SEO and the page subtitle.' +keywords: ['sei', 'evm', '...'] --- -# My Page Title - -Intro paragraph that re-states the H1 in conversational form... +Intro paragraph. (Mintlify renders `title` as the H1 automatically — do not add your own `# H1`.) ## First section @@ -65,120 +67,122 @@ Content here. Code blocks use triple-backtick fences with language hints: pragma solidity ^0.8.28; contract Foo { /* ... */ } ``` +``` -Tables, callouts, JSX components from Nextra (e.g., ``) all work. +4. **Register the page in `docs.json`** — add its path (without `.mdx`) to the correct group's `pages` array. A page that isn't in `docs.json` won't appear in the nav. + +## `docs.json` navigation + +Navigation is a nested structure of tabs → groups → pages. Page entries are file paths **relative to the repo root, without the `.mdx` extension**. + +```jsonc +// docs.json (excerpt) +{ + "navigation": { + "tabs": [ + { + "tab": "EVM", + "groups": [ + { + "group": "Sei-JS", + "pages": [ + "evm/sei-js/index", + "evm/sei-js/create-sei", + "evm/templates" // <- add your new page here, in display order + ] + } + ] + } + ] + }, + "redirects": [ + { "source": "/old-path", "destination": "/new-path", "permanent": true } + ] +} ``` -4. **Update the section's `_meta.js`** to add the new page to the nav. +- **Order** in the `pages` array = sidebar order. +- **Nested groups** are objects with their own `group` + `pages`. +- **Moved or renamed a page?** Add a `redirects` entry so old URLs keep working (CI link-checks both internal links and the redirect set). -## `_meta.js` navigation config +## Mintlify components -Each directory has a `_meta.js` that controls sidebar order and display titles. +Common components available in any `.mdx` page (no import needed): ``, ``, ``, ``, ``, ``, ``/``, ``, ``, ``, ``, ``, ``. Use `` for multi-language tabs (they auto-sync across a page) and `` for sequential instructions. -```js -// content/evm/_meta.js (excerpt) -export default { - index: { title: 'Home' }, - '-- Essentials': { type: 'separator' }, - networks: 'Network Information', - 'evm-hardhat': 'EVM with Hardhat', - 'evm-foundry': 'EVM with Foundry', - 'evm-verification': 'Contract Verification', - '-- Precompiles': { type: 'separator' }, - precompiles: 'Precompiles', - // ... -} -``` +### Snippets and custom React -Keys are the slugs of files (without `.mdx`) or subdirectory names. Values are either: -- A string (display title in the sidebar) -- An object (`{ title, type, display, theme }`) for advanced control -- A separator (`{ type: 'separator' }`) for visual groupings in the sidebar +Reusable content lives in `/snippets/`. Mintlify supports two kinds; Sei's repo currently uses only the second: +- **`.mdx` partials** — import and render shared prose/components (a Mintlify capability; the Sei repo has none today). +- **`.jsx` custom components** — interactive widgets. Mintlify's React runtime has strict rules (per Mintlify's custom-React docs): + - **Arrow-function component, exported as a named `export const` — no `export default`.** + - **No `import` statements** and **no npm packages** — React hooks (`useState`, `useEffect`, …) are pre-injected; use them without importing. + - **No dynamic `import()`** / `React.lazy`. + - Practical convention (not in Mintlify's published rules): keep declarations inside the component body and stick to plain Tailwind utility classes — use inline `style` for anything they can't express. + - Client-rendered — gate heavy widgets behind click-to-load. -To add a page named `my-new-page.mdx`, add `'my-new-page': 'My New Page'` in the right position in the parent `_meta.js`. +```mdx +import { MyWidget } from '/snippets/my-widget.jsx'; + + +``` ## Style guide essentials -From `STYLE_GUIDE.mdx`: +From `STYLE_GUIDE.md` (Vale enforces much of this in CI): 1. **Beginner-friendly** — explain Web3 jargon; spell out acronyms on first use ("Ethereum Virtual Machine (EVM)"). -2. **Simple sentences** — short, direct, avoid passive voice. -3. **Self-explanatory** — provide context; show code over describing it. -4. **Use code snippets, tables, and callouts** liberally. -5. **Cross-link** to other docs pages where useful — Nextra resolves relative `.mdx` paths. -6. **Diagrams** — Mermaid is supported in code fences with `mermaid` language hint. +2. **Simple, direct sentences** — avoid passive voice. +3. **Show code over describing it** — paste the working snippet, then explain. +4. **Use code blocks, tables, and callouts** liberally. +5. **Cross-link** with root-relative paths (`/evm/precompiles/example-usage`). +6. **Diagrams** — Mermaid is supported in ` ```mermaid ` code fences. +7. **Date/version-stamp** anything that drifts (addresses, gas values, version requirements); prefer linking the live value over hardcoding. ## Local development +Install the Mintlify CLI and run the dev server from the repo root: + ```bash -bun install -bun dev -# → http://localhost:3000 +npm i -g mint # or: npx mint dev +mint dev # → http://localhost:3000 (hot-reloads on save) ``` -Navigate to your new page and verify rendering. Hot reload picks up MDX changes. - -## Build validation (run before PR) +`mint dev` validates `docs.json` and renders pages exactly as production. Check links before opening a PR: ```bash -bun run build +mint broken-links ``` -Build runs: -- Next.js production build -- Pagefind search index generation -- Sitemap generation -- HTML scraping for downstream tools (`llms.txt`) +## CI checks (run before / expect on PR) + +The repo has best-in-class docs CI. Expect these to run on your PR: + +- **Vale** (`.vale.ini`) — prose linting against the Sei style rules. +- **typos** — spell-check. +- **lychee** (`lychee.toml`) + **`mint broken-links`** — internal and external link validation (including the `redirects` set). +- **SEO audit** and weekly **`llms.txt`** regeneration. -If any step fails, fix locally before opening a PR. +Fix Vale/link failures locally before requesting review. ## PR workflow -1. **Fork** https://github.com/sei-protocol/sei-docs. +1. **Fork** https://github.com/sei-protocol/sei-docs (or branch if you have write access). 2. **Branch** from `main` with a descriptive name (`docs/add-account-abstraction-page`). -3. **Edit** files; run `bun dev` to preview. -4. **Build** with `bun run build` to catch errors. -5. **Commit** with a clear message ("Add account abstraction guide to /evm"). -6. **Push** to your fork. -7. **Open a PR** against `sei-protocol/sei-docs:main` using the PR template. -8. **Address review feedback** — maintainers may request structural or wording changes. +3. **Edit** pages; run `mint dev` to preview and `mint broken-links` to validate. +4. **Update `docs.json`** to register new pages and add redirects for any moves. +5. **Commit** with a clear message; **open a PR** against `sei-protocol/sei-docs:main` using the PR template. +6. **Address review** — `CODEOWNERS` routes the right reviewers; CI must pass. ## Common pitfalls | Symptom | Cause | Fix | |---|---|---| -| Page doesn't appear in sidebar | Missing entry in `_meta.js` | Add the slug to the parent `_meta.js` | -| Build fails on broken link | Internal link to non-existent page | Fix or use `` for external | -| Code block doesn't highlight | Missing language hint after backticks | Add ` ```solidity ` etc. | -| MDX import error | JSX component not imported at top of file | `import { Callout } from 'nextra/components'` | -| Incorrect ordering | `_meta.js` keys are out of intended order | Reorder keys; the JS object preserves insertion order | -| Two pages with the same `title` frontmatter | Duplicate keys collide in nav | Use unique slugs and titles | - -## Adding a new top-level section - -Rare; usually contributing means adding pages within an existing section. If you must add a new top-level dir: - -1. Create `/content//`. -2. Add `_meta.js` and `index.mdx` (the section landing page). -3. Update `/content/_meta.js` to register the new section in nav order. -4. Coordinate with maintainers — top-level sections are an information-architecture decision, not a content one. - -## Specific page types - -### Tutorials / how-tos -- Start with prerequisites and goals. -- Code-first: paste the working snippet immediately, then explain. -- End with verification: how does the user know it worked? - -### Reference pages -- Tables of values (addresses, RPC endpoints, chain IDs) belong here. -- Always include "verify against [authoritative source]" notes. -- Date or version-stamp things that drift. - -### Concept pages -- Lead with a one-sentence definition. -- Use diagrams (Mermaid) for protocol flows. -- Cross-link to deeper-dive references. +| Page doesn't appear in sidebar | Path not added to `docs.json` | Add `"/"` (no `.mdx`) to the right group's `pages` | +| Duplicate H1 on the page | Added `# Title` on top of frontmatter `title` | Remove the manual `# H1` — Mintlify renders `title` as the H1 | +| Custom `.jsx` snippet throws at runtime | Declared something at module scope, used `export default`, or `import`ed a package | Move all decls inside the arrow-fn component; named `export const`; no imports | +| Broken-link CI fails | Internal link to a non-existent path, or a renamed page with no redirect | Fix the path or add a `redirects` entry in `docs.json` | +| Old URL 404s after a rename | Missing redirect | Add `{ source, destination, permanent: true }` to `docs.json` | +| Code block doesn't highlight | Missing language hint | Add ` ```solidity ` / ` ```ts ` etc. | ## Where to put what @@ -187,13 +191,15 @@ Rare; usually contributing means adding pages within an existing section. If you | New EVM dev guide | `/evm` | | Precompile reference | `/evm/precompiles` | | Wallet integration | `/evm/wallet-integrations` | -| Architecture explainer | `/learn` | -| Node setup tutorial | `/node` | -| Cosmos-SDK reference | **don't** — section deprecated | +| Architecture / accounts explainer | `/learn` | +| Node / validator setup | `/node` | +| AI tooling, skills, MCP, x402 | `/ai` | +| Agent skill (hosted) | root `skill.md` (override mode); Mintlify also supports `.mintlify/skills//SKILL.md` for multiple skills | +| Cosmos-SDK / CosmWasm | **don't** — deprecated per SIP-3 | ## Sei-specific notes -- **CosmWasm and Cosmos-SDK content** is being phased out per SIP-03 — confirm with maintainers before contributing legacy CosmWasm content. -- **EVM-first** is the current direction — most new pages should land in `/evm/`. -- **Brand kit** lives at https://docs.sei.io/learn/general-brand-kit. Updates to logos/visual identity should also be coordinated with sei.io/media. -- **The repo name `sei-docs-old`** in some references is a historical artifact — the same repo is the active source. +- **EVM-first** is the current direction — most new pages land in `/evm/`. +- **CosmWasm and Cosmos-SDK content** is being phased out per SIP-3; confirm with maintainers before adding legacy content. +- **Hosted agent skill**: Sei publishes one via a **root `skill.md`** (Mintlify "override" mode — `name: sei-docs`, `intended-host: docs.sei.io`), served at `docs.sei.io/.well-known/skills/` and installable via `npx skills add https://docs.sei.io`. (Mintlify also supports a `.mintlify/skills//SKILL.md` layout for *multiple* skills, but Sei doesn't use it — `.gitignore` excludes all of `.mintlify/`.) +- **Brand kit** lives at https://docs.sei.io/learn/general-brand-kit; coordinate visual-identity changes with sei.io/media. diff --git a/skill/references/frontend/frontend-stack.md b/skill/references/frontend/frontend-stack.md index f874661..139c3fd 100644 --- a/skill/references/frontend/frontend-stack.md +++ b/skill/references/frontend/frontend-stack.md @@ -14,7 +14,7 @@ Build dApps that interact with Sei from the browser or Node. This file replaces | **Library** | Wagmi + Viem | You want maximum control or React-free scripts → ethers v6 | | **Wallet (consumer)** | Sei Global Wallet (`@sei-js/sei-global-wallet`) | Power-user app → MetaMask, Compass, Ledger | | **Wallet UX shell** | RainbowKit or ConnectKit | You want bare bones → Wagmi `useConnect` directly | -| **Chain config** | `@sei-js/precompiles` exports | You need a chain not in `@sei-js/precompiles` → manual `defineChain` | +| **Chain config** | `sei` / `seiTestnet` from `wagmi/chains` (or `viem/chains`) | A chain not exported → viem `defineChain` | | **State / data** | TanStack Query (Wagmi default) | Already on Redux/Zustand → integrate manually | ## Quick install @@ -38,7 +38,7 @@ npm install ethers @sei-js/precompiles ```ts // wagmi.config.ts import { createConfig, http } from "wagmi"; -import { sei, seiTestnet } from "@sei-js/precompiles"; +import { sei, seiTestnet } from "wagmi/chains"; import { injected, walletConnect } from "wagmi/connectors"; export const wagmiConfig = createConfig({ @@ -76,7 +76,7 @@ export function App({ children }: { children: React.ReactNode }) { ```tsx import { useAccount, useReadContract, useWriteContract } from "wagmi"; import { parseEther, parseUnits } from "viem"; -import { sei } from "@sei-js/precompiles"; +import { sei } from "wagmi/chains"; function Balance({ token }: { token: `0x${string}` }) { const { address } = useAccount(); @@ -133,7 +133,7 @@ For a polished modal, use RainbowKit: ```tsx import { RainbowKitProvider, getDefaultConfig } from "@rainbow-me/rainbowkit"; import "@rainbow-me/rainbowkit/styles.css"; -import { sei, seiTestnet } from "@sei-js/precompiles"; +import { sei, seiTestnet } from "wagmi/chains"; const config = getDefaultConfig({ appName: "My Sei App", @@ -177,14 +177,16 @@ Every Sei account has both an EVM address (`0x...`) and a Cosmos address (`sei1. import { ADDRESS_PRECOMPILE_ADDRESS, ADDRESS_PRECOMPILE_ABI } from "@sei-js/precompiles"; function DualAddress({ evm }: { evm: `0x${string}` }) { - const { data: cosmos } = useReadContract({ + const { data: cosmos, isError } = useReadContract({ address: ADDRESS_PRECOMPILE_ADDRESS, abi: ADDRESS_PRECOMPILE_ABI, functionName: "getSeiAddr", args: [evm], }); - const associated = cosmos && cosmos !== ""; + // getSeiAddr REVERTS for an unassociated address (it does NOT return "") — + // treat the read error as "not linked", not a crash. + const associated = !isError && !!cosmos; return (
EVM: {evm} @@ -230,7 +232,7 @@ Wagmi handles multichain natively. Just include the chains you support: ```ts import { mainnet, arbitrum, optimism } from "wagmi/chains"; -import { sei } from "@sei-js/precompiles"; +import { sei } from "wagmi/chains"; export const config = createConfig({ chains: [sei, mainnet, arbitrum, optimism], @@ -255,7 +257,7 @@ If the user's wallet doesn't already know about Sei, prompt to add it: ```ts import { useSwitchChain } from "wagmi"; -import { sei } from "@sei-js/precompiles"; +import { sei } from "wagmi/chains"; const { switchChainAsync } = useSwitchChain(); @@ -263,7 +265,7 @@ await switchChainAsync({ chainId: sei.id }); // Wagmi triggers wallet_addEthereumChain if needed ``` -`@sei-js/precompiles`'s exports include the canonical `chainName`, `nativeCurrency`, `rpcUrls`, and `blockExplorers` that wallets need. +The `sei` / `seiTestnet` configs from `wagmi/chains` include the canonical `chainName`, `nativeCurrency`, `rpcUrls`, and `blockExplorers` that wallets need. (`@sei-js/precompiles` ships only the `seiLocal` dev chain — not `sei`/`seiTestnet` — so use it for precompile addresses/ABIs, not chain config.) ## ethers v6 (non-React, scripts) @@ -321,7 +323,7 @@ For most consumer apps, expose Sei Global Wallet **first** in the connect menu a | Symptom | Cause | Fix | |---|---|---| -| `unsupported chain` from wallet | Wallet doesn't know Sei | Use `useSwitchChain` to add Sei via `@sei-js/precompiles` config | +| `unsupported chain` from wallet | Wallet doesn't know Sei | Use `useSwitchChain` to add the `sei` chain from `wagmi/chains` | | `replacement transaction underpriced` | gas price < 50 gwei | Set `gasPrice: parseUnits("50", "gwei")` | | `user rejected` after delay | EIP-1559 fields confused wallet | Drop `maxFeePerGas`/`maxPriorityFeePerGas`; use legacy `gasPrice` | | Transaction confirms but UI never updates | Watching wrong chain | Pin `chainId` in writes; ensure read hooks watch the same chain | @@ -338,15 +340,17 @@ For most consumer apps, expose Sei Global Wallet **first** in the connect menu a ## Project scaffolding ```bash -npx @sei-js/create-sei my-sei-app -# Interactive: pick React/Next.js, Wagmi/Ethers, TypeScript +npx @sei-js/create-sei app --name my-sei-app +# Default template: Next.js 15 · React 19 · wagmi v2 · viem · RainbowKit · +# TanStack Query · Tailwind CSS v4 · Mantine UI · Biome · TypeScript. +# Add the precompiles examples with: --extension precompiles ``` -Includes pre-configured Sei network entries. +Includes pre-configured Sei network entries (mainnet 1329 / testnet 1328). ## Sei-specific notes -- **Always use legacy `gasPrice ≥ 50 gwei`**; never EIP-1559 priority fee fields. +- **Always use legacy `gasPrice`** (never EIP-1559 priority fee fields); the minimum is a governance-set floor (~50 gwei mainnet) — query `eth_gasPrice` for the live value rather than hardcoding. - **Always pin `chainId`** in write calls. - **Always use `wait(1)` / `confirmations: 1`** — anything more is wasted UX time. - **Always import precompile addresses + ABIs from `@sei-js/precompiles`** rather than hardcoding. diff --git a/skill/references/frontend/sites-map.md b/skill/references/frontend/sites-map.md index d2994b4..a39dbc6 100644 --- a/skill/references/frontend/sites-map.md +++ b/skill/references/frontend/sites-map.md @@ -58,7 +58,7 @@ Four top-level sections. - Bridging: LayerZero V2, Thirdweb - Oracles & VRF: API3, Chainlink, Pyth, RedStone, Pyth VRF - AI Tooling: Cambrian Agent Kit, **MCP Server**, Agentic Wallets, x402 Protocol -- Reference: RPC, Tokens, **Ecosystem Contracts** (`/evm/reference/ecosystem-contracts`), Networks, USDC Integration, Ledger Setup +- Reference: RPC, Tokens, **Ecosystem Contracts** (`/evm/ecosystem-contracts`), Networks, USDC Integration, Ledger Setup ### `/cosmos-sdk` — Cosmos-side development - **Status**: deprecated per SIP-03 — migrate to EVM-only @@ -89,12 +89,12 @@ Four top-level sections. ## Sei docs build/repo -- **Repository**: https://github.com/sei-protocol/sei-docs (despite the `-old` suffix used by some tooling, this is the live source) -- **Framework**: Nextra (Next.js) -- **Build tool**: Bun -- **Format**: `.mdx` (Markdown + JSX) under `/content/` -- **Nav config**: `_meta.js` files at each directory level -- **Style guide**: `/STYLE_GUIDE.mdx` in the repo +- **Repository**: https://github.com/sei-protocol/sei-docs +- **Framework**: Mintlify (migrated off Nextra; auto-deploys from `main`) +- **Local preview**: `mint dev` (Mintlify CLI) +- **Format**: `.mdx` (Markdown + JSX) in top-level section dirs (`evm/`, `learn/`, `node/`, `ai/`) +- **Nav config**: `docs.json` (single source of truth for navigation + redirects) +- **Style guide**: `STYLE_GUIDE.md` in the repo For contributing to the docs, see [docs-contributing.md](docs-contributing.md). diff --git a/skill/references/migration/from-ethereum.md b/skill/references/migration/from-ethereum.md index 5977bcb..56a24e6 100644 --- a/skill/references/migration/from-ethereum.md +++ b/skill/references/migration/from-ethereum.md @@ -27,7 +27,7 @@ These are not optional edge cases — they **will** break your app if ignored. ### 1. Gas Price: Prefer `gasPrice` Over EIP-1559 Fields -Sei's fee model does not burn a base fee, so EIP-1559 priority fee mechanics don't apply. `maxFeePerGas`/`maxPriorityFeePerGas` can be omitted — use legacy `gasPrice` instead. +Sei's fee model does not burn a base fee, so EIP-1559 priority fee mechanics don't apply. `maxFeePerGas`/`maxPriorityFeePerGas` can be omitted — use legacy `gasPrice` instead. The minimum gas price is a **governance-set, adjustable** value (currently ~50 gwei on mainnet, set by pacific-1 [Proposal #112](https://www.mintscan.io/sei/proposals/112) / atlantic-2 #244; it has changed before — 100 → 10 → 50). **Query the live floor with `eth_gasPrice`** rather than hardcoding a constant. ```typescript // ⚠️ EIP-1559 style — may not behave as expected on Sei (no base fee burn) @@ -36,9 +36,9 @@ const tx = await contract.myFunction({ maxPriorityFeePerGas: parseUnits("1", "gwei"), }); -// ✅ Preferred: legacy gasPrice +// ✅ Preferred: legacy gasPrice — read the live floor, don't bake in a number const tx = await contract.myFunction({ - gasPrice: parseUnits("50", "gwei"), // minimum 50 gwei + gasPrice: await provider.send("eth_gasPrice", []), // ≥ governance floor (~50 gwei mainnet) }); ``` @@ -79,10 +79,10 @@ Sei runs Pectra EVM but without blob transactions (`BLOBHASH` / `BLOBBASEFEE`). ### 6. SSTORE Costs Are Higher Than Ethereum -Storage write costs are network-dependent on Sei: -- **Both mainnet & testnet**: 72,000 gas per cold SSTORE (governance proposal #240) +Storage writes are far costlier than Ethereum's 20,000 gas: +- **Both mainnet & testnet**: 72,000 gas per cold SSTORE — set by pacific-1 governance [Proposal #109](https://www.mintscan.io/sei/proposals/109) (testnet carries the same value with no separate proposal). Governance-adjustable. -Best practice: minimize storage writes regardless of network. +Best practice: minimize storage writes. Note a `forge --gas-report --fork-url` report applies revm's standard EVM schedule and shows ~22,100 — **not** Sei's 72,000; use a live `eth_estimateGas` against a Sei RPC for the real cost. ```solidity // ❌ Bad: multiple storage writes in a loop (expensive on either network) @@ -102,14 +102,15 @@ function processAndStore(uint256[] calldata items) external { } ``` -### 7. No "safe" / "finalized" Block Tags +### 7. `safe` / `finalized` Resolve to `latest` ```typescript -// ❌ Ethereum: different commitment levels exist +// Ethereum: these are different, lagging commitment levels const safeBlock = await provider.getBlock("safe"); const finalBlock = await provider.getBlock("finalized"); -// ✅ Sei: all equivalent to "latest" +// Sei: the tags are accepted but resolve to the SAME instantly-final +// block as "latest" — there's nothing to gain from safe/finalized. const block = await provider.getBlock("latest"); ``` @@ -117,6 +118,17 @@ const block = await provider.getBlock("latest"); Sei does not expose a `pending` block tag. Use `latest`. +### 9. SELFDESTRUCT is Neutered (EIP-6780) + +Sei runs post-EIP-6780 semantics: `SELFDESTRUCT` no longer deletes the contract or its storage — it only forwards the remaining ETH, unless it runs in the *same transaction* that created the contract. Any cleanup/upgrade logic that relied on destroying a contract must be refactored to a "soft close". + +```solidity +// ❌ Don't rely on SELFDESTRUCT to remove a contract — it won't (EIP-6780). +// ✅ Soft close instead: +bool public closed; +modifier notClosed() { require(!closed, "closed"); _; } +``` + --- ## Contract Migration Checklist @@ -126,8 +138,9 @@ Sei does not expose a `pending` block tag. Use `latest`. □ Remove PREVRANDAO randomness → integrate VRF oracle □ Check COINBASE usage — does not return block proposer □ Check for blob opcodes (BLOBHASH, BLOBBASEFEE) — not available -□ Audit SSTORE patterns — consider caching in memory before writing -□ Remove "safe"/"finalized" block tag references +□ Refactor SELFDESTRUCT cleanup → soft-close pattern (EIP-6780 neutered it) +□ Audit SSTORE patterns — consider caching in memory before writing (72k gas/cold write) +□ Drop waits on "safe"/"finalized" — they resolve to "latest" on Sei; use tx.wait(1) □ Test contract on atlantic-2 testnet before mainnet ``` @@ -139,7 +152,7 @@ Sei does not expose a `pending` block tag. Use `latest`. ```typescript // Add Sei to your Wagmi config -import { sei, seiTestnet } from '@sei-js/precompiles'; +import { sei, seiTestnet } from 'viem/chains'; export const config = createConfig({ chains: [sei, seiTestnet], @@ -228,7 +241,7 @@ Once migrated, you can optionally leverage Sei-specific features: | **Precompiles** | Staking, governance, IBC from Solidity | | **Pointer contracts** | Your ERC20 token usable in Cosmos wallets | | **Dual addresses** | Users can interact via `sei1...` or `0x...` | -| **Native oracle** | Free price feeds without external dependencies | +| **Third-party oracles** | Pyth / Chainlink / API3 / RedStone price feeds (the native Oracle precompile is shut off) | See [`precompiles/overview.md`](../precompiles/overview.md) and [`pointers/overview.md`](../pointers/overview.md) for details. diff --git a/skill/references/migration/from-solana.md b/skill/references/migration/from-solana.md index 89f090e..065edf8 100644 --- a/skill/references/migration/from-solana.md +++ b/skill/references/migration/from-solana.md @@ -280,7 +280,7 @@ const rentExempt = await connection.getMinimumBalanceForRentExemption(accountSiz // Sei EVM fee estimation const gasLimit = 200_000n; -const gasPrice = parseUnits("50", "gwei"); // minimum on Sei +const gasPrice = parseUnits("50", "gwei"); // ~50 gwei floor on mainnet; query eth_gasPrice for the live value const fee = gasLimit * gasPrice; // no rent ``` @@ -342,7 +342,7 @@ await tx.wait(1); // instant finality □ Remove account declarations from functions (not needed) □ Update frontend: @solana/web3.js → ethers.js or viem □ Update wallet: wallet-adapter → wagmi + @sei-js/sei-global-wallet -□ Use gasPrice (not EIP-1559 fields): minimum 50 gwei +□ Use gasPrice (not EIP-1559 fields); query the live floor with eth_gasPrice (~50 gwei mainnet) □ Use tx.wait(1) — instant finality □ Test on atlantic-2 testnet first □ Get testnet SEI at https://atlantic-2.app.sei.io/faucet diff --git a/skill/references/networks.md b/skill/references/networks.md index 3483776..b5d858e 100644 --- a/skill/references/networks.md +++ b/skill/references/networks.md @@ -36,8 +36,8 @@ For production dApps, use a provider account rather than the public endpoints. ## Chain IDs Reference ```javascript -// Viem chain definitions — use @sei-js/precompiles for pre-built definitions -import { sei, seiTestnet } from '@sei-js/precompiles'; +// Viem chain definitions — import sei/seiTestnet from viem/chains (or wagmi/chains) +import { sei, seiTestnet } from 'viem/chains'; // Or define manually: const seiTestnet = { @@ -110,7 +110,7 @@ Get testnet SEI for development: ## Gas Configuration ```bash -# Minimum gas price: 50 gwei +# Minimum gas price: ~50 gwei (governance-set, adjustable — pacific-1 Prop #112 / atlantic-2 #244; query eth_gasPrice) # Use gasPrice, NOT maxFeePerGas/maxPriorityFeePerGas # Example with ethers.js v6 diff --git a/skill/references/precompiles/cosmwasm-bridge.md b/skill/references/precompiles/cosmwasm-bridge.md index e05e8b5..4375373 100644 --- a/skill/references/precompiles/cosmwasm-bridge.md +++ b/skill/references/precompiles/cosmwasm-bridge.md @@ -5,7 +5,7 @@ description: Addr, Bank, CosmWasm, IBC, Pointer, and PointerView precompiles for # CosmWasm Bridge Precompiles -> **Deprecation notice**: CosmWasm is deprecated per SIP-3 (governance proposal 99 on mainnet). These precompiles remain functional for existing integrations and legacy support, but new projects should use EVM-only with pointer contracts for cross-VM asset representation. +> **Deprecation notice**: CosmWasm is deprecated per SIP-3 (initiated by mainnet [Proposal #99](https://www.mintscan.io/sei/proposals/99); new uploads/instantiation disabled by mainnet #115 / atlantic-2 testnet #246). These precompiles remain functional for existing integrations and legacy support, but new projects should use EVM-only with pointer contracts for cross-VM asset representation. ## Address Summary diff --git a/skill/references/precompiles/overview.md b/skill/references/precompiles/overview.md index 99c16f2..2ba32e6 100644 --- a/skill/references/precompiles/overview.md +++ b/skill/references/precompiles/overview.md @@ -18,7 +18,7 @@ Precompiles are fixed-address contracts deployed by the Sei protocol that expose | Staking | `0x0000000000000000000000000000000000001005` | Delegate/undelegate/redelegate SEI | | Governance | `0x0000000000000000000000000000000000001006` | Vote, submit proposals, deposit | | Distribution | `0x0000000000000000000000000000000000001007` | Claim staking rewards | -| Oracle | `0x0000000000000000000000000000000000001008` | On-chain price feed data | +| Oracle | `0x0000000000000000000000000000000000001008` | ❌ Shut off (~July 2026) — returns no data; use a third-party oracle | | IBC | `0x0000000000000000000000000000000000001009` | IBC transfers from EVM (legacy) | | PointerView | `0x000000000000000000000000000000000000100A` | Query pointer registrations | | Pointer | `0x000000000000000000000000000000000000100B` | Register pointer contracts | @@ -83,7 +83,7 @@ const validators = await staking.validators("BONDED", 10, ""); ```typescript import { createWalletClient, custom, getContract } from 'viem'; -import { seiTestnet } from '@sei-js/precompiles'; +import { seiTestnet } from 'viem/chains'; import { STAKING_PRECOMPILE_ADDRESS, STAKING_PRECOMPILE_ABI } from '@sei-js/precompiles'; const walletClient = createWalletClient({ diff --git a/skill/references/resources.md b/skill/references/resources.md index ed5761d..f7ff36f 100644 --- a/skill/references/resources.md +++ b/skill/references/resources.md @@ -155,7 +155,7 @@ Additional RPC providers: https://docs.sei.io/learn/rpc-providers | Addr precompile | `0x0000000000000000000000000000000000001004` | same | | Staking precompile | `0x0000000000000000000000000000000000001005` | same | | Governance precompile | `0x0000000000000000000000000000000000001006` | same | -| Oracle precompile | `0x0000000000000000000000000000000000001008` | same | +| Oracle precompile (❌ shut off ~July 2026) | `0x0000000000000000000000000000000000001008` | same | | IBC precompile | `0x0000000000000000000000000000000000001009` | same | | Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` | same | | Permit2 | `0xB952578f3520EE8Ea45b7914994dcf4702cEe578` | same |