mcpField
I
initia-appchain-dev

initia-appchain-dev

github.com/initia-labs開発1228 回インストール33 週間前に更新
リポジトリ

initia-appchain-dev について

initia-appchain-devは、コントラクト、フロントエンド連携、アプリチェーン運用を扱うInitia開発向けスキルです。VMやネットワークなどを先に確認し、環境構築から実装上の制約、検証まで案内します。

主な機能

  1. 01作業前にチェーンとVMを確認
  2. 02MOVE、EVM、WASMの環境構築を案内
  3. 03コントラクト、フロントエンド、運用を網羅
  4. 04Initiaフロントエンド連携の制約を提示
  5. 05ツールとVM別バイナリを検証

活用シーン

  1. 01VMに応じた開発環境の構築
  2. 02Initiaのチェーン情報を使ったフロントエンド連携
  3. 03既存アプリチェーンの起動やデバッグ
  4. 04デプロイやトランザクション実装の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/initia-labs/agent-skills --skill initia-appchain-dev

インストール後、Claude Code で/initia-appchain-devを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
common-tasks.md
contracts.md
e2e-recipes.md
frontend-evm-rpc.md
frontend-interwovenkit.md
runtime-discovery.md
troubleshooting.md
weave-commands.md
weave-config-schema.md
scripts/
bech32_utils.py
check-provider-setup.sh
convert-address.py
fund-user.sh
generate-system-keys.py
install-tools.sh
lint-tags.sh
requirements.txt
scaffold-contract.sh
scaffold-frontend.sh
to_hex.py
verify-appchain.sh

詳細

Initia Appchain 開発

コントラクト、フロントエンド連携、アプリチェーンの運用に関する、実践的な Initia 開発ガイダンスを提供します。

このファイルのコマンド例では、作業ディレクトリが skill/ であることを前提としています。それに応じて scripts/... のパスを使用してください。

初回確認の質問(最初に確認)

実装に着手する前に、不足している入力情報を確認します。

  1. 必要な VM はどれですか(evm、move、wasm)?
  2. 対象のネットワークはどれですか(testnet または mainnet)?
  3. 新規ロールアップの起動ですか、それとも既存ロールアップの運用/デバッグですか?
  4. フロントエンドの作業では、EVM JSON-RPC アプリと InterwovenKit ウォレット/ブリッジアプリのどちらを使用しますか?
  5. チェーン固有の値(chain_id、RPC URL、デプロイ済みコントラクトのアドレス、denom)は分かっていますか?

重要な値が不足している場合は、最終的なコード/設定を生成する前に、簡潔な追加質問をしてください。

chain_id/エンドポイント/VM が不明な場合は、デフォルト値を仮定する前に references/runtime-discovery.md の検出フローを実行してください。

weave がインストール済みでも、シェルレベルのエラーで動作しない場合は、weave に固執せず、~/.minitia/artifacts/config.json と minitiad の直接コマンドを使って検出を続けてください。

続いて、状況に応じた確認を行います。

  • フロントエンドの作業:「ローカルのロールアップ設定/ランタイムが見つかりました。このロールアップをフロントエンド連携に使用しますか?」
  • フロントエンド以外の作業:「ローカルのランタイム値(VM、チェーン ID、エンドポイント)が見つかりました。今回の作業にこれらを使用しますか?」

環境セットアップのワークフロー(1 回のプロンプトでセットアップ)

ユーザーから「[Track] トラック用に環境をセットアップして」と依頼された場合(ステップ 5)は、次の手順を実行します。

1. トラックの要件と前提条件を特定する
  • [MOVE] トラック: minimove リポジトリ → minitiad。go が必要です。
  • [EVM] トラック: minievm リポジトリ → minitiad。go と foundry が必要です。
  • [WASM] トラック: miniwasm リポジトリ → minitiad。go と rust/cargo が必要です。
2. システムの前提条件を確認する

選択されたトラックに応じて前提条件を確認します(ツールインストーラーとの互換性を確保するため、必ず docker も確認してください)。

  • [MOVE] トラック: go、docker
  • [EVM] トラック: go、docker、foundry
  • [WASM] トラック: go、docker、cargo

選択されたトラックで必要な各ツールについて、次のように対応します。

  • 不足している場合: ユーザーに伝え、インストールコマンドを提案します(例:「Cargo が見つかりません。rustup を使ってインストールしますか?」)。
  • インストール済みの場合: 何も伝えずに先へ進みます。
3. Initia のコアツールをインストールする

