///
import type { ContextTimed } from '@matrixai/contexts';
import type { DBTransaction, KeyPath, LevelPath } from '@matrixai/db';
import type { QUICClientCrypto, QUICServerCrypto } from '@matrixai/quic';
import type { X509Certificate } from '@peculiar/x509';
import type { Hostname } from '../network/types.js';
import type { NodeAddress, NodeContact, NodeContactAddress, NodeBucket, NodeBucketIndex, NodeId, SeedNodes, AuthenticateNetworkForwardCallback, AuthenticateNetworkReverseCallback } from './types.js';
import type { NodesAuthenticateConnectionMessageNone } from './agent/types.js';
import type { ClaimNetworkAccess } from '../claims/payloads/index.js';
import { native } from '@matrixai/quic';
import Token from '../tokens/Token.js';
declare const sepBuffer: Buffer;
/**
* Calculate the bucket index that the target node should be located in
* A node's k-buckets are organised such that for the ith k-bucket where
* 0 <= i < nodeIdBits, the contacts in this ith bucket are known to adhere to
* the following inequality:
* 2^i <= distance (from current node) < 2^(i+1)
* This means lower buckets will have less nodes then the upper buckets.
* The highest bucket will contain half of all possible nodes.
* The lowest bucket will only contain 1 node.
*
* NOTE: because XOR is a commutative operation (i.e. a XOR b = b XOR a), the
* order of the passed parameters is actually irrelevant. These variables are
* purely named for communicating function purpose.
*
* NOTE: Kademlia literature generally talks about buckets with 1-based indexing
* and that the buckets are ordered from largest to smallest. This means the first
* 1th-bucket is far & large bucket, and the last 255th-bucket is the close bucket.
* This is reversed in our `NodeBucketIndex` encoding. This is so that lexicographic
* sort orders our buckets from closest bucket to farthest bucket.
*
* To convert from `NodeBucketIndex` to nth-bucket in Kademlia literature:
*
* | NodeBucketIndex | Nth-Bucket |
* | --------------- | ---------- |
* | 255 | 1 | farthest & largest
* | 254 | 2 |
* | ... | ... |
* | 1 | 254 |
* | 0 | 256 | closest & smallest
*/
declare function bucketIndex(sourceNode: NodeId, targetNode: NodeId): NodeBucketIndex;
/**
* Encodes NodeAddress to NodeAddressKey
*/
declare function nodeContactAddress([host, port]: NodeAddress): NodeContactAddress;
/**
* Encodes bucket index to bucket sublevel key
*/
declare function bucketKey(bucketIndex: NodeBucketIndex): string;
/**
* Creates key for buckets sublevel
*/
declare function bucketsDbKey(bucketIndex: NodeBucketIndex, nodeId: NodeId): Buffer;
/**
* Creates key for single bucket sublevel
*/
declare function bucketDbKey(nodeId: NodeId): Buffer;
declare function connectedKey(lastUpdated: number): Buffer;
declare function parseConnectedKey(buffer: Buffer): number;
declare function parseNodeContactAddress(nodeContactAddress: string): NodeAddress;
declare function parseNodeAddressKey(keyBuffer: Buffer): NodeAddress;
/**
* Parse the NodeGraph buckets sublevel key
* The keys look like `!!`
* It is assumed that the `!` is the sublevel prefix.
*/
declare function parseBucketsDbKey(keyPath: KeyPath): {
bucketIndex: NodeBucketIndex;
bucketKey: string;
nodeId: NodeId;
nodeContactAddress: NodeContactAddress;
};
/**
* Parse the NodeGraph bucket key
* The keys look like ``
*/
declare function parseBucketDbKey(keyBuffer: Buffer): NodeId;
/**
* Parse the NodeGraph index sublevel key
* The keys look like `!!-`
* It is assumed that the `!` is the sublevel prefix.
*/
declare function parseLastUpdatedBucketsDbKey(keyPath: KeyPath): {
bucketIndex: NodeBucketIndex;
bucketKey: string;
lastUpdated: number;
nodeId: NodeId;
};
/**
* Parse the NodeGraph index bucket sublevel key
* The keys look like `-`
* It is assumed that the `!` is the sublevel prefix.
*/
declare function parseLastUpdatedBucketDbKey(keyPath: KeyPath): {
lastUpdated: number;
nodeId: NodeId;
};
/**
* Compute the distance between two nodes.
* distance = nodeId1 ^ nodeId2
* where ^ = bitwise XOR operator
*/
declare function nodeDistance(nodeId1: NodeId, nodeId2: NodeId): bigint;
declare function nodeDistanceCmpFactory(targetNodeId: NodeId): (nodeId1: NodeId, nodeId2: NodeId) => -1 | 0 | 1;
declare function bucketSortByDistance(bucket: NodeBucket, nodeId: NodeId, order?: 'asc' | 'desc'): void;
declare function generateRandomDistanceForBucket(bucketIndex: NodeBucketIndex): NodeId;
declare function xOrNodeId(node1: NodeId, node2: NodeId): NodeId;
declare function generateRandomNodeIdForBucket(nodeId: NodeId, bucket: NodeBucketIndex): NodeId;
/**
* This is used to check if the given error is the result of a connection failure.
* Connection failures can happen due to the following.
* Failure to establish a connection,
* an existing connection fails,
* the RPC client has been destroyed,
* or the NodeConnection has been destroyed.
* This is generally used to check the connection has failed
* before cleaning it up.
*/
declare function isConnectionError(e: unknown): boolean;
/**
* This generates a random delay based on the given delay and jitter multiplier.
* For example, a delay of 100 and multiplier of 0.5 would result in a delay
* randomly between 50 and 150.
* @param delay - base delay to 'jitter' around
* @param jitterMultiplier - jitter amount as a multiple of the delay
*/
declare function refreshBucketsDelayJitter(delay: number, jitterMultiplier: number): number;
/**
* Converts transport level error reasons to codes for the quic system.
*
* Any unknown reasons default to code 0.
*
*/
declare const reasonToCode: (_type: 'read' | 'write', reason?: any) => number;
/**
* Converts any codes from the quic system back to reasons
* @param _type
* @param code
*/
declare const codeToReason: (_type: 'read' | 'write', code: number) => any;
declare function parseRemoteCertsChain(remoteCertChain: Array): {
nodeId: NodeId;
certChain: Readonly[];
};
/**
* Returns the associated hostname for a network. (`testnet.polykey.com`, etc.)
*/
declare function parseNetwork(data: any): Hostname;
/**
* Takes in a hostname/domain and performs a DNS resolution for related seednode services.
*/
declare function resolveSeednodes(hostname: Hostname, resolveSrv?: (hostname: string) => Promise>): Promise;
/**
* Seed nodes expected to be of form 'nodeId1@host:port;nodeId2@host:port;...'
* By default, any specified seed nodes (in CLI option, or environment variable)
* will overwrite the default nodes in src/config.ts.
* Special flag `` indicates that the default seed
* nodes should be added to the starting seed nodes instead of being overwritten
*/
declare function parseSeedNodes(data: any): [SeedNodes, boolean];
/**
* Verify the server certificate chain when connecting to it from a client
* This is a custom verification intended to verify that the server owned
* the relevant NodeId.
* It is possible that the server has a new NodeId. In that case we will
* verify that the new NodeId is the true descendant of the target NodeId.
*/
declare function verifyServerCertificateChain(nodeIds: Array, certs: Array): Promise<{
result: 'success';
nodeId: NodeId;
} | {
result: 'fail';
value: native.CryptoError;
}>;
/**
* Verify the client certificate chain when it connects to the server.
* The server does have a target NodeId. This means we verify the entire chain.
*/
declare function verifyClientCertificateChain(certs: Array): Promise;
/**
* QUIC Client Crypto
* This uses the keys utilities which uses `allocUnsafeSlow`.
* This ensures that the underlying buffer is not shared.
* Also all node buffers satisfy the `ArrayBuffer` interface.
*/
declare const quicClientCrypto: QUICClientCrypto;
/**
* QUIC Server Crypto
* This uses the keys utilities which uses `allocUnsafeSlow`.
* This ensures that the underlying buffer is not shared.
* Also all node buffers satisfy the `ArrayBuffer` interface.
*/
declare const quicServerCrypto: QUICServerCrypto;
declare function collectNodeContacts(levelPath: LevelPath, tran: DBTransaction, ctx: ContextTimed, options?: {
reverse?: boolean;
lt?: LevelPath;
gt?: LevelPath;
limit?: number;
pathAdjust?: KeyPath;
}): AsyncGenerator<[NodeId, NodeContact], void>;
declare function nodesAuthenticateConnectionForwardDefault(): Promise;
declare function nodesAuthenticateConnectionReverseDefault(): Promise;
declare function nodesAuthenticateConnectionForwardBasicPublicFactory(networkId: string): AuthenticateNetworkForwardCallback;
declare function nodesAuthenticateConnectionReverseBasicPublicFactory(networkId: string): AuthenticateNetworkReverseCallback;
declare function nodesAuthenticateConnectionReverseDeny(): Promise;
declare function nodesAuthenticationConnectionForwardPrivateFactory(networkAccessClaim: Token): AuthenticateNetworkForwardCallback;
declare function nodesAuthenticationConnectionReversePrivateFactory(networkAccessClaim: Token): AuthenticateNetworkReverseCallback;
export { sepBuffer, nodeContactAddress, bucketIndex, bucketKey, bucketsDbKey, bucketDbKey, connectedKey, parseConnectedKey, parseNodeContactAddress, parseNodeAddressKey, parseBucketsDbKey, parseBucketDbKey, parseLastUpdatedBucketsDbKey, parseLastUpdatedBucketDbKey, nodeDistance, nodeDistanceCmpFactory, bucketSortByDistance, generateRandomDistanceForBucket, xOrNodeId, generateRandomNodeIdForBucket, isConnectionError, refreshBucketsDelayJitter, reasonToCode, codeToReason, parseRemoteCertsChain, parseNetwork, resolveSeednodes, parseSeedNodes, verifyServerCertificateChain, verifyClientCertificateChain, quicClientCrypto, quicServerCrypto, collectNodeContacts, nodesAuthenticateConnectionForwardDefault, nodesAuthenticateConnectionReverseDefault, nodesAuthenticateConnectionForwardBasicPublicFactory, nodesAuthenticateConnectionReverseBasicPublicFactory, nodesAuthenticateConnectionReverseDeny, nodesAuthenticationConnectionForwardPrivateFactory, nodesAuthenticationConnectionReversePrivateFactory, };
export { encodeNodeId, decodeNodeId } from '../ids/index.js';