API Usage Examples
import { NHPAgent } from '@opennhp/agent';
const agent = new NHPAgent({
cipherScheme: 'curve25519',
transport: 'relay',
relayUrl: 'https://relay.opennhp.org/relay',
});
await agent.init();
agent.addServer({ publicKey: '<server-public-key-base64>' });
agent.setIdentity({
userId: 'alice@example.com',
deviceId: 'my-laptop-01',
});
const otpResult = await agent.requestOtp(
'example',
{ email: 'alice@example.com' },
);
const regResult = await agent.registerPublicKey(
'example',
'123456',
{ email: 'alice@example.com' },
);
if (regResult.success) {
console.log('Registered! Public key:', agent.getPublicKey());
} else {
console.error(regResult.error, regResult.errorCode);
}
The private key never leaves the device. registerPublicKey() sends the NHP-REG packet inside a Noise handshake that cryptographically proves key possession — no separate signature field needed.
import { NHPAgent, OtpResult, RegisterResult } from '@opennhp/agent';
const agent = new NHPAgent({
cipherScheme: 'curve25519',
transport: 'relay',
relayUrl: 'https://relay.opennhp.org/relay',
});
await agent.init();
agent.addServer({ publicKey: '<server-public-key-base64>' });
agent.setIdentity({ userId: 'alice@example.com', deviceId: 'my-laptop-01' });
const otp: OtpResult = await agent.requestOtp('example');
if (!otp.success) throw new Error(otp.error);
const reg: RegisterResult = await agent.registerPublicKey(
'example', '123456',
);
if (reg.success) {
const pubKey: string = agent.getPublicKey();
const expiresAt: number | undefined = reg.expiresAt;
}
Full type definitions are shipped with the package. OtpResult and RegisterResult are both exported from @opennhp/agent.
nhp-agentd register
nhp-agentd register \
--email alice@example.com \
--asp-id example \
--res-id demo \
--device-id my-laptop-01 \
--org-id opennhp.org
nhp-agentd register \
--email alice@example.com \
--asp-id example \
--res-id demo \
--otp 123456
The register command generates a key pair locally, self-registers its public key over NHP-OTP / NHP-REG, and offers to save the result to config.toml / resource.toml (prompting before overwriting an existing file, keeping a .bak). Flags: --email, --asp-id, --res-id, --server (cluster name from server.toml), --device-id, --org-id, --otp. The cipher scheme is always prompted; other omitted fields are prompted only when their flag is absent.
curl -X POST https://relay.opennhp.org/relay/<server-fingerprint> \
-H "Content-Type: application/octet-stream" \
--data-binary @nhp-packet.bin
There is no language-agnostic HTTP API for registration — the payload is a Noise-encrypted binary frame. Use the CLI tab (nhp-agentd register), the JavaScript SDK, or the Go endpoints/agent package; for other languages implement the Noise handshake per the NHP-OTP / NHP-REG message spec.