必要なレベルまで進めてください。
Casa Tookan では、プレイヤーのアドレスはすべて Casa の中にあります。Casa は小屋から城へと育つプロフィールです。あなたの連携も同じように育ちます。各レベルは単独で機能するので、好きなところで止めてかまいません。
もう動いています。
サイトが MetaMask、Xverse、Magic Eden、Unisat で動くなら、Casa Tookan でも動きます。インストールする SDK も、コード内の特別扱いも要りません。
window.ethereum(EIP-1193)を EIP-6963 で通知します。wagmi、RainbowKit、Web3Modal で動作します。window.unisat。SegWit、Taproot、Legacy アドレスに対応します。window.webXCP と window.web3xcp。ユーザーは署名する前に、PSBT が何をするかを確認できます。

-
アプリでサイトを開く
Casa Tookan でブラウザを開き、URL を入力します。
-
いつもどおり接続して署名する
リクエストのたびに Casa Tookan の署名シートが開きます。あなたのサイトと署名する Casa が表示されるので、UI を作る必要はありません。
const [address] = await window.ethereum.request({ method: 'eth_requestAccounts' }); const signature = await window.ethereum.request({ method: 'personal_sign', params: ['Welcome to Orb Quest!', address], });import { request } from 'sats-connect'; const res = await request('getAddresses', { purposes: ['payment', 'ordinals'] }); if (res.status === 'success') console.log(res.result.addresses); // Or the Unisat dialect: the casa's Legacy address, where Counterparty assets live. const [legacy] = await window.unisat.requestAccounts();// The classic Counterparty API, with node-style callbacks. window.webXCP.getAccounts((err, accounts) => { if (err) return showError(err); loadCards(accounts); });初代 Casa Tookan や IndieSquare 向けに作られたサイトは、そのまま動きます。新しいコードでは、
signPsbtによる PSBT をおすすめします。Casa Tookan は、ユーザーが署名する前に Counterparty の送金、注文、ディスペンサーをデコードします。 -
Casa の切り替えに追従する
ユーザーはいつでもアドレスバーから Casa を切り替えられ、ページには通常のイベントが届きます。各 Casa には専用の
localStorageもあるので、セッションが混ざりません。window.ethereum.on('accountsChanged', ([next]) => setPlayer(next));
他のウォレットの中から Casa Tookan を選ぶ · EIP-6963
デスクトップブラウザでは、MetaMask が window.ethereum をロックし、Casa Tookan のウェブ版を含む他のウォレットが使えなくなることがあります。代わりに com.everdreamsoft.casatookan として通知されるプロバイダーを選んでください。どこでも動きます。スマートフォンでは、window.ethereum はいずれにしても Casa Tookan のものです。
window.addEventListener('eip6963:announceProvider', (e) => {
if (e.detail.info.rdns === 'com.everdreamsoft.casatookan') useProvider(e.detail.provider);
});
window.dispatchEvent(new Event('eip6963:requestProvider'));
// Just want to know you're inside Casa Tookan?
const inCasaTookan = window.casaTookan?.isCasaTookan === true;検出は、あいさつを表示したり、ウォレットの選択画面を省いたりするために使ってください。機能のオン/オフには使わないでください。API はプロバイダーそのものです。
手数料を宣言する · sats-connect, unisat
sats-connect は Xverse が公開している Bitcoin ウォレット向けのリクエスト形式です(window.BitcoinProvider、またはそれを見つける npm パッケージ sats-connect)。多くの Bitcoin ウォレットが採用しています。unisat(window.unisat)は UniSat の形式で、多くの Ordinals・Counterparty マーケットプレイスが使っています。Casa Tookan は同じ署名機能で両方に応答します。Xverse や UniSat 向けに書いたコードをそのまま使えます。
トランザクションがあなたへの支払いも含む場合(購入時のサービス手数料、ロイヤリティ、チップ)、PSBT と一緒に宣言してください。Casa Tookan は「宣言されていないアドレスに BTC が送られる」と警告する代わりに、Service fee · 0.0000075 BTC → bc1q… (declared by the site) と表示します。
await window.BitcoinProvider.request('signPsbt', {
psbt, // base64
signInputs: { [address]: [0, 1] },
broadcast: true,
fees: [{ kind: 'service', address: 'bc1q…', sats: 750 }],
});
// Unisat 方式:同じ fees をオプションに(signPsbts では各 PSBT のオプションに)。
await window.unisat.signPsbt(psbtHex, {
toSignInputs,
fees: [{ kind: 'service', address: 'bc1q…', sats: 750 }],
});kind:'service'、'royalty'、'tip'のいずれか。表示文は Casa Tookan が書きます。テキスト欄はありません。addressとsats:トランザクションの出力の一つと完全に一致すること。手数料は最大 3 件。- 一致する出力がない(金額やアドレスが違う)場合、ユーザーには赤い警告が表示されます。アクション自体の支払い(dispense のディスペンサー、send の宛先)は手数料になりません。
- リストにそれ以外のもの(別の kind、ラベル、余分なフィールド)があれば、宣言全体が無視され、ユーザーに通知されます。
fees を知らないウォレットは無視するので、宣言しても問題は起きません。すべての Counterparty アクションと通常の Bitcoin トランザクションで使えます。旧来の webXCP にはオプションがないため、sats-connect か unisat を使ってください。
デスクトップからテストする · スマートフォン不要
devapp.casatookan.com は、ブラウザで動く Casa Tookan で、テスト用ウォレットが付いています。サイトはフレームの中で動くため、スマートフォンにはないルールがブラウザによって適用されます。必要な変更は 4 つで、すべてあなたの側で行います。
<head>からウェブブリッジを読み込む。- devapp がページをフレームに入れられるようにする:
frame-ancestors 'self' https://devapp.casatookan.com。 /.well-known/へのすべてのリクエストに、404 も含めてAccess-Control-Allow-Origin: *を返す(レベル 2 を参照)。- セッション Cookie に
SameSite=None; Secure; Partitionedを付ける。
ブリッジのスニペット付きの手順: ウェブ版でアプリをテストする。
プレイヤーをまっすぐ迎え入れる。
Safari や Chrome でサイトを訪れた人は、そこにウォレットを持っていません。ボタン 1 つで、同じページが Casa Tookan の中で開きます。アプリがなければ、App Store・Google Play・「ブラウザで続ける」のページが開きます。
<a id="open-casa" href="#">
<img src="https://casatookan.com/assets/badges/open-in-casatookan-ja-dark.svg"
alt="Casa Tookan で開く" width="212" height="56">
</a>
<script>
// すでに Casa Tookan の中: 開くものはありません
if (window.casaTookan) document.getElementById('open-casa').hidden = true;
else document.getElementById('open-casa').href =
'https://casatookan.com/open?url=' + encodeURIComponent(location.href) + '&ref=your-app';
</script>casatookan.com/open をそのままアプリに渡します(ウォレットがロック中なら、解除の直後にページが開きます)。アプリがなければ、リンクのページがストアとブラウザでのサイトを案内し、パソコンではスマートフォン用の QR コードを表示します。開くのは https の url だけです。ref(a–z、0–9、. _ -、64 文字まで)で、あなたが連れてきたプレイヤーを数えます。name はページの見出しになります。バッジ: /assets/badges/open-in-casatookan-{en|fr|ja}-{dark|light}.svg。
アプリになる。
サイトにはおそらく、すでにウェブマニフェストがあります。wallet メンバーを 1 つ追加すれば、Casa Tookan はあなたのサイトをアプリとして表示します。
1
2
3
4
5
6
7
- 1バナー ·
wallet.heroImageUrl、1200×630 - 2アイコン ·
icons、1024×1024、不透明 - 3名前 ·
name、32 文字 - 4サブタイトル ·
wallet.subtitle、30 文字 - 5カテゴリ ·
categoriesの最初の値 - 6チェーン ·
wallet.chains - 7説明 ·
description、170 文字
Dev Playground のページです。バリデーターが、そのマニフェストから Casa Tookan のレイアウトで描画しました。あなたのマニフェストが、これらすべてを埋めます。
- あなたの名前とアイコンアドレスバーと署名シートに
- スプラッシュ画面読み込み中、あなたの色の上にあなたのアートを
- ブラウザ › アプリ にカードバナー付きで、ワンタップで開ける
- 明確な動作要件壊れたページの代わりにお知らせを表示
-
アプリの情報を入力する
必須なのは名前だけです。入力に合わせて JSON が更新されます。
まだマニフェストがないサイト向け。
W3C 標準。すでにお持ちかもしれませんwallet、追加する部分 -
公開する
次のどちらかを使います。Casa Tookan は両方を確認し、
walletメンバーを持つ最初のものを使います。場所 選ぶとき ホームページの <link rel="manifest">でリンクされた既存のマニフェストすでにある場合。リンクはスクリプトで追加せず、配信される HTML に含めてください。 /.well-known/wallet-app.json別にしておきたい場合。同じ JSON を単独で配信します。 application/jsonとして配信してください。画像はその隣に置きます: 1024×1024 の不透明なアイコン、1200×630 のバナー、200×200 のスプラッシュ。これは Farcaster と同じサイズなので、1 セットで両方に使えます。 -
ブラウザが読めるようにする
/.well-known/以下のすべて(404 を含む)と画像に、Access-Control-Allow-Origin: *を付けてください。スマートフォンのアプリには不要ですが、バリデーターとウェブ版の Casa Tookan には必要です。これがないと、存在しないfarcaster.jsonがネットワーク障害に見えてしまいます。# THE_REQUEST, not REQUEST_URI: still /.well-known/ after a rewrite to index.php <If "%{THE_REQUEST} =~ m#\s/\.well-known/#"> Header always set Access-Control-Allow-Origin "*" </If>location /.well-known/ { add_header Access-Control-Allow-Origin "*" always; } -
確認する
バリデーターは公開中のマニフェストを読み込み、すべての画像をテストし、Casa Tookan が描画するとおりにアプリを表示します。Casa Tookan はマニフェストを起動ごとに 1 回読み込むので、変更を確認するにはアプリを再起動してください。
farcaster.json や casatookan.json がすでにある場合
どちらも引き続き読み込まれ、フィールドごとにマージされます。順番は casatookan.json(以前の形式)、次に Wallet App Manifest、最後に farcaster.json です。Farcaster ミニアプリは、バナー、Bitcoin、Counterparty など、Casa Tookan で異なる部分だけを追加すれば十分です。
wallet は、どのウォレットでも読めるオープンな形式、Wallet App Manifest です。Casa Tookan だけが理解するフィールドには casatookan: 接頭辞が付きます。サーバーに障害が起きても、Casa Tookan はアプリについてすでに知っていた情報を保持します。完全なリファレンス: Casa Tookan アプリを作る。
準備ができたらスプラッシュを閉じる。
capabilities で wallet.ready を宣言します。するとスプラッシュは最初の画面が描画されるまで表示されたままになり、プレイヤーが読み込み途中のページを見ることはありません。
await loadAssets();
renderTitleScreen();
window.wallet?.ready(); // the splash fades, your game is therewallet.ready あり | スプラッシュは ready() を最大 10 秒待ちます。 |
| なし | ページが落ち着いてから 2.5 秒後にスプラッシュが消えます。 |
| Farcaster ミニアプリ | sdk.actions.ready() も同じように動作します。 |
casatookan.ready と window.casaTookan.ready() は引き続き動作します。wallet.ready は中立的な名前で、アプリをホストするどのウォレットでも提供できます。
どこからでもログイン。
通常のブラウザやネイティブゲームから、チャレンジを付けてプレイヤーを Casa Tookan に送ります。プレイヤーは Bitcoin と Ethereum のアドレスを持って戻ってきます。どちらも署名で証明されています。パスワードも拡張機能も要りません。
-
プレイヤーを Casa Tookan に送る
サーバーがランダムで使い捨てのチャレンジを作り、ページがリンクを開きます。
const { challenge } = await fetch('/auth/challenge').then((r) => r.json()); location.href = 'casatookan://x-callback-url/getaddress' + '?x-success=' + encodeURIComponent('https://orbquest.game/auth/casa') + '&msg=' + encodeURIComponent(challenge); -
プレイヤーが承認する
プレイヤーは署名シートであなたのサイトを確認し、Casa を選んでサインインをタップします。その後 Casa Tookan は、
address、msg、sigを付けてコールバックを開きます。address = chain:bitcoin;1Ca5a…T00k;;separator;;chain:ethereum;0x1614…1313 sig = chain:bitcoin;H8k2…=;;separator;;chain:ethereum;0x5f1c…1b -
サーバーで検証する
チャレンジが自分のもので未使用であることを確認し、次に両方の署名を確認します。注意: EVM の署名は
personal_signではありません。import bitcoinMessage from 'bitcoinjs-message'; import { recoverAddress, keccak256, toUtf8Bytes } from 'ethers'; // "chain:bitcoin;1Ca5…;;separator;;chain:ethereum;0x16…" → { bitcoin, ethereum } const entries = (s) => Object.fromEntries(s.split(';;separator;;').map((e) => { const i = e.indexOf(';'); return [e.slice('chain:'.length, i), e.slice(i + 1)]; })); export function verifyCasaLogin(query, expectedChallenge) { const p = new URLSearchParams(query); const msg = p.get('msg'); if (msg !== expectedChallenge) throw new Error('challenge'); // then burn it const addr = entries(p.get('address')); const sig = entries(p.get('sig')); // Bitcoin: BIP-137, signed by the Legacy address. if (!bitcoinMessage.verify(msg, addr.bitcoin, sig.bitcoin)) throw new Error('bitcoin'); // EVM: raw secp256k1 over keccak256(msg), not EIP-191. const signer = recoverAddress(keccak256(toUtf8Bytes(msg)), sig.ethereum); if (signer.toLowerCase() !== addr.ethereum.toLowerCase()) throw new Error('ethereum'); return addr; }
ネイティブアプリや他のチェーンは?
ネイティブアプリ: コールバックにアプリのスキームを使います(x-success=orbquest)。Casa Tookan は orbquest://sendaddress?address=…&msg=…&sig=… を開きます。既存の web3XCP アプリが想定しているとおり、これらの値は URL エンコードされないので、クエリを &address=、&msg=、&sig= で分割してください。
他のチェーン: signForAddress?chain=bitcoin,base&… は、指定したチェーンで、その順に署名します。
コールバックは https:// かアプリのスキームでなければなりません。http:// は拒否されます。詳細はすべて dApp 接続とディープリンクにあります。
プレイヤーを知る。
Casa Estates ID は、デバイスやリカバリーフレーズをまたいで、プレイヤーごとに 1 つのアカウントです。セーブデータは変わらない番号に紐づけ、アドレスは必要なときだけ求めます。報酬を配るゲームのために作られています。
-
マニフェストで宣言する
walletメンバーの中に:"capabilities": { "required": ["casatookan:identity.ceid"] }, "extensions": { "casatookan": { "identity": { "reason": "Your CEID keeps your progress across devices." } } } -
プレイヤーをサインインさせる
if (window.casaTookan?.ceid?.available) { 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 }); } -
サーバーでトークンを検証する
import { createRemoteJWKSet, jwtVerify } from 'jose'; const JWKS = createRemoteJWKSet(new URL('https://ctserver.everdreamsoft.com/.well-known/jwks.json')); const { payload } = await jwtVerify(token, JWKS, { issuer: 'https://ctserver.everdreamsoft.com', audience: 'https://orbquest.game', clockTolerance: 60, }); // check payload.nonce, then key the player on payload.ceid
jwks-dev.json でテストしてください。トークン、複数アカウント対策のための情報、プレイヤーに適用されるルールは Casa Estates ID でサインインにあります。公開する前に
確認項目は 6 つです。チェックした状態はこのブラウザに保存されます。
AI に任せる。
これを Claude、Cursor など、コードを書くツールに貼り付けてください。レベル 0 から 4 までをカバーします。
Casa Tookan ウォレット(casatookan.com/docs/integrate.html)と私のサイトを連携してください。
前提:
- Casa Tookan のアプリ内ブラウザは標準のプロバイダーを注入する。独自の SDK は追加しないこと:
window.ethereum(EIP-1193、EIP-6963 rdns "com.everdreamsoft.casatookan")、
Bitcoin 用に sats-connect / WBIP-004 / Wallet Standard / window.unisat
(unisat = Legacy アドレス。Counterparty の資産はここにある)、
Counterparty 用に window.webXCP と window.web3xcp。
- トランザクションがサイトへの手数料も支払う場合は PSBT と一緒に宣言する:signPsbt の params /
unisat の options に fees: [{ kind: "service"|"royalty"|"tip", address, sats }](出力と完全一致、最大 3 件、テキストなし)。
- rdns "com.everdreamsoft.casatookan" の EIP-6963 プロバイダーを優先する(デスクトップでは
MetaMask が window.ethereum をロックすることがある)。検出は window.casaTookan?.isCasaTookan で行う。
accountsChanged を監視すること: ユーザーはいつでも casa(アカウント)を切り替えられる。
casa ごとに専用の localStorage がある。
- 「Casa Tookan で開く」リンク: https://casatookan.com/open?url={encodeURIComponent(url)}&ref={your-app}(アプリがあればアプリで、なければストアのページで開きます。window.casaTookan があるときは隠します)。casatookan://browse/{encodeURIComponent(url)} もスマートフォン上で引き続き使えます。
- アプリのマニフェスト = Wallet App Manifest(github.com/wallet-apps/manifest): W3C の
ウェブマニフェスト(name、icons 1024x1024 の不透明な PNG、start_url、scope、background_color、
description、categories)に "wallet" メンバーを加えたもの:
{ "version": "1", "subtitle"(30 文字), "heroImageUrl"(1200x630),
"splashImageUrl"(200x200), "chains": { "required": [CAIP-2] },
"capabilities": { "required": [...] }, "extensions": { "casatookan": {...} } }
ホームページの <link rel="manifest"> または /.well-known/wallet-app.json で、
application/json として配信する。/.well-known/ 以下のすべて(404 を含む)と画像に
Access-Control-Allow-Origin: * を付ける。
Bitcoin = bip122:000000000019d6689c085ae165831e93, Ethereum = eip155:1, Base = eip155:8453.
Capabilities: provider.ethereum, provider.bitcoin, provider.counterparty, wallet.ready;
Casa Tookan のみ: casatookan:identity.ceid。Counterparty = Bitcoin + provider.counterparty。
- wallet.ready を宣言した場合は、最初の画面が描画されたら window.wallet?.ready() を呼ぶ。
- 通常のブラウザやネイティブアプリからのログイン:
casatookan://x-callback-url/getaddress?x-success={encodeURIComponent(https callback)}&msg={encodeURIComponent(challenge)}
応答: callback?address=…&msg=…&sig=…(https のコールバックでは URL エンコードされる)。
address/sig = "chain:bitcoin;VALUE;;separator;;chain:ethereum;VALUE"。
Bitcoin の署名: Legacy アドレスによる BIP-137 base64(bitcoinjs-message の verify)。
EVM の署名: keccak256(utf8(msg)) に対する生の secp256k1、0x r s v(v=27+recid)。EIP-191 ではない:
ethers recoverAddress(keccak256(toUtf8Bytes(msg)), sig)。
チャレンジはランダムかつ使い捨てで、サーバーで検証する。
- devapp.casatookan.com でのデスクトップテスト(ctserver.everdreamsoft.com/docs/web.html を参照):
<head> にウェブブリッジ、frame-ancestors 'self' https://devapp.casatookan.com、
/.well-known/ に CORS、セッション Cookie に SameSite=None; Secure; Partitioned。
