@jccdex/did
v0.2.11
Published
DID for wodecards
Downloads
615
Readme
DID
Simple Profile Did文档解析.
Install
yarn add @jccdex/did @jccdex/ipfs-rpc-clientUsage in DAPP
import {
EthrDid,
EthrDidPublish,
BaseNftVC,
EthrDidResolver,
EthrDidDocument,
SwtcDid,
SwtcDidPublish,
SwtcDidResolver,
SwtcDidDocument,
DidService,
VC_TYPE,
ETHER_NFTOWNERSHIP_CONTEXT,
SWTC_NFTOWNERSHIP_CONTEXT
} from "@jccdex/did";
import { IpfsClient } from "@jccdex/ipfs-rpc-client";
const ethereum = window.ethereum;
// CCDAOConnector授权以太坊地址
const account = "";
// CCDAOConnector授权swtc地址
const swtcAccount = "";
const client = new IpfsClient({
baseURL: "https://wodecards.wh.jccdex.cn:8550",
sign: async (data, address) => {
const sign = await ethereum.request({
method: 'ipfs_personalSign',
params: [data, address],
});
return sign;
},
getPublicKey: async (address) => {
const pub = await ethereum.request({
method: 'ipfs_getPublicKey',
params: [address]
});
return pub;
}
});
// 创建did
const did = EthrDid.fromIdentifier(account);
const id = `${did.toString()}#key-1`;
// 创建NFT VC
const vc = new BaseNftVC({
sign: async (data) => {
return await ethereum.request({
method: 'did_issueCredential',
params: [data],
});
}
});
vc.addType(VC_TYPE.NFT_OWNERSHIP);
vc.addContext(ETHER_NFTOWNERSHIP_CONTEXT);
vc.setId("")
vc.setSubject({
id: did.toString(),
contractAddress: "0xED5AF388653567Af2F388E6224dC7C4b3241C544",
chainId: 1,
tokenId: "443",
owner: "0xAWalletAddress",
status: "Active"
})
// vc签名
await vc.sign({
keyDoc: {
address: account,
did: did.toString(),
// 可选, 默认值 did.toString() + "#keys-1"
id
}
});
// vc验证签名
const resolver = new EthrDidResolver(client);
const verified = await BaseNftVC.fromJSON(vc.toJSON()).verify({ resolver });
// 创建simple profile DID文档
const didDoc = new EthrDidDocument(did.toString());
const profile = DidService.generateProfile({
id: did.toString() + "#profile",
nickname: "张三",
preferredAvatar: "https://example.com/avatar.png"
});
// 现在ipfs service的ipns固定值
const ipns = "ipns://k2k4r8ntjlp1cmgped39eq1fi4yze6fsr8og1kcmjhamgs3ubwkfldei"
// 获取did文档cid, 如果是原始文件, 则不用获取, 为空字符串.
const { cid } = await resolver.stat(did.toString());
const ipfsStorage = DidService.generateIpfsStorage({
id: did.toString() + "#ipfs-storage",
ipns,
previousCid: cid
});
// 从插件获取base58公钥及加密类型
const { publicKeyBase58, type } = await ethereum.request({
method: 'did_getBase58PublicKey',
params: [account],
});
didDoc.setVersion("1.0.0")
.addAuthentication(id)
.addAssertionMethod(id)
.addVerificationMethod({
id,
type,
controller: did.toString(),
publicKeyBase58
})
.addService(profile)
.addService(ipfsStorage)
.addCredential(vc.toJSON());
.setUpdated();
// 将did doc上传到ipfs service
const didPublisher = new EthrDidPublish(client);
const res = await didPublisher.upload(did.toString(), didDoc.toJSON(), account);
console.log("did publish result: ", res);
// 创建swtc did
const swtcDid = SwtcDid.fromIdentifier(swtcAccount);
const swtcId = `${swtcDid.toString()}#key-1`;
// 创建SWTC NFT VC
const swtcVc = new BaseNftVC({
sign: async (data) => {
return await ethereum.request({
method: 'did_issueCredential',
params: [data],
});
}
});
swtcVc.setId("")
swtcVC.addContext(SWTC_NFTOWNERSHIP_CONTEXT);
swtcVC.addType(VC_TYPE.NFT_OWNERSHIP)
swtcVc.setSubject({
id: swtcDid.toString(),
chainId: 315,
tokenName: "Golden Sands",
tokenId: "2",
owner: "swtcWalletAddress",
status: "Active"
})
// swtc vc签名
await swtcVc.sign({
keyDoc: {
address: swtcAccount,
did: swtcDid.toString(),
// 可选, 默认值 swtcDid.toString() + "#keys-1"
id: swtcId
}
});
// swtc vc验证签名
const swtcResolver = new SwtcDidResolver(client);
const swtcVerified = await BaseNftVC.fromJSON(swtcVc.toJSON()).verify({ resolver: swtcResolver });
// 创建swtc simple profile DID文档
const swtcDidDoc = new SwtcDidDocument(swtcDid.toString());
const swtcProfile = DidService.generateProfile({
id: swtcDid.toString() + "#profile",
nickname: "李四",
preferredAvatar: "https://example.com/swtc-avatar.png"
});
// 获取swtc did文档cid, 如果是原始文件, 则不用获取, 为空字符串.
const { cid: swtcCid } = await swtcResolver.stat(swtcDid.toString());
const swtcIpfsStorage = DidService.generateIpfsStorage({
id: swtcDid.toString() + "#ipfs-storage",
ipns,
previousCid: swtcCid
});
// 从插件获取base58公钥及加密类型
const { publicKeyBase58, type } = await ethereum.request({
method: 'did_getBase58PublicKey',
params: [swtcAccount],
});
swtcDidDoc.setVersion("1.0.0")
.addAuthentication(swtcId)
.addAssertionMethod(swtcId)
.addVerificationMethod({
id: swtcId,
type,
controller: swtcDid.toString(),
publicKeyBase58
})
.addService(swtcProfile)
.addService(swtcIpfsStorage)
.addCredential(swtcVc.toJSON())
.setUpdated();
// 将swtc did doc上传到ipfs service
const swtcDidPublisher = new SwtcDidPublish(client);
const swtcRes = await swtcDidPublisher.upload(swtcDid.toString(), swtcDidDoc.toJSON(), swtcAccount);
console.log("swtc did publish result: ", swtcRes);
综合 README.md 和目录结构分析,frontend/did 这个 DAPP 主要实现了如下功能,并采用了相关 DID 生态开发包:
主要功能实现
多链 DID 支持
- 支持以太坊(EthrDid)和 SWTC(SwtcDid)两种 DID 标准,能为不同链的账户生成 DID 标识和文档。
DID 文档的创建、扩展与发布
- 可根据账户生成 DID 文档(DID Document),并支持添加 profile(昵称、头像)、ipfsStorage、service、credential 等扩展字段。
- 支持将 DID 文档通过 IPFS 客户端上传到后端 ipfs-service,实现去中心化存储。
可验证凭证(VC)管理
- 支持 NFT 相关的 VC(BaseNftVC),可为 DID 生成 NFT 所有权凭证,进行签名、验证。
- VC 支持多链(以太坊、SWTC)和多类型扩展。
DID 文档与 VC 的解析和验证
- 通过 EthrDidResolver、SwtcDidResolver 结合 IPFS 客户端,支持 DID 文档和 VC 的解析、CID 查询、签名验证等。
与钱包/插件集成
- 通过 window.ethereum.request 与钱包或浏览器插件交互,实现链上签名、公钥获取、凭证签发等操作,支持 DApp 场景下的用户身份和凭证管理。
IPFS 存储与版本管理
- 支持通过 ipfs-rpc-client 与后端 ipfs-service 通信,实现 DID 文档和凭证的去中心化存储、读取、CID 查询、IPNS 版本管理等。
主要依赖的开发包
@jccdex/did
- 提供 DID 标识、文档、凭证、解析、发布、服务扩展等全套能力,支持多链和多类型扩展。
- 主要类和方法:EthrDid、SwtcDid、EthrDidPublish、SwtcDidPublish、EthrDidResolver、SwtcDidResolver、BaseNftVC、DidService、VC_TYPE 等。
@jccdex/ipfs-rpc-client
- 提供与后端 ipfs-service 的 HTTP 通信能力,实现 IPFS 文件的上传、下载、CID 查询、IPNS 管理等。
代码结构与典型流程
- 代码分为 lib/(核心库)、src/(业务逻辑)、test/(测试)等目录,核心 DID 相关逻辑在 lib/ 和 src/ 下。
- 典型流程:
- 通过账户生成 DID → 构建 DID 文档 → 生成/签名 VC → 通过 IPFS 客户端上传 DID 文档 → 解析/验证 DID 文档和 VC → 支持 profile、service、ipfsStorage 等扩展 → 与钱包插件集成实现链上签名和公钥获取。
特色与优势
- 支持多链 DID 和 NFT VC,适合多链身份和资产场景。
- DID 文档和凭证均可去中心化存储,支持版本管理和扩展。
- 与钱包深度集成,适合 DApp 场景。
- 代码结构清晰,扩展性强,便于二次开发。
