UNPKG

2.73 kBPlain TextView Raw
1import {
2 BinaryWriter,
3 createSerializeWire,
4 InvalidFormatError,
5 SerializableWire,
6 SerializeWire,
7} from '@neo-one/client-common-esnext-esm';
8import { BinaryReader, DeserializeWireBaseOptions, DeserializeWireOptions } from '@neo-one/node-core-esnext-esm';
9import BN from 'bn.js';
10import { Address6 } from 'ip-address';
11
12export interface NetworkAddressAdd {
13 readonly host: string;
14 readonly port: number;
15 readonly timestamp: number;
16 readonly services: BN;
17}
18
19const BYTE_LENGTH = 16;
20
21export class NetworkAddress implements SerializableWire<NetworkAddress> {
22 public static deserializeWireBase({ reader }: DeserializeWireBaseOptions): NetworkAddress {
23 const timestamp = reader.readUInt32LE();
24 const services = reader.readUInt64LE();
25 const address = Address6.fromByteArray([...reader.readBytes(16)]) as Address6 | undefined | null;
26 const port = reader.readUInt16BE();
27
28 const canonical = address == undefined ? '' : (address.canonicalForm() as string | undefined | null);
29
30 return new this({
31 timestamp,
32 services,
33 host: canonical == undefined ? '' : canonical,
34 port,
35 });
36 }
37
38 public static deserializeWire(options: DeserializeWireOptions): NetworkAddress {
39 return this.deserializeWireBase({
40 context: options.context,
41 reader: new BinaryReader(options.buffer),
42 });
43 }
44
45 public static isValid(host: string): boolean {
46 const address = this.getAddress6(host);
47 if (address == undefined) {
48 return false;
49 }
50
51 try {
52 address.toByteArray();
53
54 return true;
55 } catch {
56 return false;
57 }
58 }
59
60 public static getAddress6(host: string): Address6 | null | undefined {
61 const parts = host.split('.');
62
63 return parts.length === 4 ? Address6.fromAddress4(host) : new Address6(host);
64 }
65
66 public readonly host: string;
67 public readonly port: number;
68 public readonly timestamp: number;
69 public readonly services: BN;
70 public readonly serializeWire: SerializeWire = createSerializeWire(this.serializeWireBase.bind(this));
71
72 public constructor({ host, port, timestamp, services }: NetworkAddressAdd) {
73 this.host = host;
74 this.port = port;
75 this.timestamp = timestamp;
76 this.services = services;
77 }
78
79 public serializeWireBase(writer: BinaryWriter): void {
80 const address = NetworkAddress.getAddress6(this.host);
81 if (address == undefined) {
82 throw new InvalidFormatError();
83 }
84 writer.writeUInt32LE(this.timestamp);
85 writer.writeUInt64LE(this.services);
86 const addressSerialized = Buffer.from(address.toByteArray());
87 writer.writeBytes(Buffer.concat([Buffer.alloc(BYTE_LENGTH - addressSerialized.length, 0), addressSerialized]));
88 writer.writeUInt16BE(this.port);
89 }
90}