@arcblock/nft 1.6.5 → 1.6.10
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 +7 -7
- package/lib/enum.d.ts +18 -0
- package/lib/factory.d.ts +165 -0
- package/lib/factory.js +66 -26
- package/lib/index.d.ts +43 -23
- package/lib/issuer.d.ts +31 -0
- package/lib/issuer.js +3 -3
- package/lib/recipient.d.ts +27 -0
- package/lib/recipient.js +3 -3
- package/lib/templates/blocklet-purchase.js +42 -0
- package/lib/templates/index.js +9 -0
- package/lib/templates/node-owner.js +56 -0
- package/lib/templates/node-purchase.js +42 -0
- package/package.json +23 -19
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/prettier/prettier)
|
|
4
4
|
[](https://docs.arcblock.io)
|
|
5
|
-
[](https://gitter.im/ArcBlock/community?utm_source=badge
|
|
5
|
+
[](https://gitter.im/ArcBlock/community?utm_source=badge\&utm_medium=badge\&utm_campaign=pr-badge)
|
|
6
6
|
|
|
7
|
-
> Utility to create standard assets that can be rendered in [
|
|
7
|
+
> Utility to create standard assets that can be rendered in [DID Wallet](https://www.abtwallet.io)
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
## Table of Contents
|
|
@@ -26,13 +26,13 @@ yarn add @arcblock/nft
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
|
28
28
|
```js
|
|
29
|
-
const
|
|
29
|
+
const { fromRandom } = require('@ocap/wallet');
|
|
30
30
|
const { NFTFactory, NFTIssuer } = require('@arcblock/nft');
|
|
31
31
|
|
|
32
|
-
const wallet =
|
|
32
|
+
const wallet = fromRandom();
|
|
33
33
|
const factory = new NFTFactory({
|
|
34
|
-
chainId: '
|
|
35
|
-
chainHost: 'https://
|
|
34
|
+
chainId: 'beta',
|
|
35
|
+
chainHost: 'https://beta.abtnetwork.io/api',
|
|
36
36
|
wallet,
|
|
37
37
|
issuer: {
|
|
38
38
|
name: 'test case',
|
|
@@ -63,4 +63,4 @@ const [asset, hash] = await factory.createTicket({
|
|
|
63
63
|
|
|
64
64
|
## Documentation
|
|
65
65
|
|
|
66
|
-
For full documentation, checkout [https://
|
|
66
|
+
For full documentation, checkout [https://asset-chain.netlify.com](https://asset-chain.netlify.com/)
|
package/lib/enum.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const NFTType: Readonly<{
|
|
2
|
+
ticket: number;
|
|
3
|
+
coupon: number;
|
|
4
|
+
certificate: number;
|
|
5
|
+
badge: number;
|
|
6
|
+
license: number;
|
|
7
|
+
giftcard: number;
|
|
8
|
+
passport: number;
|
|
9
|
+
idcard: number;
|
|
10
|
+
receipt: number;
|
|
11
|
+
other: number;
|
|
12
|
+
}>;
|
|
13
|
+
export const NFTStatus: Readonly<{
|
|
14
|
+
normal: number;
|
|
15
|
+
consumed: number;
|
|
16
|
+
invalid: number;
|
|
17
|
+
expired: number;
|
|
18
|
+
}>;
|
package/lib/factory.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
export = NFTFactory;
|
|
2
|
+
/**
|
|
3
|
+
* Used to create standard asset on forge powered blockchain
|
|
4
|
+
* All assets are signed assets, eg, the asset data are self approvable
|
|
5
|
+
*
|
|
6
|
+
* @class NFTFactory
|
|
7
|
+
*/
|
|
8
|
+
declare class NFTFactory {
|
|
9
|
+
/**
|
|
10
|
+
* Creates an instance of NFTFactory.
|
|
11
|
+
* @param {object} params
|
|
12
|
+
* @param {string} params.chainHost - on which chain to create wallet
|
|
13
|
+
* @param {WalletObject} params.wallet - issuer wallet
|
|
14
|
+
* @param {object} params.issuer - issuer attributes, such as name, url and logo
|
|
15
|
+
* @memberof NFTFactory
|
|
16
|
+
*/
|
|
17
|
+
constructor({ chainHost, wallet, issuer }: {
|
|
18
|
+
chainHost: string;
|
|
19
|
+
wallet: WalletObject;
|
|
20
|
+
issuer: object;
|
|
21
|
+
});
|
|
22
|
+
chainHost: string;
|
|
23
|
+
client: Client;
|
|
24
|
+
wallet: WalletObject;
|
|
25
|
+
issuer: NFTIssuer;
|
|
26
|
+
/**
|
|
27
|
+
* Create a ticket
|
|
28
|
+
*
|
|
29
|
+
* @param {object} params
|
|
30
|
+
* @param {string} params.display - display of the ticket { type, content }
|
|
31
|
+
* @param {object} params.data - asset payload
|
|
32
|
+
* @param {string} params.data.name - ticket name
|
|
33
|
+
* @param {string} params.data.description - ticket description
|
|
34
|
+
* @param {string} params.data.location - event location
|
|
35
|
+
* @param {number} params.data.startTime - event start time
|
|
36
|
+
* @param {number} params.data.endTime - event end time
|
|
37
|
+
* @param {object} params.attributes - asset attributes
|
|
38
|
+
* @returns {Promise} - the `[asset, hash]` on resolved
|
|
39
|
+
* @memberof NFTFactory
|
|
40
|
+
*/
|
|
41
|
+
createTicket({ display, data, attributes }: {
|
|
42
|
+
display: string;
|
|
43
|
+
data: {
|
|
44
|
+
name: string;
|
|
45
|
+
description: string;
|
|
46
|
+
location: string;
|
|
47
|
+
startTime: number;
|
|
48
|
+
endTime: number;
|
|
49
|
+
};
|
|
50
|
+
attributes: object;
|
|
51
|
+
}): Promise<any>;
|
|
52
|
+
/**
|
|
53
|
+
* Create a coupon asset
|
|
54
|
+
*
|
|
55
|
+
* @param {object} params
|
|
56
|
+
* @param {string} params.display - display of the coupon { type, content }
|
|
57
|
+
* @param {object} params.data - asset payload
|
|
58
|
+
* @param {string} params.data.name - coupon name
|
|
59
|
+
* @param {string} params.data.description - coupon description
|
|
60
|
+
* @param {number} params.data.ratio - discount ratio
|
|
61
|
+
* @param {number} params.data.amount - discount amount
|
|
62
|
+
* @param {number} params.data.minAmount - min order amount that this coupon can be used
|
|
63
|
+
* @param {number} params.data.startTime - event start time
|
|
64
|
+
* @param {number} params.data.endTime - event end time
|
|
65
|
+
* @param {object} params.attributes - asset attributes
|
|
66
|
+
* @returns {Promise} - the `[asset, hash]` on resolved
|
|
67
|
+
* @memberof NFTFactory
|
|
68
|
+
*/
|
|
69
|
+
createCoupon({ display, data, attributes }: {
|
|
70
|
+
display: string;
|
|
71
|
+
data: {
|
|
72
|
+
name: string;
|
|
73
|
+
description: string;
|
|
74
|
+
ratio: number;
|
|
75
|
+
amount: number;
|
|
76
|
+
minAmount: number;
|
|
77
|
+
startTime: number;
|
|
78
|
+
endTime: number;
|
|
79
|
+
};
|
|
80
|
+
attributes: object;
|
|
81
|
+
}): Promise<any>;
|
|
82
|
+
/**
|
|
83
|
+
* Create a coupon asset
|
|
84
|
+
*
|
|
85
|
+
* @param {object} params
|
|
86
|
+
* @param {string} params.display - display of the coupon { type, content }
|
|
87
|
+
* @param {object} params.data - asset payload
|
|
88
|
+
* @param {string} params.data.name - certificate name
|
|
89
|
+
* @param {string} params.data.description - certificate description
|
|
90
|
+
* @param {string} params.data.reason - certificate reason
|
|
91
|
+
* @param {string} params.data.logoUrl - certificate logo
|
|
92
|
+
* @param {NFTRecipient} params.data.recipient - certificate recipient
|
|
93
|
+
* @param {number} params.data.issueTime - when was certificate issued
|
|
94
|
+
* @param {number} params.data.expireTime - when will certificate expire
|
|
95
|
+
* @param {object} params.attributes - asset attributes
|
|
96
|
+
* @returns {Promise} - the `[asset, hash]` on resolved
|
|
97
|
+
* @memberof NFTFactory
|
|
98
|
+
*/
|
|
99
|
+
createCertificate({ display, data, attributes }: {
|
|
100
|
+
display: string;
|
|
101
|
+
data: {
|
|
102
|
+
name: string;
|
|
103
|
+
description: string;
|
|
104
|
+
reason: string;
|
|
105
|
+
logoUrl: string;
|
|
106
|
+
recipient: NFTRecipient;
|
|
107
|
+
issueTime: number;
|
|
108
|
+
expireTime: number;
|
|
109
|
+
};
|
|
110
|
+
attributes: object;
|
|
111
|
+
}): Promise<any>;
|
|
112
|
+
/**
|
|
113
|
+
* Create a badge
|
|
114
|
+
*
|
|
115
|
+
* @param {object} params
|
|
116
|
+
* @param {string} params.display - display of the badge { type, content }
|
|
117
|
+
* @param {object} params.data - asset payload
|
|
118
|
+
* @param {string} params.data.name - certificate name
|
|
119
|
+
* @param {string} params.data.description - certificate description
|
|
120
|
+
* @param {NFTRecipient} params.data.recipient - certificate recipient
|
|
121
|
+
* @param {object} params.attributes - asset attributes
|
|
122
|
+
* @returns {Promise} - the `[asset, hash]` on resolved
|
|
123
|
+
* @memberof NFTFactory
|
|
124
|
+
*/
|
|
125
|
+
createBadge({ display, data, attributes }: {
|
|
126
|
+
display: string;
|
|
127
|
+
data: {
|
|
128
|
+
name: string;
|
|
129
|
+
description: string;
|
|
130
|
+
recipient: NFTRecipient;
|
|
131
|
+
};
|
|
132
|
+
attributes: object;
|
|
133
|
+
}): Promise<any>;
|
|
134
|
+
/**
|
|
135
|
+
* Create a passport
|
|
136
|
+
*
|
|
137
|
+
* @param {object} params
|
|
138
|
+
* @param {string} params.display - display of the passport { type, content }
|
|
139
|
+
* @param {object} params.passport - asset payload
|
|
140
|
+
* @param {string} params.passport.name - passport name
|
|
141
|
+
* @param {string} params.passport.title - passport title
|
|
142
|
+
* @param {NFTRecipient} params.data.recipient - certificate recipient
|
|
143
|
+
* @param {object} params.attributes - asset attributes
|
|
144
|
+
* @returns {Promise} - the `[asset, hash]` on resolved
|
|
145
|
+
* @memberof NFTFactory
|
|
146
|
+
*/
|
|
147
|
+
createPassport({ display, data, attributes }: {
|
|
148
|
+
display: string;
|
|
149
|
+
passport: {
|
|
150
|
+
name: string;
|
|
151
|
+
title: string;
|
|
152
|
+
};
|
|
153
|
+
}): Promise<any>;
|
|
154
|
+
createSignedAsset(payload: any, attributes: any): Promise<any[]>;
|
|
155
|
+
_createDisplay(display: any): any;
|
|
156
|
+
_createCert({ display, data, attributes }: {
|
|
157
|
+
display?: string;
|
|
158
|
+
data?: {};
|
|
159
|
+
attributes?: {};
|
|
160
|
+
}): Promise<any[]>;
|
|
161
|
+
getVCBody(asset: any): any;
|
|
162
|
+
}
|
|
163
|
+
import Client = require("@ocap/client");
|
|
164
|
+
import NFTIssuer = require("./issuer");
|
|
165
|
+
import NFTRecipient = require("./recipient");
|
package/lib/factory.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/* eslint-disable no-underscore-dangle */
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
|
-
const
|
|
3
|
+
const Client = require('@ocap/client');
|
|
4
4
|
const { isValid } = require('@ocap/wallet');
|
|
5
|
+
const { toBase58 } = require('@ocap/util');
|
|
6
|
+
const { toAssetAddress } = require('@arcblock/did-util');
|
|
5
7
|
const get = require('lodash/get');
|
|
6
8
|
const cloneDeep = require('lodash/cloneDeep');
|
|
7
9
|
const isDate = require('lodash/isDate');
|
|
@@ -23,28 +25,22 @@ class NFTFactory {
|
|
|
23
25
|
/**
|
|
24
26
|
* Creates an instance of NFTFactory.
|
|
25
27
|
* @param {object} params
|
|
26
|
-
* @param {string} params.chainId - on which chain to create wallet
|
|
27
28
|
* @param {string} params.chainHost - on which chain to create wallet
|
|
28
29
|
* @param {WalletObject} params.wallet - issuer wallet
|
|
29
30
|
* @param {object} params.issuer - issuer attributes, such as name, url and logo
|
|
30
31
|
* @memberof NFTFactory
|
|
31
32
|
*/
|
|
32
|
-
constructor({
|
|
33
|
-
if (!chainId) {
|
|
34
|
-
throw new Error('NFTFactory requires valid chainId');
|
|
35
|
-
}
|
|
33
|
+
constructor({ chainHost, wallet, issuer }) {
|
|
36
34
|
if (!chainHost) {
|
|
37
|
-
throw new Error('NFTFactory requires valid
|
|
35
|
+
throw new Error('NFTFactory requires valid chain host');
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
OcapSDK.connect(chainHost, { chainId, name: chainId });
|
|
41
|
-
|
|
42
38
|
if (isValid(wallet) === false) {
|
|
43
39
|
throw new Error('NFTFactory requires valid wallet issuer');
|
|
44
40
|
}
|
|
45
41
|
|
|
46
|
-
this.chainId = chainId;
|
|
47
42
|
this.chainHost = chainHost;
|
|
43
|
+
this.client = new Client(chainHost);
|
|
48
44
|
this.wallet = wallet;
|
|
49
45
|
this.issuer = new NFTIssuer({ wallet, ...issuer });
|
|
50
46
|
}
|
|
@@ -103,7 +99,7 @@ class NFTFactory {
|
|
|
103
99
|
name: this.issuer.attributes.name,
|
|
104
100
|
},
|
|
105
101
|
subject: {
|
|
106
|
-
id: recipient.wallet.
|
|
102
|
+
id: recipient.wallet.address,
|
|
107
103
|
name,
|
|
108
104
|
description,
|
|
109
105
|
location,
|
|
@@ -170,6 +166,8 @@ class NFTFactory {
|
|
|
170
166
|
recipient,
|
|
171
167
|
display: innerDisplay = '',
|
|
172
168
|
issuanceDate,
|
|
169
|
+
endpoint,
|
|
170
|
+
endpointScope,
|
|
173
171
|
} = data;
|
|
174
172
|
|
|
175
173
|
const vc = create({
|
|
@@ -179,7 +177,7 @@ class NFTFactory {
|
|
|
179
177
|
name: this.issuer.attributes.name,
|
|
180
178
|
},
|
|
181
179
|
subject: {
|
|
182
|
-
id: recipient.wallet.
|
|
180
|
+
id: recipient.wallet.address,
|
|
183
181
|
name,
|
|
184
182
|
description,
|
|
185
183
|
location,
|
|
@@ -188,6 +186,8 @@ class NFTFactory {
|
|
|
188
186
|
minAmount,
|
|
189
187
|
display: this._createDisplay(display || innerDisplay),
|
|
190
188
|
},
|
|
189
|
+
endpoint,
|
|
190
|
+
endpointScope,
|
|
191
191
|
issuanceDate: issuanceDate || new Date(),
|
|
192
192
|
expirationDate: new Date(expireTime),
|
|
193
193
|
});
|
|
@@ -199,7 +199,7 @@ class NFTFactory {
|
|
|
199
199
|
* Create a coupon asset
|
|
200
200
|
*
|
|
201
201
|
* @param {object} params
|
|
202
|
-
* @param {string} params.display - display of the
|
|
202
|
+
* @param {string} params.display - display of the coupon { type, content }
|
|
203
203
|
* @param {object} params.data - asset payload
|
|
204
204
|
* @param {string} params.data.name - certificate name
|
|
205
205
|
* @param {string} params.data.description - certificate description
|
|
@@ -220,7 +220,7 @@ class NFTFactory {
|
|
|
220
220
|
* Create a badge
|
|
221
221
|
*
|
|
222
222
|
* @param {object} params
|
|
223
|
-
* @param {string} params.display - display of the
|
|
223
|
+
* @param {string} params.display - display of the badge { type, content }
|
|
224
224
|
* @param {object} params.data - asset payload
|
|
225
225
|
* @param {string} params.data.name - certificate name
|
|
226
226
|
* @param {string} params.data.description - certificate description
|
|
@@ -230,7 +230,7 @@ class NFTFactory {
|
|
|
230
230
|
* @memberof NFTFactory
|
|
231
231
|
*/
|
|
232
232
|
async createBadge({ display = '', data = {}, attributes = {} }) {
|
|
233
|
-
const { name, recipient, description, display: innerDisplay = '', type } = data;
|
|
233
|
+
const { name, recipient, description, display: innerDisplay = '', type, endpoint, endpointScope } = data;
|
|
234
234
|
|
|
235
235
|
const vc = create({
|
|
236
236
|
type: [type, 'NFTBadge', 'VerifiableCredential'].filter(Boolean),
|
|
@@ -239,17 +239,56 @@ class NFTFactory {
|
|
|
239
239
|
name: this.issuer.attributes.name,
|
|
240
240
|
},
|
|
241
241
|
subject: {
|
|
242
|
-
id: recipient.wallet.
|
|
242
|
+
id: recipient.wallet.address,
|
|
243
243
|
name,
|
|
244
244
|
description,
|
|
245
245
|
display: this._createDisplay(display || innerDisplay),
|
|
246
246
|
},
|
|
247
|
+
endpoint,
|
|
248
|
+
endpointScope,
|
|
249
|
+
});
|
|
250
|
+
return this.createSignedAsset(vc, attributes);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Create a passport
|
|
255
|
+
*
|
|
256
|
+
* @param {object} params
|
|
257
|
+
* @param {string} params.display - display of the passport { type, content }
|
|
258
|
+
* @param {object} params.passport - asset payload
|
|
259
|
+
* @param {string} params.passport.name - passport name
|
|
260
|
+
* @param {string} params.passport.title - passport title
|
|
261
|
+
* @param {NFTRecipient} params.data.recipient - certificate recipient
|
|
262
|
+
* @param {object} params.attributes - asset attributes
|
|
263
|
+
* @returns {Promise} - the `[asset, hash]` on resolved
|
|
264
|
+
* @memberof NFTFactory
|
|
265
|
+
*/
|
|
266
|
+
async createPassport({ display = '', data = {}, attributes = {} }) {
|
|
267
|
+
const { recipient, passport, display: innerDisplay = '', type, endpoint, endpointScope } = data;
|
|
268
|
+
|
|
269
|
+
if (!passport || !passport.name || !passport.title) {
|
|
270
|
+
throw new Error('NFTPassport requires valid passport object: which must have a name and a title');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const vc = create({
|
|
274
|
+
type: [type, 'NFTPassport', 'VerifiableCredential'].filter(Boolean),
|
|
275
|
+
issuer: {
|
|
276
|
+
wallet: this.wallet,
|
|
277
|
+
name: this.issuer.attributes.name,
|
|
278
|
+
},
|
|
279
|
+
subject: {
|
|
280
|
+
id: recipient.wallet.address,
|
|
281
|
+
passport,
|
|
282
|
+
display: this._createDisplay(display || innerDisplay),
|
|
283
|
+
},
|
|
284
|
+
endpoint,
|
|
285
|
+
endpointScope,
|
|
247
286
|
});
|
|
248
287
|
return this.createSignedAsset(vc, attributes);
|
|
249
288
|
}
|
|
250
289
|
|
|
251
290
|
async createSignedAsset(payload, attributes) {
|
|
252
|
-
const signature =
|
|
291
|
+
const signature = toBase58(this.wallet.sign(stringify(payload)));
|
|
253
292
|
payload.signature = signature;
|
|
254
293
|
const moniker = get(payload, 'data.name') || get(payload, 'credentialSubject.name') || 'signed_asset';
|
|
255
294
|
const asset = {
|
|
@@ -262,15 +301,12 @@ class NFTFactory {
|
|
|
262
301
|
},
|
|
263
302
|
...attributes,
|
|
264
303
|
};
|
|
265
|
-
asset.address =
|
|
304
|
+
asset.address = toAssetAddress(asset);
|
|
266
305
|
|
|
267
|
-
const hash = await
|
|
268
|
-
{
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
},
|
|
272
|
-
{ conn: this.chainId }
|
|
273
|
-
);
|
|
306
|
+
const hash = await this.client.sendCreateAssetTx({
|
|
307
|
+
tx: { itx: asset },
|
|
308
|
+
wallet: this.wallet,
|
|
309
|
+
});
|
|
274
310
|
|
|
275
311
|
return [asset, hash];
|
|
276
312
|
}
|
|
@@ -316,6 +352,8 @@ class NFTFactory {
|
|
|
316
352
|
expireTime,
|
|
317
353
|
display: innerDisplay = '',
|
|
318
354
|
issuanceDate,
|
|
355
|
+
endpoint,
|
|
356
|
+
endpointScope,
|
|
319
357
|
} = data;
|
|
320
358
|
|
|
321
359
|
const vc = create({
|
|
@@ -325,13 +363,15 @@ class NFTFactory {
|
|
|
325
363
|
name: this.issuer.attributes.name,
|
|
326
364
|
},
|
|
327
365
|
subject: {
|
|
328
|
-
id: recipient.wallet.
|
|
366
|
+
id: recipient.wallet.address,
|
|
329
367
|
name,
|
|
330
368
|
description,
|
|
331
369
|
reason,
|
|
332
370
|
logoUrl,
|
|
333
371
|
display: this._createDisplay(display || innerDisplay),
|
|
334
372
|
},
|
|
373
|
+
endpoint,
|
|
374
|
+
endpointScope,
|
|
335
375
|
issuanceDate: issuanceDate || new Date(),
|
|
336
376
|
expirationDate: +new Date(expireTime),
|
|
337
377
|
});
|
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Generate by [js2dts@0.3.3](https://github.com/whxaxes/js2dts#readme)
|
|
2
2
|
|
|
3
3
|
declare class NFTIssuer {
|
|
4
|
-
wallet: any;
|
|
5
|
-
attributes: _Lib.T104;
|
|
6
4
|
/**
|
|
7
5
|
* Creates an instance of NFTIssuer.
|
|
8
6
|
*
|
|
@@ -13,11 +11,11 @@ declare class NFTIssuer {
|
|
|
13
11
|
* @param {string} attributes.logo - issuer logo image url or logo base64
|
|
14
12
|
*/
|
|
15
13
|
constructor(T102: _Lib.T103);
|
|
14
|
+
wallet: any;
|
|
15
|
+
attributes: _Lib.T104;
|
|
16
16
|
toJSON(): _Lib.T105;
|
|
17
17
|
}
|
|
18
18
|
declare class NFTRecipient {
|
|
19
|
-
wallet: any;
|
|
20
|
-
attributes: _Lib.T108;
|
|
21
19
|
/**
|
|
22
20
|
* Creates an instance of NFTRecipient.
|
|
23
21
|
*
|
|
@@ -27,6 +25,8 @@ declare class NFTRecipient {
|
|
|
27
25
|
* @param {string} attributes.location - recipient website
|
|
28
26
|
*/
|
|
29
27
|
constructor(T106: _Lib.T107);
|
|
28
|
+
wallet: any;
|
|
29
|
+
attributes: _Lib.T108;
|
|
30
30
|
toJSON(): _Lib.T109;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
@@ -36,20 +36,19 @@ declare class NFTRecipient {
|
|
|
36
36
|
* @class NFTFactory
|
|
37
37
|
*/
|
|
38
38
|
declare class NFTFactory {
|
|
39
|
-
chainId: string;
|
|
40
|
-
chainHost: string;
|
|
41
|
-
wallet: any;
|
|
42
|
-
issuer: NFTIssuer;
|
|
43
39
|
/**
|
|
44
40
|
* Creates an instance of NFTFactory.
|
|
45
41
|
* @param {object} params
|
|
46
|
-
* @param {string} params.chainId - on which chain to create wallet
|
|
47
42
|
* @param {string} params.chainHost - on which chain to create wallet
|
|
48
43
|
* @param {WalletObject} params.wallet - issuer wallet
|
|
49
44
|
* @param {object} params.issuer - issuer attributes, such as name, url and logo
|
|
50
45
|
* @memberof NFTFactory
|
|
51
46
|
*/
|
|
52
47
|
constructor(T110: _Lib.T111);
|
|
48
|
+
chainHost: string;
|
|
49
|
+
client: Client;
|
|
50
|
+
wallet: any;
|
|
51
|
+
issuer: NFTIssuer_1;
|
|
53
52
|
/**
|
|
54
53
|
* Create a ticket
|
|
55
54
|
*
|
|
@@ -88,7 +87,7 @@ declare class NFTFactory {
|
|
|
88
87
|
* Create a coupon asset
|
|
89
88
|
*
|
|
90
89
|
* @param {object} params
|
|
91
|
-
* @param {string} params.display - display of the
|
|
90
|
+
* @param {string} params.display - display of the coupon { type, content }
|
|
92
91
|
* @param {object} params.data - asset payload
|
|
93
92
|
* @param {string} params.data.name - certificate name
|
|
94
93
|
* @param {string} params.data.description - certificate description
|
|
@@ -106,7 +105,7 @@ declare class NFTFactory {
|
|
|
106
105
|
* Create a badge
|
|
107
106
|
*
|
|
108
107
|
* @param {object} params
|
|
109
|
-
* @param {string} params.display - display of the
|
|
108
|
+
* @param {string} params.display - display of the badge { type, content }
|
|
110
109
|
* @param {object} params.data - asset payload
|
|
111
110
|
* @param {string} params.data.name - certificate name
|
|
112
111
|
* @param {string} params.data.description - certificate description
|
|
@@ -116,10 +115,24 @@ declare class NFTFactory {
|
|
|
116
115
|
* @memberof NFTFactory
|
|
117
116
|
*/
|
|
118
117
|
createBadge(T121: _Lib.T123): Promise<any>;
|
|
118
|
+
/**
|
|
119
|
+
* Create a passport
|
|
120
|
+
*
|
|
121
|
+
* @param {object} params
|
|
122
|
+
* @param {string} params.display - display of the passport { type, content }
|
|
123
|
+
* @param {object} params.passport - asset payload
|
|
124
|
+
* @param {string} params.passport.name - passport name
|
|
125
|
+
* @param {string} params.passport.title - passport title
|
|
126
|
+
* @param {NFTRecipient} params.data.recipient - certificate recipient
|
|
127
|
+
* @param {object} params.attributes - asset attributes
|
|
128
|
+
* @returns {Promise} - the `[asset, hash]` on resolved
|
|
129
|
+
* @memberof NFTFactory
|
|
130
|
+
*/
|
|
131
|
+
createPassport(T124: _Lib.T126): Promise<any>;
|
|
119
132
|
createSignedAsset(payload: any, attributes: any): Promise<any[]>;
|
|
120
133
|
getVCBody(asset: any): any;
|
|
121
134
|
}
|
|
122
|
-
declare const _Lib: _Lib.
|
|
135
|
+
declare const _Lib: _Lib.T127;
|
|
123
136
|
declare namespace _Lib {
|
|
124
137
|
export interface T100 {
|
|
125
138
|
normal: number;
|
|
@@ -155,7 +168,7 @@ declare namespace _Lib {
|
|
|
155
168
|
url: string;
|
|
156
169
|
logo: string;
|
|
157
170
|
did: any;
|
|
158
|
-
pk:
|
|
171
|
+
pk: string;
|
|
159
172
|
}
|
|
160
173
|
export interface T107 {
|
|
161
174
|
wallet: any;
|
|
@@ -170,13 +183,12 @@ declare namespace _Lib {
|
|
|
170
183
|
name: string;
|
|
171
184
|
location: string;
|
|
172
185
|
did: any;
|
|
173
|
-
pk:
|
|
186
|
+
pk: string;
|
|
174
187
|
}
|
|
175
188
|
export interface T111 {
|
|
176
|
-
chainId: string;
|
|
177
189
|
chainHost: string;
|
|
178
190
|
wallet: any;
|
|
179
|
-
issuer:
|
|
191
|
+
issuer: object;
|
|
180
192
|
}
|
|
181
193
|
export interface T113 {
|
|
182
194
|
name: string;
|
|
@@ -188,7 +200,7 @@ declare namespace _Lib {
|
|
|
188
200
|
export interface T114 {
|
|
189
201
|
display: string;
|
|
190
202
|
data: _Lib.T113;
|
|
191
|
-
attributes:
|
|
203
|
+
attributes: object;
|
|
192
204
|
}
|
|
193
205
|
export interface T116 {
|
|
194
206
|
name: string;
|
|
@@ -202,33 +214,41 @@ declare namespace _Lib {
|
|
|
202
214
|
export interface T117 {
|
|
203
215
|
display: string;
|
|
204
216
|
data: _Lib.T116;
|
|
205
|
-
attributes:
|
|
217
|
+
attributes: object;
|
|
206
218
|
}
|
|
207
219
|
export interface T119 {
|
|
208
220
|
name: string;
|
|
209
221
|
description: string;
|
|
210
222
|
reason: string;
|
|
211
223
|
logoUrl: string;
|
|
212
|
-
recipient:
|
|
224
|
+
recipient: NFTRecipient_1;
|
|
213
225
|
issueTime: number;
|
|
214
226
|
expireTime: number;
|
|
215
227
|
}
|
|
216
228
|
export interface T120 {
|
|
217
229
|
display: string;
|
|
218
230
|
data: _Lib.T119;
|
|
219
|
-
attributes:
|
|
231
|
+
attributes: object;
|
|
220
232
|
}
|
|
221
233
|
export interface T122 {
|
|
222
234
|
name: string;
|
|
223
235
|
description: string;
|
|
224
|
-
recipient:
|
|
236
|
+
recipient: NFTRecipient_1;
|
|
225
237
|
}
|
|
226
238
|
export interface T123 {
|
|
227
239
|
display: string;
|
|
228
240
|
data: _Lib.T122;
|
|
229
|
-
attributes:
|
|
241
|
+
attributes: object;
|
|
242
|
+
}
|
|
243
|
+
export interface T125 {
|
|
244
|
+
name: string;
|
|
245
|
+
title: string;
|
|
246
|
+
}
|
|
247
|
+
export interface T126 {
|
|
248
|
+
display: string;
|
|
249
|
+
passport: _Lib.T125;
|
|
230
250
|
}
|
|
231
|
-
export interface
|
|
251
|
+
export interface T127 {
|
|
232
252
|
NFTStatus: Readonly<_Lib.T100>;
|
|
233
253
|
NFTType: Readonly<_Lib.T101>;
|
|
234
254
|
NFTIssuer: typeof NFTIssuer;
|
package/lib/issuer.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export = NFTIssuer;
|
|
2
|
+
declare class NFTIssuer {
|
|
3
|
+
/**
|
|
4
|
+
* Creates an instance of NFTIssuer.
|
|
5
|
+
*
|
|
6
|
+
* @param {object} attributes
|
|
7
|
+
* @param {WalletObject} attributes.wallet - wallet
|
|
8
|
+
* @param {string} attributes.name - issuer name
|
|
9
|
+
* @param {string} attributes.url - issuer website
|
|
10
|
+
* @param {string} attributes.logo - issuer logo image url or logo base64
|
|
11
|
+
*/
|
|
12
|
+
constructor({ wallet, name, url, logo }: {
|
|
13
|
+
wallet: WalletObject;
|
|
14
|
+
name: string;
|
|
15
|
+
url: string;
|
|
16
|
+
logo: string;
|
|
17
|
+
});
|
|
18
|
+
wallet: WalletObject;
|
|
19
|
+
attributes: {
|
|
20
|
+
name: string;
|
|
21
|
+
url: string;
|
|
22
|
+
logo: string;
|
|
23
|
+
};
|
|
24
|
+
toJSON(): {
|
|
25
|
+
name: string;
|
|
26
|
+
url: string;
|
|
27
|
+
logo: string;
|
|
28
|
+
did: any;
|
|
29
|
+
pk: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
package/lib/issuer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { toBase58 } = require('@ocap/util');
|
|
2
2
|
|
|
3
3
|
module.exports = class NFTIssuer {
|
|
4
4
|
/**
|
|
@@ -17,8 +17,8 @@ module.exports = class NFTIssuer {
|
|
|
17
17
|
|
|
18
18
|
toJSON() {
|
|
19
19
|
return {
|
|
20
|
-
did: this.wallet.
|
|
21
|
-
pk:
|
|
20
|
+
did: this.wallet.address,
|
|
21
|
+
pk: toBase58(this.wallet.publicKey),
|
|
22
22
|
...this.attributes,
|
|
23
23
|
};
|
|
24
24
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export = NFTRecipient;
|
|
2
|
+
declare class NFTRecipient {
|
|
3
|
+
/**
|
|
4
|
+
* Creates an instance of NFTRecipient.
|
|
5
|
+
*
|
|
6
|
+
* @param {object} attributes
|
|
7
|
+
* @param {WalletObject} attributes.wallet - wallet
|
|
8
|
+
* @param {string} attributes.name - recipient name
|
|
9
|
+
* @param {string} attributes.location - recipient website
|
|
10
|
+
*/
|
|
11
|
+
constructor({ wallet, name, location }: {
|
|
12
|
+
wallet: WalletObject;
|
|
13
|
+
name: string;
|
|
14
|
+
location: string;
|
|
15
|
+
});
|
|
16
|
+
wallet: WalletObject;
|
|
17
|
+
attributes: {
|
|
18
|
+
name: string;
|
|
19
|
+
location: string;
|
|
20
|
+
};
|
|
21
|
+
toJSON(): {
|
|
22
|
+
name: string;
|
|
23
|
+
location: string;
|
|
24
|
+
did: any;
|
|
25
|
+
pk: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
package/lib/recipient.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { toBase58 } = require('@ocap/util');
|
|
2
2
|
|
|
3
3
|
module.exports = class NFTRecipient {
|
|
4
4
|
/**
|
|
@@ -16,8 +16,8 @@ module.exports = class NFTRecipient {
|
|
|
16
16
|
|
|
17
17
|
toJSON() {
|
|
18
18
|
return {
|
|
19
|
-
did: this.wallet.
|
|
20
|
-
pk:
|
|
19
|
+
did: this.wallet.address,
|
|
20
|
+
pk: toBase58(this.wallet.publicKey),
|
|
21
21
|
...this.attributes,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const joinUrl = require('url-join');
|
|
2
|
+
|
|
3
|
+
module.exports = (serviceUrl = 'https://registry.arcblock.io') => ({
|
|
4
|
+
type: 'vc',
|
|
5
|
+
value: {
|
|
6
|
+
'@context': 'https://schema.arcblock.io/v0.1/context.jsonld',
|
|
7
|
+
id: '{{input.id}}',
|
|
8
|
+
tag: ['{{data.did}}'],
|
|
9
|
+
type: ['VerifiableCredential', 'PurchaseCredential', 'NFTCertificate', 'BlockletPurchaseCredential'],
|
|
10
|
+
issuer: {
|
|
11
|
+
id: '{{ctx.issuer.id}}',
|
|
12
|
+
pk: '{{ctx.issuer.pk}}',
|
|
13
|
+
name: '{{ctx.issuer.name}}',
|
|
14
|
+
},
|
|
15
|
+
issuanceDate: '{{input.issuanceDate}}', // does not expire
|
|
16
|
+
credentialSubject: {
|
|
17
|
+
id: '{{ctx.owner}}',
|
|
18
|
+
purchased: {
|
|
19
|
+
blocklet: {
|
|
20
|
+
id: '{{data.did}}',
|
|
21
|
+
url: '{{{data.url}}}',
|
|
22
|
+
name: '{{data.name}}',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
display: {
|
|
26
|
+
type: 'url',
|
|
27
|
+
content: joinUrl(serviceUrl, '/api/nft/display'), // accept asset-did in query param
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
credentialStatus: {
|
|
31
|
+
id: joinUrl(serviceUrl, '/api/nft/status'),
|
|
32
|
+
type: 'NFTStatusList2021',
|
|
33
|
+
scope: 'public',
|
|
34
|
+
},
|
|
35
|
+
proof: {
|
|
36
|
+
type: '{{input.proofType}}',
|
|
37
|
+
created: '{{input.issuanceDate}}',
|
|
38
|
+
proofPurpose: 'assertionMethod',
|
|
39
|
+
jws: '{{input.signature}}',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const nodePurchase = require('./node-purchase');
|
|
2
|
+
const nodeOwner = require('./node-owner');
|
|
3
|
+
const blockletPurchase = require('./blocklet-purchase');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
getNodePurchaseTemplate: nodePurchase,
|
|
7
|
+
getNodeOwnerTemplate: nodeOwner,
|
|
8
|
+
getBlockletPurchaseTemplate: blockletPurchase,
|
|
9
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const joinUrl = require('url-join');
|
|
2
|
+
|
|
3
|
+
module.exports = (serviceUrl = 'https://launcher.arcblock.io') => ({
|
|
4
|
+
type: 'vc',
|
|
5
|
+
value: {
|
|
6
|
+
'@context': 'https://schema.arcblock.io/v0.1/context.jsonld',
|
|
7
|
+
id: '{{input.id}}',
|
|
8
|
+
tag: ['{{input.nodeId}}'],
|
|
9
|
+
type: ['VerifiableCredential', 'OwnershipCredential', 'NFTCertificate', 'NodeOwnershipCredential'],
|
|
10
|
+
issuer: {
|
|
11
|
+
id: '{{ctx.issuer.id}}',
|
|
12
|
+
pk: '{{ctx.issuer.pk}}',
|
|
13
|
+
name: '{{ctx.issuer.name}}',
|
|
14
|
+
},
|
|
15
|
+
issuanceDate: '{{input.issuanceDate}}',
|
|
16
|
+
expirationDate: '{{input.expirationDate}}',
|
|
17
|
+
credentialSubject: {
|
|
18
|
+
id: '{{ctx.owner}}',
|
|
19
|
+
isOwnerOf: {
|
|
20
|
+
abtnode: {
|
|
21
|
+
id: '{{input.nodeId}}',
|
|
22
|
+
provider: '{{input.nodeProvider}}',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
display: {
|
|
26
|
+
type: 'url',
|
|
27
|
+
content: joinUrl(serviceUrl, '/api/nft/display'), // accept asset-did in query param
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
evidence: [
|
|
31
|
+
{
|
|
32
|
+
id: '{{input.purchaseId}}',
|
|
33
|
+
type: ['NodePurchaseCredential'],
|
|
34
|
+
verifier: '{{input.purchaseIssuerId}}',
|
|
35
|
+
evidenceDocument: 'NodePurchaseCredential',
|
|
36
|
+
subjectPresence: 'Digital',
|
|
37
|
+
documentPresence: 'Digital',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
credentialStatus: {
|
|
41
|
+
id: joinUrl(serviceUrl, '/api/nft/status'),
|
|
42
|
+
type: 'NFTStatusList2021',
|
|
43
|
+
scope: 'public',
|
|
44
|
+
},
|
|
45
|
+
refreshService: {
|
|
46
|
+
id: joinUrl(serviceUrl, '/api/nft/refresh/{{input.id}}'),
|
|
47
|
+
type: 'NodeOwnershipRefreshService2021',
|
|
48
|
+
},
|
|
49
|
+
proof: {
|
|
50
|
+
type: '{{input.proofType}}',
|
|
51
|
+
created: '{{input.issuanceDate}}',
|
|
52
|
+
proofPurpose: 'assertionMethod',
|
|
53
|
+
jws: '{{input.signature}}',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const joinUrl = require('url-join');
|
|
2
|
+
|
|
3
|
+
module.exports = (serviceUrl = 'https://launcher.arcblock.io') => ({
|
|
4
|
+
type: 'vc',
|
|
5
|
+
value: {
|
|
6
|
+
'@context': 'https://schema.arcblock.io/v0.1/context.jsonld',
|
|
7
|
+
id: '{{input.id}}',
|
|
8
|
+
type: ['VerifiableCredential', 'PurchaseCredential', 'NFTTicket', 'NodePurchaseCredential'],
|
|
9
|
+
issuer: {
|
|
10
|
+
id: '{{ctx.issuer.id}}',
|
|
11
|
+
pk: '{{ctx.issuer.pk}}',
|
|
12
|
+
name: '{{ctx.issuer.name}}',
|
|
13
|
+
},
|
|
14
|
+
issuanceDate: '{{input.issuanceDate}}',
|
|
15
|
+
credentialSubject: {
|
|
16
|
+
id: '{{ctx.owner}}',
|
|
17
|
+
purchased: {
|
|
18
|
+
abtnode: {
|
|
19
|
+
type: '{{data.type}}',
|
|
20
|
+
period: '{{data.period}}',
|
|
21
|
+
name: '{{input.name}}',
|
|
22
|
+
description: '{{input.description}}',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
display: {
|
|
26
|
+
type: 'url',
|
|
27
|
+
content: joinUrl(serviceUrl, '/api/nft/display'), // accept asset-did in query param
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
credentialStatus: {
|
|
31
|
+
id: joinUrl(serviceUrl, '/api/nft/status'),
|
|
32
|
+
type: 'NFTStatusList2021',
|
|
33
|
+
scope: 'public',
|
|
34
|
+
},
|
|
35
|
+
proof: {
|
|
36
|
+
type: '{{input.proofType}}',
|
|
37
|
+
created: '{{input.issuanceDate}}',
|
|
38
|
+
proofPurpose: 'assertionMethod',
|
|
39
|
+
jws: '{{input.signature}}',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
});
|
package/package.json
CHANGED
|
@@ -1,47 +1,51 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/nft",
|
|
3
3
|
"description": "Utility to create standard asset on forge powered blockchain",
|
|
4
|
-
"version": "1.6.
|
|
4
|
+
"version": "1.6.10",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "wangshijun",
|
|
7
7
|
"email": "shijun@arcblock.io",
|
|
8
8
|
"url": "https://github.com/wangshijun"
|
|
9
9
|
},
|
|
10
|
+
"contributors": [
|
|
11
|
+
"wangshijun <shijun@arcblock.io> (https://github.com/wangshijun)"
|
|
12
|
+
],
|
|
10
13
|
"bugs": {
|
|
11
|
-
"url": "https://github.com/ArcBlock/
|
|
14
|
+
"url": "https://github.com/ArcBlock/asset-chain/issues",
|
|
12
15
|
"email": "shijun@arcblock.io"
|
|
13
16
|
},
|
|
14
17
|
"publishConfig": {
|
|
15
18
|
"access": "public"
|
|
16
19
|
},
|
|
17
20
|
"dependencies": {
|
|
18
|
-
"@arcblock/
|
|
19
|
-
"@
|
|
20
|
-
"@ocap/
|
|
21
|
-
"
|
|
21
|
+
"@arcblock/did-util": "1.6.10",
|
|
22
|
+
"@arcblock/vc": "1.6.10",
|
|
23
|
+
"@ocap/client": "1.6.10",
|
|
24
|
+
"@ocap/util": "1.6.10",
|
|
25
|
+
"@ocap/wallet": "1.6.10",
|
|
26
|
+
"debug": "^4.3.3",
|
|
22
27
|
"json-stable-stringify": "^1.0.1",
|
|
23
|
-
"lodash": "^4.17.
|
|
24
|
-
"pako": "^1.0.11"
|
|
28
|
+
"lodash": "^4.17.21",
|
|
29
|
+
"pako": "^1.0.11",
|
|
30
|
+
"url-join": "^4.0.1"
|
|
25
31
|
},
|
|
26
32
|
"devDependencies": {
|
|
27
|
-
"jest": "^
|
|
28
|
-
"remark-cli": "^
|
|
29
|
-
"remark-preset-github": "^
|
|
33
|
+
"jest": "^27.3.1",
|
|
34
|
+
"remark-cli": "^10.0.1",
|
|
35
|
+
"remark-preset-github": "^4.0.1"
|
|
30
36
|
},
|
|
31
37
|
"remarkConfig": {
|
|
32
38
|
"plugins": [
|
|
33
39
|
"preset-github",
|
|
34
40
|
[
|
|
35
|
-
"validate-links",
|
|
36
41
|
{
|
|
37
|
-
"repository": "ArcBlock/
|
|
42
|
+
"repository": "ArcBlock/asset-chain"
|
|
38
43
|
}
|
|
39
44
|
]
|
|
40
45
|
]
|
|
41
46
|
},
|
|
42
|
-
"homepage": "https://github.com/ArcBlock/
|
|
47
|
+
"homepage": "https://github.com/ArcBlock/asset-chain/tree/master/asset/nft",
|
|
43
48
|
"keywords": [
|
|
44
|
-
"forge",
|
|
45
49
|
"blockchain",
|
|
46
50
|
"arcblock",
|
|
47
51
|
"sdk",
|
|
@@ -54,18 +58,18 @@
|
|
|
54
58
|
],
|
|
55
59
|
"repository": {
|
|
56
60
|
"type": "git",
|
|
57
|
-
"url": "https://github.com/ArcBlock/
|
|
61
|
+
"url": "https://github.com/ArcBlock/asset-chain/tree/master/asset/nft"
|
|
58
62
|
},
|
|
59
63
|
"scripts": {
|
|
60
64
|
"lint": "eslint lib tests",
|
|
61
65
|
"lint:fix": "eslint --fix lib tests",
|
|
62
66
|
"docs": "yarn gen-dts && yarn gen-docs && yarn cleanup-docs && yarn format-docs",
|
|
63
|
-
"cleanup-docs": "node ../../
|
|
67
|
+
"cleanup-docs": "node ../../scripts/cleanup-docs.js docs/README.md $npm_package_name",
|
|
64
68
|
"gen-dts": "j2d lib/index.js",
|
|
65
69
|
"gen-docs": "jsdoc2md lib/index.js > docs/README.md",
|
|
66
70
|
"format-docs": "remark . -o",
|
|
67
|
-
"test": "
|
|
71
|
+
"test": "jest --forceExit --detectOpenHandles",
|
|
68
72
|
"coverage": "yarn test -- --coverage"
|
|
69
73
|
},
|
|
70
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "ab272e8db3a15c6571cc7fae7cc3d3e0fdd4bdb1"
|
|
71
75
|
}
|