jq、weave、initiad(L1)をインストールするため、scripts/install-tools.sh を実行します。

  • セキュリティ: スクリプトで sudo が必要な場合は、実行前にユーザーに説明してください。
  • 必要なツールがすでにある場合は、再インストールよりもバージョンの確認を優先してください。指定バージョンを使用するインストーラーのバージョンは、マシンにすでにインストールされているバージョンより古い場合があります。
4. VM 固有のバイナリ(minitiad)をビルドする

ソースから該当する VM をクローン、ビルドし、クリーンアップします。

ビルドはリポジトリのディレクトリ内から実行してください。実行環境によって作業ディレクトリが別々に管理される場合があるため、cd ... && make install のようにシェルコマンドを連結した例に依存しないでください。

  • [MOVE]:
    git clone --depth 1 https://github.com/initia-labs/minimove.git /tmp/minimove
    cd /tmp/minimove
    make install
    rm -rf /tmp/minimove
    
  • [EVM]:
    git clone --depth 1 https://github.com/initia-labs/minievm.git /tmp/minievm
    cd /tmp/minievm
    make install
    rm -rf /tmp/minievm
    
  • [WASM]:
    git clone --depth 1 https://github.com/initia-labs/miniwasm.git /tmp/miniwasm
    cd /tmp/miniwasm
    make install
    rm -rf /tmp/miniwasm
    
5. PATH を設定する
  • ~/go/bin がユーザーの PATH に含まれていることを確認します。
  • シェル設定ファイル(.zshrc、.bashrc)を確認し、設定がない場合は export コマンドを提案します。
  • シェル設定を更新したら、現在のシェルに変更を反映するため、source ~/.zshrc を実行する(または新しいターミナルを開く)ようユーザーに伝えてください。
  • 確認のために、zsh -lc 'source ~/.zshrc && <command>' を 1 つのコマンドとして実行できます。ただし、これは別々のアシスタントコマンド間では反映されません。
6. 最終確認

次を実行します。

  • weave version
  • initiad version
  • minitiad version --long | rg '^(name|server_name|version|commit):'

必要な VM の一致:

  • [EVM] トラック: name: minievm
  • [MOVE] トラック: name: minimove
  • [WASM] トラック: 報告された name がビルドした Wasm VM と一致することを確認します

minitiad version コマンドが成功しただけでは、確認として不十分です。PATH 上のバイナリが、別の VM トラックのものである可能性があります。

推奨するデフォルト設定

項目デフォルト備考
VMevm指定された場合に限り、move/wasm を使用します
Move のバージョン2.1minitiad move build を使用します。特定のコンパイラバージョンで必要な場合を除き、Move.toml から edition を省略することを推奨します。
ネットワークtestnet明示的に指定された場合に限り、mainnet を使用します
フロントエンド(EVM VM)wagmi + viem JSON-RPC純粋な EVM アプリのデフォルトです
フロントエンド(Move/Wasm)@initia/interwovenkit-reactInterwovenKit の機能が必要な場合に使用します
トランザクションの UXrequestTxBlock確認 UX を推奨します。ローカル開発での堅牢性を高めるには、requestTxSync を使用します。
プロバイダーの順序Wagmi -> Query -> InterwovenKitInitia SDK の安定した構成です
ロールアップの DAINITIA明示的に必要な場合に限り、Celestia を推奨します
キーとキーリングgas-station / testハッカソン用ツールでは、デフォルトのキーと --keyring-backend test を使用します
デノムGAS(EVM)/ umin(Move)テスト用/内部用ロールアップで一般的なデフォルトです

厳格な制約(絶対に違反しないこと)

タグ付け規則
  • VM 固有のガイダンスには、VM を先頭にしたタグを使用します:[EVM]、[MOVE]、[WASM]、[ALL-VM]。
  • VM の後には、任意のコンテキストタグを追加します:[CLI]、[DEV]、[REST]、[RPC]、[FRONTEND]、[INTERWOVENKIT]、[BUILD]、[TEST]。
  • 複合タグ(例:[EVM CLI])は避け、タグを連ねる形式(例:[EVM][CLI])を推奨します。
  • スキルの Markdown を編集する際は、必ず次のワークフローに従ってください。変更前に scripts/lint-tags.sh を実行し、引き渡し前に再度実行します。
