手動運用 Runbook: 申請の承認・Allowlist 追加・HENKAKU 配布
このRunbookはフェーズ1のMVP-1で、申請を確認してからAllowlist追加とHENKAKU配布を行うための手順です。アプリは申請と状態・監査記録を管理しますが、オンチェーン操作は自動実行しません。
役割
- 承認者:
ADMIN_ADDRESSESに登録されたウォレットの保持者。申請内容を確認し、/adminで審査状態を更新する - Allowlist 操作者: Allowlistを管理するコントラクトまたは管理画面を操作できる担当者
- 配布実行者: Safe Walletの承認・実行権限を持つ担当者。承認済み申請にのみHENKAKUを送付する
同じ人が複数の役割を担ってもよいですが、役割と確認責任は分けて扱います。秘密鍵やSafeの署名情報は、このアプリやリポジトリに置きません。
事前確認
.env.localまたはデプロイ先の環境変数に、管理者ウォレットをADMIN_ADDRESSES(カンマ区切り)で設定するADMIN_ADDRESSESの変更後は開発サーバーまたはデプロイを再起動するSUPABASE_URLとSUPABASE_SERVICE_ROLE_KEYが対象環境を指していることを確認する- 配布実行者はSafe WalletでPolygonネットワークと送付先・数量を確認できる状態にする
日次フロー
1. 申請を確認する
- 承認者が管理者ウォレットでサインインし、
/adminを開く pendingまたはneeds_infoの申請を選ぶ- 申請者の
/initiationの回答・クエスト完了状況と、申請先ウォレットを確認する - 判断に必要な情報が足りない場合は理由欄に不足している情報を書いて「要追加情報」を選び、コミュニティが指定した連絡手段でも申請者に確認する
2. 審査を更新する
- 条件を満たす場合は「承認」を選ぶ。承認に理由の入力は不要
- 条件を満たさない場合は、理由欄に理由を書いてから「却下」を選ぶ
- 承認前にAllowlistや配布の操作を行わない
却下と要追加情報の理由は必須で、入力した文面がそのまま /apply の申請者に表示されます。 申請者が次に何をすればよいか分かる書き方にしてください(「運営判断」のような文面は申請者に何も伝えません)。理由は実行者・時刻・変更前後の状態とともに application_events に記録され、/admin の該当行にも表示されます。
承認後、画面を再読み込みしてAllowlist・配布の操作が表示されることを確認します。
3. Allowlistへ追加する
- 承認済み申請のウォレットアドレスをコピーし、Allowlistを管理する公式のコントラクト操作画面または管理ツールを開く
- 対象ネットワーク、コントラクトアドレス、対象アドレスを二者で照合する
- Allowlist追加トランザクションを実行し、成功をブロックエクスプローラーで確認する
/adminに戻り、成功したトランザクション hash を「Allowlist tx hash」に入力して「Allowlist 追加済みにする」を選ぶ
tx hashの入力は必須です。このアプリはAllowlist追加を実行しません。入力するtx hashは、実行済みトランザクションの確認記録です。
実コントラクトの関数名・管理画面URL・承認者は、コントラクト運用が確定した時点でこの節に追記します。未確定の手順で本番トランザクションを実行しません。
4. Safe WalletからHENKAKUを送付する
- Allowlist追加済みであることと、送付数量・送付先・ネットワークを二者で照合する
- Safe WalletでHENKAKU送付トランザクションを作成する
- Safeの承認フローに従って署名・実行し、ブロックエクスプローラーで成功を確認する
- 成功したトランザクション hash を
/adminの「配布 tx hash」に入力し、「配布済みにする」を選ぶ - 申請者の
/applyで「承認済み / 追加済み / 送付済み (tx)」が表示されることを確認する
このアプリはSafeの署名・送付を実行しません。画面に入力するtx hashは、実行済みトランザクションの確認記録です。
5. 失敗・再試行
- オンチェーン操作が失敗した場合は、tx hash・エラー内容・再試行日時を運用ログに残し、原因を解消してから再試行する
/adminで「Allowlist 失敗として記録」または「配布 失敗として記録」を選び、失敗理由を入力する。理由は必須で、実行者・時刻・変更前後の状態とともにapplication_eventsに記録される- 失敗として記録した後も、原因を解消すれば「Allowlist 追加済みにする」「配布済みにする」で完了状態へ進められる
- 再試行がまた失敗した場合は、そのつど同じ操作で記録する。 完了状態(
added/sent)に達するまで、失敗は何度でも記録でき、そのたびに理由付きでapplication_eventsに1行残る。「1回目はガス不足、2回目はnonce競合」といった経緯がアプリ内に揃うため、運用ログ側に経緯を書き写す必要はない - 同じ失敗を二重に記録しないよう、ボタンは1回だけ押す。同じ内容で2回押すと監査ログに同じ行が2件残る(時刻で見分けられるが、読み手には紛らわしい)
- 申請者の
/applyでは、失敗は「運営が対応中です」と表示され、失敗の詳細は出さない - 送付済みの申請を再送付しない。再送が必要な場合は、承認者と配布実行者が既存txと残高を確認してから判断する
暫定の判断基準
コミュニティで正式な承認基準が決まるまで、次を暫定ルールとします。
- Initiationの全ステップが完了している
- 申請者の回答に、運営が確認すべき個人情報・秘密情報が含まれていない
- 承認者2名が申請内容と送付先ウォレットを確認し、合意している
- 判断に迷う場合は承認せず「要追加情報」とし、コミュニティで確認する
最終的な確認者、承認人数、却下基準、Allowlist追加の条件はコミュニティで決定し、決定後にこの節を更新します。
権限と鍵
ADMIN_ADDRESSESは管理画面へのアクセス制御だけに使い、配布権限を与えるものではない- Safe Walletの署名者・秘密鍵・リカバリ情報はアプリ、リポジトリ、Issue、運用ログに記録しない
SESSION_PASSWORD、Supabaseキー、Safeの認証情報は環境変数またはSafeが定める安全な保管場所で管理するADMIN_ADDRESSESの変更は、変更理由を運用ログに残してから環境変数を更新し、再デプロイまたは再起動するSESSION_PASSWORDの変更は、サインイン済みのメンバー全員を即座にサインアウトさせる。 セッションはこの値で暗号化されているため、鍵が変わると復号できなくなる。変更する場合は、全員が再度ウォレットで署名し直す必要があることを事前に告知し、変更理由を運用ログに残す- セッションの有効期限は14日で、サインインした時点からの絶対期限(閲覧では延長されない)。運営メンバーのセッションも同じ扱い
記録
- 状態変更は
application_eventsに実行者アドレス、時刻、変更前後の状態、理由、tx hash(Allowlist追加・配布のいずれも)が自動記録される- 記録は状態更新と同一トランザクションで行われるため、「状態は変わったのに記録が残っていない」状態は発生しない。 記録に失敗した場合は状態変更ごと巻き戻り、操作は適用されない
- 逆に言えば、
applicationsの状態とapplication_eventsの記録が食い違っていた場合、それはアプリ経由ではない直接のDB書き込みを疑う根拠になる - 記録は
/adminの各申請行の「履歴」を開いて確認する。実行者・時刻・変更前後の状態・理由・tx hashが新しい順に並ぶ。確認のためにDBへ直接繋ぐ必要はない
- Allowlist操作のオンチェーンtx hashは
/adminで入力し、application_eventsに残す。運用ログ側へ書き写す必要はない - 申請者への連絡や、アプリ外で行った特記事項は下記の運用ログに追記する
運用ログ
| 日時(UTC) | 申請ID | 操作 | 実行者の役割 | tx hash / 参照 | 備考 |
|---|---|---|---|---|---|
| YYYY-MM-DDThh:mm:ssZ |