Ensure `ENR.create` is used instead of the constructor

This commit is contained in:
Franck Royer 2022-05-18 16:30:28 +10:00
parent 95d1ef4b4a
commit 4639537fd6
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
4 changed files with 43 additions and 43 deletions

View File

@ -8,7 +8,7 @@ import fetchNodesUntilCapabilitiesFulfilled from "./fetch_nodes";
async function createEnr(waku2: Waku2): Promise<ENR> { async function createEnr(waku2: Waku2): Promise<ENR> {
const peerId = await PeerId.create({ keyType: "secp256k1" }); const peerId = await PeerId.create({ keyType: "secp256k1" });
const enr = ENR.createFromPeerId(peerId); const enr = await ENR.createFromPeerId(peerId);
enr.setLocationMultiaddr(new Multiaddr("/ip4/18.223.219.100/udp/9000")); enr.setLocationMultiaddr(new Multiaddr("/ip4/18.223.219.100/udp/9000"));
enr.multiaddrs = [ enr.multiaddrs = [
new Multiaddr("/dns4/node1.do-ams.wakuv2.test.statusim.net/tcp/443/wss"), new Multiaddr("/dns4/node1.do-ams.wakuv2.test.statusim.net/tcp/443/wss"),

View File

@ -35,7 +35,7 @@ describe("ENR Interop: nwaku", function () {
const nimPeerId = await nwaku.getPeerId(); const nimPeerId = await nwaku.getPeerId();
expect(nwakuInfo.enrUri).to.not.be.undefined; expect(nwakuInfo.enrUri).to.not.be.undefined;
const dec = ENR.decodeTxt(nwakuInfo.enrUri ?? ""); const dec = await ENR.decodeTxt(nwakuInfo.enrUri ?? "");
expect(dec.peerId?.toB58String()).to.eq(nimPeerId.toB58String()); expect(dec.peerId?.toB58String()).to.eq(nimPeerId.toB58String());
expect(dec.waku2).to.deep.eq({ expect(dec.waku2).to.deep.eq({
relay: true, relay: true,
@ -66,7 +66,7 @@ describe("ENR Interop: nwaku", function () {
const nimPeerId = await nwaku.getPeerId(); const nimPeerId = await nwaku.getPeerId();
expect(nwakuInfo.enrUri).to.not.be.undefined; expect(nwakuInfo.enrUri).to.not.be.undefined;
const dec = ENR.decodeTxt(nwakuInfo.enrUri ?? ""); const dec = await ENR.decodeTxt(nwakuInfo.enrUri ?? "");
expect(dec.peerId?.toB58String()).to.eq(nimPeerId.toB58String()); expect(dec.peerId?.toB58String()).to.eq(nimPeerId.toB58String());
expect(dec.waku2).to.deep.eq({ expect(dec.waku2).to.deep.eq({
relay: true, relay: true,
@ -97,7 +97,7 @@ describe("ENR Interop: nwaku", function () {
const nimPeerId = await nwaku.getPeerId(); const nimPeerId = await nwaku.getPeerId();
expect(nwakuInfo.enrUri).to.not.be.undefined; expect(nwakuInfo.enrUri).to.not.be.undefined;
const dec = ENR.decodeTxt(nwakuInfo.enrUri ?? ""); const dec = await ENR.decodeTxt(nwakuInfo.enrUri ?? "");
expect(dec.peerId?.toB58String()).to.eq(nimPeerId.toB58String()); expect(dec.peerId?.toB58String()).to.eq(nimPeerId.toB58String());
expect(dec.waku2).to.deep.eq({ expect(dec.waku2).to.deep.eq({
relay: true, relay: true,

View File

@ -15,7 +15,7 @@ describe("ENR", function () {
describe("Txt codec", () => { describe("Txt codec", () => {
it("should encodeTxt and decodeTxt", async () => { it("should encodeTxt and decodeTxt", async () => {
const peerId = await PeerId.create({ keyType: "secp256k1" }); const peerId = await PeerId.create({ keyType: "secp256k1" });
const enr = ENR.createFromPeerId(peerId); const enr = await ENR.createFromPeerId(peerId);
const keypair = createKeypairFromPeerId(peerId); const keypair = createKeypairFromPeerId(peerId);
enr.setLocationMultiaddr(new Multiaddr("/ip4/18.223.219.100/udp/9000")); enr.setLocationMultiaddr(new Multiaddr("/ip4/18.223.219.100/udp/9000"));
enr.multiaddrs = [ enr.multiaddrs = [
@ -38,7 +38,7 @@ describe("ENR", function () {
}; };
const txt = await enr.encodeTxt(keypair.privateKey); const txt = await enr.encodeTxt(keypair.privateKey);
const enr2 = ENR.decodeTxt(txt); const enr2 = await ENR.decodeTxt(txt);
if (!enr.signature) throw "enr.signature is undefined"; if (!enr.signature) throw "enr.signature is undefined";
if (!enr2.signature) throw "enr.signature is undefined"; if (!enr2.signature) throw "enr.signature is undefined";
@ -66,19 +66,19 @@ describe("ENR", function () {
}); });
}); });
it("should decode valid enr successfully", () => { it("should decode valid enr successfully", async () => {
const txt = const txt =
"enr:-Ku4QMh15cIjmnq-co5S3tYaNXxDzKTgj0ufusA-QfZ66EWHNsULt2kb0eTHoo1Dkjvvf6CAHDS1Di-htjiPFZzaIPcLh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD2d10HAAABE________x8AgmlkgnY0gmlwhHZFkMSJc2VjcDI1NmsxoQIWSDEWdHwdEA3Lw2B_byeFQOINTZ0GdtF9DBjes6JqtIN1ZHCCIyg"; "enr:-Ku4QMh15cIjmnq-co5S3tYaNXxDzKTgj0ufusA-QfZ66EWHNsULt2kb0eTHoo1Dkjvvf6CAHDS1Di-htjiPFZzaIPcLh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD2d10HAAABE________x8AgmlkgnY0gmlwhHZFkMSJc2VjcDI1NmsxoQIWSDEWdHwdEA3Lw2B_byeFQOINTZ0GdtF9DBjes6JqtIN1ZHCCIyg";
const enr = ENR.decodeTxt(txt); const enr = await ENR.decodeTxt(txt);
const eth2 = enr.get("eth2"); const eth2 = enr.get("eth2");
if (!eth2) throw "eth2 is undefined"; if (!eth2) throw "eth2 is undefined";
expect(bytesToHex(eth2)).to.be.equal("f6775d0700000113ffffffffffff1f00"); expect(bytesToHex(eth2)).to.be.equal("f6775d0700000113ffffffffffff1f00");
}); });
it("should decode valid ENR with multiaddrs successfully [shared test vector]", () => { it("should decode valid ENR with multiaddrs successfully [shared test vector]", async () => {
const txt = const txt =
"enr:-QEnuEBEAyErHEfhiQxAVQoWowGTCuEF9fKZtXSd7H_PymHFhGJA3rGAYDVSHKCyJDGRLBGsloNbS8AZF33IVuefjOO6BIJpZIJ2NIJpcIQS39tkim11bHRpYWRkcnO4lgAvNihub2RlLTAxLmRvLWFtczMud2FrdXYyLnRlc3Quc3RhdHVzaW0ubmV0BgG73gMAODcxbm9kZS0wMS5hYy1jbi1ob25na29uZy1jLndha3V2Mi50ZXN0LnN0YXR1c2ltLm5ldAYBu94DACm9A62t7AQL4Ef5ZYZosRpQTzFVAB8jGjf1TER2wH-0zBOe1-MDBNLeA4lzZWNwMjU2azGhAzfsxbxyCkgCqq8WwYsVWH7YkpMLnU2Bw5xJSimxKav-g3VkcIIjKA"; "enr:-QEnuEBEAyErHEfhiQxAVQoWowGTCuEF9fKZtXSd7H_PymHFhGJA3rGAYDVSHKCyJDGRLBGsloNbS8AZF33IVuefjOO6BIJpZIJ2NIJpcIQS39tkim11bHRpYWRkcnO4lgAvNihub2RlLTAxLmRvLWFtczMud2FrdXYyLnRlc3Quc3RhdHVzaW0ubmV0BgG73gMAODcxbm9kZS0wMS5hYy1jbi1ob25na29uZy1jLndha3V2Mi50ZXN0LnN0YXR1c2ltLm5ldAYBu94DACm9A62t7AQL4Ef5ZYZosRpQTzFVAB8jGjf1TER2wH-0zBOe1-MDBNLeA4lzZWNwMjU2azGhAzfsxbxyCkgCqq8WwYsVWH7YkpMLnU2Bw5xJSimxKav-g3VkcIIjKA";
const enr = ENR.decodeTxt(txt); const enr = await ENR.decodeTxt(txt);
expect(enr.multiaddrs).to.not.be.undefined; expect(enr.multiaddrs).to.not.be.undefined;
expect(enr.multiaddrs!.length).to.be.equal(3); expect(enr.multiaddrs!.length).to.be.equal(3);
@ -97,7 +97,7 @@ describe("ENR", function () {
it("should decode valid enr with tcp successfully", async () => { it("should decode valid enr with tcp successfully", async () => {
const txt = const txt =
"enr:-IS4QAmC_o1PMi5DbR4Bh4oHVyQunZblg4bTaottPtBodAhJZvxVlWW-4rXITPNg4mwJ8cW__D9FBDc9N4mdhyMqB-EBgmlkgnY0gmlwhIbRi9KJc2VjcDI1NmsxoQOevTdO6jvv3fRruxguKR-3Ge4bcFsLeAIWEDjrfaigNoN0Y3CCdl8"; "enr:-IS4QAmC_o1PMi5DbR4Bh4oHVyQunZblg4bTaottPtBodAhJZvxVlWW-4rXITPNg4mwJ8cW__D9FBDc9N4mdhyMqB-EBgmlkgnY0gmlwhIbRi9KJc2VjcDI1NmsxoQOevTdO6jvv3fRruxguKR-3Ge4bcFsLeAIWEDjrfaigNoN0Y3CCdl8";
const enr = ENR.decodeTxt(txt); const enr = await ENR.decodeTxt(txt);
expect(enr.tcp).to.not.be.undefined; expect(enr.tcp).to.not.be.undefined;
expect(enr.tcp).to.be.equal(30303); expect(enr.tcp).to.be.equal(30303);
expect(enr.ip).to.not.be.undefined; expect(enr.ip).to.not.be.undefined;
@ -111,7 +111,7 @@ describe("ENR", function () {
it("should throw error - no id", async () => { it("should throw error - no id", async () => {
try { try {
const peerId = await PeerId.create({ keyType: "secp256k1" }); const peerId = await PeerId.create({ keyType: "secp256k1" });
const enr = ENR.createFromPeerId(peerId); const enr = await ENR.createFromPeerId(peerId);
const keypair = createKeypairFromPeerId(peerId); const keypair = createKeypairFromPeerId(peerId);
enr.setLocationMultiaddr(new Multiaddr("/ip4/18.223.219.100/udp/9000")); enr.setLocationMultiaddr(new Multiaddr("/ip4/18.223.219.100/udp/9000"));
@ -140,9 +140,9 @@ describe("ENR", function () {
}); });
describe("Verify", () => { describe("Verify", () => {
it("should throw error - no id", () => { it("should throw error - no id", async () => {
try { try {
const enr = new ENR({}, BigInt(0), new Uint8Array()); const enr = await ENR.create({}, BigInt(0), new Uint8Array());
enr.verify(new Uint8Array(), new Uint8Array()); enr.verify(new Uint8Array(), new Uint8Array());
assert.fail("Expect error here"); assert.fail("Expect error here");
} catch (err: unknown) { } catch (err: unknown) {
@ -151,9 +151,9 @@ describe("ENR", function () {
} }
}); });
it("should throw error - invalid id", () => { it("should throw error - invalid id", async () => {
try { try {
const enr = new ENR( const enr = await ENR.create(
{ id: utf8ToBytes("v3") }, { id: utf8ToBytes("v3") },
BigInt(0), BigInt(0),
new Uint8Array() new Uint8Array()
@ -166,9 +166,9 @@ describe("ENR", function () {
} }
}); });
it("should throw error - no public key", () => { it("should throw error - no public key", async () => {
try { try {
const enr = new ENR( const enr = await ENR.create(
{ id: utf8ToBytes("v4") }, { id: utf8ToBytes("v4") },
BigInt(0), BigInt(0),
new Uint8Array() new Uint8Array()
@ -181,10 +181,10 @@ describe("ENR", function () {
} }
}); });
it("should return false", () => { it("should return false", async () => {
const txt = const txt =
"enr:-Ku4QMh15cIjmnq-co5S3tYaNXxDzKTgj0ufusA-QfZ66EWHNsULt2kb0eTHoo1Dkjvvf6CAHDS1Di-htjiPFZzaIPcLh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD2d10HAAABE________x8AgmlkgnY0gmlwhHZFkMSJc2VjcDI1NmsxoQIWSDEWdHwdEA3Lw2B_byeFQOINTZ0GdtF9DBjes6JqtIN1ZHCCIyg"; "enr:-Ku4QMh15cIjmnq-co5S3tYaNXxDzKTgj0ufusA-QfZ66EWHNsULt2kb0eTHoo1Dkjvvf6CAHDS1Di-htjiPFZzaIPcLh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD2d10HAAABE________x8AgmlkgnY0gmlwhHZFkMSJc2VjcDI1NmsxoQIWSDEWdHwdEA3Lw2B_byeFQOINTZ0GdtF9DBjes6JqtIN1ZHCCIyg";
const enr = ENR.decodeTxt(txt); const enr = await ENR.decodeTxt(txt);
// should have id and public key inside ENR // should have id and public key inside ENR
expect(enr.verify(new Uint8Array(32), new Uint8Array(64))).to.be.false; expect(enr.verify(new Uint8Array(32), new Uint8Array(64))).to.be.false;
}); });
@ -199,7 +199,7 @@ describe("ENR", function () {
privateKey = hexToBytes( privateKey = hexToBytes(
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
); );
record = ENR.createV4(v4.publicKey(privateKey)); record = await ENR.createV4(v4.publicKey(privateKey));
record.setLocationMultiaddr(new Multiaddr("/ip4/127.0.0.1/udp/30303")); record.setLocationMultiaddr(new Multiaddr("/ip4/127.0.0.1/udp/30303"));
record.seq = seq; record.seq = seq;
await record.encodeTxt(privateKey); await record.encodeTxt(privateKey);
@ -212,7 +212,7 @@ describe("ENR", function () {
}); });
it("should encode/decode to RLP encoding", async function () { it("should encode/decode to RLP encoding", async function () {
const decoded = ENR.decode(await record.encode(privateKey)); const decoded = await ENR.decode(await record.encode(privateKey));
expect(decoded).to.deep.equal(record); expect(decoded).to.deep.equal(record);
}); });
@ -220,7 +220,7 @@ describe("ENR", function () {
// spec enr https://eips.ethereum.org/EIPS/eip-778 // spec enr https://eips.ethereum.org/EIPS/eip-778
const testTxt = const testTxt =
"enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8"; "enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8";
const decoded = ENR.decodeTxt(testTxt); const decoded = await ENR.decodeTxt(testTxt);
// Note: Signatures are different due to the extra entropy added // Note: Signatures are different due to the extra entropy added
// by @noble/secp256k1: // by @noble/secp256k1:
// https://github.com/paulmillr/noble-secp256k1#signmsghash-privatekey // https://github.com/paulmillr/noble-secp256k1#signmsghash-privatekey
@ -236,11 +236,11 @@ describe("ENR", function () {
let privateKey: Uint8Array; let privateKey: Uint8Array;
let record: ENR; let record: ENR;
beforeEach(() => { beforeEach(async () => {
privateKey = hexToBytes( privateKey = hexToBytes(
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
); );
record = ENR.createV4(v4.publicKey(privateKey)); record = await ENR.createV4(v4.publicKey(privateKey));
}); });
it("should get / set UDP multiaddr", () => { it("should get / set UDP multiaddr", () => {
@ -309,7 +309,7 @@ describe("ENR", function () {
before(async function () { before(async function () {
peerId = await PeerId.create({ keyType: "secp256k1" }); peerId = await PeerId.create({ keyType: "secp256k1" });
enr = ENR.createFromPeerId(peerId); enr = await ENR.createFromPeerId(peerId);
enr.ip = ip4; enr.ip = ip4;
enr.ip6 = ip6; enr.ip6 = ip6;
enr.tcp = tcp; enr.tcp = tcp;
@ -389,7 +389,7 @@ describe("ENR", function () {
beforeEach(async function () { beforeEach(async function () {
peerId = await PeerId.create({ keyType: "secp256k1" }); peerId = await PeerId.create({ keyType: "secp256k1" });
enr = ENR.createFromPeerId(peerId); enr = await ENR.createFromPeerId(peerId);
keypair = createKeypairFromPeerId(peerId); keypair = createKeypairFromPeerId(peerId);
waku2Protocols = { waku2Protocols = {
relay: false, relay: false,
@ -403,7 +403,7 @@ describe("ENR", function () {
enr.waku2 = waku2Protocols; enr.waku2 = waku2Protocols;
const txt = await enr.encodeTxt(keypair.privateKey); const txt = await enr.encodeTxt(keypair.privateKey);
const decoded = ENR.decodeTxt(txt).waku2!; const decoded = (await ENR.decodeTxt(txt)).waku2!;
expect(decoded.relay).to.equal(false); expect(decoded.relay).to.equal(false);
expect(decoded.store).to.equal(false); expect(decoded.store).to.equal(false);
@ -419,7 +419,7 @@ describe("ENR", function () {
enr.waku2 = waku2Protocols; enr.waku2 = waku2Protocols;
const txt = await enr.encodeTxt(keypair.privateKey); const txt = await enr.encodeTxt(keypair.privateKey);
const decoded = ENR.decodeTxt(txt).waku2!; const decoded = (await ENR.decodeTxt(txt)).waku2!;
expect(decoded.relay).to.equal(true); expect(decoded.relay).to.equal(true);
expect(decoded.store).to.equal(true); expect(decoded.store).to.equal(true);
@ -432,7 +432,7 @@ describe("ENR", function () {
enr.waku2 = waku2Protocols; enr.waku2 = waku2Protocols;
const txt = await enr.encodeTxt(keypair.privateKey); const txt = await enr.encodeTxt(keypair.privateKey);
const decoded = ENR.decodeTxt(txt).waku2!; const decoded = (await ENR.decodeTxt(txt)).waku2!;
expect(decoded.relay).to.equal(true); expect(decoded.relay).to.equal(true);
expect(decoded.store).to.equal(false); expect(decoded.store).to.equal(false);
@ -445,7 +445,7 @@ describe("ENR", function () {
enr.waku2 = waku2Protocols; enr.waku2 = waku2Protocols;
const txt = await enr.encodeTxt(keypair.privateKey); const txt = await enr.encodeTxt(keypair.privateKey);
const decoded = ENR.decodeTxt(txt).waku2!; const decoded = (await ENR.decodeTxt(txt)).waku2!;
expect(decoded.relay).to.equal(false); expect(decoded.relay).to.equal(false);
expect(decoded.store).to.equal(true); expect(decoded.store).to.equal(true);
@ -458,7 +458,7 @@ describe("ENR", function () {
enr.waku2 = waku2Protocols; enr.waku2 = waku2Protocols;
const txt = await enr.encodeTxt(keypair.privateKey); const txt = await enr.encodeTxt(keypair.privateKey);
const decoded = ENR.decodeTxt(txt).waku2!; const decoded = (await ENR.decodeTxt(txt)).waku2!;
expect(decoded.relay).to.equal(false); expect(decoded.relay).to.equal(false);
expect(decoded.store).to.equal(false); expect(decoded.store).to.equal(false);
@ -471,7 +471,7 @@ describe("ENR", function () {
enr.waku2 = waku2Protocols; enr.waku2 = waku2Protocols;
const txt = await enr.encodeTxt(keypair.privateKey); const txt = await enr.encodeTxt(keypair.privateKey);
const decoded = ENR.decodeTxt(txt).waku2!; const decoded = (await ENR.decodeTxt(txt)).waku2!;
expect(decoded.relay).to.equal(false); expect(decoded.relay).to.equal(false);
expect(decoded.store).to.equal(false); expect(decoded.store).to.equal(false);
@ -481,11 +481,11 @@ describe("ENR", function () {
}); });
describe("Waku2 key: decode", () => { describe("Waku2 key: decode", () => {
it("Relay + Store", function () { it("Relay + Store", async function () {
const txt = const txt =
"enr:-Iu4QADPfXNCM6iYyte0pIdbMirIw_AsKR7J1DeJBysXDWz4DZvyjgIwpMt-sXTVUzLJdE9FaStVy2ZKtHUVQAH61-KAgmlkgnY0gmlwhMCosvuJc2VjcDI1NmsxoQI0OCNtPJtBayNgvFvKp-0YyCozcvE1rqm_V1W51nHVv4N0Y3CC6mCFd2FrdTIH"; "enr:-Iu4QADPfXNCM6iYyte0pIdbMirIw_AsKR7J1DeJBysXDWz4DZvyjgIwpMt-sXTVUzLJdE9FaStVy2ZKtHUVQAH61-KAgmlkgnY0gmlwhMCosvuJc2VjcDI1NmsxoQI0OCNtPJtBayNgvFvKp-0YyCozcvE1rqm_V1W51nHVv4N0Y3CC6mCFd2FrdTIH";
const decoded = ENR.decodeTxt(txt).waku2!; const decoded = (await ENR.decodeTxt(txt)).waku2!;
expect(decoded.relay).to.equal(true); expect(decoded.relay).to.equal(true);
expect(decoded.store).to.equal(true); expect(decoded.store).to.equal(true);

View File

@ -33,7 +33,7 @@ export class ENR extends Map<ENRKey, ENRValue> {
public signature: Uint8Array | null; public signature: Uint8Array | null;
public peerId?: PeerId; public peerId?: PeerId;
constructor( private constructor(
kvs: Record<ENRKey, ENRValue> = {}, kvs: Record<ENRKey, ENRValue> = {},
seq: SequenceNumber = BigInt(1), seq: SequenceNumber = BigInt(1),
signature: Uint8Array | null = null signature: Uint8Array | null = null
@ -65,12 +65,12 @@ export class ENR extends Map<ENRKey, ENRValue> {
static createV4( static createV4(
publicKey: Uint8Array, publicKey: Uint8Array,
kvs: Record<ENRKey, ENRValue> = {} kvs: Record<ENRKey, ENRValue> = {}
): ENR { ): Promise<ENR> {
// EIP-778 specifies that the key must be in compressed format, 33 bytes // EIP-778 specifies that the key must be in compressed format, 33 bytes
if (publicKey.length !== 33) { if (publicKey.length !== 33) {
publicKey = compressPublicKey(publicKey); publicKey = compressPublicKey(publicKey);
} }
return new ENR({ return ENR.create({
...kvs, ...kvs,
id: utf8ToBytes("v4"), id: utf8ToBytes("v4"),
secp256k1: publicKey, secp256k1: publicKey,
@ -80,7 +80,7 @@ export class ENR extends Map<ENRKey, ENRValue> {
static createFromPeerId( static createFromPeerId(
peerId: PeerId, peerId: PeerId,
kvs: Record<ENRKey, ENRValue> = {} kvs: Record<ENRKey, ENRValue> = {}
): ENR { ): Promise<ENR> {
const keypair = createKeypairFromPeerId(peerId); const keypair = createKeypairFromPeerId(peerId);
switch (keypair.type) { switch (keypair.type) {
case KeypairType.secp256k1: case KeypairType.secp256k1:
@ -90,7 +90,7 @@ export class ENR extends Map<ENRKey, ENRValue> {
} }
} }
static decodeFromValues(decoded: Uint8Array[]): ENR { static async decodeFromValues(decoded: Uint8Array[]): Promise<ENR> {
if (!Array.isArray(decoded)) { if (!Array.isArray(decoded)) {
throw new Error("Decoded ENR must be an array"); throw new Error("Decoded ENR must be an array");
} }
@ -117,7 +117,7 @@ export class ENR extends Map<ENRKey, ENRValue> {
// If seq is an empty array, translate as value 0 // If seq is an empty array, translate as value 0
const hexSeq = "0x" + (seq.length ? bytesToHex(seq) : "00"); const hexSeq = "0x" + (seq.length ? bytesToHex(seq) : "00");
const enr = new ENR(obj, BigInt(hexSeq), signature); const enr = await ENR.create(obj, BigInt(hexSeq), signature);
const rlpEncodedBytes = hexToBytes(RLP.encode([seq, ...kvs])); const rlpEncodedBytes = hexToBytes(RLP.encode([seq, ...kvs]));
if (!enr.verify(rlpEncodedBytes, signature)) { if (!enr.verify(rlpEncodedBytes, signature)) {
@ -126,12 +126,12 @@ export class ENR extends Map<ENRKey, ENRValue> {
return enr; return enr;
} }
static decode(encoded: Uint8Array): ENR { static decode(encoded: Uint8Array): Promise<ENR> {
const decoded = RLP.decode(encoded).map(hexToBytes); const decoded = RLP.decode(encoded).map(hexToBytes);
return ENR.decodeFromValues(decoded); return ENR.decodeFromValues(decoded);
} }
static decodeTxt(encoded: string): ENR { static decodeTxt(encoded: string): Promise<ENR> {
if (!encoded.startsWith(this.RECORD_PREFIX)) { if (!encoded.startsWith(this.RECORD_PREFIX)) {
throw new Error( throw new Error(
`"string encoded ENR must start with '${this.RECORD_PREFIX}'` `"string encoded ENR must start with '${this.RECORD_PREFIX}'`