@ocap/wallet 1.19.0 → 1.19.2
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 +89 -0
- package/esm/index.js +161 -0
- package/lib/index.d.ts +89 -0
- package/lib/index.js +171 -0
- package/package.json +10 -14
- package/.eslintrc.js +0 -12
- package/docs/README.md +0 -186
- package/jest.config.js +0 -7
- package/src/index.ts +0 -235
- package/tests/index.spec.ts +0 -116
- package/tsconfig.cjs.json +0 -9
- package/tsconfig.eslint.json +0 -4
- package/tsconfig.esm.json +0 -9
package/esm/index.d.ts
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
import { EncodingType, BytesType } from '@ocap/util';
|
2
|
+
import { DidType, DIDType, DIDTypeStr, DIDTypeArg } from '@arcblock/did';
|
3
|
+
type KeyPairType<T extends BytesType = string> = {
|
4
|
+
sk?: T;
|
5
|
+
pk?: T;
|
6
|
+
address?: string;
|
7
|
+
};
|
8
|
+
export type SerializedWallet = {
|
9
|
+
type: DIDTypeStr;
|
10
|
+
pk: string;
|
11
|
+
sk: string;
|
12
|
+
address: string;
|
13
|
+
};
|
14
|
+
export interface WalletObject<T extends BytesType = string> {
|
15
|
+
type: DIDType;
|
16
|
+
secretKey: T;
|
17
|
+
publicKey: T;
|
18
|
+
address: string;
|
19
|
+
hash(data: BytesType, round?: number, encoding?: 'hex'): string;
|
20
|
+
hash(data: BytesType, round?: number, encoding?: 'base16'): string;
|
21
|
+
hash(data: BytesType, round?: number, encoding?: 'base58'): string;
|
22
|
+
hash(data: BytesType, round?: number, encoding?: 'base64'): string;
|
23
|
+
hash(data: BytesType, round?: number, encoding?: 'buffer'): Buffer;
|
24
|
+
hash(data: BytesType, round?: number, encoding?: 'Uint8Array'): Uint8Array;
|
25
|
+
hash(data: BytesType, round?: number, encoding?: EncodingType): BytesType;
|
26
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'hex'): string;
|
27
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base16'): string;
|
28
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base58'): string;
|
29
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base64'): string;
|
30
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'buffer'): Buffer;
|
31
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'Uint8Array'): Uint8Array;
|
32
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: EncodingType): BytesType;
|
33
|
+
verify(data: BytesType, signature: BytesType, hashBeforeVerify?: boolean, extra?: any): Promise<boolean>;
|
34
|
+
ethHash(data: string): string;
|
35
|
+
ethSign(data: string, hashBeforeSign?: boolean): string;
|
36
|
+
ethVerify(data: string, signature: string, hashBeforeVerify?: boolean): boolean;
|
37
|
+
toJSON(): SerializedWallet;
|
38
|
+
/**
|
39
|
+
* @deprecated ES6: use `wallet.address` instead
|
40
|
+
*/
|
41
|
+
toAddress(): string;
|
42
|
+
}
|
43
|
+
export declare const WalletType: typeof DidType;
|
44
|
+
/**
|
45
|
+
* Generate an wallet instance that can be used to sign a message or verify a signature
|
46
|
+
*/
|
47
|
+
export declare function Wallet<T extends BytesType = string>(keyPair: KeyPairType<T>, t?: DIDTypeArg): WalletObject<T>;
|
48
|
+
/**
|
49
|
+
* Generate a wallet from secretKey
|
50
|
+
*
|
51
|
+
* @example
|
52
|
+
* const assert = require('assert');
|
53
|
+
* const { fromSecretKey } = require('@ocap/wallet');
|
54
|
+
*
|
55
|
+
* const sk =
|
56
|
+
* '0xD67C071B6F51D2B61180B9B1AA9BE0DD0704619F0E30453AB4A592B036EDE644E4852B7091317E3622068E62A5127D1FB0D4AE2FC50213295E10652D2F0ABFC7';
|
57
|
+
* const sig =
|
58
|
+
* '0x08a102851c38c072e42756c1cc70938b5499c8e9358dfe5f383823f56cdb282ffda60fcd581a02c6c673069e5afc0bf09abbe3639b61b84d64fd58ef9f083003';
|
59
|
+
*
|
60
|
+
* const wallet = fromSecretKey(sk, type);
|
61
|
+
* const message = 'data to sign';
|
62
|
+
* const signature = wallet.sign(message);
|
63
|
+
* assert.equal(signature, sig, "signature should match");
|
64
|
+
* assert.ok(wallet.verify(message, signature), "signature should be verified");
|
65
|
+
*/
|
66
|
+
export declare function fromSecretKey<T extends BytesType = string>(sk: T, _type?: DIDTypeArg): WalletObject<T>;
|
67
|
+
/**
|
68
|
+
* Generate a wallet from publicKey
|
69
|
+
*/
|
70
|
+
export declare function fromPublicKey<T extends BytesType = string>(pk: T, _type?: DIDTypeArg): WalletObject<T>;
|
71
|
+
/**
|
72
|
+
* Generate a wallet from address (did)
|
73
|
+
*
|
74
|
+
* Since we do not know the publicKey and secretKey, this kind of wallet cannot be used for signing and verifying
|
75
|
+
*/
|
76
|
+
export declare function fromAddress<T extends BytesType = string>(address: string): WalletObject<T>;
|
77
|
+
/**
|
78
|
+
* Generate a wallet by generating a random secretKey
|
79
|
+
*/
|
80
|
+
export declare function fromRandom<T extends BytesType = string>(_type?: DIDTypeArg): WalletObject<T>;
|
81
|
+
/**
|
82
|
+
* Generating a wallet from a serialized json presentation of another wallet
|
83
|
+
*/
|
84
|
+
export declare function fromJSON<T extends BytesType = string>(json: SerializedWallet): WalletObject<T>;
|
85
|
+
/**
|
86
|
+
* Check if an object is valid wallet object
|
87
|
+
*/
|
88
|
+
export declare function isValid(wallet: WalletObject, canSign?: boolean): boolean;
|
89
|
+
export {};
|
package/esm/index.js
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
import { toHex } from '@ocap/util';
|
2
|
+
import { getSigner, getHasher } from '@ocap/mcrypto';
|
3
|
+
import { toAddress, fromPublicKey as DIDFromPublicKey, toTypeInfo, DidType, } from '@arcblock/did';
|
4
|
+
export const WalletType = DidType;
|
5
|
+
/**
|
6
|
+
* Generate an wallet instance that can be used to sign a message or verify a signature
|
7
|
+
*/
|
8
|
+
export function Wallet(keyPair, t = 'default') {
|
9
|
+
const type = DidType(t);
|
10
|
+
const signer = getSigner(type.pk);
|
11
|
+
const hasher = getHasher(type.hash);
|
12
|
+
return {
|
13
|
+
type,
|
14
|
+
secretKey: keyPair.sk,
|
15
|
+
publicKey: keyPair.pk,
|
16
|
+
address: keyPair.pk ? DIDFromPublicKey(keyPair.pk, type) : keyPair.address,
|
17
|
+
// @ts-ignore
|
18
|
+
hash(data, round = 1, encoding = 'hex') {
|
19
|
+
return hasher(data, round, encoding);
|
20
|
+
},
|
21
|
+
// @ts-ignore
|
22
|
+
sign(data, hashBeforeSign = true, encoding = 'hex') {
|
23
|
+
if (!keyPair.sk) {
|
24
|
+
throw new Error('Cannot sign data without a secretKey');
|
25
|
+
}
|
26
|
+
if (hashBeforeSign) {
|
27
|
+
const hash = hasher(data, 1);
|
28
|
+
return signer.sign(hash, keyPair.sk, encoding);
|
29
|
+
}
|
30
|
+
return signer.sign(data, keyPair.sk, encoding);
|
31
|
+
},
|
32
|
+
// eslint-disable-next-line require-await
|
33
|
+
async verify(data, signature, hashBeforeVerify = true, extra) {
|
34
|
+
if (!keyPair.pk) {
|
35
|
+
throw new Error('Cannot verify data without a publicKey');
|
36
|
+
}
|
37
|
+
const hash = hashBeforeVerify ? hasher(data, 1) : data;
|
38
|
+
return signer.verify(hash, signature, keyPair.pk, extra);
|
39
|
+
},
|
40
|
+
ethHash(data) {
|
41
|
+
if (typeof signer.ethHash !== 'function') {
|
42
|
+
throw new Error('ethHash is not supported by signer');
|
43
|
+
}
|
44
|
+
return signer.ethHash(data);
|
45
|
+
},
|
46
|
+
ethSign(data, hashBeforeSign = true) {
|
47
|
+
if (!keyPair.sk) {
|
48
|
+
throw new Error('Cannot sign data without a secretKey');
|
49
|
+
}
|
50
|
+
if (typeof signer.ethHash !== 'function') {
|
51
|
+
throw new Error('ethSign is not supported by signer');
|
52
|
+
}
|
53
|
+
if (hashBeforeSign) {
|
54
|
+
return signer.ethSign(signer.ethHash(data), toHex(keyPair.sk));
|
55
|
+
}
|
56
|
+
return signer.ethSign(data, toHex(keyPair.sk));
|
57
|
+
},
|
58
|
+
ethVerify(data, signature, hashBeforeVerify = true) {
|
59
|
+
if (typeof signer.ethHash !== 'function') {
|
60
|
+
throw new Error('ethVerify is not supported by signer');
|
61
|
+
}
|
62
|
+
const hash = hashBeforeVerify ? signer.ethHash(data) : data;
|
63
|
+
return signer.ethRecover(hash, signature) === this.address;
|
64
|
+
},
|
65
|
+
// deprecated
|
66
|
+
toAddress() {
|
67
|
+
return keyPair.pk ? DIDFromPublicKey(keyPair.pk, type) : keyPair.address;
|
68
|
+
},
|
69
|
+
toJSON() {
|
70
|
+
return {
|
71
|
+
type: DidType.toJSON(type),
|
72
|
+
sk: toHex(keyPair.sk),
|
73
|
+
pk: toHex(keyPair.pk),
|
74
|
+
address: this.address,
|
75
|
+
};
|
76
|
+
},
|
77
|
+
};
|
78
|
+
}
|
79
|
+
/**
|
80
|
+
* Generate a wallet from secretKey
|
81
|
+
*
|
82
|
+
* @example
|
83
|
+
* const assert = require('assert');
|
84
|
+
* const { fromSecretKey } = require('@ocap/wallet');
|
85
|
+
*
|
86
|
+
* const sk =
|
87
|
+
* '0xD67C071B6F51D2B61180B9B1AA9BE0DD0704619F0E30453AB4A592B036EDE644E4852B7091317E3622068E62A5127D1FB0D4AE2FC50213295E10652D2F0ABFC7';
|
88
|
+
* const sig =
|
89
|
+
* '0x08a102851c38c072e42756c1cc70938b5499c8e9358dfe5f383823f56cdb282ffda60fcd581a02c6c673069e5afc0bf09abbe3639b61b84d64fd58ef9f083003';
|
90
|
+
*
|
91
|
+
* const wallet = fromSecretKey(sk, type);
|
92
|
+
* const message = 'data to sign';
|
93
|
+
* const signature = wallet.sign(message);
|
94
|
+
* assert.equal(signature, sig, "signature should match");
|
95
|
+
* assert.ok(wallet.verify(message, signature), "signature should be verified");
|
96
|
+
*/
|
97
|
+
export function fromSecretKey(sk, _type = 'default') {
|
98
|
+
const type = DidType(_type);
|
99
|
+
const keyPair = { sk, pk: getSigner(type.pk).getPublicKey(sk) };
|
100
|
+
return Wallet(keyPair, type);
|
101
|
+
}
|
102
|
+
/**
|
103
|
+
* Generate a wallet from publicKey
|
104
|
+
*/
|
105
|
+
export function fromPublicKey(pk, _type = 'default') {
|
106
|
+
return Wallet({ pk }, DidType(_type));
|
107
|
+
}
|
108
|
+
/**
|
109
|
+
* Generate a wallet from address (did)
|
110
|
+
*
|
111
|
+
* Since we do not know the publicKey and secretKey, this kind of wallet cannot be used for signing and verifying
|
112
|
+
*/
|
113
|
+
export function fromAddress(address) {
|
114
|
+
return Wallet({ address: toAddress(address) }, toTypeInfo(address));
|
115
|
+
}
|
116
|
+
/**
|
117
|
+
* Generate a wallet by generating a random secretKey
|
118
|
+
*/
|
119
|
+
export function fromRandom(_type = 'default') {
|
120
|
+
const type = DidType(_type);
|
121
|
+
const signer = getSigner(type.pk);
|
122
|
+
const keyPair = signer.genKeyPair();
|
123
|
+
return Wallet({ sk: keyPair.secretKey, pk: keyPair.publicKey }, type);
|
124
|
+
}
|
125
|
+
/**
|
126
|
+
* Generating a wallet from a serialized json presentation of another wallet
|
127
|
+
*/
|
128
|
+
export function fromJSON(json) {
|
129
|
+
const type = DidType.fromJSON(json.type);
|
130
|
+
// @ts-ignore
|
131
|
+
return Wallet(json, type);
|
132
|
+
}
|
133
|
+
/**
|
134
|
+
* Check if an object is valid wallet object
|
135
|
+
*/
|
136
|
+
export function isValid(wallet, canSign = true) {
|
137
|
+
if (!wallet || typeof wallet !== 'object') {
|
138
|
+
return false;
|
139
|
+
}
|
140
|
+
if (typeof wallet.verify !== 'function') {
|
141
|
+
return false;
|
142
|
+
}
|
143
|
+
if (typeof wallet.toAddress !== 'function') {
|
144
|
+
return false;
|
145
|
+
}
|
146
|
+
if (typeof wallet.toJSON !== 'function') {
|
147
|
+
return false;
|
148
|
+
}
|
149
|
+
if (!wallet.type || !wallet.publicKey) {
|
150
|
+
return false;
|
151
|
+
}
|
152
|
+
if (canSign) {
|
153
|
+
if (!wallet.secretKey) {
|
154
|
+
return false;
|
155
|
+
}
|
156
|
+
if (typeof wallet.sign !== 'function') {
|
157
|
+
return false;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
return true;
|
161
|
+
}
|
package/lib/index.d.ts
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
import { EncodingType, BytesType } from '@ocap/util';
|
2
|
+
import { DidType, DIDType, DIDTypeStr, DIDTypeArg } from '@arcblock/did';
|
3
|
+
type KeyPairType<T extends BytesType = string> = {
|
4
|
+
sk?: T;
|
5
|
+
pk?: T;
|
6
|
+
address?: string;
|
7
|
+
};
|
8
|
+
export type SerializedWallet = {
|
9
|
+
type: DIDTypeStr;
|
10
|
+
pk: string;
|
11
|
+
sk: string;
|
12
|
+
address: string;
|
13
|
+
};
|
14
|
+
export interface WalletObject<T extends BytesType = string> {
|
15
|
+
type: DIDType;
|
16
|
+
secretKey: T;
|
17
|
+
publicKey: T;
|
18
|
+
address: string;
|
19
|
+
hash(data: BytesType, round?: number, encoding?: 'hex'): string;
|
20
|
+
hash(data: BytesType, round?: number, encoding?: 'base16'): string;
|
21
|
+
hash(data: BytesType, round?: number, encoding?: 'base58'): string;
|
22
|
+
hash(data: BytesType, round?: number, encoding?: 'base64'): string;
|
23
|
+
hash(data: BytesType, round?: number, encoding?: 'buffer'): Buffer;
|
24
|
+
hash(data: BytesType, round?: number, encoding?: 'Uint8Array'): Uint8Array;
|
25
|
+
hash(data: BytesType, round?: number, encoding?: EncodingType): BytesType;
|
26
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'hex'): string;
|
27
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base16'): string;
|
28
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base58'): string;
|
29
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base64'): string;
|
30
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'buffer'): Buffer;
|
31
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'Uint8Array'): Uint8Array;
|
32
|
+
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: EncodingType): BytesType;
|
33
|
+
verify(data: BytesType, signature: BytesType, hashBeforeVerify?: boolean, extra?: any): Promise<boolean>;
|
34
|
+
ethHash(data: string): string;
|
35
|
+
ethSign(data: string, hashBeforeSign?: boolean): string;
|
36
|
+
ethVerify(data: string, signature: string, hashBeforeVerify?: boolean): boolean;
|
37
|
+
toJSON(): SerializedWallet;
|
38
|
+
/**
|
39
|
+
* @deprecated ES6: use `wallet.address` instead
|
40
|
+
*/
|
41
|
+
toAddress(): string;
|
42
|
+
}
|
43
|
+
export declare const WalletType: typeof DidType;
|
44
|
+
/**
|
45
|
+
* Generate an wallet instance that can be used to sign a message or verify a signature
|
46
|
+
*/
|
47
|
+
export declare function Wallet<T extends BytesType = string>(keyPair: KeyPairType<T>, t?: DIDTypeArg): WalletObject<T>;
|
48
|
+
/**
|
49
|
+
* Generate a wallet from secretKey
|
50
|
+
*
|
51
|
+
* @example
|
52
|
+
* const assert = require('assert');
|
53
|
+
* const { fromSecretKey } = require('@ocap/wallet');
|
54
|
+
*
|
55
|
+
* const sk =
|
56
|
+
* '0xD67C071B6F51D2B61180B9B1AA9BE0DD0704619F0E30453AB4A592B036EDE644E4852B7091317E3622068E62A5127D1FB0D4AE2FC50213295E10652D2F0ABFC7';
|
57
|
+
* const sig =
|
58
|
+
* '0x08a102851c38c072e42756c1cc70938b5499c8e9358dfe5f383823f56cdb282ffda60fcd581a02c6c673069e5afc0bf09abbe3639b61b84d64fd58ef9f083003';
|
59
|
+
*
|
60
|
+
* const wallet = fromSecretKey(sk, type);
|
61
|
+
* const message = 'data to sign';
|
62
|
+
* const signature = wallet.sign(message);
|
63
|
+
* assert.equal(signature, sig, "signature should match");
|
64
|
+
* assert.ok(wallet.verify(message, signature), "signature should be verified");
|
65
|
+
*/
|
66
|
+
export declare function fromSecretKey<T extends BytesType = string>(sk: T, _type?: DIDTypeArg): WalletObject<T>;
|
67
|
+
/**
|
68
|
+
* Generate a wallet from publicKey
|
69
|
+
*/
|
70
|
+
export declare function fromPublicKey<T extends BytesType = string>(pk: T, _type?: DIDTypeArg): WalletObject<T>;
|
71
|
+
/**
|
72
|
+
* Generate a wallet from address (did)
|
73
|
+
*
|
74
|
+
* Since we do not know the publicKey and secretKey, this kind of wallet cannot be used for signing and verifying
|
75
|
+
*/
|
76
|
+
export declare function fromAddress<T extends BytesType = string>(address: string): WalletObject<T>;
|
77
|
+
/**
|
78
|
+
* Generate a wallet by generating a random secretKey
|
79
|
+
*/
|
80
|
+
export declare function fromRandom<T extends BytesType = string>(_type?: DIDTypeArg): WalletObject<T>;
|
81
|
+
/**
|
82
|
+
* Generating a wallet from a serialized json presentation of another wallet
|
83
|
+
*/
|
84
|
+
export declare function fromJSON<T extends BytesType = string>(json: SerializedWallet): WalletObject<T>;
|
85
|
+
/**
|
86
|
+
* Check if an object is valid wallet object
|
87
|
+
*/
|
88
|
+
export declare function isValid(wallet: WalletObject, canSign?: boolean): boolean;
|
89
|
+
export {};
|
package/lib/index.js
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.WalletType = void 0;
|
4
|
+
exports.Wallet = Wallet;
|
5
|
+
exports.fromSecretKey = fromSecretKey;
|
6
|
+
exports.fromPublicKey = fromPublicKey;
|
7
|
+
exports.fromAddress = fromAddress;
|
8
|
+
exports.fromRandom = fromRandom;
|
9
|
+
exports.fromJSON = fromJSON;
|
10
|
+
exports.isValid = isValid;
|
11
|
+
const util_1 = require("@ocap/util");
|
12
|
+
const mcrypto_1 = require("@ocap/mcrypto");
|
13
|
+
const did_1 = require("@arcblock/did");
|
14
|
+
exports.WalletType = did_1.DidType;
|
15
|
+
/**
|
16
|
+
* Generate an wallet instance that can be used to sign a message or verify a signature
|
17
|
+
*/
|
18
|
+
function Wallet(keyPair, t = 'default') {
|
19
|
+
const type = (0, did_1.DidType)(t);
|
20
|
+
const signer = (0, mcrypto_1.getSigner)(type.pk);
|
21
|
+
const hasher = (0, mcrypto_1.getHasher)(type.hash);
|
22
|
+
return {
|
23
|
+
type,
|
24
|
+
secretKey: keyPair.sk,
|
25
|
+
publicKey: keyPair.pk,
|
26
|
+
address: keyPair.pk ? (0, did_1.fromPublicKey)(keyPair.pk, type) : keyPair.address,
|
27
|
+
// @ts-ignore
|
28
|
+
hash(data, round = 1, encoding = 'hex') {
|
29
|
+
return hasher(data, round, encoding);
|
30
|
+
},
|
31
|
+
// @ts-ignore
|
32
|
+
sign(data, hashBeforeSign = true, encoding = 'hex') {
|
33
|
+
if (!keyPair.sk) {
|
34
|
+
throw new Error('Cannot sign data without a secretKey');
|
35
|
+
}
|
36
|
+
if (hashBeforeSign) {
|
37
|
+
const hash = hasher(data, 1);
|
38
|
+
return signer.sign(hash, keyPair.sk, encoding);
|
39
|
+
}
|
40
|
+
return signer.sign(data, keyPair.sk, encoding);
|
41
|
+
},
|
42
|
+
// eslint-disable-next-line require-await
|
43
|
+
async verify(data, signature, hashBeforeVerify = true, extra) {
|
44
|
+
if (!keyPair.pk) {
|
45
|
+
throw new Error('Cannot verify data without a publicKey');
|
46
|
+
}
|
47
|
+
const hash = hashBeforeVerify ? hasher(data, 1) : data;
|
48
|
+
return signer.verify(hash, signature, keyPair.pk, extra);
|
49
|
+
},
|
50
|
+
ethHash(data) {
|
51
|
+
if (typeof signer.ethHash !== 'function') {
|
52
|
+
throw new Error('ethHash is not supported by signer');
|
53
|
+
}
|
54
|
+
return signer.ethHash(data);
|
55
|
+
},
|
56
|
+
ethSign(data, hashBeforeSign = true) {
|
57
|
+
if (!keyPair.sk) {
|
58
|
+
throw new Error('Cannot sign data without a secretKey');
|
59
|
+
}
|
60
|
+
if (typeof signer.ethHash !== 'function') {
|
61
|
+
throw new Error('ethSign is not supported by signer');
|
62
|
+
}
|
63
|
+
if (hashBeforeSign) {
|
64
|
+
return signer.ethSign(signer.ethHash(data), (0, util_1.toHex)(keyPair.sk));
|
65
|
+
}
|
66
|
+
return signer.ethSign(data, (0, util_1.toHex)(keyPair.sk));
|
67
|
+
},
|
68
|
+
ethVerify(data, signature, hashBeforeVerify = true) {
|
69
|
+
if (typeof signer.ethHash !== 'function') {
|
70
|
+
throw new Error('ethVerify is not supported by signer');
|
71
|
+
}
|
72
|
+
const hash = hashBeforeVerify ? signer.ethHash(data) : data;
|
73
|
+
return signer.ethRecover(hash, signature) === this.address;
|
74
|
+
},
|
75
|
+
// deprecated
|
76
|
+
toAddress() {
|
77
|
+
return keyPair.pk ? (0, did_1.fromPublicKey)(keyPair.pk, type) : keyPair.address;
|
78
|
+
},
|
79
|
+
toJSON() {
|
80
|
+
return {
|
81
|
+
type: did_1.DidType.toJSON(type),
|
82
|
+
sk: (0, util_1.toHex)(keyPair.sk),
|
83
|
+
pk: (0, util_1.toHex)(keyPair.pk),
|
84
|
+
address: this.address,
|
85
|
+
};
|
86
|
+
},
|
87
|
+
};
|
88
|
+
}
|
89
|
+
/**
|
90
|
+
* Generate a wallet from secretKey
|
91
|
+
*
|
92
|
+
* @example
|
93
|
+
* const assert = require('assert');
|
94
|
+
* const { fromSecretKey } = require('@ocap/wallet');
|
95
|
+
*
|
96
|
+
* const sk =
|
97
|
+
* '0xD67C071B6F51D2B61180B9B1AA9BE0DD0704619F0E30453AB4A592B036EDE644E4852B7091317E3622068E62A5127D1FB0D4AE2FC50213295E10652D2F0ABFC7';
|
98
|
+
* const sig =
|
99
|
+
* '0x08a102851c38c072e42756c1cc70938b5499c8e9358dfe5f383823f56cdb282ffda60fcd581a02c6c673069e5afc0bf09abbe3639b61b84d64fd58ef9f083003';
|
100
|
+
*
|
101
|
+
* const wallet = fromSecretKey(sk, type);
|
102
|
+
* const message = 'data to sign';
|
103
|
+
* const signature = wallet.sign(message);
|
104
|
+
* assert.equal(signature, sig, "signature should match");
|
105
|
+
* assert.ok(wallet.verify(message, signature), "signature should be verified");
|
106
|
+
*/
|
107
|
+
function fromSecretKey(sk, _type = 'default') {
|
108
|
+
const type = (0, did_1.DidType)(_type);
|
109
|
+
const keyPair = { sk, pk: (0, mcrypto_1.getSigner)(type.pk).getPublicKey(sk) };
|
110
|
+
return Wallet(keyPair, type);
|
111
|
+
}
|
112
|
+
/**
|
113
|
+
* Generate a wallet from publicKey
|
114
|
+
*/
|
115
|
+
function fromPublicKey(pk, _type = 'default') {
|
116
|
+
return Wallet({ pk }, (0, did_1.DidType)(_type));
|
117
|
+
}
|
118
|
+
/**
|
119
|
+
* Generate a wallet from address (did)
|
120
|
+
*
|
121
|
+
* Since we do not know the publicKey and secretKey, this kind of wallet cannot be used for signing and verifying
|
122
|
+
*/
|
123
|
+
function fromAddress(address) {
|
124
|
+
return Wallet({ address: (0, did_1.toAddress)(address) }, (0, did_1.toTypeInfo)(address));
|
125
|
+
}
|
126
|
+
/**
|
127
|
+
* Generate a wallet by generating a random secretKey
|
128
|
+
*/
|
129
|
+
function fromRandom(_type = 'default') {
|
130
|
+
const type = (0, did_1.DidType)(_type);
|
131
|
+
const signer = (0, mcrypto_1.getSigner)(type.pk);
|
132
|
+
const keyPair = signer.genKeyPair();
|
133
|
+
return Wallet({ sk: keyPair.secretKey, pk: keyPair.publicKey }, type);
|
134
|
+
}
|
135
|
+
/**
|
136
|
+
* Generating a wallet from a serialized json presentation of another wallet
|
137
|
+
*/
|
138
|
+
function fromJSON(json) {
|
139
|
+
const type = did_1.DidType.fromJSON(json.type);
|
140
|
+
// @ts-ignore
|
141
|
+
return Wallet(json, type);
|
142
|
+
}
|
143
|
+
/**
|
144
|
+
* Check if an object is valid wallet object
|
145
|
+
*/
|
146
|
+
function isValid(wallet, canSign = true) {
|
147
|
+
if (!wallet || typeof wallet !== 'object') {
|
148
|
+
return false;
|
149
|
+
}
|
150
|
+
if (typeof wallet.verify !== 'function') {
|
151
|
+
return false;
|
152
|
+
}
|
153
|
+
if (typeof wallet.toAddress !== 'function') {
|
154
|
+
return false;
|
155
|
+
}
|
156
|
+
if (typeof wallet.toJSON !== 'function') {
|
157
|
+
return false;
|
158
|
+
}
|
159
|
+
if (!wallet.type || !wallet.publicKey) {
|
160
|
+
return false;
|
161
|
+
}
|
162
|
+
if (canSign) {
|
163
|
+
if (!wallet.secretKey) {
|
164
|
+
return false;
|
165
|
+
}
|
166
|
+
if (typeof wallet.sign !== 'function') {
|
167
|
+
return false;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
return true;
|
171
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ocap/wallet",
|
3
|
-
"version": "1.19.
|
3
|
+
"version": "1.19.2",
|
4
4
|
"description": "Utility function to create and use an forge compatible crypto wallet",
|
5
5
|
"keywords": [
|
6
6
|
"crypto",
|
@@ -21,15 +21,11 @@
|
|
21
21
|
"homepage": "https://github.com/ArcBlock/blockchain/tree/master/core/forge-wallet",
|
22
22
|
"license": "Apache-2.0",
|
23
23
|
"main": "./lib/index.js",
|
24
|
-
"
|
25
|
-
"
|
26
|
-
|
27
|
-
"
|
28
|
-
|
29
|
-
"require": "./lib/index.js",
|
30
|
-
"default": "./esm/index.js"
|
31
|
-
}
|
32
|
-
},
|
24
|
+
"types": "./lib/index.d.ts",
|
25
|
+
"files": [
|
26
|
+
"lib",
|
27
|
+
"esm"
|
28
|
+
],
|
33
29
|
"devDependencies": {
|
34
30
|
"@arcblock/eslint-config-ts": "0.3.3",
|
35
31
|
"@types/jest": "^29.5.13",
|
@@ -59,9 +55,9 @@
|
|
59
55
|
"url": "https://github.com/ArcBlock/blockchain/issues"
|
60
56
|
},
|
61
57
|
"dependencies": {
|
62
|
-
"@arcblock/did": "1.19.
|
63
|
-
"@ocap/mcrypto": "1.19.
|
64
|
-
"@ocap/util": "1.19.
|
58
|
+
"@arcblock/did": "1.19.2",
|
59
|
+
"@ocap/mcrypto": "1.19.2",
|
60
|
+
"@ocap/util": "1.19.2"
|
65
61
|
},
|
66
|
-
"gitHead": "
|
62
|
+
"gitHead": "6fd339211e6500fbb5cac6401a25130e629345b9"
|
67
63
|
}
|
package/.eslintrc.js
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
const path = require('path');
|
2
|
-
|
3
|
-
module.exports = {
|
4
|
-
root: true,
|
5
|
-
extends: ['@arcblock/eslint-config-ts/base'],
|
6
|
-
parserOptions: {
|
7
|
-
project: path.resolve(__dirname, 'tsconfig.eslint.json'),
|
8
|
-
},
|
9
|
-
rules: {
|
10
|
-
'@typescript-eslint/comma-dangle': 'off',
|
11
|
-
},
|
12
|
-
};
|
package/docs/README.md
DELETED
@@ -1,186 +0,0 @@
|
|
1
|
-
## Modules
|
2
|
-
|
3
|
-
<dl>
|
4
|
-
<dt><a href="#module_@ocap/wallet">@ocap/wallet</a></dt>
|
5
|
-
<dd><p>This module wraps common utility functions to help developers manipulate crypto wallets</p>
|
6
|
-
</dd>
|
7
|
-
</dl>
|
8
|
-
|
9
|
-
## Typedefs
|
10
|
-
|
11
|
-
<dl>
|
12
|
-
<dt><a href="#WalletObject">WalletObject</a></dt>
|
13
|
-
<dd></dd>
|
14
|
-
</dl>
|
15
|
-
|
16
|
-
## @ocap/wallet
|
17
|
-
|
18
|
-
This module wraps common utility functions to help developers manipulate crypto wallets
|
19
|
-
|
20
|
-
**Requires**: `module:@ocap/mcrypto`, `module:@arcblock/did`\
|
21
|
-
**Example**
|
22
|
-
|
23
|
-
```js
|
24
|
-
yarn add @ocap/wallet
|
25
|
-
```
|
26
|
-
|
27
|
-
* [Wallet(keyPair, \[type\])](#Wallet) ⇒ [`WalletObject`](#WalletObject)
|
28
|
-
* [fromSecretKey(sk, \[type\])](#fromSecretKey) ⇒ [`WalletObject`](#WalletObject)
|
29
|
-
* [fromPublicKey(pk, \[type\])](#fromPublicKey) ⇒ [`WalletObject`](#WalletObject)
|
30
|
-
* [fromAddress(address)](#fromAddress) ⇒ [`WalletObject`](#WalletObject)
|
31
|
-
* [fromRandom(\[type\])](#fromRandom) ⇒ [`WalletObject`](#WalletObject)
|
32
|
-
* [fromJSON(json)](#fromJSON) ⇒ [`WalletObject`](#WalletObject)
|
33
|
-
* [isValid(wallet, canSign)](#isValid)
|
34
|
-
|
35
|
-
### Wallet(keyPair, \[type]) ⇒ [`WalletObject`](#WalletObject)
|
36
|
-
|
37
|
-
Generate an wallet instance that can be used to sign a message or verify a signature
|
38
|
-
|
39
|
-
**Kind**: static method\
|
40
|
-
**Returns**: [`WalletObject`](#WalletObject) - wallet object that can be used to sign/verify/getAddress\
|
41
|
-
**Access**: public
|
42
|
-
|
43
|
-
| Param | Type | Default | Description |
|
44
|
-
| --- | --- | --- | --- |
|
45
|
-
| keyPair | `object` | | the key pair |
|
46
|
-
| keyPair.sk | `string` | | the secretKey |
|
47
|
-
| keyPair.pk | `string` | | the wallet publicKey |
|
48
|
-
| \[type] | `DidType` | `'default'` | wallet type |
|
49
|
-
|
50
|
-
### fromSecretKey(sk, \[type]) ⇒ [`WalletObject`](#WalletObject)
|
51
|
-
|
52
|
-
Generate a wallet from secretKey
|
53
|
-
|
54
|
-
**Kind**: static method\
|
55
|
-
**Returns**: [`WalletObject`](#WalletObject) - wallet object that can be used to sign/verify/getAddress\
|
56
|
-
**Access**: public
|
57
|
-
|
58
|
-
| Param | Type | Default | Description |
|
59
|
-
| --- | --- | --- | --- |
|
60
|
-
| sk | `string` | | the secret key, `hex encoded string` |
|
61
|
-
| \[type] | `DidType` | `'default'` | wallet type |
|
62
|
-
|
63
|
-
**Example**
|
64
|
-
|
65
|
-
```js
|
66
|
-
const assert = require('assert');
|
67
|
-
const { fromSecretKey } = require('@ocap/wallet');
|
68
|
-
|
69
|
-
const sk =
|
70
|
-
'0xD67C071B6F51D2B61180B9B1AA9BE0DD0704619F0E30453AB4A592B036EDE644E4852B7091317E3622068E62A5127D1FB0D4AE2FC50213295E10652D2F0ABFC7';
|
71
|
-
const sig =
|
72
|
-
'0x08a102851c38c072e42756c1cc70938b5499c8e9358dfe5f383823f56cdb282ffda60fcd581a02c6c673069e5afc0bf09abbe3639b61b84d64fd58ef9f083003';
|
73
|
-
|
74
|
-
const wallet = fromSecretKey(sk, type);
|
75
|
-
const message = 'data to sign';
|
76
|
-
const signature = wallet.sign(message);
|
77
|
-
assert.equal(signature, sig, "signature should match");
|
78
|
-
assert.ok(wallet.verify(message, signature), "signature should be verified");
|
79
|
-
```
|
80
|
-
|
81
|
-
### fromPublicKey(pk, \[type]) ⇒ [`WalletObject`](#WalletObject)
|
82
|
-
|
83
|
-
Generate a wallet from publicKey
|
84
|
-
|
85
|
-
**Kind**: static method\
|
86
|
-
**Returns**: [`WalletObject`](#WalletObject) - wallet object that can be used to sign/verify/getAddress\
|
87
|
-
**Access**: public
|
88
|
-
|
89
|
-
| Param | Type | Default | Description |
|
90
|
-
| --- | --- | --- | --- |
|
91
|
-
| pk | `string` | | the public key, `hex encoded string` |
|
92
|
-
| \[type] | `DidType` | `'default'` | wallet type |
|
93
|
-
|
94
|
-
### fromAddress(address) ⇒ [`WalletObject`](#WalletObject)
|
95
|
-
|
96
|
-
Generate a wallet from address (did)
|
97
|
-
|
98
|
-
Since we do not know the publicKey and secretKey, this kind of wallet cannot be used for signing and verifying
|
99
|
-
|
100
|
-
**Kind**: static method\
|
101
|
-
**Returns**: [`WalletObject`](#WalletObject) - wallet object that can be used to sign/verify/getAddress\
|
102
|
-
**Access**: public
|
103
|
-
|
104
|
-
| Param | Type | Description |
|
105
|
-
| --- | --- | --- |
|
106
|
-
| address | `string` | the wallet address |
|
107
|
-
|
108
|
-
**Example**
|
109
|
-
|
110
|
-
```js
|
111
|
-
const assert = require('assert');
|
112
|
-
const { fromAddress } = require('@ocap/wallet');
|
113
|
-
|
114
|
-
const address = 'zNKtCNqYWLYWYW3gWRA1vnRykfCBZYHZvzKr';
|
115
|
-
const wallet = fromAddress(address);
|
116
|
-
console.log(wallet.toJSON());
|
117
|
-
```
|
118
|
-
|
119
|
-
### fromRandom(\[type]) ⇒ [`WalletObject`](#WalletObject)
|
120
|
-
|
121
|
-
Generate a wallet by generating a random secretKey
|
122
|
-
|
123
|
-
**Kind**: static method\
|
124
|
-
**Returns**: [`WalletObject`](#WalletObject) - wallet object that can be used to sign/verify/getAddress\
|
125
|
-
**Access**: public
|
126
|
-
|
127
|
-
| Param | Type | Default | Description |
|
128
|
-
| --- | --- | --- | --- |
|
129
|
-
| \[type] | `DidType` | `'default'` | wallet type |
|
130
|
-
|
131
|
-
**Example**
|
132
|
-
|
133
|
-
```js
|
134
|
-
const { fromRandom } = require('@ocap/wallet');
|
135
|
-
const wallet = fromRandom();
|
136
|
-
// Do something with wallet
|
137
|
-
```
|
138
|
-
|
139
|
-
### fromJSON(json) ⇒ [`WalletObject`](#WalletObject)
|
140
|
-
|
141
|
-
Generating a wallet from a serialized json presentation of another wallet
|
142
|
-
|
143
|
-
**Kind**: static method\
|
144
|
-
**Returns**: [`WalletObject`](#WalletObject) - wallet object that can be used to sign/verify/getAddress\
|
145
|
-
**Access**: public
|
146
|
-
|
147
|
-
| Param | Type | Description |
|
148
|
-
| --- | --- | --- |
|
149
|
-
| json | `object` | json presentation of a wallet |
|
150
|
-
|
151
|
-
**Example**
|
152
|
-
|
153
|
-
```js
|
154
|
-
const { fromJSON, fromRandom } = require('@ocap/wallet');
|
155
|
-
const wallet = fromRandom();
|
156
|
-
const wallet2 = fromJSON(wallet.toJSON());
|
157
|
-
// wallet2 is identical to wallet
|
158
|
-
```
|
159
|
-
|
160
|
-
### isValid(wallet, canSign)
|
161
|
-
|
162
|
-
Check if an object is valid wallet object
|
163
|
-
|
164
|
-
**Kind**: static method\
|
165
|
-
**Access**: public
|
166
|
-
|
167
|
-
| Param | Type | Default | Description |
|
168
|
-
| --- | --- | --- | --- |
|
169
|
-
| wallet | `object` | | |
|
170
|
-
| canSign | `boolean` | `true` | should the wallet support sign |
|
171
|
-
|
172
|
-
## WalletObject
|
173
|
-
|
174
|
-
**Kind**: global typedef\
|
175
|
-
**Access**: public\
|
176
|
-
**Properties**
|
177
|
-
|
178
|
-
| Name | Type | Description |
|
179
|
-
| --- | --- | --- |
|
180
|
-
| type | `DidType` | Indicates the wallet type |
|
181
|
-
| secretKey | `secretKey` | Wallet secretKey |
|
182
|
-
| publicKey | `publicKey` | Wallet publicKey |
|
183
|
-
| sign | `function` | Sign `data`, data is hashed using the `HashType` defined in type before signing |
|
184
|
-
| verify | `function` | Verify `signature`, data is hashed using the `HashType` defined in type before verifying |
|
185
|
-
| toAddress | `function` | Get wallet address without `did:abt:` prefix |
|
186
|
-
| toJSON | `function` | Serialize wallet to json object, checkout [fromJSON](fromJSON) for deserialisation |
|
package/jest.config.js
DELETED
package/src/index.ts
DELETED
@@ -1,235 +0,0 @@
|
|
1
|
-
import { toHex, EncodingType, BytesType } from '@ocap/util';
|
2
|
-
import { getSigner, getHasher } from '@ocap/mcrypto';
|
3
|
-
import {
|
4
|
-
toAddress,
|
5
|
-
fromPublicKey as DIDFromPublicKey,
|
6
|
-
toTypeInfo,
|
7
|
-
DidType,
|
8
|
-
DIDType,
|
9
|
-
DIDTypeStr,
|
10
|
-
DIDTypeArg,
|
11
|
-
} from '@arcblock/did';
|
12
|
-
|
13
|
-
type KeyPairType<T extends BytesType = string> = {
|
14
|
-
sk?: T;
|
15
|
-
pk?: T;
|
16
|
-
address?: string;
|
17
|
-
};
|
18
|
-
|
19
|
-
export type SerializedWallet = {
|
20
|
-
type: DIDTypeStr;
|
21
|
-
pk: string;
|
22
|
-
sk: string;
|
23
|
-
address: string;
|
24
|
-
};
|
25
|
-
|
26
|
-
export interface WalletObject<T extends BytesType = string> {
|
27
|
-
type: DIDType;
|
28
|
-
secretKey: T;
|
29
|
-
publicKey: T;
|
30
|
-
address: string;
|
31
|
-
|
32
|
-
hash(data: BytesType, round?: number, encoding?: 'hex'): string;
|
33
|
-
hash(data: BytesType, round?: number, encoding?: 'base16'): string;
|
34
|
-
hash(data: BytesType, round?: number, encoding?: 'base58'): string;
|
35
|
-
hash(data: BytesType, round?: number, encoding?: 'base64'): string;
|
36
|
-
hash(data: BytesType, round?: number, encoding?: 'buffer'): Buffer;
|
37
|
-
hash(data: BytesType, round?: number, encoding?: 'Uint8Array'): Uint8Array;
|
38
|
-
hash(data: BytesType, round?: number, encoding?: EncodingType): BytesType;
|
39
|
-
|
40
|
-
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'hex'): string;
|
41
|
-
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base16'): string;
|
42
|
-
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base58'): string;
|
43
|
-
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'base64'): string;
|
44
|
-
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'buffer'): Buffer;
|
45
|
-
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: 'Uint8Array'): Uint8Array;
|
46
|
-
sign(data: BytesType, hashBeforeSign?: boolean, encoding?: EncodingType): BytesType;
|
47
|
-
|
48
|
-
verify(data: BytesType, signature: BytesType, hashBeforeVerify?: boolean, extra?: any): Promise<boolean>;
|
49
|
-
|
50
|
-
ethHash(data: string): string;
|
51
|
-
ethSign(data: string, hashBeforeSign?: boolean): string;
|
52
|
-
ethVerify(data: string, signature: string, hashBeforeVerify?: boolean): boolean;
|
53
|
-
|
54
|
-
toJSON(): SerializedWallet;
|
55
|
-
|
56
|
-
/**
|
57
|
-
* @deprecated ES6: use `wallet.address` instead
|
58
|
-
*/
|
59
|
-
toAddress(): string;
|
60
|
-
}
|
61
|
-
|
62
|
-
export const WalletType = DidType;
|
63
|
-
|
64
|
-
/**
|
65
|
-
* Generate an wallet instance that can be used to sign a message or verify a signature
|
66
|
-
*/
|
67
|
-
export function Wallet<T extends BytesType = string>(
|
68
|
-
keyPair: KeyPairType<T>,
|
69
|
-
t: DIDTypeArg = 'default'
|
70
|
-
): WalletObject<T> {
|
71
|
-
const type = DidType(t);
|
72
|
-
const signer = getSigner(type.pk);
|
73
|
-
const hasher = getHasher(type.hash);
|
74
|
-
return {
|
75
|
-
type,
|
76
|
-
secretKey: keyPair.sk,
|
77
|
-
publicKey: keyPair.pk,
|
78
|
-
address: keyPair.pk ? DIDFromPublicKey(keyPair.pk, type) : keyPair.address,
|
79
|
-
|
80
|
-
// @ts-ignore
|
81
|
-
hash(data: BytesType, round = 1, encoding: EncodingType = 'hex'): BytesType {
|
82
|
-
return hasher(data, round, encoding);
|
83
|
-
},
|
84
|
-
|
85
|
-
// @ts-ignore
|
86
|
-
sign(data: BytesType, hashBeforeSign = true, encoding: EncodingType = 'hex'): BytesType {
|
87
|
-
if (!keyPair.sk) {
|
88
|
-
throw new Error('Cannot sign data without a secretKey');
|
89
|
-
}
|
90
|
-
if (hashBeforeSign) {
|
91
|
-
const hash = hasher(data, 1);
|
92
|
-
return signer.sign(hash, keyPair.sk, encoding);
|
93
|
-
}
|
94
|
-
return signer.sign(data, keyPair.sk, encoding);
|
95
|
-
},
|
96
|
-
|
97
|
-
// eslint-disable-next-line require-await
|
98
|
-
async verify(data: BytesType, signature: BytesType, hashBeforeVerify = true, extra?: any): Promise<boolean> {
|
99
|
-
if (!keyPair.pk) {
|
100
|
-
throw new Error('Cannot verify data without a publicKey');
|
101
|
-
}
|
102
|
-
const hash = hashBeforeVerify ? hasher(data, 1) : data;
|
103
|
-
return signer.verify(hash, signature, keyPair.pk, extra);
|
104
|
-
},
|
105
|
-
|
106
|
-
ethHash(data: string): string {
|
107
|
-
if (typeof signer.ethHash !== 'function') {
|
108
|
-
throw new Error('ethHash is not supported by signer');
|
109
|
-
}
|
110
|
-
return signer.ethHash(data);
|
111
|
-
},
|
112
|
-
ethSign(data: string, hashBeforeSign = true): string {
|
113
|
-
if (!keyPair.sk) {
|
114
|
-
throw new Error('Cannot sign data without a secretKey');
|
115
|
-
}
|
116
|
-
if (typeof signer.ethHash !== 'function') {
|
117
|
-
throw new Error('ethSign is not supported by signer');
|
118
|
-
}
|
119
|
-
if (hashBeforeSign) {
|
120
|
-
return signer.ethSign(signer.ethHash(data), toHex(keyPair.sk));
|
121
|
-
}
|
122
|
-
return signer.ethSign(data, toHex(keyPair.sk));
|
123
|
-
},
|
124
|
-
ethVerify(data: string, signature: string, hashBeforeVerify = true): boolean {
|
125
|
-
if (typeof signer.ethHash !== 'function') {
|
126
|
-
throw new Error('ethVerify is not supported by signer');
|
127
|
-
}
|
128
|
-
const hash = hashBeforeVerify ? signer.ethHash(data) : data;
|
129
|
-
return signer.ethRecover(hash, signature) === this.address;
|
130
|
-
},
|
131
|
-
|
132
|
-
// deprecated
|
133
|
-
toAddress(): string {
|
134
|
-
return keyPair.pk ? DIDFromPublicKey(keyPair.pk, type) : keyPair.address;
|
135
|
-
},
|
136
|
-
|
137
|
-
toJSON(): SerializedWallet {
|
138
|
-
return {
|
139
|
-
type: DidType.toJSON(type),
|
140
|
-
sk: toHex(keyPair.sk),
|
141
|
-
pk: toHex(keyPair.pk),
|
142
|
-
address: this.address,
|
143
|
-
};
|
144
|
-
},
|
145
|
-
};
|
146
|
-
}
|
147
|
-
|
148
|
-
/**
|
149
|
-
* Generate a wallet from secretKey
|
150
|
-
*
|
151
|
-
* @example
|
152
|
-
* const assert = require('assert');
|
153
|
-
* const { fromSecretKey } = require('@ocap/wallet');
|
154
|
-
*
|
155
|
-
* const sk =
|
156
|
-
* '0xD67C071B6F51D2B61180B9B1AA9BE0DD0704619F0E30453AB4A592B036EDE644E4852B7091317E3622068E62A5127D1FB0D4AE2FC50213295E10652D2F0ABFC7';
|
157
|
-
* const sig =
|
158
|
-
* '0x08a102851c38c072e42756c1cc70938b5499c8e9358dfe5f383823f56cdb282ffda60fcd581a02c6c673069e5afc0bf09abbe3639b61b84d64fd58ef9f083003';
|
159
|
-
*
|
160
|
-
* const wallet = fromSecretKey(sk, type);
|
161
|
-
* const message = 'data to sign';
|
162
|
-
* const signature = wallet.sign(message);
|
163
|
-
* assert.equal(signature, sig, "signature should match");
|
164
|
-
* assert.ok(wallet.verify(message, signature), "signature should be verified");
|
165
|
-
*/
|
166
|
-
export function fromSecretKey<T extends BytesType = string>(sk: T, _type: DIDTypeArg = 'default'): WalletObject<T> {
|
167
|
-
const type = DidType(_type);
|
168
|
-
const keyPair = { sk, pk: getSigner(type.pk).getPublicKey(sk) as T };
|
169
|
-
return Wallet<T>(keyPair, type);
|
170
|
-
}
|
171
|
-
|
172
|
-
/**
|
173
|
-
* Generate a wallet from publicKey
|
174
|
-
*/
|
175
|
-
export function fromPublicKey<T extends BytesType = string>(pk: T, _type: DIDTypeArg = 'default'): WalletObject<T> {
|
176
|
-
return Wallet<T>({ pk }, DidType(_type));
|
177
|
-
}
|
178
|
-
|
179
|
-
/**
|
180
|
-
* Generate a wallet from address (did)
|
181
|
-
*
|
182
|
-
* Since we do not know the publicKey and secretKey, this kind of wallet cannot be used for signing and verifying
|
183
|
-
*/
|
184
|
-
export function fromAddress<T extends BytesType = string>(address: string): WalletObject<T> {
|
185
|
-
return Wallet<T>({ address: toAddress(address) }, toTypeInfo(address));
|
186
|
-
}
|
187
|
-
|
188
|
-
/**
|
189
|
-
* Generate a wallet by generating a random secretKey
|
190
|
-
*/
|
191
|
-
export function fromRandom<T extends BytesType = string>(_type: DIDTypeArg = 'default'): WalletObject<T> {
|
192
|
-
const type = DidType(_type);
|
193
|
-
const signer = getSigner(type.pk);
|
194
|
-
const keyPair = signer.genKeyPair();
|
195
|
-
return Wallet<T>({ sk: keyPair.secretKey as T, pk: keyPair.publicKey as T }, type);
|
196
|
-
}
|
197
|
-
|
198
|
-
/**
|
199
|
-
* Generating a wallet from a serialized json presentation of another wallet
|
200
|
-
*/
|
201
|
-
export function fromJSON<T extends BytesType = string>(json: SerializedWallet): WalletObject<T> {
|
202
|
-
const type = DidType.fromJSON(json.type);
|
203
|
-
// @ts-ignore
|
204
|
-
return Wallet<T>(json, type);
|
205
|
-
}
|
206
|
-
|
207
|
-
/**
|
208
|
-
* Check if an object is valid wallet object
|
209
|
-
*/
|
210
|
-
export function isValid(wallet: WalletObject, canSign = true): boolean {
|
211
|
-
if (!wallet || typeof wallet !== 'object') {
|
212
|
-
return false;
|
213
|
-
}
|
214
|
-
if (typeof wallet.verify !== 'function') {
|
215
|
-
return false;
|
216
|
-
}
|
217
|
-
if (typeof wallet.toAddress !== 'function') {
|
218
|
-
return false;
|
219
|
-
}
|
220
|
-
if (typeof wallet.toJSON !== 'function') {
|
221
|
-
return false;
|
222
|
-
}
|
223
|
-
if (!wallet.type || !wallet.publicKey) {
|
224
|
-
return false;
|
225
|
-
}
|
226
|
-
if (canSign) {
|
227
|
-
if (!wallet.secretKey) {
|
228
|
-
return false;
|
229
|
-
}
|
230
|
-
if (typeof wallet.sign !== 'function') {
|
231
|
-
return false;
|
232
|
-
}
|
233
|
-
}
|
234
|
-
return true;
|
235
|
-
}
|
package/tests/index.spec.ts
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
import { types } from '@ocap/mcrypto';
|
2
|
-
import { fromBase64 } from '@ocap/util';
|
3
|
-
import { fromRandom, fromPublicKey, fromSecretKey, fromJSON, fromAddress, isValid } from '../src/index';
|
4
|
-
|
5
|
-
const sk =
|
6
|
-
'0xD67C071B6F51D2B61180B9B1AA9BE0DD0704619F0E30453AB4A592B036EDE644E4852B7091317E3622068E62A5127D1FB0D4AE2FC50213295E10652D2F0ABFC7';
|
7
|
-
const pk = '0xE4852B7091317E3622068E62A5127D1FB0D4AE2FC50213295E10652D2F0ABFC7';
|
8
|
-
const appId = 'zNKtCNqYWLYWYW3gWRA1vnRykfCBZYHZvzKr';
|
9
|
-
const sig =
|
10
|
-
'0x8122c608f61b04f6b574f005dc8e0463d393a7fb50e0426bca587b20778a8a9f6376bab87bc3983b0a5f1c9581f6d94162317c715a3c1c0f086be1e514399109';
|
11
|
-
const type = {
|
12
|
-
role: types.RoleType.ROLE_APPLICATION,
|
13
|
-
pk: types.KeyType.ED25519,
|
14
|
-
hash: types.HashType.SHA3,
|
15
|
-
address: types.EncodingType.BASE58,
|
16
|
-
};
|
17
|
-
describe('#Wallet', () => {
|
18
|
-
test('should have basic functions', () => {
|
19
|
-
expect(typeof fromPublicKey).toEqual('function');
|
20
|
-
expect(typeof fromSecretKey).toEqual('function');
|
21
|
-
expect(typeof fromJSON).toEqual('function');
|
22
|
-
});
|
23
|
-
|
24
|
-
test('should serialize to json as expected', () => {
|
25
|
-
const wallet = fromPublicKey(pk, type);
|
26
|
-
const json = wallet.toJSON();
|
27
|
-
expect(json.address).toEqual(appId);
|
28
|
-
const wallet2 = fromJSON(json);
|
29
|
-
expect(wallet2.address).toEqual(appId);
|
30
|
-
expect(wallet2.address).toEqual(appId);
|
31
|
-
});
|
32
|
-
|
33
|
-
test('should throw error when sign without sk', () => {
|
34
|
-
const wallet = fromPublicKey(pk, type);
|
35
|
-
const hash = wallet.hash('abc');
|
36
|
-
expect(hash).toEqual('0x3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532');
|
37
|
-
try {
|
38
|
-
wallet.sign('data to sign');
|
39
|
-
} catch (err) {
|
40
|
-
expect(err).toBeTruthy();
|
41
|
-
}
|
42
|
-
});
|
43
|
-
|
44
|
-
test('should sign when sk is provided', async () => {
|
45
|
-
const wallet = fromSecretKey(sk, type);
|
46
|
-
const hash = wallet.hash('abc');
|
47
|
-
expect(hash).toEqual('0x3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532');
|
48
|
-
const message = 'data to sign';
|
49
|
-
const signature = wallet.sign(message);
|
50
|
-
expect(signature).toEqual(sig);
|
51
|
-
expect(await wallet.verify(message, signature)).toEqual(true);
|
52
|
-
expect(() => fromSecretKey('abc')).toThrow();
|
53
|
-
});
|
54
|
-
|
55
|
-
test('should gen type from address', () => {
|
56
|
-
const wallet = fromAddress(appId);
|
57
|
-
expect(wallet.type.pk).toEqual(type.pk);
|
58
|
-
expect(wallet.type.hash).toEqual(type.hash);
|
59
|
-
expect(wallet.type.role).toEqual(type.role);
|
60
|
-
});
|
61
|
-
|
62
|
-
test('should detect invalid wallets', () => {
|
63
|
-
const wallet = fromRandom();
|
64
|
-
expect(isValid(wallet)).toEqual(true);
|
65
|
-
const wallet2 = fromPublicKey(pk, type);
|
66
|
-
expect(isValid(wallet2, false)).toEqual(true);
|
67
|
-
});
|
68
|
-
|
69
|
-
test('should generate base58 address', () => {
|
70
|
-
const wallet = fromRandom();
|
71
|
-
expect(wallet.toAddress().startsWith('z')).toBeTruthy();
|
72
|
-
expect(wallet.address.startsWith('z')).toBeTruthy();
|
73
|
-
expect(() => wallet.ethHash('abc')).toThrow();
|
74
|
-
expect(() => wallet.ethSign('abc')).toThrow();
|
75
|
-
});
|
76
|
-
|
77
|
-
test('should generate base16 address', () => {
|
78
|
-
const wallet = fromRandom('eth');
|
79
|
-
expect(wallet.address.startsWith('0x')).toBeTruthy();
|
80
|
-
});
|
81
|
-
|
82
|
-
test('should work with ethereum', async () => {
|
83
|
-
// eslint-disable-next-line
|
84
|
-
const sk = '0xfe51dc1dfe30e2f4b06f7941bdfe0341704c10e28d28e4ecd7871f8f0204fa33';
|
85
|
-
const address = '0x5547a73ed3c2Ad599114866fA1d5E8a02147D1C9';
|
86
|
-
const data = '0xef56b956483ebe2fa8ed6c35c8b884d940d57fdf535a70a2df245661c9cf42e4';
|
87
|
-
// eslint-disable-next-line
|
88
|
-
const sig = '0x242ad32e16c38307e2909600cb641da17734121d9d50df93b6240db40ad3fc2d562f3e41cc6409730cbb81c5bc90a914f24baf0d3537a7db8334dc67ed2000fe1c'; // prettier-ignore
|
89
|
-
const wallet = fromSecretKey(sk, 'eth');
|
90
|
-
expect(wallet.address).toEqual(address);
|
91
|
-
expect(wallet.ethSign(data)).toEqual(sig);
|
92
|
-
expect(wallet.ethHash(data)).toEqual('0x9f5dc66bef3e8053b02c4cb6a8504cb4d7e48862245a4d34fc69bc615080d276');
|
93
|
-
expect(await wallet.ethVerify(data, sig)).toEqual(true);
|
94
|
-
expect(() => fromSecretKey('abc', 'eth')).toThrow();
|
95
|
-
});
|
96
|
-
|
97
|
-
test('should work with passkey', async () => {
|
98
|
-
const publicKey = fromBase64(
|
99
|
-
'pQECAyYgASFYIA3GyM4rSxM_HyV52QTRwGJOdkXurky3cwTLvb_gKSF-Ilggpd0fhMlPdxHBl45_eJxqywCRl-a4IDpeFa4pcfmrxuM'
|
100
|
-
);
|
101
|
-
|
102
|
-
const wallet = fromPublicKey(publicKey, 'passkey');
|
103
|
-
expect(wallet.address).toEqual('z3i165rPumFgyQZpZ1W3VLEYBPuV2xSCAjoqo');
|
104
|
-
|
105
|
-
const challenge = '0x7E093B990CB41A97990657D6AD688BD4E28267C9FCC0A36BC15D241D5D302CEF';
|
106
|
-
const response = {
|
107
|
-
authenticatorData: 'u_rJjitfFaLnT_p0uECHZ0CSuRQE7psYSUxv2p-nql0dAAAAAA',
|
108
|
-
clientDataJSON:
|
109
|
-
'eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZmdrN21ReTBHcGVaQmxmV3JXaUwxT0tDWjhuOHdLTnJ3VjBrSFYwd0xPOCIsIm9yaWdpbiI6Imh0dHBzOi8vYmJxYXhlN2lhZGZpbWRkY2c0cmZycHRmdXp4bW12NWI2dnBudXB1bmk0NC5kaWQuYWJ0bmV0LmlvIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ',
|
110
|
-
signature: 'MEUCIQCo51Gg_3UrSotxrguG92iXcuSbW5fNZqcSsHS8zlZbdAIgEmaBD0cQeiML3Mr60HSPP176EyqNvqfTdEV1oGWhQ-o',
|
111
|
-
};
|
112
|
-
|
113
|
-
const verified = await wallet.verify(challenge, response.signature, false, JSON.stringify(response));
|
114
|
-
expect(verified).toEqual(true);
|
115
|
-
});
|
116
|
-
});
|
package/tsconfig.cjs.json
DELETED
package/tsconfig.eslint.json
DELETED