Casa Estates ID でサインイン

ゲームやアプリが CEID で Casa Tookan のプレイヤーを識別する方法:プレイヤーごとにひとつのアカウント、プレイヤーが開示を選んだアドレス、そして複数アカウントを防ぐための事実情報。

プレビュー:Casa Tookan の開発ビルドのみ。ストア版アプリにはまだ含まれていません
ひとことで言うとwindow.casaTookan.ceid.signIn({ nonce }) を呼び出します。プレイヤーが一度承認すると、CEID とユーザー名を含む、Casa Tookan が署名した24時間有効のトークンを受け取れます。さらに、あなたが求め、プレイヤーが同意した場合に限り、アドレスも含まれます。そのアセットはあなた自身がオンチェーンで読み取ります。

CEID

Casa Estates ID はプレイヤーのアカウントで、Farcaster の id と同じく公開されています。プレイヤーがアドレスを一度も開示しないこともあります。ブロックチェーンを使わないゲームでも、数か月後の報酬配布のときに初めてアドレスが必要になるゲームでも、同じように動作します。

アカウント

番号 + ユーザー名

  • ceid:ランダムに選ばれる8桁の数字。決して変わらず、再利用もされません。プレイヤーの人数については何も示しません。プレイヤーはこれをキーにしてください。
  • username:グローバルで一意。デフォルトは CasaTookanUser#48213907 で、変更は30日に1回までです。
  • 代わりに、ゲーム内の独自の名前を表示してもかまいません。
アドレス

任意、アプリごとに選択

  • あなたが求めない限り、サインイン時にはアドレスは含まれません。
  • どの Casa を見せるかは、プレイヤーがチェーンごとに選びます。
  • アドレスは同時にひとつの CEID にしか属しません。
端末

1台の端末に、ひとつの CEID

  • 同じスマートフォンで新しいリカバリーフレーズを使うと、CEID は移動します。2つ目が作られることはありません。
  • トークンには、端末が証明済みかどうか、CEID が何回移動したかが含まれます。

流れ

  1. サーバーが nonce を作るランダムで、使い捨てで、有効期間が短く、トークンを受け取るセッションに結び付いたもの。
  2. ページが依頼するsignIn({ nonce })。Casa Tookan はあなたの名前、アイコン、ドメインを表示したシートを出します。初回はプレイヤーの CEID を作成します。入力するものは何もありません。
  3. プレイヤーが承認するCasa Tookan のネイティブ署名機能の中で、CEID の鍵があなたの nonce を含む内容に署名します。プレイヤーのリカバリーフレーズがそこから出ることはありません。
  4. Casa Tookan のサーバーがトークンを発行する署名と端末を確認し、事実情報を加え、あなたのオリジン(aud)向けの JWT に署名します。
  5. あなたのサーバーが検証する公開鍵(JWKS)に対して検証します。Casa Tookan を呼び出す必要はありません。その後、共有されたアドレスをあなた自身がオンチェーンで読み取ります。プレイヤーが何を持っているかについて、ウォレットを信用してはいけません。
  6. 後から、アドレスを求めるドロップやインベントリなど、必要になったときに requestAddresses({ nonce, chains, reason }) を呼びます。新しいトークンにアドレスが含まれます。

マニフェスト

Wallet App Manifest で宣言します:casatookan:identity.ceid 機能と、wallet.extensions.casatookan の下の identity オブジェクトです。これは Casa Tookan 独自のもので、ほかのウォレットは無視します。

{
  "name": "Orb Quest",
  "wallet": {
    "version": "1",
    "capabilities": { "required": ["casatookan:identity.ceid"] },
    "extensions": {
      "casatookan": {
        "identity": {
          "reason": "Your CEID keeps your progress across devices.",
          "addresses": [
            { "chain": "bip122:000000000019d6689c085ae165831e93", "max": 2, "reason": "Activate the orbs you hold on Counterparty" },
            { "chain": "eip155:1", "max": 1, "reason": "Your Ethereum cards" }
          ]
        }
      }
    }
  }
}
フィールド型備考
identity.reasonstring最大120文字。サインインのシートに表示されます。
identity.addressesarrayチェーンごとに、求めることのできる上限。それを超える依頼は拒否されます。アカウントだけが必要なら省略してください。
…chainCAIP-2Counterparty のアセットは Bitcoin 上にあります。Bitcoin の id を使ってください(レガシーアドレスが共有されます)。
…max1–5そのチェーンでプレイヤーがチェックできるアドレスの数。
…reasonstring最大80文字。そのチェーンのチェックボックスの上に表示されます。