Initia ユーザー名(明示的な要望がある場合のみ)
  • 「ユーザー名サポートを追加」のように明示的に要求されない限り、スキャフォールド、コンポーネント、コードスニペットにユーザー名サポートを実装してはなりません。
  • 要求された場合、接続中のウォレット自身の表示名にのみ useInterwovenKit().username を使用します。
  • パターン:{username ? username : shortenAddress(initiaAddress)}
  • 任意のウォレットアドレスのユーザー名(例:MemoBoard の送信者行)を解決するには、送信者のアドレスを指定して useUsernameQuery(address?) を使用します。これには @initia/interwovenkit-react 2.4.6 以降が必要です。
  • フィード、ボード、その他メッセージ/アカウントを表示するリストでは、子の行コンポーネント(例:MessageRow)内で送信者のユーザー名を解決し、そこで useUsernameQuery(address) を呼び出します。親コンポーネントの .map() コールバック内や条件付きループの本体でフックを直接呼び出してはなりません。
  • フックによる解決では不十分な場合を除き、REST 経由で解決してはなりません。
  • useUsernameQuery の動作:
    • 引数なし:接続中のウォレットアドレスを解決します(useAddress() にフォールバック)。
    • 引数あり:指定されたアドレスを解決します。
ワークスペースのクリーンアップ(重要)
  • タスク完了後、プロジェクトディレクトリに一時ファイルやメタデータ JSON ファイル(例:store_tx.json、tx.json、.bin)を残してはなりません。
  • 完了前に、デプロイに使用したバイナリファイルを削除してください。
InterwovenKit ローカルアプリチェーン(重大)
  • ローカルアプリチェーン用のフロントエンドを設定する場合、InterwovenKitProvider では customChain と customChains: [customChain] の両方のプロパティを使用する必要があります。
  • 使用例:
    <InterwovenKitProvider 
      {...TESTNET} 
      customChain={customChain} 
      customChains={[customChain]}
    >
      <App />
    </InterwovenKitProvider>
    
  • ブリッジのサポート:ブリッジで initiation-2 などのパブリックチェーンを解決できるようにするには、@initia/interwovenkit-react からインポートした {...TESTNET} プリセットを必ず InterwovenKitProvider に展開してください:<InterwovenKitProvider {...TESTNET} ... />。
  • アドレスプレフィックス:customChain にはトップレベルの bech32_prefix 文字列(例:bech32_prefix: "init")を必ず含めてください。これはすべてのアプリチェーンタイプで必須です。
  • メタデータの完全性:「Chain not found」エラーを避けるため、customChain オブジェクトには network_type: 'testnet'、staking、(low/average/high_gas_price: 0 を含む)fees、および native_assets 配列を必ず含めてください。
  • API の要件:キットの検出ロジックを満たすため、apis オブジェクトには rpc、rest、および indexer を必ず含めてください(必要に応じてプレースホルダーを使用してください)。
  • ブリッジのサポート(openBridge):openBridge を使用する場合は、srcChainId と srcDenom(例:initiation-2 と uinit)のみを指定してください。ローカルチェーンがまだインデックスされていない場合に解決エラーが発生する可能性があるため、ローカルの dstChainId は指定しないでください。
  • customChain の構造例:
    const customChain = {
      chain_id: '<INSERT_APPCHAIN_ID_HERE>',
      chain_name: '<INSERT_APP_NAME_HERE>',
      network_type: 'testnet', // MANDATORY
      bech32_prefix: 'init',
      apis: {
        rpc: [{ address: 'http://localhost:26657' }],
        rest: [{ address: 'http://localhost:1317' }],
        indexer: [{ address: 'http://localhost:8080' }], // MANDATORY
        'json-rpc': [{ address: 'http://localhost:8545' }],
      },
      fees: { fee_tokens: [{ denom: 'umin', fixed_min_gas_price: 0, low_gas_price: 0, average_gas_price: 0, high_gas_price: 0 }] },
      staking: { staking_tokens: [{ denom: 'umin' }] },
      native_assets: [{ denom: 'umin', name: 'Token', symbol: 'TKN', decimals: 6 }],
      metadata: { is_l1: false, minitia: { type: 'minimove' } }
    }
    
