43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import * as fs from "node:fs/promises";
|
|
|
|
/**
|
|
* Discover running n_signer instances by reading `/proc/net/unix`.
|
|
*
|
|
* Abstract socket paths appear in `/proc/net/unix` with a leading NUL byte
|
|
* (`\0`). n_signer binds to `@nsigner` (explicit `--socket-name nsigner`) or
|
|
* `@nsigner_<word1>_<word2>` (random BIP-39 pair). See
|
|
* `n_signer/plans/nsigner.md` and `n_signer/documents/CLIENT_IMPLEMENTATION.md`.
|
|
*
|
|
* Returns socket names **without** the leading `@` (i.e. ready to pass to
|
|
* `NsignerClient`).
|
|
*/
|
|
export async function discoverNsignerSockets(): Promise<string[]> {
|
|
let content: string;
|
|
try {
|
|
content = await fs.readFile("/proc/net/unix", "utf8");
|
|
} catch {
|
|
return [];
|
|
}
|
|
|
|
const sockets = new Set<string>();
|
|
for (const line of content.split("\n")) {
|
|
// Abstract socket paths in /proc/net/unix are prefixed with a NUL byte.
|
|
// Match `\0nsigner...` and strip the NUL.
|
|
const match = line.match(/\x00(nsigner[^\s]*)/);
|
|
if (match) {
|
|
sockets.add(match[1]);
|
|
}
|
|
}
|
|
return [...sockets];
|
|
}
|
|
|
|
/**
|
|
* Check whether a given abstract socket name appears to be bound.
|
|
*
|
|
* Reads `/proc/net/unix` and looks for `\0<socketName>`. Returns true if found.
|
|
*/
|
|
export async function isNsignerSocketBound(socketName: string): Promise<boolean> {
|
|
const sockets = await discoverNsignerSockets();
|
|
return sockets.includes(socketName);
|
|
}
|