🔖
didkit-wasm, Next.jsでVerifiable Credentialsを検証してみる
はじめに
DIDKitを使って、Verifiable Credentialsをブラウザで検証してみます。
didkit-wasm
を使います。
バージョン
nextjs: 14.0.4
@spruceid/didkit-wasm: 0.2.1
Next.jsプロジェクトを用意する
以下のように用意したNext.jsを使います。
hide@hidenoMacBook-Pro didkit-examples % npx create-next-app@latest
✔ What is your project named? … with-nextjs
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Creating a new Next.js app in /Users/hide/hid3h/didkit-examples/with-nextjs.
Using npm.
Initializing project with template: app-tw
Installing dependencies:
- react
- react-dom
- next
Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- autoprefixer
- postcss
- tailwindcss
- eslint
- eslint-config-next
added 362 packages, and audited 363 packages in 15s
128 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Initialized a git repository.
Success! Created with-nextjs at /Users/hide/hid3h/didkit-examples/with-nextjs
didkit-wasmを用意する
yarn add @spruceid/didkit-wasm
didkit-wasm
はWebAssemblyを用います。
Next.jsで使用できるようにするためには設定が必要です。
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
config.experiments = {
asyncWebAssembly: true,
layers: true,
};
return config;
},
};
module.exports = nextConfig;
検証部分のコンポーネントを用意します。
app/Verification.tsx
"use client";
export const Verification = () => {
const verify = async () => {
console.log("検証スタート");
// didkit-wasmをサーバー側でimportしようとするとエラーになるので、
// クライアント側でimportするようにする
const didkit = await import("@spruceid/didkit-wasm");
const result = await didkit.verifyCredential("{}", "{}");
console.log(result);
};
return (
<div>
<button onClick={verify}>検証する</button>
</div>
);
};
以下のようにdidkit-wasm
をimportしようとするとエラーになるので、上記ではconst verify()
の中でimportしています。
app/Verification.tsx
"use client";
import didkit from "@spruceid/didkit-wasm";
export const Verification = () => {
const verify = async () => {
console.log("検証スタート");
const result = await didkit.verifyCredential("{}", "{}");
console.log(result);
};
return (
<div>
<button onClick={verify}>検証する</button>
</div>
);
};
Unhandled Runtime Error
Error: Element type is invalid. Received a promise that resolves to: undefined. Lazy element type must resolve to a class or function.
このコンポーネントを読み込むようにして、サーバを起動してブラウザで開いてみると、
app/page.tsx
import { Verification } from "./Verification";
export default function Home() {
return <Verification />;
}
となり、
「検証する」を押すとdidkitで検証できるようになりました。
VCを検証してみる
VCはsampleとして、
で署名したものを使ってみます。app/Verification.tsx
"use client";
export const Verification = () => {
const signedSampleVc = {
"@context": "https://www.w3.org/2018/credentials/v1",
id: "urn:uuid:86a109aa-a3f6-4374-b46f-92c58fcb16a1",
type: ["VerifiableCredential"],
credentialSubject: {
id: "did:example:my-data-subject-identifier",
},
issuer: "did:key:z6Mkv2hGUtUdKdEVdqc7esowafyriuqPvxQFnVTrRqjMknj2",
issuanceDate: "2023-01-08T18:23:56Z",
proof: {
type: "Ed25519Signature2018",
proofPurpose: "assertionMethod",
verificationMethod:
"did:key:z6Mkv2hGUtUdKdEVdqc7esowafyriuqPvxQFnVTrRqjMknj2#z6Mkv2hGUtUdKdEVdqc7esowafyriuqPvxQFnVTrRqjMknj2",
created: "2023-01-08T07:43:50.818Z",
jws: "eyJhbGciOiJFZERTQSIsImNyaXQiOlsiYjY0Il0sImI2NCI6ZmFsc2V9..jyR9O8nb-ino0TXSCAhUdP2Z9iBc0E-aX7tyTHcFuOzOGd_uWpwHhA4gTOX961SUHB0un34e2YV41qc2lk0nCw",
},
};
const verify = async () => {
console.log("検証スタート");
// didkit-wasmをサーバー側でimportしようとするとエラーになるので、
// クライアント側でimportするようにする
const didkit = await import("@spruceid/didkit-wasm");
const proofOptions = {};
const result = await didkit.verifyCredential(
JSON.stringify(signedSampleVc),
JSON.stringify(proofOptions)
);
console.log(result);
};
return (
<div>
<button onClick={verify}>検証する</button>
</div>
);
};
「検証する」ボタンを押してみると、
{"checks":["proof"],"warnings":[],"errors":[]}
ブラウザでVCの検証ができていることが確認できました。
改ざんの検知も確認してみます。
VCの一部を変更してみます。
credentialSubject: {
id: "did:example:my-data-subject-identifier-fix",
},
{"checks":["proof"],"warnings":[],"errors":["signature error: Verification equation was not satisfied"]}
検証に失敗しており、改ざんを検知できることも確認できました。
おわりに
サンプルコードを以下に用意しています。
Discussion
大変参考になりました。おかげでDidikitへの理解も深まりました。本当にありがとうございます。