ページ内

マニフェストで casatookan:identity.ceid を宣言すると、Casa Tookan のブラウザ内で利用できます。呼び出しが失敗すると、理由を示す code を持つエラーで reject されます:

code発生する場合
rejectedプレイヤーが Casa のシートを閉じたか、署名をキャンセルした。
not_declaredマニフェストで casatookan:identity.ceid が宣言されていない。
over_limitidentity.addresses が許すより多いアドレス、または別のチェーンを求めた。シートを出す前に確認されます。
invalidnonce がない、chains の形式が不正。
failedCasa Tookan のサーバーが拒否した(たとえば、端末で別の CEID が有効になっている)。理由はメッセージに示されます。
unavailableここでは提供されていない(ブラウザの外、古いバージョン)。

const { nonce } = await fetch('/auth/nonce').then((r) => r.json());

// アカウントのみ:アドレスはウォレットから出ない
const { token } = await window.casaTookan.ceid.signIn({ nonce });
await fetch('/auth/casa', { method: 'POST', body: token });

// 数か月後、ドロップのために
const { nonce: n2 } = await fetch('/auth/nonce').then((r) => r.json());
const { token: withAddresses } = await window.casaTookan.ceid.requestAddresses({
  nonce: n2,
  chains: [{ chain: 'bip122:000000000019d6689c085ae165831e93', max: 1 }],
  reason: 'Where should we send your reward?',
});
呼び出し戻り値備考
ceid.signIn({ nonce }){ token }あなたのオリジンとすでに共有されたアドレスは再び含まれます。新たに追加されることはありません。
ceid.requestAddresses({ nonce, chains, reason }){ token }マニフェストの上限の範囲内。共有済みのアドレスはあらかじめチェックされています。プレイヤーがチェックを外すと、そのアドレスはトークンから外れます。
ceid.availablebooleanCasa Tookan の外や古いバージョンでは false。別のサインイン方法を提供してください。

トークン

Casa Tookan のサーバーが署名した JWT(ES256)で、24時間有効です。その後は新しいトークンを求めてください。何も変わっていなければシートは表示されません。

{
  "iss": "https://ctserver.everdreamsoft.com",
  "aud": "https://orbquest.game",
  "sub": "ceid:48213907",
  "env": "production",
  "ceid": 48213907,
  "username": "CasaTookanUser#48213907",
  "usernameDefault": true,
  "addresses": [
    { "chain": "bip122:000000000019d6689c085ae165831e93", "address": "1Abc…k9Z", "since": "2026-03-02" }
  ],
  "facts": {
    "deviceAttested": true,
    "deviceUnique": true,
    "transfers": 0,
    "ceidAge": 214,
    "farcaster": { "fid": 4242 }
  },
  "nonce": "…", "iat": 1791878400, "exp": 1791964800
}
クレーム意味
ceid / subプレイヤー。生涯変わりません。ユーザー名は変わっても、これは変わりません。
envproduction、または Casa Tookan Dev ビルド・シミュレーター・未証明の端末では development。開発用の CEID は別の集合で、その番号とユーザー名は本番のものとは異なります。
username, usernameDefault現在のグローバルなユーザー名。まだ CasaTookanUser#… のままなら true。
addressesプレイヤーがあなたのオリジンと共有したものだけ。since:そのアドレスがこの CEID に加わった日。なければ空の配列。
facts.deviceAttestedリクエストが、実機上の正規の Casa Tookan アプリから来たこと(App Attest / Play Integrity)。
facts.deviceUniqueその端末でほかの CEID が有効になっていないこと。
facts.transfersCEID が新しいリカバリーフレーズに移動した回数。
facts.ceidAgeCEID が作成されてからの日数。
facts.farcasterプレイヤーが Farcaster アカウントを連携している場合に含まれます。

サーバーで検証する

ページの中だけで検証してはいけません。ブラウザでしか確認していないトークンは、プレイヤーが偽造できます。

  1. 署名https://ctserver.everdreamsoft.com/.well-known/jwks.json の鍵に対して検証します(キャッシュし、kid に従ってください)。これらは本番のトークンにしか署名しないため、開発用のトークンはそれだけで検証に失敗します。
  2. オーディエンスと発行者aud があなたのオリジンと完全に一致し、iss が Casa Tookan のサーバーであること。
  3. nonceこのセッションのためにあなたが発行した、未使用のもの。使ったら破棄します。
  4. 時刻exp を過ぎていないこと(時計のずれを1分まで許容)。
