@aria-cli/wireguard 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/.aria-build-stamp.json +4 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/bootstrap-authority.d.ts +2 -0
  4. package/dist/bootstrap-authority.d.ts.map +1 -0
  5. package/dist/bootstrap-authority.js +47 -0
  6. package/dist/bootstrap-authority.js.map +1 -0
  7. package/dist/bootstrap-tls.d.ts +14 -0
  8. package/dist/bootstrap-tls.d.ts.map +1 -0
  9. package/dist/bootstrap-tls.js +69 -0
  10. package/dist/bootstrap-tls.js.map +1 -0
  11. package/dist/db-owner-fencing.d.ts +10 -0
  12. package/dist/db-owner-fencing.d.ts.map +1 -0
  13. package/dist/db-owner-fencing.js +44 -0
  14. package/dist/db-owner-fencing.js.map +1 -0
  15. package/dist/derp-relay.d.ts +75 -0
  16. package/dist/derp-relay.d.ts.map +1 -0
  17. package/dist/derp-relay.js +311 -0
  18. package/dist/derp-relay.js.map +1 -0
  19. package/dist/index.d.ts +53 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +100 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/nat.d.ts +84 -0
  24. package/dist/nat.d.ts.map +1 -0
  25. package/dist/nat.js +397 -0
  26. package/dist/nat.js.map +1 -0
  27. package/dist/network-state-store.d.ts +46 -0
  28. package/dist/network-state-store.d.ts.map +1 -0
  29. package/dist/network-state-store.js +248 -0
  30. package/dist/network-state-store.js.map +1 -0
  31. package/dist/network.d.ts +590 -0
  32. package/dist/network.d.ts.map +1 -0
  33. package/dist/network.js +3391 -0
  34. package/dist/network.js.map +1 -0
  35. package/dist/peer-discovery.d.ts +133 -0
  36. package/dist/peer-discovery.d.ts.map +1 -0
  37. package/dist/peer-discovery.js +486 -0
  38. package/dist/peer-discovery.js.map +1 -0
  39. package/dist/resilient-tunnel.d.ts +70 -0
  40. package/dist/resilient-tunnel.d.ts.map +1 -0
  41. package/dist/resilient-tunnel.js +389 -0
  42. package/dist/resilient-tunnel.js.map +1 -0
  43. package/dist/route-ownership.d.ts +23 -0
  44. package/dist/route-ownership.d.ts.map +1 -0
  45. package/dist/route-ownership.js +79 -0
  46. package/dist/route-ownership.js.map +1 -0
  47. package/dist/tunnel.d.ts +141 -0
  48. package/dist/tunnel.d.ts.map +1 -0
  49. package/dist/tunnel.js +474 -0
  50. package/dist/tunnel.js.map +1 -0
  51. package/dist/wireguard.node +0 -0
  52. package/index.d.ts +59 -0
  53. package/index.js +580 -0
  54. package/package.json +76 -0
  55. package/wireguard.darwin-arm64.node +0 -0
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ /**
3
+ * DerpRelay — DERP relay client for NAT traversal.
4
+ *
5
+ * When both peers are behind symmetric NAT, direct WireGuard tunnels fail.
6
+ * DerpRelay connects to a relay server via WebSocket and forwards encrypted
7
+ * WireGuard packets through it. The relay CANNOT read the content (WireGuard
8
+ * encryption is end-to-end).
9
+ *
10
+ * Implements the same { send(data: Buffer): void } interface as tunnel transports,
11
+ * so it plugs into Mailbox.registerTunnel() transparently.
12
+ *
13
+ * Authentication: Ed25519 signature challenge on connect to prevent impersonation.
14
+ * Auto-reconnect: Exponential backoff, matching ResilientTunnel's pattern.
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.DerpRelay = void 0;
54
+ const node_events_1 = require("node:events");
55
+ const crypto = __importStar(require("node:crypto"));
56
+ const ws_1 = __importDefault(require("ws"));
57
+ const tools_1 = require("@aria/tools");
58
+ /** Max payload size matching WireGuard MTU */
59
+ const MAX_PAYLOAD_BYTES = 65535;
60
+ /** Max reconnection attempts before declaring dead */
61
+ const MAX_RECONNECT_ATTEMPTS = 10;
62
+ /** Base backoff interval */
63
+ const BASE_BACKOFF_MS = 1_000;
64
+ /** Max backoff interval */
65
+ const MAX_BACKOFF_MS = 60_000;
66
+ /**
67
+ * DERP relay client.
68
+ *
69
+ * Emits: "plaintext" (data: Buffer, fromNodeId: NodeId, displayNameSnapshot?: string), "connected", "disconnected",
70
+ * "dead", "error" (Error), "stateChange" (newState, prevState)
71
+ */
72
+ class DerpRelay extends node_events_1.EventEmitter {
73
+ ws = null;
74
+ _state = "disconnected";
75
+ reconnectAttempts = 0;
76
+ reconnectTimer = null;
77
+ stopped = false;
78
+ closing = false;
79
+ relayUrl;
80
+ nodeId;
81
+ displayNameSnapshot;
82
+ signingPrivateKey;
83
+ signingPublicKey;
84
+ targetNodeId;
85
+ signal;
86
+ /** Queued messages while not connected */
87
+ queue = [];
88
+ static MAX_QUEUE = 200;
89
+ constructor(options) {
90
+ super();
91
+ this.relayUrl = options.relayUrl;
92
+ this.nodeId = options.nodeId;
93
+ this.displayNameSnapshot = options.displayNameSnapshot;
94
+ this.signingPrivateKey = options.signingPrivateKey;
95
+ this.signingPublicKey = options.signingPublicKey;
96
+ this.targetNodeId = options.targetNodeId;
97
+ this.signal = options.signal;
98
+ if (this.signal) {
99
+ this.signal.addEventListener("abort", () => this.disconnect(), { once: true });
100
+ }
101
+ }
102
+ /** Connect to the relay server */
103
+ async connect() {
104
+ if (this.stopped || this._state === "connected" || this._state === "connecting")
105
+ return;
106
+ this.closing = false;
107
+ this.setState("connecting");
108
+ return new Promise((resolve, reject) => {
109
+ try {
110
+ const ws = new ws_1.default(this.relayUrl);
111
+ this.ws = ws;
112
+ const timeout = setTimeout(() => {
113
+ ws.close();
114
+ reject(new Error("Relay connection timeout"));
115
+ }, 15_000);
116
+ ws.on("open", () => {
117
+ clearTimeout(timeout);
118
+ if (this.closing) {
119
+ ws.close();
120
+ reject(new Error("Relay connection aborted: disconnect() called during connect"));
121
+ return;
122
+ }
123
+ this.setState("authenticating");
124
+ // Send auth message with our identity
125
+ ws.send(JSON.stringify({
126
+ type: "auth",
127
+ nodeId: this.nodeId,
128
+ signingPublicKey: this.signingPublicKey,
129
+ }));
130
+ });
131
+ ws.on("message", (rawData) => {
132
+ try {
133
+ const data = typeof rawData === "string" ? rawData : rawData.toString();
134
+ const msg = JSON.parse(data);
135
+ if (msg.type === "challenge" && this._state === "authenticating") {
136
+ // Sign the challenge to prove identity
137
+ const signature = this.signChallenge(msg.nonce);
138
+ ws.send(JSON.stringify({ type: "challenge_response", signature }));
139
+ }
140
+ else if (msg.type === "auth_ok") {
141
+ if (this.closing) {
142
+ ws.close();
143
+ reject(new Error("Relay connection aborted: disconnect() called during auth"));
144
+ return;
145
+ }
146
+ this.setState("connected");
147
+ this.reconnectAttempts = 0;
148
+ this.flushQueue();
149
+ this.emit("connected");
150
+ resolve();
151
+ }
152
+ else if (msg.type === "auth_error") {
153
+ ws.close();
154
+ reject(new Error(`Relay auth failed: ${msg.error}`));
155
+ }
156
+ else if (msg.type === "relay" && this._state === "connected") {
157
+ // Incoming relayed data from another peer
158
+ const fromNodeId = tools_1.NodeIdSchema.parse(msg.fromNodeId);
159
+ const payload = Buffer.from(msg.data, "base64");
160
+ this.emit("plaintext", payload, fromNodeId, msg.displayNameSnapshot);
161
+ }
162
+ else if (msg.type === "peer_offline") {
163
+ // Target peer is not connected to relay
164
+ const peerLabel = typeof msg.displayNameSnapshot === "string" && msg.displayNameSnapshot.length > 0
165
+ ? msg.displayNameSnapshot
166
+ : typeof msg.nodeId === "string" && msg.nodeId.length > 0
167
+ ? msg.nodeId
168
+ : this.targetNodeId;
169
+ this.emit("error", new Error(`Peer ${peerLabel} is offline on relay`));
170
+ }
171
+ }
172
+ catch (err) {
173
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
174
+ }
175
+ });
176
+ ws.on("close", () => {
177
+ clearTimeout(timeout);
178
+ const wasConnecting = this._state === "connecting" || this._state === "authenticating";
179
+ this.setState("disconnected");
180
+ if (this.stopped || this.closing) {
181
+ // Reject the pending connect promise so callers don't hang
182
+ if (wasConnecting) {
183
+ reject(new Error("Relay connection closed during setup"));
184
+ }
185
+ }
186
+ else {
187
+ this.emit("disconnected");
188
+ this.attemptReconnect();
189
+ }
190
+ });
191
+ ws.on("error", (err) => {
192
+ clearTimeout(timeout);
193
+ this.emit("error", err);
194
+ if (this._state === "connecting" || this._state === "authenticating") {
195
+ reject(err);
196
+ }
197
+ });
198
+ }
199
+ catch (err) {
200
+ this.setState("disconnected");
201
+ reject(err);
202
+ }
203
+ });
204
+ }
205
+ /** Send data through the relay to the target peer */
206
+ send(data) {
207
+ if (this.stopped)
208
+ throw new Error("Relay is stopped");
209
+ if (data.length > MAX_PAYLOAD_BYTES) {
210
+ throw new Error(`Payload exceeds max size (${data.length} > ${MAX_PAYLOAD_BYTES})`);
211
+ }
212
+ if (this._state !== "connected" || !this.ws) {
213
+ this.enqueue(data);
214
+ return;
215
+ }
216
+ this.ws.send(JSON.stringify({
217
+ type: "relay",
218
+ toNodeId: this.targetNodeId,
219
+ data: data.toString("base64"),
220
+ }));
221
+ }
222
+ /** Disconnect from the relay server */
223
+ disconnect() {
224
+ this.closing = true;
225
+ this.stopped = true;
226
+ this.clearReconnectTimer();
227
+ if (this.ws) {
228
+ try {
229
+ this.ws.close();
230
+ }
231
+ catch {
232
+ // ignore close errors
233
+ }
234
+ this.ws = null;
235
+ }
236
+ this.queue = [];
237
+ this.setState("disconnected");
238
+ }
239
+ /** Get current relay state */
240
+ getState() {
241
+ return this._state;
242
+ }
243
+ /** Whether the relay is actively connected */
244
+ get isConnected() {
245
+ return this._state === "connected";
246
+ }
247
+ // ── Internal ─────────────────────────────────────────────────────
248
+ setState(newState) {
249
+ const prev = this._state;
250
+ if (prev === newState)
251
+ return;
252
+ this._state = newState;
253
+ this.emit("stateChange", newState, prev);
254
+ }
255
+ signChallenge(nonce) {
256
+ const keyDer = Buffer.from(this.signingPrivateKey, "base64");
257
+ const privateKey = crypto.createPrivateKey({
258
+ key: keyDer,
259
+ format: "der",
260
+ type: "pkcs8",
261
+ });
262
+ const signature = crypto.sign(null, Buffer.from(nonce), privateKey);
263
+ return signature.toString("base64");
264
+ }
265
+ attemptReconnect() {
266
+ if (this.stopped)
267
+ return;
268
+ if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
269
+ this.setState("dead");
270
+ this.emit("dead");
271
+ return;
272
+ }
273
+ const backoff = Math.min(BASE_BACKOFF_MS * Math.pow(2, this.reconnectAttempts), MAX_BACKOFF_MS);
274
+ this.reconnectAttempts++;
275
+ this.reconnectTimer = setTimeout(() => {
276
+ if (this.stopped)
277
+ return;
278
+ void this.connect().catch((err) => {
279
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
280
+ });
281
+ }, backoff);
282
+ }
283
+ clearReconnectTimer() {
284
+ if (this.reconnectTimer) {
285
+ clearTimeout(this.reconnectTimer);
286
+ this.reconnectTimer = null;
287
+ }
288
+ }
289
+ enqueue(data) {
290
+ if (this.queue.length >= DerpRelay.MAX_QUEUE) {
291
+ // Drop oldest to make room
292
+ this.queue.shift();
293
+ }
294
+ this.queue.push(data);
295
+ }
296
+ flushQueue() {
297
+ if (this._state !== "connected" || !this.ws)
298
+ return;
299
+ const pending = this.queue.splice(0);
300
+ for (const data of pending) {
301
+ try {
302
+ this.send(data);
303
+ }
304
+ catch {
305
+ // Drop on failure during flush
306
+ }
307
+ }
308
+ }
309
+ }
310
+ exports.DerpRelay = DerpRelay;
311
+ //# sourceMappingURL=derp-relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derp-relay.js","sourceRoot":"","sources":["../derp-relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @aria/wireguard — WireGuard native addon for ARIA secure networking.
3
+ *
4
+ * Wraps Cloudflare's boringtun (BSD-3) via napi-rs for userspace
5
+ * encrypted tunnels. Three hot-path functions: encrypt, decrypt, tick.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export interface WireGuardResult {
10
+ /** "done" | "write_to_network" | "write_to_tunnel" | "error" */
11
+ op: string;
12
+ /** Output data (if any) */
13
+ data?: Buffer;
14
+ }
15
+ export interface KeyPair {
16
+ publicKey: string;
17
+ privateKey: string;
18
+ }
19
+ export interface WireGuardTunnelOptions {
20
+ /** Base64-encoded X25519 private key */
21
+ privateKey: string;
22
+ /** Base64-encoded X25519 peer public key */
23
+ peerPublicKey: string;
24
+ /** Optional base64-encoded preshared key */
25
+ presharedKey?: string;
26
+ /** Persistent keepalive interval in seconds (0 = disabled) */
27
+ keepalive?: number;
28
+ /** Tunnel index for session disambiguation (random if not provided) */
29
+ index?: number;
30
+ }
31
+ /** Validate that the native addon can be loaded in the current runtime. */
32
+ export declare function assertNativeAddonAvailable(): void;
33
+ /** Create a new WireGuard tunnel */
34
+ export declare function createTunnel(options: WireGuardTunnelOptions): {
35
+ encrypt(src: Buffer): WireGuardResult;
36
+ decrypt(src: Buffer, srcAddr?: string | undefined | null): WireGuardResult;
37
+ tick(): WireGuardResult;
38
+ };
39
+ /** Generate a new X25519 keypair for WireGuard */
40
+ export declare function generateKeypair(): KeyPair;
41
+ export { SecureTunnel } from "./tunnel.js";
42
+ export type { SecureTunnelOptions, TunnelStats } from "./tunnel.js";
43
+ export { ResilientTunnel } from "./resilient-tunnel.js";
44
+ export type { TunnelState, ResilientTunnelStats } from "./resilient-tunnel.js";
45
+ export { StunClient, discoverEndpoint, detectNatType } from "./nat.js";
46
+ export type { StunResult, NatType } from "./nat.js";
47
+ export { NetworkManager, PeerRegistry, generateKeyPair, generateSigningKeypair, createInviteToken, decodeInviteToken, ensureSecureNetwork, } from "./network.js";
48
+ export type { NetworkConfig, PeerInfo, InviteToken } from "./network.js";
49
+ export { PeerDiscoveryService } from "./peer-discovery.js";
50
+ export type { PeerDiscoveryOptions, DiscoveredPeer, PeerDiscoveryNetworkManager, } from "./peer-discovery.js";
51
+ export { DerpRelay } from "./derp-relay.js";
52
+ export type { DerpRelayOptions, DerpRelayState } from "./derp-relay.js";
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkCD,2EAA2E;AAC3E,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED,oCAAoC;AACpC,wBAAgB,YAAY,CAAC,OAAO,EAAE,sBAAsB;iBA7B3C,MAAM,GAAG,eAAe;iBACxB,MAAM,YAAY,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,eAAe;YAClE,eAAe;EAoC1B;AAED,kDAAkD;AAClD,wBAAgB,eAAe,IAAI,OAAO,CAGzC;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EACL,cAAc,EACd,YAAY,EACZ,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,YAAY,EACV,oBAAoB,EACpB,cAAc,EACd,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ /**
3
+ * @aria/wireguard — WireGuard native addon for ARIA secure networking.
4
+ *
5
+ * Wraps Cloudflare's boringtun (BSD-3) via napi-rs for userspace
6
+ * encrypted tunnels. Three hot-path functions: encrypt, decrypt, tick.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.DerpRelay = exports.PeerDiscoveryService = exports.ensureSecureNetwork = exports.decodeInviteToken = exports.createInviteToken = exports.generateSigningKeypair = exports.generateKeyPair = exports.PeerRegistry = exports.NetworkManager = exports.detectNatType = exports.discoverEndpoint = exports.StunClient = exports.ResilientTunnel = exports.SecureTunnel = void 0;
45
+ exports.assertNativeAddonAvailable = assertNativeAddonAvailable;
46
+ exports.createTunnel = createTunnel;
47
+ exports.generateKeypair = generateKeypair;
48
+ const path = __importStar(require("node:path"));
49
+ /** Lazy-loaded native addon */
50
+ let _native = null;
51
+ function loadNative() {
52
+ if (_native)
53
+ return _native;
54
+ try {
55
+ // The package-root napi loader resolves the platform-specific native addon.
56
+ // The dist/ runtime must not depend on a copied dist/wireguard.node shim.
57
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
58
+ _native = require("../index.js");
59
+ return _native;
60
+ }
61
+ catch (err) {
62
+ const reason = err instanceof Error ? err.message : String(err);
63
+ throw new Error(`@aria/wireguard: Failed to load native addon via ${path.join(__dirname, "../index.js")} (${process.platform}-${process.arch}). ${reason}`);
64
+ }
65
+ }
66
+ /** Validate that the native addon can be loaded in the current runtime. */
67
+ function assertNativeAddonAvailable() {
68
+ loadNative();
69
+ }
70
+ /** Create a new WireGuard tunnel */
71
+ function createTunnel(options) {
72
+ const native = loadNative();
73
+ return new native.WireGuardTunnel(options.privateKey, options.peerPublicKey, options.presharedKey ?? null, options.keepalive ?? 0, options.index ?? null);
74
+ }
75
+ /** Generate a new X25519 keypair for WireGuard */
76
+ function generateKeypair() {
77
+ const native = loadNative();
78
+ return native.generateKeypair();
79
+ }
80
+ var tunnel_js_1 = require("./tunnel.js");
81
+ Object.defineProperty(exports, "SecureTunnel", { enumerable: true, get: function () { return tunnel_js_1.SecureTunnel; } });
82
+ var resilient_tunnel_js_1 = require("./resilient-tunnel.js");
83
+ Object.defineProperty(exports, "ResilientTunnel", { enumerable: true, get: function () { return resilient_tunnel_js_1.ResilientTunnel; } });
84
+ var nat_js_1 = require("./nat.js");
85
+ Object.defineProperty(exports, "StunClient", { enumerable: true, get: function () { return nat_js_1.StunClient; } });
86
+ Object.defineProperty(exports, "discoverEndpoint", { enumerable: true, get: function () { return nat_js_1.discoverEndpoint; } });
87
+ Object.defineProperty(exports, "detectNatType", { enumerable: true, get: function () { return nat_js_1.detectNatType; } });
88
+ var network_js_1 = require("./network.js");
89
+ Object.defineProperty(exports, "NetworkManager", { enumerable: true, get: function () { return network_js_1.NetworkManager; } });
90
+ Object.defineProperty(exports, "PeerRegistry", { enumerable: true, get: function () { return network_js_1.PeerRegistry; } });
91
+ Object.defineProperty(exports, "generateKeyPair", { enumerable: true, get: function () { return network_js_1.generateKeyPair; } });
92
+ Object.defineProperty(exports, "generateSigningKeypair", { enumerable: true, get: function () { return network_js_1.generateSigningKeypair; } });
93
+ Object.defineProperty(exports, "createInviteToken", { enumerable: true, get: function () { return network_js_1.createInviteToken; } });
94
+ Object.defineProperty(exports, "decodeInviteToken", { enumerable: true, get: function () { return network_js_1.decodeInviteToken; } });
95
+ Object.defineProperty(exports, "ensureSecureNetwork", { enumerable: true, get: function () { return network_js_1.ensureSecureNetwork; } });
96
+ var peer_discovery_js_1 = require("./peer-discovery.js");
97
+ Object.defineProperty(exports, "PeerDiscoveryService", { enumerable: true, get: function () { return peer_discovery_js_1.PeerDiscoveryService; } });
98
+ var derp_relay_js_1 = require("./derp-relay.js");
99
+ Object.defineProperty(exports, "DerpRelay", { enumerable: true, get: function () { return derp_relay_js_1.DerpRelay; } });
100
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DH,gEAEC;AAGD,oCASC;AAGD,0CAGC;AAjFD,gDAAkC;AA4BlC,+BAA+B;AAC/B,IAAI,OAAO,GAaA,IAAI,CAAC;AAEhB,SAAS,UAAU;IACjB,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,IAAI,CAAC;QACH,4EAA4E;QAC5E,0EAA0E;QAC1E,iEAAiE;QACjE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QACjC,OAAO,OAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,oDAAoD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,KAAK,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,MAAM,MAAM,EAAE,CAC3I,CAAC;IACJ,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,SAAgB,0BAA0B;IACxC,UAAU,EAAE,CAAC;AACf,CAAC;AAED,oCAAoC;AACpC,SAAgB,YAAY,CAAC,OAA+B;IAC1D,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,IAAI,MAAM,CAAC,eAAe,CAC/B,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,YAAY,IAAI,IAAI,EAC5B,OAAO,CAAC,SAAS,IAAI,CAAC,EACtB,OAAO,CAAC,KAAK,IAAI,IAAI,CACtB,CAAC;AACJ,CAAC;AAED,kDAAkD;AAClD,SAAgB,eAAe;IAC7B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,eAAe,EAAE,CAAC;AAClC,CAAC;AAED,yCAA2C;AAAlC,yGAAA,YAAY,OAAA;AAErB,6DAAwD;AAA/C,sHAAA,eAAe,OAAA;AAExB,mCAAuE;AAA9D,oGAAA,UAAU,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AAAE,uGAAA,aAAa,OAAA;AAEpD,2CAQsB;AAPpB,4GAAA,cAAc,OAAA;AACd,0GAAA,YAAY,OAAA;AACZ,6GAAA,eAAe,OAAA;AACf,oHAAA,sBAAsB,OAAA;AACtB,+GAAA,iBAAiB,OAAA;AACjB,+GAAA,iBAAiB,OAAA;AACjB,iHAAA,mBAAmB,OAAA;AAGrB,yDAA2D;AAAlD,yHAAA,oBAAoB,OAAA;AAM7B,iDAA4C;AAAnC,0GAAA,SAAS,OAAA"}
package/dist/nat.d.ts ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * STUN client + NAT traversal for ARIA secure networking.
3
+ *
4
+ * Discovers external IP:port via STUN (RFC 5389), enabling WireGuard
5
+ * peers to find each other through NAT. Falls back to a UDP relay
6
+ * when symmetric NAT prevents direct connectivity.
7
+ *
8
+ * No external dependencies — implements STUN binding request/response
9
+ * directly using node:dgram.
10
+ */
11
+ import * as dgram from "node:dgram";
12
+ /** Result of STUN endpoint discovery */
13
+ export interface StunResult {
14
+ /** External (public) IP address */
15
+ address: string;
16
+ /** External (public) port */
17
+ port: number;
18
+ /** STUN server used for discovery */
19
+ server: string;
20
+ }
21
+ /**
22
+ * Discover our external endpoint by sending a STUN Binding Request.
23
+ *
24
+ * Tries multiple STUN servers in parallel, returns the first successful response.
25
+ * Timeout: 3 seconds per server, 5 second total.
26
+ */
27
+ /**
28
+ * Discover external endpoint via STUN.
29
+ *
30
+ * @param server STUN server hostname:port (or undefined to try defaults)
31
+ * @param timeoutMs Timeout in milliseconds
32
+ * @param existingSocket Optional: use this socket for STUN instead of creating
33
+ * ephemeral ones. This is critical for the shared-socket WG model — STUN must
34
+ * discover the NAT mapping of the ACTUAL listening socket, not a throwaway one.
35
+ * When provided, the socket is NOT closed after discovery.
36
+ */
37
+ export declare function discoverEndpoint(server?: string, timeoutMs?: number, existingSocket?: dgram.Socket): Promise<StunResult>;
38
+ /**
39
+ * NAT type classification.
40
+ *
41
+ * Detected by comparing mapped ports from two different STUN servers:
42
+ * - Same port from both servers → Full Cone or Restricted Cone (direct tunnel works)
43
+ * - Different port from each server → Symmetric NAT (needs relay)
44
+ */
45
+ export type NatType = "full_cone" | "restricted" | "symmetric" | "unknown";
46
+ /**
47
+ * Detect NAT type by querying two STUN servers and comparing mapped ports.
48
+ *
49
+ * Symmetric NAT allocates a new external port for each destination,
50
+ * so mapped ports will differ across STUN servers. Cone NATs reuse
51
+ * the same external port, so mapped ports will match.
52
+ *
53
+ * Returns "unknown" if fewer than 2 STUN servers respond.
54
+ */
55
+ export declare function detectNatType(servers?: string[], timeoutMs?: number): Promise<{
56
+ natType: NatType;
57
+ results: StunResult[];
58
+ }>;
59
+ /**
60
+ * STUN client for periodic endpoint discovery.
61
+ *
62
+ * Use for ongoing NAT traversal — discovers and tracks endpoint changes.
63
+ */
64
+ export declare class StunClient {
65
+ private servers;
66
+ private pollIntervalMs;
67
+ private interval;
68
+ private lastResult;
69
+ private _natType;
70
+ /** Number of consecutive discovery failures (reset to 0 on success) */
71
+ consecutiveFailures: number;
72
+ constructor(servers?: string[], pollIntervalMs?: number);
73
+ /** Get the detected NAT type (null if not yet detected) */
74
+ getNatType(): NatType | null;
75
+ /** Get the last discovered endpoint */
76
+ getEndpoint(): StunResult | null;
77
+ /** Discover endpoint once — uses first configured server (or defaults) */
78
+ discover(): Promise<StunResult>;
79
+ /** Start periodic endpoint discovery. Detects NAT type on first call. */
80
+ start(onUpdate?: (result: StunResult) => void): void;
81
+ /** Stop periodic discovery */
82
+ stop(): void;
83
+ }
84
+ //# sourceMappingURL=nat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nat.d.ts","sourceRoot":"","sources":["../nat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AAIpC,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;CAChB;AA6ID;;;;;GAKG;AACH;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,SAAO,EAChB,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,GAC5B,OAAO,CAAC,UAAU,CAAC,CA2ErB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;AAE3E;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,MAAM,EAAyB,EACxC,SAAS,SAAO,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC,CA8BtD;AAED;;;;GAIG;AACH,qBAAa,UAAU;IAQnB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,cAAc;IARxB,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,QAAQ,CAAwB;IACxC,uEAAuE;IACvE,mBAAmB,SAAK;gBAGd,OAAO,GAAE,MAAM,EAAyB,EACxC,cAAc,SAAS;IAGjC,2DAA2D;IAC3D,UAAU,IAAI,OAAO,GAAG,IAAI;IAI5B,uCAAuC;IACvC,WAAW,IAAI,UAAU,GAAG,IAAI;IAIhC,0EAA0E;IACpE,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;IAMrC,yEAAyE;IACzE,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IA4DpD,8BAA8B;IAC9B,IAAI,IAAI,IAAI;CAMb"}