103 lines
3.0 KiB
TypeScript
Raw Normal View History

2022-02-04 14:12:00 +11:00
import "@ethersproject/shims";
2021-08-12 15:26:06 +10:00
2022-02-04 14:12:00 +11:00
import { PublicKeyMessage } from "./messaging/wire";
2022-03-25 11:59:14 +11:00
import { hexToBytes, bytesToHex } from "js-waku/lib/utils";
2022-02-04 14:12:00 +11:00
import * as sigUtil from "eth-sig-util";
2022-03-25 11:59:14 +11:00
import { equals } from "uint8arrays/equals";
2021-08-12 15:26:06 +10:00
/**
* Sign the encryption public key with Web3. This can then be published to let other
* users know to use this encryption public key to encrypt messages for the
2021-08-12 15:26:06 +10:00
* Ethereum Address holder.
*/
export async function createPublicKeyMessage(
address: string,
2021-08-12 16:36:28 +10:00
encryptionPublicKey: Uint8Array,
providerRequest: (request: {
method: string;
params?: Array<any>;
}) => Promise<any>
2021-08-12 15:26:06 +10:00
): Promise<PublicKeyMessage> {
2021-08-12 16:36:28 +10:00
const signature = await signEncryptionKey(
encryptionPublicKey,
address,
providerRequest
2021-08-12 15:26:06 +10:00
);
2021-08-12 16:36:28 +10:00
2022-02-04 14:12:00 +11:00
console.log("Asking wallet to sign Public Key Message");
console.log("Public Key Message signed");
2021-08-12 15:26:06 +10:00
return new PublicKeyMessage({
encryptionPublicKey: encryptionPublicKey,
2022-02-14 10:50:02 +11:00
ethAddress: hexToBytes(address),
signature: hexToBytes(signature),
2021-08-12 15:26:06 +10:00
});
}
2021-08-12 16:36:28 +10:00
function buildMsgParams(encryptionPublicKey: Uint8Array, fromAddress: string) {
return JSON.stringify({
domain: {
2022-02-04 14:12:00 +11:00
name: "Ethereum Private Message over Waku",
version: "1",
2021-08-12 16:36:28 +10:00
},
message: {
2022-02-23 13:06:13 +11:00
message:
"By signing this message you certify that messages addressed to `ownerAddress` must be encrypted with `encryptionPublicKey`",
2022-02-14 10:50:02 +11:00
encryptionPublicKey: bytesToHex(encryptionPublicKey),
2021-08-12 16:36:28 +10:00
ownerAddress: fromAddress,
},
// Refers to the keys of the *types* object below.
2022-02-04 14:12:00 +11:00
primaryType: "PublishEncryptionPublicKey",
2021-08-12 16:36:28 +10:00
types: {
EIP712Domain: [
2022-02-04 14:12:00 +11:00
{ name: "name", type: "string" },
{ name: "version", type: "string" },
2021-08-12 16:36:28 +10:00
],
PublishEncryptionPublicKey: [
2022-02-23 13:06:13 +11:00
{ name: "message", type: "string" },
2022-02-04 14:12:00 +11:00
{ name: "encryptionPublicKey", type: "string" },
{ name: "ownerAddress", type: "string" },
2021-08-12 16:36:28 +10:00
],
},
});
}
export async function signEncryptionKey(
encryptionPublicKey: Uint8Array,
fromAddress: string,
providerRequest: (request: {
method: string;
params?: Array<any>;
from?: string;
}) => Promise<any>
): Promise<Uint8Array> {
const msgParams = buildMsgParams(encryptionPublicKey, fromAddress);
const result = await providerRequest({
2022-02-23 13:06:13 +11:00
method: "eth_signTypedData_v4",
2021-08-12 16:36:28 +10:00
params: [fromAddress, msgParams],
from: fromAddress,
});
2022-02-04 14:12:00 +11:00
console.log("TYPED SIGNED:" + JSON.stringify(result));
2021-08-12 16:36:28 +10:00
2022-02-14 10:50:02 +11:00
return hexToBytes(result);
2021-08-12 15:26:06 +10:00
}
/**
2021-08-12 16:36:28 +10:00
* Validate that the Encryption Public Key was signed by the holder of the given Ethereum address.
2021-08-12 15:26:06 +10:00
*/
2021-08-12 16:36:28 +10:00
export function validatePublicKeyMessage(msg: PublicKeyMessage): boolean {
const recovered = sigUtil.recoverTypedSignature_v4({
data: JSON.parse(
2022-02-14 10:50:02 +11:00
buildMsgParams(msg.encryptionPublicKey, "0x" + bytesToHex(msg.ethAddress))
2021-08-12 16:36:28 +10:00
),
2022-02-14 10:50:02 +11:00
sig: "0x" + bytesToHex(msg.signature),
2021-08-12 15:26:06 +10:00
});
2021-08-12 16:36:28 +10:00
2022-02-04 14:12:00 +11:00
console.log("Recovered", recovered);
2022-02-14 10:50:02 +11:00
console.log("ethAddress", "0x" + bytesToHex(msg.ethAddress));
2021-08-12 16:36:28 +10:00
2022-03-25 11:59:14 +11:00
return equals(hexToBytes(recovered), msg.ethAddress);
2021-08-12 15:26:06 +10:00
}