フロントエンドの要件(重大)
  • プレースホルダーの同期:フロントエンドのスキャフォールディング直後に、main.jsx 内のすべてのプレースホルダー(<INSERT_APPCHAIN_ID_HERE>、<INSERT_NATIVE_DENOM_HERE> など)を、調査フェーズで確認した実際の値(例:bank-1、GAS、minievm)に必ず更新してください。
  • ランタイム設定の同期:フロントエンドがデプロイ済みのコントラクトアドレスに依存する場合、プレースホルダーや例だけを残さず、解決済みの実アドレスをランタイム設定(例:.env / VITE_*)に必ず反映してください。Move 固有の API とコードでは、区別が重要な場合は module address という用語を維持してください。実行中の Vite アプリの .env の値を追加または変更した場合は、開発サーバーの再起動が必要であることをユーザーに伝えてください。
  • フックのエクスポート:useInterwovenKit は initiaAddress、address、username、openConnect、openWallet、openBridge、requestTxBlock、requestTxSync、および autoSign をエクスポートします。
  • トランザクションのガード:requestTxBlock または requestTxSync を呼び出す前に、initiaAddress が定義されていることを必ず確認してください。
  • [ALL-VM] 送信元アドレス:Initia では、すべてのメッセージタイプ(MsgCall、MsgExecute、MsgExecuteContract)の sender フィールドに Bech32 アドレスを指定する必要があります。EVM、Move、Wasm のアプリチェーン全体で互換性を確保するため、このフィールドには initiaAddress を使用してください。Cosmos 形式のメッセージの sender フィールドに、EVM チェーン上の 16 進数の address を使用すると、「empty address string」または「decoding bech32 failed」エラーが発生します。
セキュリティと鍵の保護(厳格に適用)
  • キーリングから生の秘密鍵をエクスポートしてはなりません。
  • [MOVE][DEV] 開発(公開用ビルド):公開前に、デプロイ担当者が使用する Hex アドレスを指定してモジュールを再ビルドする必要があります:minitiad move build --named-addresses <name>=0x<hex_addr>。
  • [MOVE][DEV][BUILD] 名前付きアドレスの再割り当て:Move.toml の [addresses].<name> がハードコードされている場合(例:0x42)、異なる --named-addresses <name>=0x... を渡すと、名前付きアドレスの再割り当てエラーが発生してコンパイルに失敗します。[addresses] では "<name>" = "_" を使い、ローカルテスト用のデフォルト値は [dev-addresses] に設定してください。
  • [MOVE][DEV] 依存関係の解決:InitiaStdlib の解決に失敗する場合は、次を使用してください:{ git = "https://github.com/initia-labs/movevm.git", subdir = "precompile/modules/initia_stdlib", rev = "main" }。
  • [MOVE][DEV] パッケージのスキャフォールディング:minitiad move new <NAME> は、兄弟ディレクトリを作成せずに、現在の作業ディレクトリにパッケージを書き込むことがあります。blockforge/ のような特定のフォルダーが必要な場合は、minitiad move new を実行する前に、そのフォルダーを作成して移動してください。
  • [MOVE][DEV] クリーン(非対話型シェル):minitiad move clean は確認を求め、TTY がないとパニックを起こす場合があります。自動化されたワークフローでクリーンビルドが必要な場合は、パッケージの build/ ディレクトリを直接削除してください。
  • [MOVE][CLI] デプロイの仕様:Move モジュールには、独立したインスタンス化トランザクションはありません。「インスタンス化」は通常、最初の状態変更を伴うエントリー呼び出し(例:初回の mint_shard でプレイヤーごとのリソースを作成すること)を指します。
  • [EVM][CLI] デプロイ:EVM のデプロイには、--from を指定して minitiad tx evm create を使用してください。
  • [EVM][CLI] バイトコードの抽出:Foundry のアーティファクトから jq を使ってバイトコードを抽出してください。.bin ファイルには 0x プレフィックスを付けず、末尾の改行も含めないでください。
  • [EVM][DEV][CLI] tx evm create の入力形式:minitiad tx evm create の位置引数はバイトコードのファイルパスです。生のバイトコードを直接渡す場合は、--input 0x... を使用してください。位置引数として生の16進数を渡すと、file name too long エラーが発生する場合があります。
  • [ALL-VM][SECURITY] 秘密鍵の取り扱い:ツールが秘密鍵を必要とする場合は、Initia CLI または InterwovenKit を使う代替ワークフローを探してください。
