@jccdex/vc-vocabularies 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -0
- package/lib/brands/ccdao.d.ts +3 -0
- package/lib/brands/ccdao.js +6 -0
- package/lib/brands/jdid.d.ts +3 -0
- package/lib/brands/jdid.js +6 -0
- package/lib/index.d.ts +29 -0
- package/lib/index.js +45 -0
- package/lib/inline-contexts.d.ts +199 -0
- package/lib/inline-contexts.js +146 -0
- package/lib/profiles/nft-ownership.d.ts +8 -0
- package/lib/profiles/nft-ownership.js +20 -0
- package/lib/profiles/nft-usage-authorization.d.ts +5 -0
- package/lib/profiles/nft-usage-authorization.js +17 -0
- package/lib/profiles/phone-verification.d.ts +5 -0
- package/lib/profiles/phone-verification.js +17 -0
- package/lib/types.d.ts +41 -0
- package/lib/types.js +2 -0
- package/lib/vc-types.d.ts +7 -0
- package/lib/vc-types.js +9 -0
- package/package.json +53 -0
- package/src/contexts/ccda-did-v1.json +30 -0
- package/src/contexts/ccda-vc-v1.json +20 -0
- package/src/contexts/jdid-did-v1.json +30 -0
- package/src/contexts/jdid-vc-v1.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# @jccdex/vc-vocabularies
|
|
2
|
+
|
|
3
|
+
VC 业务词汇表与签发 Profile,配合 [`@jccdex/did`](../did) 的 `issueVC()` 使用。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
yarn add @jccdex/vc-vocabularies @jccdex/did
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 快速开始
|
|
12
|
+
|
|
13
|
+
使用 Profile 组装签发描述符,再交给 DID SDK 签名:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { issueVC } from "@jccdex/did";
|
|
17
|
+
import { buildNftOwnershipDescriptor } from "@jccdex/vc-vocabularies";
|
|
18
|
+
|
|
19
|
+
const descriptor = buildNftOwnershipDescriptor(
|
|
20
|
+
"ccdao", // 品牌:ccdao | jdid
|
|
21
|
+
{
|
|
22
|
+
id: holderDid,
|
|
23
|
+
owner: holderDid,
|
|
24
|
+
chainId: 1,
|
|
25
|
+
tokenId: "123",
|
|
26
|
+
contractAddress: "0x...",
|
|
27
|
+
standard: "ERC-721",
|
|
28
|
+
status: "Active",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: `${holderDid}#vc-1`,
|
|
32
|
+
expirationDate: "2099-01-01T00:00:00.000Z",
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const vcJSON = await issueVC(descriptor, { sign, keyDoc });
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`subject` 由调用方按业务填写;Profile 负责组装 `types` 与 `@context`,签名由 `@jccdex/did` 完成。
|
|
40
|
+
|
|
41
|
+
## 主要 API
|
|
42
|
+
|
|
43
|
+
| 导出 | 说明 |
|
|
44
|
+
|------|------|
|
|
45
|
+
| `buildNftOwnershipDescriptor` | NFT 所有权 VC |
|
|
46
|
+
| `buildNftUsageAuthorizationDescriptor` | NFT 授权 VC |
|
|
47
|
+
| `buildPhoneVerificationDescriptor` | 电话验证 VC |
|
|
48
|
+
| `buildInlineContext` | 按字段生成最小内联 `@context` |
|
|
49
|
+
| `VC_TYPES` | VC 业务类型常量 |
|
|
50
|
+
| `getNftOwnershipContext` 等 | 按品牌获取内联 context 对象 |
|
|
51
|
+
|
|
52
|
+
品牌 ID:`"ccdao"`(`ccda.ooo`)、`"jdid"`(`jdid.cn`)。
|
|
53
|
+
|
|
54
|
+
## 自定义 Descriptor
|
|
55
|
+
|
|
56
|
+
不经过 Profile 时,可自行组装后调用 `issueVC`:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import {
|
|
60
|
+
buildInlineContext,
|
|
61
|
+
VC_TYPES,
|
|
62
|
+
W3C_VC_CONTEXT_URL,
|
|
63
|
+
} from "@jccdex/vc-vocabularies";
|
|
64
|
+
|
|
65
|
+
const descriptor = {
|
|
66
|
+
types: [VC_TYPES.NFT_OWNERSHIP],
|
|
67
|
+
contexts: [
|
|
68
|
+
W3C_VC_CONTEXT_URL,
|
|
69
|
+
buildInlineContext("jdid", {
|
|
70
|
+
types: ["NFTOwnership"],
|
|
71
|
+
fields: ["chainId", "tokenId", "tokenName", "nftIssuer", "owner", "standard", "status"],
|
|
72
|
+
}),
|
|
73
|
+
],
|
|
74
|
+
subject: { id: holderDid, /* ... */ },
|
|
75
|
+
id: `${holderDid}#vc-1`,
|
|
76
|
+
expirationDate: "2099-01-01T00:00:00.000Z",
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 词汇表 JSON(高级)
|
|
81
|
+
|
|
82
|
+
验签缓存与品牌服务器部署使用 `contexts/*.json`,可通过子路径引用:
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
import jdidDidV1 from "@jccdex/vc-vocabularies/contexts/jdid-did-v1.json";
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
一般由 `@jccdex/did` 内部引用,应用层通常无需直接 import。
|
|
89
|
+
|
|
90
|
+
## 开发
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
yarn build
|
|
94
|
+
yarn test
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 相关包
|
|
98
|
+
|
|
99
|
+
- [`@jccdex/did`](../did) — DID 文档与 VC 签发/验签
|
|
100
|
+
- [`did_DApp`](../did_DApp) — 参考集成示例
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CCDAO_VC_VOCAB_URL = exports.CCDAO_DID_VOCAB_URL = void 0;
|
|
4
|
+
/** CCDAO 品牌(EVM 链)的 DID / VC 词汇表根 URL,术语 URI 形如 {url}#tokenId */
|
|
5
|
+
exports.CCDAO_DID_VOCAB_URL = "https://ccda.ooo/did/v1";
|
|
6
|
+
exports.CCDAO_VC_VOCAB_URL = "https://ccda.ooo/vc/v1";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JDID_VC_VOCAB_URL = exports.JDID_DID_VOCAB_URL = void 0;
|
|
4
|
+
/** JDID 品牌(SWTC 链)的 DID / VC 词汇表根 URL */
|
|
5
|
+
exports.JDID_DID_VOCAB_URL = "https://jdid.cn/did/v1";
|
|
6
|
+
exports.JDID_VC_VOCAB_URL = "https://jdid.cn/vc/v1";
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jccdex/vc-vocabularies 包入口。
|
|
3
|
+
*
|
|
4
|
+
* 职责:品牌词汇表 URL、内联 context 预设、VC 类型常量、签发 Profile。
|
|
5
|
+
* 协议能力(issueVC / verifyVC)在 @jccdex/did,本包只描述「签什么」不描述「怎么签」。
|
|
6
|
+
*/
|
|
7
|
+
export * from "./brands/ccdao.js";
|
|
8
|
+
export * from "./brands/jdid.js";
|
|
9
|
+
export * from "./inline-contexts.js";
|
|
10
|
+
export * from "./types.js";
|
|
11
|
+
export * from "./vc-types.js";
|
|
12
|
+
export { buildNftOwnershipDescriptor } from "./profiles/nft-ownership.js";
|
|
13
|
+
export { buildNftUsageAuthorizationDescriptor } from "./profiles/nft-usage-authorization.js";
|
|
14
|
+
export { buildPhoneVerificationDescriptor } from "./profiles/phone-verification.js";
|
|
15
|
+
import { buildNftOwnershipDescriptor } from "./profiles/nft-ownership.js";
|
|
16
|
+
import { buildNftUsageAuthorizationDescriptor } from "./profiles/nft-usage-authorization.js";
|
|
17
|
+
import { buildPhoneVerificationDescriptor } from "./profiles/phone-verification.js";
|
|
18
|
+
/** 按业务场景索引的 Profile 注册表,便于 DApp 动态选择签发模板 */
|
|
19
|
+
export declare const profiles: {
|
|
20
|
+
nftOwnership: {
|
|
21
|
+
buildDescriptor: typeof buildNftOwnershipDescriptor;
|
|
22
|
+
};
|
|
23
|
+
nftUsageAuthorization: {
|
|
24
|
+
buildDescriptor: typeof buildNftUsageAuthorizationDescriptor;
|
|
25
|
+
};
|
|
26
|
+
phoneVerification: {
|
|
27
|
+
buildDescriptor: typeof buildPhoneVerificationDescriptor;
|
|
28
|
+
};
|
|
29
|
+
};
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.profiles = exports.buildPhoneVerificationDescriptor = exports.buildNftUsageAuthorizationDescriptor = exports.buildNftOwnershipDescriptor = void 0;
|
|
18
|
+
/**
|
|
19
|
+
* @jccdex/vc-vocabularies 包入口。
|
|
20
|
+
*
|
|
21
|
+
* 职责:品牌词汇表 URL、内联 context 预设、VC 类型常量、签发 Profile。
|
|
22
|
+
* 协议能力(issueVC / verifyVC)在 @jccdex/did,本包只描述「签什么」不描述「怎么签」。
|
|
23
|
+
*/
|
|
24
|
+
__exportStar(require("./brands/ccdao.js"), exports);
|
|
25
|
+
__exportStar(require("./brands/jdid.js"), exports);
|
|
26
|
+
__exportStar(require("./inline-contexts.js"), exports);
|
|
27
|
+
__exportStar(require("./types.js"), exports);
|
|
28
|
+
__exportStar(require("./vc-types.js"), exports);
|
|
29
|
+
var nft_ownership_js_1 = require("./profiles/nft-ownership.js");
|
|
30
|
+
Object.defineProperty(exports, "buildNftOwnershipDescriptor", { enumerable: true, get: function () { return nft_ownership_js_1.buildNftOwnershipDescriptor; } });
|
|
31
|
+
var nft_usage_authorization_js_1 = require("./profiles/nft-usage-authorization.js");
|
|
32
|
+
Object.defineProperty(exports, "buildNftUsageAuthorizationDescriptor", { enumerable: true, get: function () { return nft_usage_authorization_js_1.buildNftUsageAuthorizationDescriptor; } });
|
|
33
|
+
var phone_verification_js_1 = require("./profiles/phone-verification.js");
|
|
34
|
+
Object.defineProperty(exports, "buildPhoneVerificationDescriptor", { enumerable: true, get: function () { return phone_verification_js_1.buildPhoneVerificationDescriptor; } });
|
|
35
|
+
const nft_ownership_js_2 = require("./profiles/nft-ownership.js");
|
|
36
|
+
const nft_usage_authorization_js_2 = require("./profiles/nft-usage-authorization.js");
|
|
37
|
+
const phone_verification_js_2 = require("./profiles/phone-verification.js");
|
|
38
|
+
/** 按业务场景索引的 Profile 注册表,便于 DApp 动态选择签发模板 */
|
|
39
|
+
exports.profiles = {
|
|
40
|
+
nftOwnership: { buildDescriptor: nft_ownership_js_2.buildNftOwnershipDescriptor },
|
|
41
|
+
nftUsageAuthorization: {
|
|
42
|
+
buildDescriptor: nft_usage_authorization_js_2.buildNftUsageAuthorizationDescriptor
|
|
43
|
+
},
|
|
44
|
+
phoneVerification: { buildDescriptor: phone_verification_js_2.buildPhoneVerificationDescriptor }
|
|
45
|
+
};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 品牌内联 context 定义。
|
|
3
|
+
*
|
|
4
|
+
* 品牌(ccdao / jdid)仅区分国内外词汇表 URL 命名空间,术语字段集相同。
|
|
5
|
+
* 链差异(EVM 用 contractAddress、SWTC 用 tokenName/nftIssuer)由应用层 subject 决定,
|
|
6
|
+
* 不在词汇层按品牌或链裁剪。
|
|
7
|
+
*
|
|
8
|
+
* 维护原则:只增不删、不改 URI(append-only)。
|
|
9
|
+
*/
|
|
10
|
+
import type { BrandId } from "./types.js";
|
|
11
|
+
export declare const W3C_VC_CONTEXT_URL = "https://www.w3.org/2018/credentials/v1";
|
|
12
|
+
/** 统一 NFTOwnership 术语集,品牌只替换 URL 前缀 */
|
|
13
|
+
export declare function buildNftOwnershipContext(brand: BrandId): {
|
|
14
|
+
NFTOwnership: string;
|
|
15
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
16
|
+
chainId: string;
|
|
17
|
+
contractAddress: string;
|
|
18
|
+
tokenName: string;
|
|
19
|
+
tokenId: string;
|
|
20
|
+
owner: string;
|
|
21
|
+
nftIssuer: string;
|
|
22
|
+
standard: string;
|
|
23
|
+
status: string;
|
|
24
|
+
};
|
|
25
|
+
/** 统一 NFTUsageAuthorization 术语集 */
|
|
26
|
+
export declare function buildNftUsageAuthorizationContext(brand: BrandId): {
|
|
27
|
+
NFTUsageAuthorization: string;
|
|
28
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
29
|
+
grantee: string;
|
|
30
|
+
usageRights: string;
|
|
31
|
+
restrictions: {
|
|
32
|
+
"@id": string;
|
|
33
|
+
"@context": {
|
|
34
|
+
commercial: string;
|
|
35
|
+
derivative: string;
|
|
36
|
+
sublicense: string;
|
|
37
|
+
territories: string;
|
|
38
|
+
platforms: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
chainId: string;
|
|
42
|
+
contractAddress: string;
|
|
43
|
+
tokenName: string;
|
|
44
|
+
tokenId: string;
|
|
45
|
+
owner: string;
|
|
46
|
+
nftIssuer: string;
|
|
47
|
+
standard: string;
|
|
48
|
+
status: string;
|
|
49
|
+
};
|
|
50
|
+
/** DID 文档 version 内联 context */
|
|
51
|
+
export declare function buildVersionContext(brand: BrandId): {
|
|
52
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
53
|
+
credentials: string;
|
|
54
|
+
};
|
|
55
|
+
/** 电话验证 VC 术语集(两品牌结构相同,仅 URL 不同) */
|
|
56
|
+
export declare function buildPhoneVerificationContext(brand: BrandId): {
|
|
57
|
+
PhoneVerificationCredential: string;
|
|
58
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
59
|
+
standard: string;
|
|
60
|
+
status: string;
|
|
61
|
+
verificationMethod: string;
|
|
62
|
+
verificationProcess: {
|
|
63
|
+
"@id": string;
|
|
64
|
+
"@context": {
|
|
65
|
+
verifiedAt: string;
|
|
66
|
+
updateAt: string;
|
|
67
|
+
verifierId: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
/** 便捷 getter,供 DApp / Profile 使用 */
|
|
72
|
+
export declare const getNftOwnershipContext: typeof buildNftOwnershipContext;
|
|
73
|
+
export declare const getNftUsageAuthorizationContext: typeof buildNftUsageAuthorizationContext;
|
|
74
|
+
export declare const getVersionContext: typeof buildVersionContext;
|
|
75
|
+
export declare const getPhoneVerificationContext: typeof buildPhoneVerificationContext;
|
|
76
|
+
/** 向后兼容的具名导出(结构已统一,仅 URL 命名空间不同) */
|
|
77
|
+
export declare const CCDAO_NFT_OWNERSHIP_CONTEXT: {
|
|
78
|
+
NFTOwnership: string;
|
|
79
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
80
|
+
chainId: string;
|
|
81
|
+
contractAddress: string;
|
|
82
|
+
tokenName: string;
|
|
83
|
+
tokenId: string;
|
|
84
|
+
owner: string;
|
|
85
|
+
nftIssuer: string;
|
|
86
|
+
standard: string;
|
|
87
|
+
status: string;
|
|
88
|
+
};
|
|
89
|
+
export declare const JDID_NFT_OWNERSHIP_CONTEXT: {
|
|
90
|
+
NFTOwnership: string;
|
|
91
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
92
|
+
chainId: string;
|
|
93
|
+
contractAddress: string;
|
|
94
|
+
tokenName: string;
|
|
95
|
+
tokenId: string;
|
|
96
|
+
owner: string;
|
|
97
|
+
nftIssuer: string;
|
|
98
|
+
standard: string;
|
|
99
|
+
status: string;
|
|
100
|
+
};
|
|
101
|
+
export declare const CCDAO_NFT_USAGE_AUTHORIZATION_CONTEXT: {
|
|
102
|
+
NFTUsageAuthorization: string;
|
|
103
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
104
|
+
grantee: string;
|
|
105
|
+
usageRights: string;
|
|
106
|
+
restrictions: {
|
|
107
|
+
"@id": string;
|
|
108
|
+
"@context": {
|
|
109
|
+
commercial: string;
|
|
110
|
+
derivative: string;
|
|
111
|
+
sublicense: string;
|
|
112
|
+
territories: string;
|
|
113
|
+
platforms: string;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
chainId: string;
|
|
117
|
+
contractAddress: string;
|
|
118
|
+
tokenName: string;
|
|
119
|
+
tokenId: string;
|
|
120
|
+
owner: string;
|
|
121
|
+
nftIssuer: string;
|
|
122
|
+
standard: string;
|
|
123
|
+
status: string;
|
|
124
|
+
};
|
|
125
|
+
export declare const JDID_NFT_USAGE_AUTHORIZATION_CONTEXT: {
|
|
126
|
+
NFTUsageAuthorization: string;
|
|
127
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
128
|
+
grantee: string;
|
|
129
|
+
usageRights: string;
|
|
130
|
+
restrictions: {
|
|
131
|
+
"@id": string;
|
|
132
|
+
"@context": {
|
|
133
|
+
commercial: string;
|
|
134
|
+
derivative: string;
|
|
135
|
+
sublicense: string;
|
|
136
|
+
territories: string;
|
|
137
|
+
platforms: string;
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
chainId: string;
|
|
141
|
+
contractAddress: string;
|
|
142
|
+
tokenName: string;
|
|
143
|
+
tokenId: string;
|
|
144
|
+
owner: string;
|
|
145
|
+
nftIssuer: string;
|
|
146
|
+
standard: string;
|
|
147
|
+
status: string;
|
|
148
|
+
};
|
|
149
|
+
export declare const CCDAO_VERSION_CONTEXT: {
|
|
150
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
151
|
+
credentials: string;
|
|
152
|
+
};
|
|
153
|
+
export declare const JDID_VERSION_CONTEXT: {
|
|
154
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
155
|
+
credentials: string;
|
|
156
|
+
};
|
|
157
|
+
export declare const CCDAO_PHONE_VERIFICATION_CONTEXT: {
|
|
158
|
+
PhoneVerificationCredential: string;
|
|
159
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
160
|
+
standard: string;
|
|
161
|
+
status: string;
|
|
162
|
+
verificationMethod: string;
|
|
163
|
+
verificationProcess: {
|
|
164
|
+
"@id": string;
|
|
165
|
+
"@context": {
|
|
166
|
+
verifiedAt: string;
|
|
167
|
+
updateAt: string;
|
|
168
|
+
verifierId: string;
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
export declare const JDID_PHONE_VERIFICATION_CONTEXT: {
|
|
173
|
+
PhoneVerificationCredential: string;
|
|
174
|
+
version: "https://ccda.ooo/did/v1" | "https://jdid.cn/did/v1";
|
|
175
|
+
standard: string;
|
|
176
|
+
status: string;
|
|
177
|
+
verificationMethod: string;
|
|
178
|
+
verificationProcess: {
|
|
179
|
+
"@id": string;
|
|
180
|
+
"@context": {
|
|
181
|
+
verifiedAt: string;
|
|
182
|
+
updateAt: string;
|
|
183
|
+
verifierId: string;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* 按本次签发需要的字段,生成最小内联 @context 对象。
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* // 仅解释 tokenId、owner,不会带上 contractAddress
|
|
192
|
+
* buildInlineContext("ccdao", { types: ["NFTOwnership"], fields: ["tokenId", "owner"] })
|
|
193
|
+
*
|
|
194
|
+
* 未传 fields 时返回该类型的完整预设(与 Profile 行为一致)。
|
|
195
|
+
*/
|
|
196
|
+
export declare function buildInlineContext(brand: BrandId, opts: {
|
|
197
|
+
types: string[];
|
|
198
|
+
fields?: string[];
|
|
199
|
+
}): Record<string, unknown>;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JDID_PHONE_VERIFICATION_CONTEXT = exports.CCDAO_PHONE_VERIFICATION_CONTEXT = exports.JDID_VERSION_CONTEXT = exports.CCDAO_VERSION_CONTEXT = exports.JDID_NFT_USAGE_AUTHORIZATION_CONTEXT = exports.CCDAO_NFT_USAGE_AUTHORIZATION_CONTEXT = exports.JDID_NFT_OWNERSHIP_CONTEXT = exports.CCDAO_NFT_OWNERSHIP_CONTEXT = exports.getPhoneVerificationContext = exports.getVersionContext = exports.getNftUsageAuthorizationContext = exports.getNftOwnershipContext = exports.W3C_VC_CONTEXT_URL = void 0;
|
|
4
|
+
exports.buildNftOwnershipContext = buildNftOwnershipContext;
|
|
5
|
+
exports.buildNftUsageAuthorizationContext = buildNftUsageAuthorizationContext;
|
|
6
|
+
exports.buildVersionContext = buildVersionContext;
|
|
7
|
+
exports.buildPhoneVerificationContext = buildPhoneVerificationContext;
|
|
8
|
+
exports.buildInlineContext = buildInlineContext;
|
|
9
|
+
const ccdao_js_1 = require("./brands/ccdao.js");
|
|
10
|
+
const jdid_js_1 = require("./brands/jdid.js");
|
|
11
|
+
exports.W3C_VC_CONTEXT_URL = "https://www.w3.org/2018/credentials/v1";
|
|
12
|
+
const BRAND_URLS = {
|
|
13
|
+
ccdao: { did: ccdao_js_1.CCDAO_DID_VOCAB_URL, vc: ccdao_js_1.CCDAO_VC_VOCAB_URL },
|
|
14
|
+
jdid: { did: jdid_js_1.JDID_DID_VOCAB_URL, vc: jdid_js_1.JDID_VC_VOCAB_URL }
|
|
15
|
+
};
|
|
16
|
+
function vocab(brand) {
|
|
17
|
+
return BRAND_URLS[brand];
|
|
18
|
+
}
|
|
19
|
+
/** 统一 NFTOwnership 术语集,品牌只替换 URL 前缀 */
|
|
20
|
+
function buildNftOwnershipContext(brand) {
|
|
21
|
+
const { did, vc } = vocab(brand);
|
|
22
|
+
return {
|
|
23
|
+
NFTOwnership: `${vc}#NFTOwnership`,
|
|
24
|
+
version: did,
|
|
25
|
+
chainId: `${did}#chainId`,
|
|
26
|
+
contractAddress: `${did}#contractAddress`,
|
|
27
|
+
tokenName: `${did}#tokenName`,
|
|
28
|
+
tokenId: `${did}#tokenId`,
|
|
29
|
+
owner: `${did}#owner`,
|
|
30
|
+
nftIssuer: `${did}#nftIssuer`,
|
|
31
|
+
standard: `${did}#standard`,
|
|
32
|
+
status: `${did}#status`
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** 统一 NFTUsageAuthorization 术语集 */
|
|
36
|
+
function buildNftUsageAuthorizationContext(brand) {
|
|
37
|
+
const { did, vc } = vocab(brand);
|
|
38
|
+
return {
|
|
39
|
+
NFTUsageAuthorization: `${vc}#NFTUsageAuthorization`,
|
|
40
|
+
version: did,
|
|
41
|
+
grantee: `${vc}#grantee`,
|
|
42
|
+
usageRights: `${vc}#usageRights`,
|
|
43
|
+
restrictions: {
|
|
44
|
+
"@id": `${vc}#restrictions`,
|
|
45
|
+
"@context": {
|
|
46
|
+
commercial: `${vc}#commercial`,
|
|
47
|
+
derivative: `${vc}#derivative`,
|
|
48
|
+
sublicense: `${vc}#sublicense`,
|
|
49
|
+
territories: `${vc}#territories`,
|
|
50
|
+
platforms: `${vc}#platforms`
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
chainId: `${did}#chainId`,
|
|
54
|
+
contractAddress: `${did}#contractAddress`,
|
|
55
|
+
tokenName: `${did}#tokenName`,
|
|
56
|
+
tokenId: `${did}#tokenId`,
|
|
57
|
+
owner: `${did}#owner`,
|
|
58
|
+
nftIssuer: `${did}#nftIssuer`,
|
|
59
|
+
standard: `${did}#standard`,
|
|
60
|
+
status: `${did}#status`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** DID 文档 version 内联 context */
|
|
64
|
+
function buildVersionContext(brand) {
|
|
65
|
+
const { did } = vocab(brand);
|
|
66
|
+
return {
|
|
67
|
+
version: did,
|
|
68
|
+
credentials: `${did}#credentials`
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** 电话验证 VC 术语集(两品牌结构相同,仅 URL 不同) */
|
|
72
|
+
function buildPhoneVerificationContext(brand) {
|
|
73
|
+
const { did, vc } = vocab(brand);
|
|
74
|
+
return {
|
|
75
|
+
PhoneVerificationCredential: `${vc}#PhoneVerificationCredential`,
|
|
76
|
+
version: did,
|
|
77
|
+
standard: `${did}#standard`,
|
|
78
|
+
status: `${did}#status`,
|
|
79
|
+
verificationMethod: `${did}#verificationMethod`,
|
|
80
|
+
verificationProcess: {
|
|
81
|
+
"@id": `${did}#verificationProcess`,
|
|
82
|
+
"@context": {
|
|
83
|
+
verifiedAt: `${did}#verifiedAt`,
|
|
84
|
+
updateAt: `${did}#updateAt`,
|
|
85
|
+
verifierId: `${did}#verifierId`
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** 便捷 getter,供 DApp / Profile 使用 */
|
|
91
|
+
exports.getNftOwnershipContext = buildNftOwnershipContext;
|
|
92
|
+
exports.getNftUsageAuthorizationContext = buildNftUsageAuthorizationContext;
|
|
93
|
+
exports.getVersionContext = buildVersionContext;
|
|
94
|
+
exports.getPhoneVerificationContext = buildPhoneVerificationContext;
|
|
95
|
+
/** 向后兼容的具名导出(结构已统一,仅 URL 命名空间不同) */
|
|
96
|
+
exports.CCDAO_NFT_OWNERSHIP_CONTEXT = buildNftOwnershipContext("ccdao");
|
|
97
|
+
exports.JDID_NFT_OWNERSHIP_CONTEXT = buildNftOwnershipContext("jdid");
|
|
98
|
+
exports.CCDAO_NFT_USAGE_AUTHORIZATION_CONTEXT = buildNftUsageAuthorizationContext("ccdao");
|
|
99
|
+
exports.JDID_NFT_USAGE_AUTHORIZATION_CONTEXT = buildNftUsageAuthorizationContext("jdid");
|
|
100
|
+
exports.CCDAO_VERSION_CONTEXT = buildVersionContext("ccdao");
|
|
101
|
+
exports.JDID_VERSION_CONTEXT = buildVersionContext("jdid");
|
|
102
|
+
exports.CCDAO_PHONE_VERIFICATION_CONTEXT = buildPhoneVerificationContext("ccdao");
|
|
103
|
+
exports.JDID_PHONE_VERIFICATION_CONTEXT = buildPhoneVerificationContext("jdid");
|
|
104
|
+
const VC_TYPE_BUILDERS = {
|
|
105
|
+
NFTOwnership: buildNftOwnershipContext,
|
|
106
|
+
NFTUsageAuthorization: buildNftUsageAuthorizationContext,
|
|
107
|
+
PhoneVerificationCredential: buildPhoneVerificationContext
|
|
108
|
+
};
|
|
109
|
+
/** 从完整词汇表中仅取出 fields 列出的键,用于「最小内联 context」 */
|
|
110
|
+
function pickFields(source, fields) {
|
|
111
|
+
const result = {};
|
|
112
|
+
for (const field of fields) {
|
|
113
|
+
if (field in source) {
|
|
114
|
+
result[field] = source[field];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 按本次签发需要的字段,生成最小内联 @context 对象。
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* // 仅解释 tokenId、owner,不会带上 contractAddress
|
|
124
|
+
* buildInlineContext("ccdao", { types: ["NFTOwnership"], fields: ["tokenId", "owner"] })
|
|
125
|
+
*
|
|
126
|
+
* 未传 fields 时返回该类型的完整预设(与 Profile 行为一致)。
|
|
127
|
+
*/
|
|
128
|
+
function buildInlineContext(brand, opts) {
|
|
129
|
+
const merged = {};
|
|
130
|
+
for (const type of opts.types) {
|
|
131
|
+
const builder = VC_TYPE_BUILDERS[type];
|
|
132
|
+
if (!builder) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const preset = builder(brand);
|
|
136
|
+
const subset = opts.fields?.length
|
|
137
|
+
? pickFields(preset, [
|
|
138
|
+
...opts.types,
|
|
139
|
+
"version",
|
|
140
|
+
...opts.fields
|
|
141
|
+
])
|
|
142
|
+
: preset;
|
|
143
|
+
Object.assign(merged, subset);
|
|
144
|
+
}
|
|
145
|
+
return merged;
|
|
146
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BrandId, DescriptorMeta, VCIssuanceDescriptor } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* NFTOwnership 签发 Profile。
|
|
4
|
+
* 词汇表与链无关;subject 中填 contractAddress 或 tokenName/nftIssuer 由 DApp 策略决定。
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildNftOwnershipDescriptor(brand: BrandId, subject: Record<string, unknown> & {
|
|
7
|
+
id: string;
|
|
8
|
+
}, meta: DescriptorMeta): VCIssuanceDescriptor;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildNftOwnershipDescriptor = buildNftOwnershipDescriptor;
|
|
4
|
+
const inline_contexts_js_1 = require("../inline-contexts.js");
|
|
5
|
+
const vc_types_js_1 = require("../vc-types.js");
|
|
6
|
+
/**
|
|
7
|
+
* NFTOwnership 签发 Profile。
|
|
8
|
+
* 词汇表与链无关;subject 中填 contractAddress 或 tokenName/nftIssuer 由 DApp 策略决定。
|
|
9
|
+
*/
|
|
10
|
+
function buildNftOwnershipDescriptor(brand, subject, meta) {
|
|
11
|
+
return {
|
|
12
|
+
types: [vc_types_js_1.VC_TYPES.NFT_OWNERSHIP],
|
|
13
|
+
contexts: [inline_contexts_js_1.W3C_VC_CONTEXT_URL, (0, inline_contexts_js_1.getNftOwnershipContext)(brand)],
|
|
14
|
+
subject,
|
|
15
|
+
id: meta.id,
|
|
16
|
+
expirationDate: meta.expirationDate,
|
|
17
|
+
issuanceDate: meta.issuanceDate,
|
|
18
|
+
issuer: meta.issuer
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BrandId, DescriptorMeta, VCIssuanceDescriptor } from "../types.js";
|
|
2
|
+
/** NFT 授权类 VC 签发 Profile */
|
|
3
|
+
export declare function buildNftUsageAuthorizationDescriptor(brand: BrandId, subject: Record<string, unknown> & {
|
|
4
|
+
id: string;
|
|
5
|
+
}, meta: DescriptorMeta): VCIssuanceDescriptor;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildNftUsageAuthorizationDescriptor = buildNftUsageAuthorizationDescriptor;
|
|
4
|
+
const inline_contexts_js_1 = require("../inline-contexts.js");
|
|
5
|
+
const vc_types_js_1 = require("../vc-types.js");
|
|
6
|
+
/** NFT 授权类 VC 签发 Profile */
|
|
7
|
+
function buildNftUsageAuthorizationDescriptor(brand, subject, meta) {
|
|
8
|
+
return {
|
|
9
|
+
types: [vc_types_js_1.VC_TYPES.NFT_USAGE_AUTHORIZATION],
|
|
10
|
+
contexts: [inline_contexts_js_1.W3C_VC_CONTEXT_URL, (0, inline_contexts_js_1.getNftUsageAuthorizationContext)(brand)],
|
|
11
|
+
subject,
|
|
12
|
+
id: meta.id,
|
|
13
|
+
expirationDate: meta.expirationDate,
|
|
14
|
+
issuanceDate: meta.issuanceDate,
|
|
15
|
+
issuer: meta.issuer
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BrandId, DescriptorMeta, VCIssuanceDescriptor } from "../types.js";
|
|
2
|
+
/** 电话验证 VC 签发 Profile;两品牌词汇结构相同,仅 URL 命名空间不同 */
|
|
3
|
+
export declare function buildPhoneVerificationDescriptor(brand: BrandId, subject: Record<string, unknown> & {
|
|
4
|
+
id: string;
|
|
5
|
+
}, meta: DescriptorMeta): VCIssuanceDescriptor;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildPhoneVerificationDescriptor = buildPhoneVerificationDescriptor;
|
|
4
|
+
const inline_contexts_js_1 = require("../inline-contexts.js");
|
|
5
|
+
const vc_types_js_1 = require("../vc-types.js");
|
|
6
|
+
/** 电话验证 VC 签发 Profile;两品牌词汇结构相同,仅 URL 命名空间不同 */
|
|
7
|
+
function buildPhoneVerificationDescriptor(brand, subject, meta) {
|
|
8
|
+
return {
|
|
9
|
+
types: [vc_types_js_1.VC_TYPES.PHONE_VERIFICATION],
|
|
10
|
+
contexts: [inline_contexts_js_1.W3C_VC_CONTEXT_URL, (0, inline_contexts_js_1.getPhoneVerificationContext)(brand)],
|
|
11
|
+
subject,
|
|
12
|
+
id: meta.id,
|
|
13
|
+
expirationDate: meta.expirationDate,
|
|
14
|
+
issuanceDate: meta.issuanceDate,
|
|
15
|
+
issuer: meta.issuer
|
|
16
|
+
};
|
|
17
|
+
}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** 产品品牌:决定使用哪套词汇表域名(ccda.ooo / jdid.cn) */
|
|
2
|
+
export type BrandId = "ccdao" | "jdid";
|
|
3
|
+
/**
|
|
4
|
+
* VC @context 数组中的单项:
|
|
5
|
+
* - string:远程词汇表 URL(如 W3C credentials/v1)
|
|
6
|
+
* - object:内联术语映射(签发时写入 VC,验签不依赖 SDK 版本)
|
|
7
|
+
*/
|
|
8
|
+
export type VCContextValue = string | Record<string, unknown>;
|
|
9
|
+
/**
|
|
10
|
+
* 签发描述符:交给 @jccdex/did 的 issueVC(),与具体业务范式(NFT/电话等)无关。
|
|
11
|
+
* Profile 函数(如 buildNftOwnershipDescriptor)负责组装此结构。
|
|
12
|
+
*/
|
|
13
|
+
export interface VCIssuanceDescriptor {
|
|
14
|
+
/** 业务类型字符串,如 NFTOwnership;不含 VerifiableCredential(issueVC 会自动补上) */
|
|
15
|
+
types: string[];
|
|
16
|
+
/** W3C 标准 URL + 品牌内联 context */
|
|
17
|
+
contexts: VCContextValue[];
|
|
18
|
+
/**
|
|
19
|
+
* credentialSubject。协议层仅要求含 id(一般为 holder DID);
|
|
20
|
+
* 其余字段(tokenId、verificationProcess 等)由业务 Profile 填入。
|
|
21
|
+
*/
|
|
22
|
+
subject: Record<string, unknown> & {
|
|
23
|
+
id: string;
|
|
24
|
+
};
|
|
25
|
+
/** VC 凭证 id,如 did:ethr:0x...#vc-1 */
|
|
26
|
+
id?: string;
|
|
27
|
+
issuer?: string | Record<string, unknown>;
|
|
28
|
+
issuanceDate?: string;
|
|
29
|
+
expirationDate?: string;
|
|
30
|
+
credentialStatus?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Profile 元数据:与 subject 业务字段分离。
|
|
34
|
+
* id / expirationDate 通常由 DApp 策略生成(如 generateVCId、默认有效期)。
|
|
35
|
+
*/
|
|
36
|
+
export interface DescriptorMeta {
|
|
37
|
+
id: string;
|
|
38
|
+
expirationDate: string;
|
|
39
|
+
issuanceDate?: string;
|
|
40
|
+
issuer?: string | Record<string, unknown>;
|
|
41
|
+
}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** 已知 VC 业务类型常量;新增类型在此追加即可,无需改 @jccdex/did */
|
|
2
|
+
export declare const VC_TYPES: {
|
|
3
|
+
readonly NFT_OWNERSHIP: "NFTOwnership";
|
|
4
|
+
readonly NFT_USAGE_AUTHORIZATION: "NFTUsageAuthorization";
|
|
5
|
+
readonly PHONE_VERIFICATION: "PhoneVerificationCredential";
|
|
6
|
+
};
|
|
7
|
+
export type VCType = (typeof VC_TYPES)[keyof typeof VC_TYPES];
|
package/lib/vc-types.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VC_TYPES = void 0;
|
|
4
|
+
/** 已知 VC 业务类型常量;新增类型在此追加即可,无需改 @jccdex/did */
|
|
5
|
+
exports.VC_TYPES = {
|
|
6
|
+
NFT_OWNERSHIP: "NFTOwnership",
|
|
7
|
+
NFT_USAGE_AUTHORIZATION: "NFTUsageAuthorization",
|
|
8
|
+
PHONE_VERIFICATION: "PhoneVerificationCredential"
|
|
9
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jccdex/vc-vocabularies",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "VC vocabulary and issuance profiles for JCCDEx DID ecosystem",
|
|
5
|
+
"main": "./lib/index.js",
|
|
6
|
+
"types": "./lib/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./lib/index.d.ts",
|
|
10
|
+
"import": "./lib/index.js",
|
|
11
|
+
"require": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./contexts/ccda-did-v1.json": {
|
|
14
|
+
"import": "./src/contexts/ccda-did-v1.json",
|
|
15
|
+
"require": "./src/contexts/ccda-did-v1.json",
|
|
16
|
+
"default": "./src/contexts/ccda-did-v1.json"
|
|
17
|
+
},
|
|
18
|
+
"./contexts/ccda-vc-v1.json": {
|
|
19
|
+
"import": "./src/contexts/ccda-vc-v1.json",
|
|
20
|
+
"require": "./src/contexts/ccda-vc-v1.json",
|
|
21
|
+
"default": "./src/contexts/ccda-vc-v1.json"
|
|
22
|
+
},
|
|
23
|
+
"./contexts/jdid-did-v1.json": {
|
|
24
|
+
"import": "./src/contexts/jdid-did-v1.json",
|
|
25
|
+
"require": "./src/contexts/jdid-did-v1.json",
|
|
26
|
+
"default": "./src/contexts/jdid-did-v1.json"
|
|
27
|
+
},
|
|
28
|
+
"./contexts/jdid-vc-v1.json": {
|
|
29
|
+
"import": "./src/contexts/jdid-vc-v1.json",
|
|
30
|
+
"require": "./src/contexts/jdid-vc-v1.json",
|
|
31
|
+
"default": "./src/contexts/jdid-vc-v1.json"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"lib",
|
|
36
|
+
"src/contexts"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"clean": "rm -rf lib",
|
|
43
|
+
"build": "yarn clean && tsc -p tsconfig.build.json",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest --watch"
|
|
46
|
+
},
|
|
47
|
+
"author": "JCCDex",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"typescript": "^5.9.2",
|
|
51
|
+
"vitest": "^4.1.0"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": {
|
|
3
|
+
"@version": 1.1,
|
|
4
|
+
"@protected": true,
|
|
5
|
+
"id": "@id",
|
|
6
|
+
"type": "@type",
|
|
7
|
+
"NFTOwnership": "https://ccda.ooo/vc/v1#NFTOwnership",
|
|
8
|
+
"NFTUsageAuthorization": "https://ccda.ooo/vc/v1#NFTUsageAuthorization",
|
|
9
|
+
"PhoneVerificationCredential": "https://ccda.ooo/vc/v1#PhoneVerificationCredential",
|
|
10
|
+
"version": "https://ccda.ooo/did/v1#version",
|
|
11
|
+
"chainId": "https://ccda.ooo/did/v1#chainId",
|
|
12
|
+
"contractAddress": "https://ccda.ooo/did/v1#contractAddress",
|
|
13
|
+
"tokenName": "https://ccda.ooo/did/v1#tokenName",
|
|
14
|
+
"tokenId": "https://ccda.ooo/did/v1#tokenId",
|
|
15
|
+
"owner": "https://ccda.ooo/did/v1#owner",
|
|
16
|
+
"nftIssuer": "https://ccda.ooo/did/v1#nftIssuer",
|
|
17
|
+
"standard": "https://ccda.ooo/did/v1#standard",
|
|
18
|
+
"status": "https://ccda.ooo/did/v1#status",
|
|
19
|
+
"credentials": "https://ccda.ooo/did/v1#credentials",
|
|
20
|
+
"verificationMethod": "https://ccda.ooo/did/v1#verificationMethod",
|
|
21
|
+
"verificationProcess": {
|
|
22
|
+
"@id": "https://ccda.ooo/did/v1#verificationProcess",
|
|
23
|
+
"@context": {
|
|
24
|
+
"verifiedAt": "https://ccda.ooo/did/v1#verifiedAt",
|
|
25
|
+
"updateAt": "https://ccda.ooo/did/v1#updateAt",
|
|
26
|
+
"verifierId": "https://ccda.ooo/did/v1#verifierId"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": {
|
|
3
|
+
"@version": 1.1,
|
|
4
|
+
"@protected": true,
|
|
5
|
+
"id": "@id",
|
|
6
|
+
"type": "@type",
|
|
7
|
+
"grantee": "https://ccda.ooo/vc/v1#grantee",
|
|
8
|
+
"usageRights": "https://ccda.ooo/vc/v1#usageRights",
|
|
9
|
+
"restrictions": {
|
|
10
|
+
"@id": "https://ccda.ooo/vc/v1#restrictions",
|
|
11
|
+
"@context": {
|
|
12
|
+
"commercial": "https://ccda.ooo/vc/v1#commercial",
|
|
13
|
+
"derivative": "https://ccda.ooo/vc/v1#derivative",
|
|
14
|
+
"sublicense": "https://ccda.ooo/vc/v1#sublicense",
|
|
15
|
+
"territories": "https://ccda.ooo/vc/v1#territories",
|
|
16
|
+
"platforms": "https://ccda.ooo/vc/v1#platforms"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": {
|
|
3
|
+
"@version": 1.1,
|
|
4
|
+
"@protected": true,
|
|
5
|
+
"id": "@id",
|
|
6
|
+
"type": "@type",
|
|
7
|
+
"NFTOwnership": "https://jdid.cn/vc/v1#NFTOwnership",
|
|
8
|
+
"NFTUsageAuthorization": "https://jdid.cn/vc/v1#NFTUsageAuthorization",
|
|
9
|
+
"PhoneVerificationCredential": "https://jdid.cn/vc/v1#PhoneVerificationCredential",
|
|
10
|
+
"version": "https://jdid.cn/did/v1#version",
|
|
11
|
+
"chainId": "https://jdid.cn/did/v1#chainId",
|
|
12
|
+
"contractAddress": "https://jdid.cn/did/v1#contractAddress",
|
|
13
|
+
"tokenName": "https://jdid.cn/did/v1#tokenName",
|
|
14
|
+
"tokenId": "https://jdid.cn/did/v1#tokenId",
|
|
15
|
+
"owner": "https://jdid.cn/did/v1#owner",
|
|
16
|
+
"nftIssuer": "https://jdid.cn/did/v1#nftIssuer",
|
|
17
|
+
"standard": "https://jdid.cn/did/v1#standard",
|
|
18
|
+
"status": "https://jdid.cn/did/v1#status",
|
|
19
|
+
"credentials": "https://jdid.cn/did/v1#credentials",
|
|
20
|
+
"verificationMethod": "https://jdid.cn/did/v1#verificationMethod",
|
|
21
|
+
"verificationProcess": {
|
|
22
|
+
"@id": "https://jdid.cn/did/v1#verificationProcess",
|
|
23
|
+
"@context": {
|
|
24
|
+
"verifiedAt": "https://jdid.cn/did/v1#verifiedAt",
|
|
25
|
+
"updateAt": "https://jdid.cn/did/v1#updateAt",
|
|
26
|
+
"verifierId": "https://jdid.cn/did/v1#verifierId"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": {
|
|
3
|
+
"@version": 1.1,
|
|
4
|
+
"@protected": true,
|
|
5
|
+
"id": "@id",
|
|
6
|
+
"type": "@type",
|
|
7
|
+
"grantee": "https://jdid.cn/vc/v1#grantee",
|
|
8
|
+
"usageRights": "https://jdid.cn/vc/v1#usageRights",
|
|
9
|
+
"restrictions": {
|
|
10
|
+
"@id": "https://jdid.cn/vc/v1#restrictions",
|
|
11
|
+
"@context": {
|
|
12
|
+
"commercial": "https://jdid.cn/vc/v1#commercial",
|
|
13
|
+
"derivative": "https://jdid.cn/vc/v1#derivative",
|
|
14
|
+
"sublicense": "https://jdid.cn/vc/v1#sublicense",
|
|
15
|
+
"territories": "https://jdid.cn/vc/v1#territories",
|
|
16
|
+
"platforms": "https://jdid.cn/vc/v1#platforms"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|