|
|
|
@ -1,3 +1,6 @@ |
|
|
|
|
const leftPad = require('left-pad'); |
|
|
|
|
const padIpv6 = require('pad-ipv6'); |
|
|
|
|
|
|
|
|
|
export type Enode = { |
|
|
|
|
enodeHigh: string; |
|
|
|
|
enodeLow: string; |
|
|
|
@ -10,26 +13,33 @@ export const enodeToParams = (enodeURL: string) => { |
|
|
|
|
let enodeLow = ''; |
|
|
|
|
let ip = ''; |
|
|
|
|
let port = ''; |
|
|
|
|
let extraParams = new Map(); |
|
|
|
|
|
|
|
|
|
const splitURL = enodeURL.split('//')[1]; |
|
|
|
|
if (splitURL) { |
|
|
|
|
const [enodeId, rawIpAndPort] = splitURL.split('@'); |
|
|
|
|
if (enodeId && enodeId.length === 128) { |
|
|
|
|
enodeHigh = '0x' + enodeId.slice(0, 64); |
|
|
|
|
enodeLow = '0x' + enodeId.slice(64); |
|
|
|
|
} |
|
|
|
|
if (rawIpAndPort) { |
|
|
|
|
const [ipAndPort] = rawIpAndPort.split('?'); |
|
|
|
|
if (ipAndPort) { |
|
|
|
|
[ip, port] = ipAndPort.split(':'); |
|
|
|
|
} |
|
|
|
|
try { |
|
|
|
|
const node = new URL(enodeURL); |
|
|
|
|
if (node.protocol === 'enode:') { |
|
|
|
|
// Change to Special protocol in order to parse the fields properly
|
|
|
|
|
node.protocol = 'https'; |
|
|
|
|
|
|
|
|
|
if (node.username.length === 128) { |
|
|
|
|
enodeHigh = '0x' + node.username.slice(0, 64); |
|
|
|
|
enodeLow = '0x' + node.username.slice(64); |
|
|
|
|
} |
|
|
|
|
ip = parseHostname(node.hostname); |
|
|
|
|
port = node.port; |
|
|
|
|
|
|
|
|
|
node.searchParams.forEach((value, name, searchParams) => { |
|
|
|
|
extraParams.set(name.toLowerCase(), value); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} catch (err) {} |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
enodeHigh, |
|
|
|
|
enodeLow, |
|
|
|
|
ip: ip ? getHexIpv4(ip) : '', |
|
|
|
|
port |
|
|
|
|
ip, |
|
|
|
|
port, |
|
|
|
|
extraParams |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -47,16 +57,35 @@ export const paramsToIdentifier = ({ |
|
|
|
|
return `${enodeHigh}_${enodeLow}_${ip}_${port}`; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
function parseHostname(stringHostname: string) { |
|
|
|
|
if (stringHostname[0] === '[') { |
|
|
|
|
const ipv6 = stringHostname.slice(1, -1); |
|
|
|
|
return getHexIpv6(ipv6); |
|
|
|
|
} |
|
|
|
|
return getHexIpv4(stringHostname); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getHexIpv4(stringIp: string) { |
|
|
|
|
const splitIp = stringIp.split('.'); |
|
|
|
|
return `0x00000000000000000000ffff${toHex(splitIp[0])}${toHex(splitIp[1])}${toHex(splitIp[2])}${toHex(splitIp[3])}`; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getHexIpv6(stringIpv6: string) { |
|
|
|
|
const ipv6 = padIpv6(stringIpv6) |
|
|
|
|
.split(':') |
|
|
|
|
.join(''); |
|
|
|
|
return '0x' + ipv6; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function toHex(number: string) { |
|
|
|
|
const num = Number(number).toString(16); |
|
|
|
|
return num.length < 2 ? `0${num}` : num; |
|
|
|
|
return leftPad(num, 2, '0'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export const buildEnode = (enodeHigh: string, enodeLow: string) => { |
|
|
|
|
return `${enodeHigh.slice(2)}${enodeLow.slice(2)}`; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export const identifierToParams = (identifier: string) => { |
|
|
|
|
const [enodeHigh, enodeLow, ip, port] = identifier.split('_'); |
|
|
|
|
return { |
|
|
|
|