フロントエンドの要件(追加)
  • ポリフィル:vite.config.jsでvite-plugin-node-polyfillsを使用し、globals: { Buffer: true, process: true }を指定します。また、Viteでプロバイダーのコンテキストが分割されるのを防ぐため、resolve.dedupeを['react', 'react-dom', 'wagmi', '@tanstack/react-query', 'viem']に設定します。手動でポリフィルを使用する場合は、main.jsxの先頭でBufferとprocessのグローバルポリフィルを定義します。
    import { Buffer } from "buffer";
    window.Buffer = Buffer;
    window.process = { env: {} };
    
  • スタイル:
    • CSSをインポートします:import "@initia/interwovenkit-react/styles.css".
    • スタイルデータをインポートします:import InterwovenKitStyles from "@initia/interwovenkit-react/styles.js".
    • インジェクター関数をインポートします:import { injectStyles } from "@initia/interwovenkit-react".
    • インジェクター関数を呼び出します:injectStyles(InterwovenKitStyles).
    • 注:InterwovenKitStylesはstylesサブパスからのデフォルトエクスポートで、injectStylesはメインパッケージからの名前付きエクスポートです。
  • プロバイダーの順序:WagmiProvider -> QueryClientProvider -> InterwovenKitProvider。
  • ウォレットモーダル:
    • 接続モーダルを開くには、openModalではなくopenConnectを使用します(v2.4.0以降)。
    • 接続状態(重要):initiaAddressがある場合は、必ずクリック可能なUI要素(短縮アドレスを表示するボタンなど)を用意し、openWalletを呼び出して、ユーザーが接続を管理したり切断したりできるようにします。
  • 自動署名の実装(明示的な要求がある場合のみ):
    • 「自動署名を追加」などの明示的な要求がない限り、スキャフォールド、プロバイダー、コンポーネントのいずれにも自動署名機能を実装してはいけません。
    • 要求された場合:
      • プロバイダー:InterwovenKitProviderにenableAutoSign={true}を渡します。
      • フック:useInterwovenKitからautoSignの関数ではなくオブジェクトを分割代入します。
      • 安全性:オプショナルチェイニング(autoSign?.)を使用し、autoSign?.isEnabledByChain[chainId]で状態を確認します。
      • 操作:await autoSign?.enable(chainId)とawait autoSign?.disable(chainId)は非同期です。
      • 権限(重要):セッションキーで特定のメッセージタイプに署名できるようにするには、必ずautoSign.enableで権限を明示的に指定します。
        await autoSign.enable(chainId, { permissions: ["/initia.move.v1.MsgExecute"] })
        
      • エラー処理:autoSign.disableが「authorization not found」エラーで失敗した場合は、必要な権限を指定してautoSign.enableを呼び出し、セッションをリセットします。
  • RESTクライアント:@initia/initia.jsからRESTClientを手動でインスタンス化します。これはフックからエクスポートされていません。
    • 重要:useInterwovenKitからnetworksやrestを分割代入しようとしてはいけません。これらのオブジェクトはフックでは利用できません。REST/RPCエンドポイントは必ず手動で定義するか、独自の設定を通じて指定します。
トランザクションのメッセージフロー(重要)
  • [WASM][INTERWOVENKIT] トランザクションエンベロープ:必ず chainId を含めてください。requestTxSync を推奨します。
    • [WASM][INTERWOVENKIT] ペイロードのエンコード:MsgExecuteContract では、msg フィールドにバイト列(Uint8Array)を指定する必要があります。new TextEncoder().encode(JSON.stringify(msg)) を使用してください。
  • [ALL-VM][INTERWOVENKIT] 自動署名(ヘッドレス):自動署名されるトランザクションを「ヘッドレス」(手数料選択のプロンプトなし)にするには、リクエストに明示的な feeDenom(例:feeDenom: "umin")と autoSign: true フラグを必ず含めてください。
    await requestTxSync({ 
      chainId, 
      autoSign: true, // CRITICAL: Required for silent signing flow
      messages: [...] 
    })
    
  • [EVM] 送信者(MsgCall):MsgCall の sender には bech32 アドレスを使用し、contractAddr には hex を使用してください。
    • 正規化:「decoding bech32 failed」エラーを避けるため、bech32 形式の送信者アドレスは必ず小文字にしてください。
  • [EVM][INTERWOVENKIT] ペイロード:typeUrl: "/minievm.evm.v1.MsgCall" を持つプレーンオブジェクトを使用してください。実際のメッセージフィールドは、必ず value キーの中に入れてください。
    • 誤り:{ typeUrl: "...", sender: "...", contractAddr: "..." }
    • 正しい:{ typeUrl: "...", value: { sender: "...", contractAddr: "...", ... } }
  • [EVM][INTERWOVENKIT] requestTxBlock のキー:必ず msgs ではなく messages(複数形)を使用してください。msgs を渡すと、Cannot read properties of undefined (reading 'map') が発生することがあります。
  • [EVM] フィールド名:フィールドには camelCase(contractAddr、accessList、authList)を使用し、リストには空の配列も含めてください。
  • [MOVE][INTERWOVENKIT] MsgExecute のフィールド名:フィールドには camelCase を使用してください。moduleAddress は必ず bech32 形式にしてください。
    • [MOVE][INTERWOVENKIT] 必須の配列:空の場合でも、必ず typeArgs: [] と args: [] を含めてください。Move 実行メッセージでこれらのフィールドを省略すると、フロントエンドでの Amino 変換処理中に TypeError(Cannot read properties of undefined reading 'length')が発生します。
