/
index.ts
56 lines (48 loc) · 2.16 KB
/
index.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
import { ethers, UnsignedTransaction } from "ethers";
import { getPublicKey, getEthereumAddress, requestKmsSignature, determineCorrectV } from "./util/aws-kms-utils";
export interface AwsKmsSignerCredentials {
accessKeyId?: string;
secretAccessKey?: string;
sessionToken?: string;
region: string;
keyId: string;
}
export class AwsKmsSigner extends ethers.Signer {
kmsCredentials: AwsKmsSignerCredentials;
ethereumAddress: string;
constructor(kmsCredentials: AwsKmsSignerCredentials, provider?: ethers.providers.Provider) {
super();
ethers.utils.defineReadOnly(this, "provider", provider || null);
ethers.utils.defineReadOnly(this, "kmsCredentials", kmsCredentials);
}
async getAddress(): Promise<string> {
if (this.ethereumAddress === undefined) {
const key = await getPublicKey(this.kmsCredentials);
this.ethereumAddress = getEthereumAddress(key.PublicKey as Buffer);
}
return Promise.resolve(this.ethereumAddress);
}
async _signDigest(digestString: string): Promise<string> {
const digestBuffer = Buffer.from(ethers.utils.arrayify(digestString));
const sig = await requestKmsSignature(digestBuffer, this.kmsCredentials);
const ethAddr = await this.getAddress();
const { v } = determineCorrectV(digestBuffer, sig.r, sig.s, ethAddr);
return ethers.utils.joinSignature({
v,
r: `0x${sig.r.toString("hex")}`,
s: `0x${sig.s.toString("hex")}`,
});
}
async signMessage(message: string | ethers.utils.Bytes): Promise<string> {
return this._signDigest(ethers.utils.hashMessage(message));
}
async signTransaction(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>): Promise<string> {
const unsignedTx = await ethers.utils.resolveProperties(transaction);
const serializedTx = ethers.utils.serializeTransaction(<UnsignedTransaction>unsignedTx);
const transactionSignature = await this._signDigest(ethers.utils.keccak256(serializedTx));
return ethers.utils.serializeTransaction(<UnsignedTransaction>unsignedTx, transactionSignature);
}
connect(provider: ethers.providers.Provider): AwsKmsSigner {
return new AwsKmsSigner(this.kmsCredentials, provider);
}
}