This repository has been archived by the owner on Aug 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 463
/
Copy patheosjs-jssig.ts
87 lines (75 loc) · 2.85 KB
/
eosjs-jssig.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
/**
* @module JS-Sig
*/
// copyright defined in eosjs/LICENSE.txt
import { ec } from 'elliptic';
import { SignatureProvider, SignatureProviderArgs } from './eosjs-api-interfaces';
import { PushTransactionArgs } from './eosjs-rpc-interfaces';
import {
PrivateKey,
PublicKey,
Signature,
} from './eosjs-key-conversions';
import { convertLegacyPublicKey } from './eosjs-numeric';
/** expensive to construct; so we do it once and reuse it */
const defaultEc = new ec('secp256k1');
/** Construct the digest from transaction details */
const digestFromSerializedData = (
chainId: string,
serializedTransaction: Uint8Array,
serializedContextFreeData?: Uint8Array,
e = defaultEc): string => {
const signBuf = Buffer.concat([
Buffer.from(chainId, 'hex'),
Buffer.from(serializedTransaction),
Buffer.from(
serializedContextFreeData ?
new Uint8Array(e.hash().update(serializedContextFreeData).digest()) :
new Uint8Array(32)
),
]);
return e.hash().update(signBuf).digest();
};
/** Signs transactions using in-process private keys */
class JsSignatureProvider implements SignatureProvider {
/** map public to private keys */
public keys = new Map<string, ec.KeyPair>();
/** public keys */
public availableKeys = [] as string[];
/** @param privateKeys private keys to sign with */
constructor(privateKeys: string[]) {
for (const k of privateKeys) {
const priv = PrivateKey.fromString(k);
const privElliptic = priv.toElliptic();
const pubStr = priv.getPublicKey().toString();
this.keys.set(pubStr, privElliptic);
this.availableKeys.push(pubStr);
}
}
/** Public keys associated with the private keys that the `SignatureProvider` holds */
public async getAvailableKeys(): Promise<string[]> {
return this.availableKeys;
}
/** Sign a transaction */
public async sign(
{ chainId, requiredKeys, serializedTransaction, serializedContextFreeData }: SignatureProviderArgs,
): Promise<PushTransactionArgs> {
const digest = digestFromSerializedData( chainId, serializedTransaction, serializedContextFreeData, defaultEc);
const signatures = [] as string[];
for (const key of requiredKeys) {
const publicKey = PublicKey.fromString(key);
const ellipticPrivateKey = this.keys.get(convertLegacyPublicKey(key));
const privateKey = PrivateKey.fromElliptic(ellipticPrivateKey, publicKey.getType());
const signature = privateKey.sign(digest, false);
signatures.push(signature.toString());
}
return { signatures, serializedTransaction, serializedContextFreeData };
}
}
export {
PrivateKey,
PublicKey,
Signature,
digestFromSerializedData,
JsSignatureProvider,
};