Wasm REST クエリ(重要)
  • [WASM][REST] クエリのエンコード:RESTClient(例:rest.wasm.smartContractState)を使って Wasm コントラクトの状態をクエリする場合、クエリメッセージは必ず Base64 エンコードされた文字列にしてください。
  • クエリ JSON と実行 JSON は、コントラクトの Rust メッセージスキーマに正確に一致させてください。all_messages のような名前や、text、message などの特定のフィールド名を想定しないでください。たとえば、MemoBoard のバリアントでは post_message: { message: ... } を指定する get_messages がよく使われますが、他のコントラクトではフィールド名が異なることがあります。
  • 実装例:
    const queryData = Buffer.from(JSON.stringify({ get_messages: {} })).toString("base64");
    const res = await rest.wasm.smartContractState(CONTRACT_ADDR, queryData);
    
  • [WASM][REST] レスポンスの形式:smartContractState は、通常、res.data の中ではなく、デコードされたペイロードを直接返します(例:res.messages)。具体的なレスポンス形式を確認せずに、.data でラップされていると想定しないでください。
  • [WASM][REST] メソッド名:必ず smartContractState を使用してください。queryContractSmart などのメソッドは、Initia の RESTClient では利用できません。
  • [WASM][CLI] 代替手段:minitiad query wasm contract-state smart <CONTRACT_ADDRESS> ... が、アドレスが instantiate イベントまたは list-contract-by-code から取得されたものであるにもかかわらず Bech32 チェックサムエラーで失敗する場合は、チェーンが出力したアドレスを正しいものとして扱ってください。minitiad query wasm list-contract-by-code <CODE_ID> で確認し、CLI パーサーに固執せず、REST エンドポイントのパスまたは RESTClient を使用してください。
Wasm Rust のテスト(重要)
  • [WASM][TEST] アドレスの比較:Wasm コントラクトのユニットテストを書く際、cosmwasm_std::Addr と文字列リテラルまたは String を比較するときは、必ず .as_str() を使用してください。Addr は PartialEq<&str> または PartialEq<String> を直接実装していません。
  • 誤り:assert_eq!("user1", value.sender);
  • 正しい:assert_eq!("user1", value.sender.as_str());
トークンの精度と資金調達(EVM 固有)
  • [EVM] 精度:EVM アプリチェーン上のすべてのネイティブトークン(例:GAS)では、標準的な EVM の精度($10^{18}$ 基本単位)を前提とします。
  • [EVM] 資金調達リクエスト:ユーザーが EVM チェーンで「N トークン」を求めた場合:
    • フロントエンド:$10^{18}$ を乗算します(例:parseUnits(amount, 18))。
    • CLI:値を手動でスケーリングする必要があります。「100 トークン」の場合、bank send コマンドでは 100000000000000000000GAS(100 に 0 が 18 個続く値)を使用します。
  • [EVM][FRONTEND] 人間が読み取れる UI:EVM 残高を表示する際は、必ず viem の formatUnits(balance, 18) を使用します。UI に基本単位の生の値を表示してはいけません。
  • [EVM][FRONTEND][DEV] parseEther / formatEther の使用:parseEther と formatEther は、チェーントークンが小数点以下 18 桁を正確に使用する場合に限り、有効な省略形です。小数点以下の桁数が変わる可能性がある場合は、ランタイム設定の parseUnits(amount, decimals) と formatUnits(balance, decimals) を使用します。
