@arcblock/did 1.18.165 → 1.19.0
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/esm/index.d.ts +57 -0
- package/esm/index.js +123 -0
- package/esm/type.d.ts +53 -0
- package/esm/type.js +228 -0
- package/esm/util.d.ts +22 -0
- package/esm/util.js +45 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -1
- package/lib/type.d.ts +7 -6
- package/lib/type.js +12 -2
- package/lib/util.d.ts +0 -1
- package/package.json +28 -14
package/esm/index.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { types } from '@ocap/mcrypto';
|
|
2
|
+
import { toAddress, toDid, BytesType } from '@ocap/util';
|
|
3
|
+
import { DidType, DIDType, DIDTypeShortcut, DIDTypeStr, DIDTypeArg, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, fromTypeInfo, isEthereumDid, isEthereumType, toTypeInfo, toTypeInfoStr } from './type';
|
|
4
|
+
import { DID_PREFIX, toStrictHex } from './util';
|
|
5
|
+
/**
|
|
6
|
+
* Gen DID from private key and type config
|
|
7
|
+
*
|
|
8
|
+
* Spec: https://github.com/ArcBlock/ABT-DID-Protocol#create-did
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
* @static
|
|
12
|
+
* @param {string} sk - hex encoded secret key string
|
|
13
|
+
* @param {object} type - wallet type, {@see @ocap/wallet#WalletType}
|
|
14
|
+
* @returns {string} DID string
|
|
15
|
+
*/
|
|
16
|
+
declare const fromSecretKey: (sk: BytesType, type?: DIDTypeArg) => string;
|
|
17
|
+
/**
|
|
18
|
+
* Gen DID from public key and type config
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
* @static
|
|
22
|
+
* @param {string} pk - hex encoded public key
|
|
23
|
+
* @param {object} type - wallet type, {@see @ocap/wallet#WalletType}
|
|
24
|
+
* @returns {string} DID string
|
|
25
|
+
*/
|
|
26
|
+
declare const fromPublicKey: (pk: BytesType, type?: DIDTypeArg) => string;
|
|
27
|
+
declare const fromPublicKeyHash: (buffer: string, type: DIDTypeArg) => string;
|
|
28
|
+
/**
|
|
29
|
+
* Gen DID from an hex encoded hash and role type
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
* @static
|
|
33
|
+
* @param {string} hash - hex encoded hash
|
|
34
|
+
* @param {enum} role - role type, {@see @ocap/mcrypto#types}
|
|
35
|
+
* @returns {string} DID string
|
|
36
|
+
*/
|
|
37
|
+
declare const fromHash: (hash: string, role?: number) => string;
|
|
38
|
+
/**
|
|
39
|
+
* Check if an DID is generated from a publicKey
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
* @static
|
|
43
|
+
* @param {string} did - string of the did, usually base58btc format
|
|
44
|
+
* @param {string} pk - hex encoded publicKey string
|
|
45
|
+
* @returns {boolean}
|
|
46
|
+
*/
|
|
47
|
+
declare const isFromPublicKey: (did: string, pk: BytesType) => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a DID string is valid
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
* @static
|
|
53
|
+
* @param {string} did - address string
|
|
54
|
+
* @returns {boolean}
|
|
55
|
+
*/
|
|
56
|
+
declare const isValid: (did: string) => boolean;
|
|
57
|
+
export { DIDType, DIDTypeStr, DIDTypeArg, DIDTypeShortcut, types, toStrictHex, fromSecretKey, fromPublicKey, fromPublicKeyHash, fromHash, toAddress, toDid, isFromPublicKey, isValid, isEthereumDid, isEthereumType, toTypeInfo, toTypeInfoStr, fromTypeInfo, DidType, DID_PREFIX, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, };
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
3
|
+
import { types, getSigner, getHasher } from '@ocap/mcrypto';
|
|
4
|
+
import { stripHexPrefix, toAddress, toBase58, toDid } from '@ocap/util';
|
|
5
|
+
import { DidType, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, fromTypeInfo, isEthereumDid, isEthereumType, toChecksumAddress, toTypeInfo, toTypeInfoStr, } from './type';
|
|
6
|
+
import { DID_PREFIX, toBytes, toStrictHex } from './util';
|
|
7
|
+
/**
|
|
8
|
+
* Gen DID from private key and type config
|
|
9
|
+
*
|
|
10
|
+
* Spec: https://github.com/ArcBlock/ABT-DID-Protocol#create-did
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
* @static
|
|
14
|
+
* @param {string} sk - hex encoded secret key string
|
|
15
|
+
* @param {object} type - wallet type, {@see @ocap/wallet#WalletType}
|
|
16
|
+
* @returns {string} DID string
|
|
17
|
+
*/
|
|
18
|
+
const fromSecretKey = (sk, type) => {
|
|
19
|
+
const info = DidType(type);
|
|
20
|
+
const pub = getSigner(info.pk).getPublicKey(sk);
|
|
21
|
+
return fromPublicKey(pub.indexOf('0x') === 0 ? pub : `0x${pub}`, info);
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Gen DID from public key and type config
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
* @static
|
|
28
|
+
* @param {string} pk - hex encoded public key
|
|
29
|
+
* @param {object} type - wallet type, {@see @ocap/wallet#WalletType}
|
|
30
|
+
* @returns {string} DID string
|
|
31
|
+
*/
|
|
32
|
+
const fromPublicKey = (pk, type) => {
|
|
33
|
+
const info = DidType(type);
|
|
34
|
+
const hashFn = getHasher(info.hash);
|
|
35
|
+
const pkHash = hashFn(pk, 1);
|
|
36
|
+
return fromPublicKeyHash(pkHash, info);
|
|
37
|
+
};
|
|
38
|
+
const fromPublicKeyHash = (buffer, type) => {
|
|
39
|
+
const info = DidType(type);
|
|
40
|
+
const pkHash = stripHexPrefix(buffer).slice(0, 40); // 20 bytes
|
|
41
|
+
const hashFn = getHasher(info.hash);
|
|
42
|
+
const typeHex = fromTypeInfo(info);
|
|
43
|
+
const checksum = stripHexPrefix(hashFn(`0x${typeHex}${pkHash}`, 1)).slice(0, 8); // 4 bytes
|
|
44
|
+
const didHash = `0x${typeHex}${pkHash}${checksum}`;
|
|
45
|
+
// ethereum-compatible address, this address does not contain any type info
|
|
46
|
+
// but we can infer from the address itself
|
|
47
|
+
if (isEthereumType(info)) {
|
|
48
|
+
return toChecksumAddress(`0x${buffer.slice(-40)}`);
|
|
49
|
+
}
|
|
50
|
+
// default forge-compatible did
|
|
51
|
+
if (info.address === types.EncodingType.BASE58) {
|
|
52
|
+
return toBase58(didHash);
|
|
53
|
+
}
|
|
54
|
+
// fallback base16 encoding
|
|
55
|
+
return didHash;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Gen DID from an hex encoded hash and role type
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
* @static
|
|
62
|
+
* @param {string} hash - hex encoded hash
|
|
63
|
+
* @param {enum} role - role type, {@see @ocap/mcrypto#types}
|
|
64
|
+
* @returns {string} DID string
|
|
65
|
+
*/
|
|
66
|
+
const fromHash = (hash, role = types.RoleType.ROLE_ACCOUNT) => {
|
|
67
|
+
const roleKeys = Object.keys(types.RoleType);
|
|
68
|
+
const roleValues = Object.values(types.RoleType);
|
|
69
|
+
if (roleValues.indexOf(role) === -1) {
|
|
70
|
+
throw new Error(`Unsupported role type ${role} when gen ddi from hash`);
|
|
71
|
+
}
|
|
72
|
+
const type = DidType({
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
role: types.RoleType[roleKeys[roleValues.indexOf(role)]],
|
|
75
|
+
});
|
|
76
|
+
return fromPublicKeyHash(hash, type);
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Check if an DID is generated from a publicKey
|
|
80
|
+
*
|
|
81
|
+
* @public
|
|
82
|
+
* @static
|
|
83
|
+
* @param {string} did - string of the did, usually base58btc format
|
|
84
|
+
* @param {string} pk - hex encoded publicKey string
|
|
85
|
+
* @returns {boolean}
|
|
86
|
+
*/
|
|
87
|
+
const isFromPublicKey = (did, pk) => {
|
|
88
|
+
if (isValid(did) === false) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
const type = toTypeInfo(did);
|
|
92
|
+
const didNew = fromPublicKey(pk, type);
|
|
93
|
+
const didClean = did.replace(DID_PREFIX, '');
|
|
94
|
+
return didNew === didClean;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Check if a DID string is valid
|
|
98
|
+
*
|
|
99
|
+
* @public
|
|
100
|
+
* @static
|
|
101
|
+
* @param {string} did - address string
|
|
102
|
+
* @returns {boolean}
|
|
103
|
+
*/
|
|
104
|
+
const isValid = (did) => {
|
|
105
|
+
if (!did) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const address = toAddress(String(did));
|
|
109
|
+
const { hash } = toTypeInfo(address);
|
|
110
|
+
if (typeof hash === 'undefined') {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
if (isEthereumDid(address)) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
const hashFn = getHasher(hash);
|
|
117
|
+
const bytes = toBytes(address);
|
|
118
|
+
const bytesHex = toStrictHex(Buffer.from(bytes.slice(0, 22)).toString('hex'));
|
|
119
|
+
const didChecksum = toStrictHex(Buffer.from(bytes.slice(22, 26)).toString('hex'));
|
|
120
|
+
const checksum = stripHexPrefix(hashFn(`0x${bytesHex}`, 1)).slice(0, 8);
|
|
121
|
+
return didChecksum === checksum;
|
|
122
|
+
};
|
|
123
|
+
export { types, toStrictHex, fromSecretKey, fromPublicKey, fromPublicKeyHash, fromHash, toAddress, toDid, isFromPublicKey, isValid, isEthereumDid, isEthereumType, toTypeInfo, toTypeInfoStr, fromTypeInfo, DidType, DID_PREFIX, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, };
|
package/esm/type.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { LiteralUnion } from 'type-fest';
|
|
2
|
+
export type DIDTypeKey = LiteralUnion<'role' | 'pk' | 'hash' | 'address', string>;
|
|
3
|
+
export type DIDTypeShortcut = LiteralUnion<'default' | 'arcblock' | 'eth' | 'ethereum' | 'passkey', string>;
|
|
4
|
+
export type DIDType = {
|
|
5
|
+
[key in DIDTypeKey]?: number;
|
|
6
|
+
};
|
|
7
|
+
export type DIDTypeStr = {
|
|
8
|
+
[key in DIDTypeKey]?: string;
|
|
9
|
+
};
|
|
10
|
+
export type DIDTypeArg = DIDTypeShortcut | DIDType;
|
|
11
|
+
declare const DID_TYPE_ARCBLOCK: DIDType;
|
|
12
|
+
declare const DID_TYPE_PASSKEY: DIDType;
|
|
13
|
+
declare const DID_TYPE_ETHEREUM: DIDType;
|
|
14
|
+
declare const isEthereumType: (type: DIDType) => any;
|
|
15
|
+
/**
|
|
16
|
+
* Checks if the given string is an address
|
|
17
|
+
*
|
|
18
|
+
* @method isEthereumDid
|
|
19
|
+
* @param {String} address the given HEX address
|
|
20
|
+
* @return {Boolean}
|
|
21
|
+
*/
|
|
22
|
+
declare const isEthereumDid: (did: string) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Converts to a checksum address
|
|
25
|
+
*
|
|
26
|
+
* @method toChecksumAddress
|
|
27
|
+
* @param {String} address the given HEX address
|
|
28
|
+
* @return {String}
|
|
29
|
+
*/
|
|
30
|
+
declare const toChecksumAddress: (address: string) => string;
|
|
31
|
+
/**
|
|
32
|
+
* Create an wallet type object that be used as param to create a new wallet
|
|
33
|
+
*/
|
|
34
|
+
declare function DidType(type?: DIDTypeArg): DIDType;
|
|
35
|
+
declare namespace DidType {
|
|
36
|
+
var toJSON: (type: DIDType) => DIDTypeStr;
|
|
37
|
+
var fromJSON: (json: DIDTypeStr) => DIDType;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Convert type info object to hex string
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
* @static
|
|
44
|
+
* @param {object} type - wallet type, {@see @arcblock/did#DidType}
|
|
45
|
+
* @returns string
|
|
46
|
+
*/
|
|
47
|
+
declare const fromTypeInfo: (type: DIDTypeArg) => string;
|
|
48
|
+
/**
|
|
49
|
+
* Get type info from did
|
|
50
|
+
*/
|
|
51
|
+
declare const toTypeInfo: (did: string) => DIDType;
|
|
52
|
+
declare const toTypeInfoStr: (did: string) => DIDTypeStr;
|
|
53
|
+
export { DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, fromTypeInfo, toTypeInfo, toTypeInfoStr, isEthereumType, isEthereumDid, toChecksumAddress, DidType, };
|
package/esm/type.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
3
|
+
import { BN, numberToHex, stripHexPrefix, toAddress, isHex } from '@ocap/util';
|
|
4
|
+
import upperFirst from 'lodash/upperFirst';
|
|
5
|
+
import isEqual from 'lodash/isEqual';
|
|
6
|
+
import pick from 'lodash/pick';
|
|
7
|
+
import { types, Hasher } from '@ocap/mcrypto';
|
|
8
|
+
import { toBits, toBytes, toStrictHex } from './util';
|
|
9
|
+
const mapping = {
|
|
10
|
+
pk: 'key',
|
|
11
|
+
address: 'encoding',
|
|
12
|
+
};
|
|
13
|
+
const DID_TYPE_ARCBLOCK = {
|
|
14
|
+
role: types.RoleType.ROLE_ACCOUNT,
|
|
15
|
+
pk: types.KeyType.ED25519,
|
|
16
|
+
hash: types.HashType.SHA3,
|
|
17
|
+
address: types.EncodingType.BASE58,
|
|
18
|
+
};
|
|
19
|
+
const DID_TYPE_PASSKEY = {
|
|
20
|
+
role: types.RoleType.ROLE_PASSKEY,
|
|
21
|
+
pk: types.KeyType.PASSKEY,
|
|
22
|
+
hash: types.HashType.SHA2,
|
|
23
|
+
address: types.EncodingType.BASE58,
|
|
24
|
+
};
|
|
25
|
+
const DID_TYPE_ETHEREUM = {
|
|
26
|
+
role: types.RoleType.ROLE_ACCOUNT,
|
|
27
|
+
pk: types.KeyType.ETHEREUM,
|
|
28
|
+
hash: types.HashType.KECCAK,
|
|
29
|
+
address: types.EncodingType.BASE16,
|
|
30
|
+
};
|
|
31
|
+
const isEthereumType = (type) => {
|
|
32
|
+
const props = ['pk', 'hash', 'address'];
|
|
33
|
+
return isEqual(pick(type, props), pick(DID_TYPE_ETHEREUM, props));
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Checks if the given string is an address
|
|
37
|
+
*
|
|
38
|
+
* @method isEthereumDid
|
|
39
|
+
* @param {String} address the given HEX address
|
|
40
|
+
* @return {Boolean}
|
|
41
|
+
*/
|
|
42
|
+
const isEthereumDid = (did) => {
|
|
43
|
+
const address = toAddress(did);
|
|
44
|
+
// check if it has the basic requirements of an address
|
|
45
|
+
if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
// If it's ALL lowercase or ALL upppercase
|
|
49
|
+
if (/^(0x|0X)?[0-9a-f]{40}$/.test(address) || /^(0x|0X)?[0-9A-F]{40}$/.test(address)) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
// Otherwise check each case
|
|
53
|
+
return checkAddressChecksum(address);
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Checks if the given string is a checksummed address
|
|
57
|
+
*
|
|
58
|
+
* @method checkAddressChecksum
|
|
59
|
+
* @param {String} address the given HEX address
|
|
60
|
+
* @return {Boolean}
|
|
61
|
+
*/
|
|
62
|
+
const checkAddressChecksum = (address) => {
|
|
63
|
+
// Check each case
|
|
64
|
+
const origin = address.replace(/^0x/i, '');
|
|
65
|
+
const addressHash = Hasher.Keccak.hash256(origin.toLowerCase()).replace(/^0x/i, '');
|
|
66
|
+
for (let i = 0; i < 40; i++) {
|
|
67
|
+
// the nth letter should be uppercase if the nth digit of casemap is 1
|
|
68
|
+
if ((parseInt(addressHash[i], 16) > 7 && origin[i].toUpperCase() !== origin[i]) ||
|
|
69
|
+
(parseInt(addressHash[i], 16) <= 7 && origin[i].toLowerCase() !== origin[i])) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Converts to a checksum address
|
|
77
|
+
*
|
|
78
|
+
* @method toChecksumAddress
|
|
79
|
+
* @param {String} address the given HEX address
|
|
80
|
+
* @return {String}
|
|
81
|
+
*/
|
|
82
|
+
const toChecksumAddress = (address) => {
|
|
83
|
+
if (typeof address === 'undefined') {
|
|
84
|
+
return '';
|
|
85
|
+
}
|
|
86
|
+
if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
|
|
87
|
+
throw new Error(`Given address "${address}" is not a valid Ethereum address.`);
|
|
88
|
+
}
|
|
89
|
+
const lower = address.toLowerCase().replace(/^0x/i, '');
|
|
90
|
+
const addressHash = Hasher.Keccak.hash256(lower).replace(/^0x/i, '');
|
|
91
|
+
let checksumAddress = '0x';
|
|
92
|
+
for (let i = 0; i < lower.length; i++) {
|
|
93
|
+
// If ith character is 8 to f then make it uppercase
|
|
94
|
+
if (parseInt(addressHash[i], 16) > 7) {
|
|
95
|
+
checksumAddress += lower[i].toUpperCase();
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
checksumAddress += lower[i];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return checksumAddress;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Create an wallet type object that be used as param to create a new wallet
|
|
105
|
+
*/
|
|
106
|
+
function DidType(type = {}) {
|
|
107
|
+
let input = {};
|
|
108
|
+
if (['default', 'arcblock'].includes(type)) {
|
|
109
|
+
input = DID_TYPE_ARCBLOCK;
|
|
110
|
+
}
|
|
111
|
+
else if (['eth', 'ethereum'].includes(type)) {
|
|
112
|
+
input = DID_TYPE_ETHEREUM;
|
|
113
|
+
}
|
|
114
|
+
else if (['passkey'].includes(type)) {
|
|
115
|
+
input = DID_TYPE_PASSKEY;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
input = { ...DID_TYPE_ARCBLOCK, ...type };
|
|
119
|
+
}
|
|
120
|
+
const { role, pk, hash, address } = input;
|
|
121
|
+
Object.keys(input).forEach((x) => {
|
|
122
|
+
const key = upperFirst(`${mapping[x] || x}Type`);
|
|
123
|
+
// @ts-ignore
|
|
124
|
+
if (Object.values(types[key]).includes(input[x]) === false) {
|
|
125
|
+
throw new Error(`Unsupported ${x} type: ${input[x]}`);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
const output = { role, pk, hash, address };
|
|
129
|
+
// Overwrite hash methods for some role type if we are not eth-type
|
|
130
|
+
if (isEthereumType(output) === false) {
|
|
131
|
+
const sha2Roles = [
|
|
132
|
+
types.RoleType.ROLE_NODE,
|
|
133
|
+
types.RoleType.ROLE_VALIDATOR,
|
|
134
|
+
types.RoleType.ROLE_TETHER,
|
|
135
|
+
types.RoleType.ROLE_SWAP,
|
|
136
|
+
];
|
|
137
|
+
if (sha2Roles.includes(output.role)) {
|
|
138
|
+
output.hash = types.HashType.SHA2;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return output;
|
|
142
|
+
}
|
|
143
|
+
DidType.toJSON = (type) => Object.keys(type).reduce((acc, x) => {
|
|
144
|
+
const key = upperFirst(`${mapping[x] || x}Type`);
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
const typeStr = Object.keys(types[key]);
|
|
147
|
+
// @ts-ignore
|
|
148
|
+
const typeValues = Object.values(types[key]);
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
acc[x] = typeStr[typeValues.indexOf(type[x])];
|
|
151
|
+
return acc;
|
|
152
|
+
}, {});
|
|
153
|
+
DidType.fromJSON = (json) => Object.keys(json).reduce((acc, x) => {
|
|
154
|
+
const key = upperFirst(`${mapping[x] || x}Type`);
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
const typeStr = Object.keys(types[key]);
|
|
157
|
+
// @ts-ignore
|
|
158
|
+
const typeValues = Object.values(types[key]);
|
|
159
|
+
// @ts-ignore
|
|
160
|
+
acc[x] = typeValues[typeStr.indexOf(json[x])];
|
|
161
|
+
return acc;
|
|
162
|
+
}, {});
|
|
163
|
+
/**
|
|
164
|
+
* Convert type info object to hex string
|
|
165
|
+
*
|
|
166
|
+
* @public
|
|
167
|
+
* @static
|
|
168
|
+
* @param {object} type - wallet type, {@see @arcblock/did#DidType}
|
|
169
|
+
* @returns string
|
|
170
|
+
*/
|
|
171
|
+
const fromTypeInfo = (type) => {
|
|
172
|
+
const info = DidType(type);
|
|
173
|
+
const roleBits = toBits(info.role, 6);
|
|
174
|
+
const keyBits = toBits(info.pk, 5);
|
|
175
|
+
const hashBits = toBits(info.hash, 5);
|
|
176
|
+
const infoBits = `${roleBits}${keyBits}${hashBits}`;
|
|
177
|
+
const infoHex = stripHexPrefix(numberToHex(parseInt(infoBits, 2)));
|
|
178
|
+
return toStrictHex(infoHex, 4);
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Get type info from did
|
|
182
|
+
*/
|
|
183
|
+
const toTypeInfo = (did) => {
|
|
184
|
+
let type = {};
|
|
185
|
+
try {
|
|
186
|
+
if (isEthereumDid(did)) {
|
|
187
|
+
type = DID_TYPE_ETHEREUM;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const bytes = toBytes(did);
|
|
191
|
+
const typeBytes = bytes.slice(0, 2);
|
|
192
|
+
const typeHex = toStrictHex(Buffer.from(typeBytes).toString('hex'));
|
|
193
|
+
const typeBits = toBits(new BN(typeHex, 16), 16);
|
|
194
|
+
const roleBits = typeBits.slice(0, 6);
|
|
195
|
+
const keyBits = typeBits.slice(6, 11);
|
|
196
|
+
const hashBits = typeBits.slice(11, 16);
|
|
197
|
+
type = {
|
|
198
|
+
role: parseInt(roleBits, 2),
|
|
199
|
+
pk: parseInt(keyBits, 2),
|
|
200
|
+
hash: parseInt(hashBits, 2),
|
|
201
|
+
address: isHex(toAddress(did)) ? types.EncodingType.BASE16 : types.EncodingType.BASE58,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
// remove unsupported types
|
|
205
|
+
Object.keys(type).forEach((x) => {
|
|
206
|
+
// @ts-ignore
|
|
207
|
+
const enums = Object.values(types[`${upperFirst(mapping[x] || x)}Type`]);
|
|
208
|
+
if (enums.includes(type[x]) === false) {
|
|
209
|
+
delete type[x];
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
return type;
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return type;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const toTypeInfoStr = (did) => {
|
|
219
|
+
const type = toTypeInfo(did);
|
|
220
|
+
return Object.keys(type).reduce((acc, x) => {
|
|
221
|
+
// @ts-ignore
|
|
222
|
+
const enums = types[`${upperFirst(mapping[x] || x)}Type`];
|
|
223
|
+
// @ts-ignore
|
|
224
|
+
acc[x] = Object.keys(enums).find((d) => enums[d] === type[x]);
|
|
225
|
+
return acc;
|
|
226
|
+
}, {});
|
|
227
|
+
};
|
|
228
|
+
export { DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, fromTypeInfo, toTypeInfo, toTypeInfoStr, isEthereumType, isEthereumDid, toChecksumAddress, DidType, };
|
package/esm/util.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BN } from '@ocap/util';
|
|
2
|
+
declare const DID_PREFIX = "did:abt:";
|
|
3
|
+
/**
|
|
4
|
+
* Convert did to bytes with length of 26
|
|
5
|
+
*
|
|
6
|
+
* @param {string} did
|
|
7
|
+
* @returns {Buffer}
|
|
8
|
+
*/
|
|
9
|
+
declare const toBytes: (did: string) => Buffer;
|
|
10
|
+
/**
|
|
11
|
+
* Convert number to bit string with predefined length
|
|
12
|
+
*/
|
|
13
|
+
declare const toBits: (number: string | number | BN, length: number) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Ensure the hex length is even number, 2, 4, 6, 8
|
|
16
|
+
*
|
|
17
|
+
* @param {string} hex
|
|
18
|
+
* @param {number} length
|
|
19
|
+
* @returns {string} hex
|
|
20
|
+
*/
|
|
21
|
+
declare const toStrictHex: (hex: string, length?: number) => any;
|
|
22
|
+
export { DID_PREFIX, toBits, toBytes, toStrictHex };
|
package/esm/util.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
|
+
import padStart from 'lodash/padStart';
|
|
3
|
+
import { toBN, fromBase58, isHexStrict, stripHexPrefix } from '@ocap/util';
|
|
4
|
+
const DID_PREFIX = 'did:abt:';
|
|
5
|
+
/**
|
|
6
|
+
* Convert did to bytes with length of 26
|
|
7
|
+
*
|
|
8
|
+
* @param {string} did
|
|
9
|
+
* @returns {Buffer}
|
|
10
|
+
*/
|
|
11
|
+
const toBytes = (did) => {
|
|
12
|
+
try {
|
|
13
|
+
if (isHexStrict(did)) {
|
|
14
|
+
return Buffer.from(stripHexPrefix(did), 'hex');
|
|
15
|
+
}
|
|
16
|
+
let bytes = fromBase58(did.replace(DID_PREFIX, ''));
|
|
17
|
+
while (bytes.length < 26) {
|
|
18
|
+
bytes = Buffer.concat([Buffer.from([0]), bytes]);
|
|
19
|
+
}
|
|
20
|
+
return bytes;
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
throw new Error(`Cannot convert DID string to byte array: ${err.message}`);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Convert number to bit string with predefined length
|
|
29
|
+
*/
|
|
30
|
+
const toBits = (number, length) => padStart(toBN(number).toString(2), length, '0');
|
|
31
|
+
/**
|
|
32
|
+
* Ensure the hex length is even number, 2, 4, 6, 8
|
|
33
|
+
*
|
|
34
|
+
* @param {string} hex
|
|
35
|
+
* @param {number} length
|
|
36
|
+
* @returns {string} hex
|
|
37
|
+
*/
|
|
38
|
+
const toStrictHex = (hex, length) => {
|
|
39
|
+
const str = hex.replace(/^0x/i, '');
|
|
40
|
+
if (typeof length === 'number' && length % 2 === 0) {
|
|
41
|
+
return padStart(hex, length, '0');
|
|
42
|
+
}
|
|
43
|
+
return str.length % 2 === 0 ? str : `0${str}`;
|
|
44
|
+
};
|
|
45
|
+
export { DID_PREFIX, toBits, toBytes, toStrictHex };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { types } from '@ocap/mcrypto';
|
|
2
2
|
import { toAddress, toDid, BytesType } from '@ocap/util';
|
|
3
|
-
import { DidType, DIDType, DIDTypeShortcut, DIDTypeStr, DIDTypeArg, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, fromTypeInfo, isEthereumDid, isEthereumType, toTypeInfo, toTypeInfoStr } from './type';
|
|
3
|
+
import { DidType, DIDType, DIDTypeShortcut, DIDTypeStr, DIDTypeArg, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, fromTypeInfo, isEthereumDid, isEthereumType, toTypeInfo, toTypeInfoStr } from './type';
|
|
4
4
|
import { DID_PREFIX, toStrictHex } from './util';
|
|
5
5
|
/**
|
|
6
6
|
* Gen DID from private key and type config
|
|
@@ -54,4 +54,4 @@ declare const isFromPublicKey: (did: string, pk: BytesType) => boolean;
|
|
|
54
54
|
* @returns {boolean}
|
|
55
55
|
*/
|
|
56
56
|
declare const isValid: (did: string) => boolean;
|
|
57
|
-
export { DIDType, DIDTypeStr, DIDTypeArg, DIDTypeShortcut, types, toStrictHex, fromSecretKey, fromPublicKey, fromPublicKeyHash, fromHash, toAddress, toDid, isFromPublicKey, isValid, isEthereumDid, isEthereumType, toTypeInfo, toTypeInfoStr, fromTypeInfo, DidType, DID_PREFIX, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, };
|
|
57
|
+
export { DIDType, DIDTypeStr, DIDTypeArg, DIDTypeShortcut, types, toStrictHex, fromSecretKey, fromPublicKey, fromPublicKeyHash, fromHash, toAddress, toDid, isFromPublicKey, isValid, isEthereumDid, isEthereumType, toTypeInfo, toTypeInfoStr, fromTypeInfo, DidType, DID_PREFIX, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, };
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DID_TYPE_ETHEREUM = exports.DID_TYPE_ARCBLOCK = exports.DID_PREFIX = exports.DidType = exports.fromTypeInfo = exports.toTypeInfoStr = exports.toTypeInfo = exports.isEthereumType = exports.isEthereumDid = exports.isValid = exports.isFromPublicKey = exports.toDid = exports.toAddress = exports.fromHash = exports.fromPublicKeyHash = exports.fromPublicKey = exports.fromSecretKey = exports.toStrictHex = exports.types = void 0;
|
|
3
|
+
exports.DID_TYPE_PASSKEY = exports.DID_TYPE_ETHEREUM = exports.DID_TYPE_ARCBLOCK = exports.DID_PREFIX = exports.DidType = exports.fromTypeInfo = exports.toTypeInfoStr = exports.toTypeInfo = exports.isEthereumType = exports.isEthereumDid = exports.isValid = exports.isFromPublicKey = exports.toDid = exports.toAddress = exports.fromHash = exports.fromPublicKeyHash = exports.fromPublicKey = exports.fromSecretKey = exports.toStrictHex = exports.types = void 0;
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
5
5
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
6
6
|
const mcrypto_1 = require("@ocap/mcrypto");
|
|
@@ -12,6 +12,7 @@ const type_1 = require("./type");
|
|
|
12
12
|
Object.defineProperty(exports, "DidType", { enumerable: true, get: function () { return type_1.DidType; } });
|
|
13
13
|
Object.defineProperty(exports, "DID_TYPE_ARCBLOCK", { enumerable: true, get: function () { return type_1.DID_TYPE_ARCBLOCK; } });
|
|
14
14
|
Object.defineProperty(exports, "DID_TYPE_ETHEREUM", { enumerable: true, get: function () { return type_1.DID_TYPE_ETHEREUM; } });
|
|
15
|
+
Object.defineProperty(exports, "DID_TYPE_PASSKEY", { enumerable: true, get: function () { return type_1.DID_TYPE_PASSKEY; } });
|
|
15
16
|
Object.defineProperty(exports, "fromTypeInfo", { enumerable: true, get: function () { return type_1.fromTypeInfo; } });
|
|
16
17
|
Object.defineProperty(exports, "isEthereumDid", { enumerable: true, get: function () { return type_1.isEthereumDid; } });
|
|
17
18
|
Object.defineProperty(exports, "isEthereumType", { enumerable: true, get: function () { return type_1.isEthereumType; } });
|
package/lib/type.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { LiteralUnion } from 'type-fest';
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
2
|
+
export type DIDTypeKey = LiteralUnion<'role' | 'pk' | 'hash' | 'address', string>;
|
|
3
|
+
export type DIDTypeShortcut = LiteralUnion<'default' | 'arcblock' | 'eth' | 'ethereum' | 'passkey', string>;
|
|
4
|
+
export type DIDType = {
|
|
5
5
|
[key in DIDTypeKey]?: number;
|
|
6
6
|
};
|
|
7
|
-
export
|
|
7
|
+
export type DIDTypeStr = {
|
|
8
8
|
[key in DIDTypeKey]?: string;
|
|
9
9
|
};
|
|
10
|
-
export
|
|
10
|
+
export type DIDTypeArg = DIDTypeShortcut | DIDType;
|
|
11
11
|
declare const DID_TYPE_ARCBLOCK: DIDType;
|
|
12
|
+
declare const DID_TYPE_PASSKEY: DIDType;
|
|
12
13
|
declare const DID_TYPE_ETHEREUM: DIDType;
|
|
13
14
|
declare const isEthereumType: (type: DIDType) => any;
|
|
14
15
|
/**
|
|
@@ -49,4 +50,4 @@ declare const fromTypeInfo: (type: DIDTypeArg) => string;
|
|
|
49
50
|
*/
|
|
50
51
|
declare const toTypeInfo: (did: string) => DIDType;
|
|
51
52
|
declare const toTypeInfoStr: (did: string) => DIDTypeStr;
|
|
52
|
-
export { DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, fromTypeInfo, toTypeInfo, toTypeInfoStr, isEthereumType, isEthereumDid, toChecksumAddress, DidType, };
|
|
53
|
+
export { DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM, DID_TYPE_PASSKEY, fromTypeInfo, toTypeInfo, toTypeInfoStr, isEthereumType, isEthereumDid, toChecksumAddress, DidType, };
|
package/lib/type.js
CHANGED
|
@@ -3,7 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.toChecksumAddress = exports.isEthereumDid = exports.isEthereumType = exports.toTypeInfoStr = exports.toTypeInfo = exports.fromTypeInfo = exports.DID_TYPE_PASSKEY = exports.DID_TYPE_ETHEREUM = exports.DID_TYPE_ARCBLOCK = void 0;
|
|
7
|
+
exports.DidType = DidType;
|
|
7
8
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
8
9
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
9
10
|
const util_1 = require("@ocap/util");
|
|
@@ -23,6 +24,13 @@ const DID_TYPE_ARCBLOCK = {
|
|
|
23
24
|
address: mcrypto_1.types.EncodingType.BASE58,
|
|
24
25
|
};
|
|
25
26
|
exports.DID_TYPE_ARCBLOCK = DID_TYPE_ARCBLOCK;
|
|
27
|
+
const DID_TYPE_PASSKEY = {
|
|
28
|
+
role: mcrypto_1.types.RoleType.ROLE_PASSKEY,
|
|
29
|
+
pk: mcrypto_1.types.KeyType.PASSKEY,
|
|
30
|
+
hash: mcrypto_1.types.HashType.SHA2,
|
|
31
|
+
address: mcrypto_1.types.EncodingType.BASE58,
|
|
32
|
+
};
|
|
33
|
+
exports.DID_TYPE_PASSKEY = DID_TYPE_PASSKEY;
|
|
26
34
|
const DID_TYPE_ETHEREUM = {
|
|
27
35
|
role: mcrypto_1.types.RoleType.ROLE_ACCOUNT,
|
|
28
36
|
pk: mcrypto_1.types.KeyType.ETHEREUM,
|
|
@@ -116,6 +124,9 @@ function DidType(type = {}) {
|
|
|
116
124
|
else if (['eth', 'ethereum'].includes(type)) {
|
|
117
125
|
input = DID_TYPE_ETHEREUM;
|
|
118
126
|
}
|
|
127
|
+
else if (['passkey'].includes(type)) {
|
|
128
|
+
input = DID_TYPE_PASSKEY;
|
|
129
|
+
}
|
|
119
130
|
else {
|
|
120
131
|
input = { ...DID_TYPE_ARCBLOCK, ...type };
|
|
121
132
|
}
|
|
@@ -142,7 +153,6 @@ function DidType(type = {}) {
|
|
|
142
153
|
}
|
|
143
154
|
return output;
|
|
144
155
|
}
|
|
145
|
-
exports.DidType = DidType;
|
|
146
156
|
DidType.toJSON = (type) => Object.keys(type).reduce((acc, x) => {
|
|
147
157
|
const key = (0, upperFirst_1.default)(`${mapping[x] || x}Type`);
|
|
148
158
|
// @ts-ignore
|
package/lib/util.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/did",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
4
4
|
"description": "Javascript lib to work with ArcBlock DID",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"arcblock",
|
|
@@ -21,20 +21,32 @@
|
|
|
21
21
|
],
|
|
22
22
|
"homepage": "https://github.com/ArcBlock/blockchain/tree/master/did/did",
|
|
23
23
|
"license": "Apache-2.0",
|
|
24
|
-
"main": "lib/index.js",
|
|
25
|
-
"
|
|
24
|
+
"main": "./lib/index.js",
|
|
25
|
+
"module": "./lib/index.js",
|
|
26
|
+
"types": "./esm/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"import": "./esm/index.js",
|
|
30
|
+
"require": "./lib/index.js",
|
|
31
|
+
"default": "./esm/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./lib/*": {
|
|
34
|
+
"require": "./lib/*.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
26
37
|
"files": [
|
|
27
|
-
"lib"
|
|
38
|
+
"lib",
|
|
39
|
+
"esm"
|
|
28
40
|
],
|
|
29
41
|
"devDependencies": {
|
|
30
|
-
"@arcblock/eslint-config-ts": "0.
|
|
31
|
-
"@types/jest": "^29.5.
|
|
32
|
-
"@types/node": "^
|
|
33
|
-
"eslint": "^8.
|
|
42
|
+
"@arcblock/eslint-config-ts": "0.3.3",
|
|
43
|
+
"@types/jest": "^29.5.13",
|
|
44
|
+
"@types/node": "^22.7.5",
|
|
45
|
+
"eslint": "^8.57.0",
|
|
34
46
|
"jest": "^29.7.0",
|
|
35
47
|
"ts-jest": "^29.2.5",
|
|
36
48
|
"type-fest": "^3.1.0",
|
|
37
|
-
"typescript": "^
|
|
49
|
+
"typescript": "^5.6.2"
|
|
38
50
|
},
|
|
39
51
|
"repository": {
|
|
40
52
|
"type": "git",
|
|
@@ -45,20 +57,22 @@
|
|
|
45
57
|
"lint:fix": "npm run lint -- --fix",
|
|
46
58
|
"test": "jest --forceExit --detectOpenHandles",
|
|
47
59
|
"coverage": "npm run test -- --coverage",
|
|
48
|
-
"clean": "rm -fr lib",
|
|
60
|
+
"clean": "rm -fr lib esm",
|
|
49
61
|
"prebuild": "npm run clean",
|
|
50
|
-
"build": "tsc",
|
|
62
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
63
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
64
|
+
"build": "npm run build:cjs && npm run build:esm",
|
|
51
65
|
"build:watch": "npm run build -- -w"
|
|
52
66
|
},
|
|
53
67
|
"bugs": {
|
|
54
68
|
"url": "https://github.com/ArcBlock/blockchain/issues"
|
|
55
69
|
},
|
|
56
70
|
"dependencies": {
|
|
57
|
-
"@ocap/mcrypto": "1.
|
|
58
|
-
"@ocap/util": "1.
|
|
71
|
+
"@ocap/mcrypto": "1.19.0",
|
|
72
|
+
"@ocap/util": "1.19.0",
|
|
59
73
|
"bn.js": "^5.2.1",
|
|
60
74
|
"debug": "^4.3.6",
|
|
61
75
|
"lodash": "^4.17.21"
|
|
62
76
|
},
|
|
63
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "1b6fac03988fb18507c8ef4c21de282762005f87"
|
|
64
78
|
}
|