本文へ移動

パスキー

WebAuthnのユーザー存在確認、PRFから導出する素材、RP IDの範囲、パスキーの復元境界を理解します。

パスキー ​

パスキーは、WebAuthnでユーザーの存在を確認します。 利用可能な場合は、疑似乱数関数(PRF)で保持者側の素材を導出します。

モデル内の役割 ​

パスキーは、次の処理に使えます。

  1. ローカルのユーザーの存在を証明する。
  2. 保持者側の素材を導出またはアンロックする。
  3. 期限切れや消費済みのウォレットセッション利用枠を、追加認証で更新する。
  4. ポリシーが暗号学的要素を要求する場合に、機密性の高い操作を承認する。

パスキーは、アプリセッションに署名権限を与えません。 SDKは、結果を、他の認証方法と共通のレーン、ウォレットセッション利用枠、機能の許可、ポリシーのモデルへ変換します。

パスキーで登録する ​

Reactへの導入では、機能とプロビジョニング状態に応じた登録結果の型を維持します。

実行可能なReactの実装例
tsx
import type { RegistrationFlowEvent, SeamsWeb } from '@seams/wallet';
import { useSeams, type SeamsContextType } from '@seams/wallet/react';

function logRegistrationEvent(event: RegistrationFlowEvent): void {
  console.log(event.phase, event.status, event.message);
}

function assertNever(value: never): never {
  throw new Error(`Unexpected NEAR readiness result: ${JSON.stringify(value)}`);
}

async function createWallet(
  registerWallet: SeamsContextType['registerWallet'],
  seams: SeamsWeb,
  registration: Parameters<SeamsContextType['registerWallet']>[0],
): Promise<void> {
  try {
    const result = await registerWallet({
      ...registration,
      options: { ...registration.options, onEvent: logRegistrationEvent },
    });
    if (!result.success) {
      console.error('Registration failed:', result.error);
      return;
    }
    // `walletId` is the stable identifier for every later wallet operation.
    console.log(`Wallet ${result.walletId} registered (${result.kind})`);

    if (
      result.kind === 'ecdsa_wallet_registered_near_pending' ||
      result.kind === 'near_wallet_registered_pending'
    ) {
      const near = await seams.registration.waitForNearAccount({ walletId: result.walletId });
      switch (near.kind) {
        case 'near_ready':
          console.log('NEAR account ready:', near.nearAccountId);
          break;
        case 'near_failed_retryable':
          console.warn('NEAR provisioning needs a retry:', near.reason);
          break;
        case 'timed_out':
          console.warn('NEAR is still pending. Keep this wallet id and check readiness again.');
          break;
        default:
          assertNever(near);
      }
    }
  } catch (error) {
    console.error('Wallet creation interrupted:', error);
  }
}

export function CreateWalletButton({ registration }: {
  registration: Parameters<SeamsContextType['registerWallet']>[0];
}) {
  const { registerWallet, seams } = useSeams();

  return (
    <button onClick={createWallet.bind(null, registerWallet, seams, registration)}>
      Create wallet
    </button>
  );
}