EVM のクエリとトランザクション(重要)
  • [EVM][FRONTEND] ABI の同期:コンパイル済みの ABI/関数名を信頼できる情報源として扱います。フロントエンドの encodeFunctionData 呼び出しを組み込む前に、生成されたアーティファクト(例:out/<Contract>.sol/<Contract>.json)で名前/シグネチャを確認し、getMyBalance のような名前を推測してはいけません。
  • [EVM][RPC] 状態クエリ:EVM の状態クエリでは、プロパティの未定義エラーを避けるため、RESTClient より標準の JSON-RPC eth_call を優先します。
  • [EVM][FRONTEND][RPC] 読み取りパスのプロバイダー:読み取り専用の EVM クエリ(eth_call)には、注入されたウォレットプロバイダー(window.ethereum)に依存せず、設定済みの JSON-RPC エンドポイント(例:VITE_JSON_RPC_URL)を使用します。これにより、EVM 拡張機能が注入されていない場合の「EVM ウォレットプロバイダーが見つかりません」というエラーを回避できます。
  • [EVM][RPC] アドレス変換:EVM の状態をクエリする場合(例:eth_call)、必ず AccAddress.toHex(addr) を使用して bech32 アドレスを hex に変換し、hex アドレスを小文字にします。
  • [EVM][CLI] 送信者の形式:minitiad query evm call の最初の引数には、bech32 形式の送信者(init1...)を指定する必要があります。
  • [EVM][CLI] クエリ出力フィールド:minitiad query evm call -o json は、呼び出し結果を .response(hex 文字列)で返します。
  • [EVM][CLI] Tx 検索のタイミング:ブロードキャスト直後は、minitiad query tx <hash> が一時的に tx not found を返すことがあります。失敗と判断する前に、少し待ってから再試行します。
  • [EVM][CLI] Calldata のエンコード:
    • [EVM][FRONTEND] 推奨:コントラクトの input hex の生成には、viem(例:encodeFunctionData)を優先して使用します。
    • [EVM][CLI] 推奨:コントラクトの input hex の生成には、必ず cast calldata(例:$(cast calldata "func(type)" arg))を使用します。手動でのエンコード(例:printf)は壊れやすいため、必ず避けてください。
    • [EVM][CLI] 手動パディング:手動でのエンコードが避けられない場合は、BigInt の値を hex に変換し、uint256 引数用に正確に 64 文字までパディングします。
Move REST クエリ(重要)
  • [MOVE][REST] モジュールアドレスの形式:RESTClient を使用して Move コントラクトの状態をクエリする場合(例:rest.move.view)、モジュールアドレスは bech32 形式である必要があります。
  • [MOVE][REST] 構造体タグアドレスの形式:rest.move.resource を使用して Move リソースをクエリする場合、リソース所有者は bech32 のままですが、構造体タグのモジュールアドレスは hex 形式(0x...::module::Struct)である必要があります。bech32 のモジュールアドレスを使って構造体タグを作成しないでください。
  • [MOVE][REST] アドレス引数:args 内のアドレス引数は、hex に変換し、0x を取り除き、64 文字(32 バイト)になるようにパディングしてから、Base64 でエンコードする必要があります。
  • 実装例:
    const b64Addr = Buffer.from(
      AccAddress.toHex(addr).replace('0x', '').padStart(64, '0'), 
      'hex'
    ).toString('base64');
    const res = await rest.move.view(mod_bech32, mod_name, func_name, [], [b64Addr]);
    
  • リソースのクエリ例:
    const structTag = `${AccAddress.toHex(moduleBech32)}::items::Inventory`;
    const res = await rest.move.resource(walletBech32, structTag);
    
  • [MOVE][REST] レスポンスの解析:rest.move.view のレスポンスは ViewResponse オブジェクトです。実際の値にアクセスするには、JSON.parse(res.data) を解析する必要があります。
  • [MOVE][REST] リソースが存在しない場合の処理:インベントリなど、初回使用時の状態では、リソースがまだ存在しないことがあります。rest.move.resource から「見つかりません」というレスポンスが返された場合は、ハードエラーとして表面化させず、有効なゼロ値/デフォルト状態として扱ってください。
  • [MOVE][REST] トラブルシューティング(400 Bad Request):rest.move.view が 400 エラーを返す場合、ほとんどの場合、原因は次のいずれかです。
    1. モジュールアドレスが bech32 ではありません。
    2. args 内のアドレス引数が、hex にパディングして Base64 でエンコードされていません。
  • [MOVE][INTERWOVENKIT] 自動署名(メッセージタイプが設定されていない):autoSign.enable が "No message types configured" で失敗する場合は、次の点を確認してください。
    1. metadata.minitia.type が正しく設定されている(例:minimove、minievm)。
    2. InterwovenKitProvider の defaultChainId が customChain.chain_id と一致している。
    3. customChain のトップレベルに bech32_prefix がある。

