--- title: "claude code webを使い切った" slug: "aicard" date: "2025-11-18" tags: ["react", "ios"] language: ["ja", "en"] draft: false --- 11/18までの無料配布のtokenがあります。今回はギリギリ使い切れました。`anthropic`に感謝。 [https://support.claude.com/en/articles/12690958-claude-code-promotion](https://support.claude.com/en/articles/12690958-claude-code-promotion) [msg type="info" content="claudeは性能劣化、limitの多発、突然動かなくなる現象が多発した時期があり、`plan:max`でもほとんど使えない期間がありました。1ヶ月間、ほとんど使わなかったのに`plan:max`は無駄だったという経験から、それ以降は`plan:pro`に切り替えています。claudeが使えなくなった期間は他のサービスを使っていました。"] 今回は、特に印象的だったことを紹介。 ## 色々作っていた 全部自分の手で書いていたものをベースにclaudeに書き直してもらったり、あるいは、一緒に最初から設計を考え直したりといった作業でした。 ```json { "ai" : ["gpt", "shell", "os", "app", "bot", "card"] } ``` ## aicard for ios `ai.card`, つまり、`aicard for ios`に関しては、ueで書いていたものを全部作り直しました。 今回は`react + expo`という構成ですが、あのままueで作り続けていたら、やばかった。 ### atproto oauth 1. PKCE生成 → PAR → Authorization → Callback 2. Token Exchange(DPoP nonce自動リトライ) 3. Profile取得(DPoP + ath) 4. Session保存 `Universal Links` ```json:apple-app-site-association.json { "applinks": { "apps": [], "details": [{ "appID": "{apple-dev}.{id}", "paths": ["/oauth/callback"] }] } } ``` #### 1. ellipticへの移行 **解決策**: ES256署名を`elliptic`ライブラリで実装 ```js import elliptic from 'elliptic'; const EC = elliptic.ec; const ec = new EC('p256'); const key = ec.genKeyPair(); ``` **成功**: DPoP proof JWTの生成に成功 #### 2. DPoP nonce対応 **問題**: トークン交換時に`use_dpop_nonce`エラー **解決策**: 自動リトライロジック実装 ```js // 1回目失敗 → DPoP-Nonceヘッダー取得 → 2回目成功 if (errorData.error === 'use_dpop_nonce') { const nonce = response.headers.get('DPoP-Nonce'); // nonceを含めてリトライ } ``` #### 3. プロファイル取得エラー **問題**: `DPoP "ath" mismatch`エラー ``` {"error":"invalid_dpop_proof","message":"DPoP \"ath\" mismatch"} ``` **原因**: プロファイル取得時のDPoPプルーフにaccess token hash (`ath`) が欠落 **解決策**: `generateDPoPProof`に`accessToken`パラメータ追加 ```js // アクセストークンのSHA-256ハッシュを計算 if (accessToken) { const tokenHash = await Crypto.digestStringAsync( Crypto.CryptoDigestAlgorithm.SHA256, accessToken, { encoding: Crypto.CryptoEncoding.BASE64 } ); payload.ath = base64UrlEncode(tokenHash); } ``` ### glb 結論から言うと、`react-native-filament`を使います。 `three`でやる通常の方法ではうまくテクスチャが表示されませんでした。 ```diff + react-native-filament - expo-three, expo-gl ```