import { createRemoteJWKSet, jwtVerify } from 'jose';

const JWKS = createRemoteJWKSet(new URL('https://ctserver.everdreamsoft.com/.well-known/jwks.json'));

export async function verifyCasaToken(token, expectedNonce) {
  const { payload } = await jwtVerify(token, JWKS, {
    issuer: 'https://ctserver.everdreamsoft.com',
    audience: 'https://orbquest.game',
    clockTolerance: 60,
  });
  if (payload.nonce !== expectedNonce) throw new Error('nonce');
  return payload; // プレイヤーは payload.ceid をキーにする
}

開発ビルド

Casa Tookan Dev でテストしてください。その CEID は本番のものとは分けられており、https://ctserver.everdreamsoft.com/.well-known/jwks-dev.json で公開される開発用の鍵で署名されます。ステージングサーバーはそちらを参照して env === "development" を確認し、本番サーバーは本番の鍵のままにしておけば、テスト用アカウントを目にすることはありません。メインアプリの TestFlight ビルドは本番として証明されるので、テストには使わないでください。

複数アカウント

アプリごとにアドレスを共有する仕組みは、ひとりが複数人としてプレイすることを防ぐためのものではありません。対策は攻撃の種類ごとに次のとおりです。

攻撃対処する側方法
ひとつの CEID が2回プレイするCasa Tookanどのアドレスが共有されても、常に同じ ceid が届きます。
1台のスマートフォンに多数の CEIDCasa Tookan1台の端末に、ひとつの CEID。新しいフレーズは CEID を新たに作らず、移動させます。
ひとつのアドレスが2人のプレイヤーに使われるCasa Tookanアドレスはひとつの CEID に属します。連携を解除したアドレスは、90日経たないと別の CEID に加われません。
アセットがウォレット間を移動するあなたCasa Tookan からは見えません。保有状況のスナップショットを取る、ロックする、または保有期間を求めてください。
多数のスマートフォン両方Casa Tookan が事実情報を提供し、あなたがしきい値を決めます(例:deviceAttested かつ ceidAge ≥ 30 の場合のみ報酬)。

プレイヤーに適用されるルール

ルールあなたにとっての意味
ユーザー名:30日に1回トークンを受け取るたびに更新し、キーとしては決して使わないでください。古い名前は30日間予約されたままです。
デフォルトのパターンは予約済みCasaTookanUser#… は誰も選べません。常に「まだ名前を選んでいない」ことを意味します。
アドレスの連携解除次のトークンから外れます。その時点で使用をやめてください。
トークン:24時間毎日、またはセッションごとに再取得し、その間はあなた自身のセッションを保持してください。
フレーズを紛失し、移動していないプレイヤーはその端末で新しい CEID を取得できません。サポートでアカウントを統合することもできません。統合先が存在しないからです。

プライバシー

表示されない

プライベートな Casa

プレイヤーがあなたのために選ばなかった Casa は、あなたにとって存在しません。ほかのアドレスをゲームに貼り付けるよう、プレイヤーに求めないでください。

あなたの判断

共有されたアドレス

共有された時点で、それがこのプレイヤーのものだとわかります。それを公開する場合(ランキング、プロフィールなど)は、reason でその旨を伝えてください。

オリジンごと

何も持ち出されない

ほかのアプリと共有されたアドレスがあなたに届くことはなく、CEID のアドレス一覧も公開されません。

プレイグラウンドで試す

開発者向けプレイグラウンドのミニアプリには CEID タブがあり、上記のすべてのシナリオを再現できます:初回サインイン、アドレスなしでのプレイ、ドロップ、拒否、期限切れ・再利用・別オリジンのトークン、名前の変更、新しいフレーズ、アンチシビルのしきい値。環境、マニフェスト、プロバイダー、ディープリンクのタブもあります。Casa Tookan で ctserver.everdreamsoft.com/playground/ を開くと、Casa Tookan のサーバーに対してサインインします(開発ビルドでは env: "development" のトークンになります)。通常のブラウザでは、独自の発行者と鍵を持つモックのウォレットとモックの発行者を相手に動作するため、モックのトークンが Casa Tookan のものとして通ることはありません。