-
Notifications
You must be signed in to change notification settings - Fork 66
/
public_key.ts
126 lines (110 loc) · 2.82 KB
/
public_key.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { base58 } from "@scure/base";
import { concat } from "../utils";
export enum CurveType {
ED25519 = 0,
SECP256K1 = 1,
}
enum DataLength {
ED25519 = 32,
SECP256K1 = 64,
}
function getCurveType(curveType: CurveType | number): CurveType {
switch (curveType) {
case CurveType.ED25519:
case CurveType.SECP256K1:
return curveType;
default:
throw new UnknownCurve();
}
}
function dataLength(curveType: CurveType | number): DataLength {
switch (curveType) {
case CurveType.ED25519:
case CurveType.SECP256K1:
return {
[CurveType.ED25519]: DataLength.ED25519,
[CurveType.SECP256K1]: DataLength.SECP256K1,
}[curveType];
default:
throw new UnknownCurve();
}
}
function splitKeyTypeData(value: string): [CurveType, string] {
const idx = value.indexOf(":");
if (idx >= 0) {
return [
curveTypeFromStr(value.substring(0, idx)),
value.substring(idx + 1),
];
} else {
return [CurveType.ED25519, value];
}
}
export function curveTypeFromStr(value: string): CurveType {
switch (value) {
case "ed25519":
return CurveType.ED25519;
case "secp256k1":
return CurveType.SECP256K1;
default:
throw new UnknownCurve();
}
}
export class ParsePublicKeyError extends Error {}
export class InvalidLengthError extends ParsePublicKeyError {
constructor(public length: number, public expectedLength: number) {
super(`Invalid length: ${length}. Expected: ${expectedLength}`);
}
}
export class Base58Error extends ParsePublicKeyError {
constructor(public error: string) {
super(`Base58 error: ${error}`);
}
}
export class UnknownCurve extends ParsePublicKeyError {
constructor() {
super("Unknown curve");
}
}
/**
* A abstraction on top of the NEAR public key string.
*/
export class PublicKey {
/**
* The actual value of the public key.
*/
public data: Uint8Array;
private type: CurveType;
/**
* @param data - The string you want to create a PublicKey from.
*/
constructor(data: Uint8Array) {
const curveLenght = dataLength(data[0]);
if (data.length !== curveLenght + 1) {
throw new InvalidLengthError(data.length, curveLenght + 1);
}
this.type = getCurveType(data[0]);
this.data = data;
}
/**
* The curve type of the public key.
*/
curveType(): CurveType {
return this.type;
}
/**
* Create a public key from a public key string.
*
* @param publicKeyString - The public key string you want to create a PublicKey from.
*/
static fromString(publicKeyString: string) {
const [curve, keyData] = splitKeyTypeData(publicKeyString);
let data: Uint8Array;
try {
data = base58.decode(keyData);
} catch (error) {
throw new Base58Error(error.message);
}
return new PublicKey(concat(new Uint8Array([curve]), data));
}
}