Build the agent-native compute CRM platform
CI / verify (push) Successful in 3m6s

This commit is contained in:
2026-08-13 01:39:01 -07:00
parent bfd2f8d95a
commit 853bde2265
160 changed files with 61812 additions and 483 deletions
+311
View File
@@ -0,0 +1,311 @@
import { createHash, randomUUID } from 'node:crypto';
import { schnorr } from '@noble/curves/secp256k1.js';
import { finalizeEvent, getPublicKey, nip19, type Event, verifyEvent } from 'nostr-tools';
import {
NotificationDeliveryError,
type Notification,
type NotificationEnvelope,
type NotificationReceipt,
type Notifier,
} from './notifier';
interface BuzzNotifierOptions {
relayUrl: string;
privateKey: string;
authTag?: string;
fetchImpl?: typeof fetch;
now?: () => Date;
nonce?: () => string;
}
interface BuzzRelayResponse {
event_id?: string;
accepted?: boolean;
}
export class BuzzNotifier implements Notifier {
readonly provider = 'buzz';
readonly relayUrl: string;
readonly workspaceId: string;
private readonly eventsUrl: string;
private readonly secretKey: Uint8Array;
private readonly publicKey: string;
private readonly authTag: string[] | null;
private readonly authTagJson: string | null;
private readonly fetchImpl: typeof fetch;
private readonly now: () => Date;
private readonly nonce: () => string;
constructor(options: BuzzNotifierOptions) {
this.relayUrl = normaliseBuzzRelayUrl(options.relayUrl);
this.workspaceId = new URL(this.relayUrl).host;
this.eventsUrl = `${this.relayUrl}/events`;
this.secretKey = parseBuzzPrivateKey(options.privateKey);
this.publicKey = getPublicKey(this.secretKey);
const parsedAuth = options.authTag
? parseAndVerifyBuzzAuthTag(options.authTag, this.publicKey)
: null;
this.authTag = parsedAuth;
this.authTagJson = parsedAuth ? JSON.stringify(parsedAuth) : null;
this.fetchImpl = options.fetchImpl ?? fetch;
this.now = options.now ?? (() => new Date());
this.nonce = options.nonce ?? randomUUID;
}
async send(
envelope: NotificationEnvelope,
signal?: AbortSignal,
): Promise<NotificationReceipt> {
if (envelope.workspaceId && envelope.workspaceId !== this.workspaceId) {
throw new NotificationDeliveryError('buzz_workspace_mismatch', false);
}
if (!isUuid(envelope.destination)) {
throw new NotificationDeliveryError('invalid_buzz_channel', false);
}
const createdAt = notificationTimestamp(envelope.notification);
if (this.authTag && !buzzAuthConditionsAllow(this.authTag[2]!, 9, createdAt)) {
throw new NotificationDeliveryError('buzz_auth_tag_conditions', false);
}
const event = finalizeEvent(
{
kind: 9,
created_at: createdAt,
tags: [
['h', envelope.destination],
[
'client',
'PIG',
createHash('sha256').update(envelope.idempotencyKey).digest('hex'),
],
...(this.authTag ? [this.authTag] : []),
],
content: formatBuzzNotification(envelope.notification),
},
this.secretKey,
);
const body = JSON.stringify(event);
const authorization = this.createNip98Authorization(body);
let response: Response;
try {
response = await this.fetchImpl(this.eventsUrl, {
method: 'POST',
headers: {
authorization,
'content-type': 'application/json',
...(this.authTagJson ? { 'x-auth-tag': this.authTagJson } : {}),
},
body,
signal,
});
} catch {
// The event id is content-addressed and remains stable on a retry, so an
// ambiguous network outcome cannot create a second Buzz message.
throw new NotificationDeliveryError('buzz_network_error', true);
}
if (response.status === 429) {
throw new NotificationDeliveryError(
'buzz_rate_limited',
true,
retryAfterMs(response.headers.get('retry-after')),
);
}
if (response.status === 408 || response.status >= 500) {
throw new NotificationDeliveryError('buzz_unavailable', true);
}
if (!response.ok) {
throw new NotificationDeliveryError(`buzz_http_${response.status}`, false);
}
let result: BuzzRelayResponse;
try {
result = (await response.json()) as BuzzRelayResponse;
} catch {
throw new NotificationDeliveryError('invalid_buzz_response', true);
}
if (result.accepted !== true || !isEventId(result.event_id)) {
throw new NotificationDeliveryError('buzz_rejected', false);
}
if (result.event_id !== event.id) {
throw new NotificationDeliveryError('buzz_event_id_mismatch', false);
}
return { externalId: event.id };
}
private createNip98Authorization(body: string): string {
const authEvent = finalizeEvent(
{
kind: 27235,
created_at: Math.floor(this.now().getTime() / 1_000),
tags: [
['u', this.eventsUrl],
['method', 'POST'],
['nonce', this.nonce()],
['payload', createHash('sha256').update(body).digest('hex')],
],
content: '',
},
this.secretKey,
);
return `Nostr ${Buffer.from(JSON.stringify(authEvent), 'utf8').toString('base64')}`;
}
}
export function normaliseBuzzRelayUrl(value: string): string {
const trimmed = value.trim().replace(/^wss:/i, 'https:').replace(/^ws:/i, 'http:');
let url: URL;
try {
url = new URL(trimmed);
} catch {
throw new Error('BUZZ_RELAY_URL must be a valid http(s) or ws(s) URL.');
}
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) {
throw new Error('BUZZ_RELAY_URL must be a credential-free http(s) or ws(s) URL.');
}
url.pathname = url.pathname.replace(/\/+$/, '');
url.search = '';
url.hash = '';
return url.toString().replace(/\/$/, '');
}
export function parseBuzzPrivateKey(value: string): Uint8Array {
const trimmed = value.trim();
let key: Uint8Array;
try {
if (trimmed.startsWith('nsec1')) {
const decoded = nip19.decode(trimmed);
if (decoded.type !== 'nsec') throw new Error('wrong key type');
key = decoded.data;
} else {
if (!/^[a-f0-9]{64}$/i.test(trimmed)) throw new Error('invalid hex');
key = Uint8Array.from(Buffer.from(trimmed, 'hex'));
}
getPublicKey(key);
} catch {
throw new Error('BUZZ_PRIVATE_KEY must be a valid 32-byte hex or nsec private key.');
}
return key;
}
export function parseAndVerifyBuzzAuthTag(value: string, agentPublicKey: string): string[] {
let tag: unknown;
try {
tag = JSON.parse(value);
} catch {
throw new Error('BUZZ_AUTH_TAG must be a valid JSON array.');
}
if (
!Array.isArray(tag) ||
tag.length !== 4 ||
tag.some((part) => typeof part !== 'string') ||
tag[0] !== 'auth' ||
!/^[a-f0-9]{64}$/.test(tag[1] as string) ||
!/^[a-f0-9]{128}$/.test(tag[3] as string)
) {
throw new Error('BUZZ_AUTH_TAG has an invalid NIP-OA structure.');
}
const parts = tag as string[];
validateBuzzAuthConditions(parts[2]!);
if (parts[1] === agentPublicKey) {
throw new Error('BUZZ_AUTH_TAG must be signed by an owner distinct from the agent.');
}
const digest = createHash('sha256')
.update(`nostr:agent-auth:${agentPublicKey}:${parts[2]}`)
.digest();
let verified = false;
try {
verified = schnorr.verify(hexBytes(parts[3]!), digest, hexBytes(parts[1]!));
} catch {
verified = false;
}
if (!verified) throw new Error('BUZZ_AUTH_TAG signature does not authorize this agent key.');
return parts;
}
function notificationTimestamp(notification: Notification): number {
const value = notification.kind === 'stage_change' ? notification.changedAt : notification.observedAt;
const milliseconds = Date.parse(value);
if (!Number.isFinite(milliseconds)) {
throw new NotificationDeliveryError('invalid_notification_timestamp', false);
}
return Math.floor(milliseconds / 1_000);
}
function formatBuzzNotification(notification: Notification): string {
if (notification.kind === 'stage_change') {
return [
`**${notification.dealName}** moved from \`${notification.fromStage}\` to \`${notification.toStage}\`.`,
`${notification.dealSide === 'demand' ? 'Demand' : 'Supply'} pipeline stage changed in PIG.`,
].join('\n');
}
return [
`**Idle capacity: ${notification.commitmentName}**`,
`${notification.gpuType} has ${formatNumber(notification.idleGpuHours)} unsold GPU-hours (${Math.round(notification.utilisation * 100)}% utilised).`,
`Idle committed cost: ${formatMoney(notification.idleCostCents)}.`,
].join('\n');
}
function formatNumber(value: number): string {
return new Intl.NumberFormat('en-US', { maximumFractionDigits: 1 }).format(value);
}
function formatMoney(cents: number): string {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
maximumFractionDigits: 0,
}).format(cents / 100);
}
function validateBuzzAuthConditions(conditions: string): void {
if (conditions === '') return;
for (const clause of conditions.split('&')) {
const match = /^(kind=|created_at<|created_at>)(0|[1-9]\d*)$/.exec(clause);
if (!match) throw new Error('BUZZ_AUTH_TAG contains invalid NIP-OA conditions.');
const value = Number(match[2]);
const maximum = match[1] === 'kind=' ? 65_535 : 4_294_967_295;
if (!Number.isSafeInteger(value) || value > maximum) {
throw new Error('BUZZ_AUTH_TAG contains out-of-range NIP-OA conditions.');
}
}
}
function buzzAuthConditionsAllow(conditions: string, kind: number, createdAt: number): boolean {
if (conditions === '') return true;
return conditions.split('&').every((clause) => {
if (clause.startsWith('kind=')) return kind === Number(clause.slice(5));
if (clause.startsWith('created_at<')) return createdAt < Number(clause.slice(11));
if (clause.startsWith('created_at>')) return createdAt > Number(clause.slice(11));
return false;
});
}
function retryAfterMs(value: string | null): number | undefined {
const seconds = Number(value);
return Number.isFinite(seconds) && seconds > 0 ? Math.min(seconds, 3_600) * 1_000 : undefined;
}
function hexBytes(value: string): Uint8Array {
return Uint8Array.from(Buffer.from(value, 'hex'));
}
function isUuid(value: string): boolean {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
}
function isEventId(value: string | undefined): value is string {
return Boolean(value && /^[a-f0-9]{64}$/.test(value));
}
export function decodeBuzzAuthorization(value: string): Event | null {
if (!value.startsWith('Nostr ')) return null;
try {
const event = JSON.parse(Buffer.from(value.slice(6), 'base64').toString('utf8')) as Event;
return verifyEvent(event) ? event : null;
} catch {
return null;
}
}