運用手順(タスクの実行方法)

  1. レイヤーの分類:コントラクト、フロントエンド、Appchain Ops、またはインテグレーションに分類します。
  2. 環境の確認:ツール(cargo、forge、minitiad)が PATH にあることを確認します。必要に応じて絶対パスを使用します。
  3. ワークスペースの把握:スキャフォールディングの前に、既存の Move.toml または package.json がないか確認します。対話なしのスキャフォールディングには、提供されているスクリプトを使用します。
  4. デプロイ前チェックリスト(CLI):CLI でコントラクトをデプロイしたり、トークンを送信したりする前に、実際の環境を確認します(実行時の検出結果から RPC_ENDPOINT を設定します)。
    • チェーン ID:curl -s "${RPC_ENDPOINT}/status" | jq -r '.result.node_info.network'
    • ネイティブデノム:minitiad q bank total --node "${RPC_ENDPOINT}"
    • 残高:from アカウントに、実際のネイティブデノムが十分にあることを確認します。
  5. スキャフォールディングのクリーンアップ:スキャフォールディング後に、プレースホルダーモジュール/コントラクトを削除します。
  6. Appchain の健全性:RPC が停止している場合は、weave rollup start -d を試し、scripts/verify-appchain.sh で確認します。
  7. [MOVE][DEV] Acquires アノテーション:グローバルストレージにアクセスするすべての関数(borrow_global、borrow_global_mut、move_from を使用する、またはこれらを行う関数を呼び出す関数)には、そのリソース型の acquires アノテーションを必ず含めます。
  8. [MOVE][DEV] 参照のルール:関数は、グローバルリソースに由来する参照(可変または不変。例:borrow_global_mut 経由)を、パラメーターとして渡されていない限り返してはいけません。必要に応じてロジックをインライン化するか、リソースをパラメーターとして渡します。
  9. [MOVE][DEV] 構文:ドキュメントコメント(///)は、#[view] や #[test] などの属性の後に配置します。
  10. [MOVE][CLI] Publish:minitiad tx move publish コマンドは --path フラグを使用しません。コンパイル済み .mv ファイルのパスを位置引数として渡します:minitiad tx move publish <path_to_file>.mv ...。
  11. [MOVE][DEV][CLI] 再公開の互換性:同じアカウントからの再公開が BACKWARD_INCOMPATIBLE_MODULE_UPDATE で失敗する場合は、既存の公開 API を維持する(たとえば、以前の公開 entry/view 関数を互換性ラッパーとして残す)か、公開前にモジュール名を変更します。
  12. [ALL-VM][CLI] ブロードキャストモードの互換性:現在の Initia CLI でブロードキャストモードがサポートするのは sync|async です。block が使えるとは想定しないでください。
  13. [MOVE][CLI] Tx 検索のタイミング:minitiad でブロードキャストした直後は、minitiad query tx <hash> が一時的に tx not found を返すことがあります。失敗と判断する前に、ポーリング/再試行してください。
  14. [WASM][BUILD] 最適化:本番環境向けバイナリには、必ず CosmWasm オプティマイザーの Docker イメージを使用します。
  15. ビジュアルの仕上げ:粘着性のあるグラスモーフィズムのヘッダー、中央揃えのアプリカードレイアウト、明確な視覚的階層を優先します。
  16. 優れた UX:フィードの並び順(新しいものを先頭にする)、入力欄のアクセシビリティ(フィードの上に配置する)、インタラクティブなフィードバック(ホバー/フォーカス)を重視します。
  17. [ALL-VM][INTERWOVENKIT] ブリッジのサポート:useInterwovenKit の openBridge を使用します。ローカルデモでは、srcChainId のデフォルトとしてパブリックテストネット(例:initiation-2)を設定します。
  18. 検証:scripts/verify-appchain.sh --gas-station --bots を実行し、引き渡し前にトランザクションの成功を確認します。

段階的な情報開示(必要に応じて参照)

  • 一般的なタスク(資金調達、アドレス、精度):references/common-tasks.md
  • コントラクト(Move/Wasm/EVM):references/contracts.md
  • フロントエンド(InterwovenKit):references/frontend-interwovenkit.md
  • フロントエンド(EVM JSON-RPC):references/frontend-evm-rpc.md
  • エンドツーエンドのレシピ:references/e2e-recipes.md
  • 実行時の検出:references/runtime-discovery.md
  • Weave CLI リファレンス:references/weave-commands.md
  • Rollup 設定スキーマ:references/weave-config-schema.md
  • トラブルシューティングと復旧:references/troubleshooting.md

ドキュメントの代替参照先

  • コアドキュメント:https://docs.initia.xyz
  • InterwovenKit ドキュメント:https://docs.initia.xyz/interwovenkit

スクリプトの使用方法

  • スキャフォールディング:scripts/scaffold-contract.sh、scripts/scaffold-frontend.sh
  • ヘルスチェック:scripts/verify-appchain.sh
  • ユーティリティ:scripts/convert-address.py、scripts/to_hex.py、scripts/generate-system-keys.py
  • セットアップ:scripts/install-tools.sh、scripts/fund-user.sh

期待される成果物

  1. 変更したファイルの正確な一覧。
  2. セットアップ/ビルド/テストのコマンド。
  3. 検証手順と出力。
  4. リスクに関する注意事項(セキュリティ、鍵、手数料)。

コメント