@zerox1/sdk 0.1.14 → 0.1.16
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.
- package/dist/index.js +10 -2
- package/package.json +5 -5
- package/packages/darwin-arm64/bin/zerox1-node +0 -0
- package/packages/darwin-arm64/package.json +1 -1
- package/packages/darwin-x64/bin/zerox1-node +0 -0
- package/packages/darwin-x64/package.json +1 -1
- package/packages/linux-x64/bin/zerox1-node +0 -0
- package/packages/linux-x64/package.json +1 -1
- package/packages/win32-x64/package.json +1 -1
- package/packages/windows-x64/package.json +1 -1
- package/src/index.ts +92 -86
package/dist/index.js
CHANGED
|
@@ -251,10 +251,18 @@ class Zerox1Agent {
|
|
|
251
251
|
headers: { 'Content-Type': 'application/json' },
|
|
252
252
|
body: JSON.stringify(body),
|
|
253
253
|
});
|
|
254
|
-
const
|
|
254
|
+
const isJson = res.headers.get('content-type')?.includes('application/json');
|
|
255
255
|
if (!res.ok) {
|
|
256
|
-
|
|
256
|
+
if (isJson) {
|
|
257
|
+
const errJson = await res.json();
|
|
258
|
+
throw new Error(errJson['error'] ?? `HTTP ${res.status}`);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
const text = await res.text();
|
|
262
|
+
throw new Error(text || `HTTP ${res.status}`);
|
|
263
|
+
}
|
|
257
264
|
}
|
|
265
|
+
const json = await res.json();
|
|
258
266
|
return {
|
|
259
267
|
nonce: json['nonce'],
|
|
260
268
|
payloadHash: json['payload_hash'],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerox1/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "0x01 mesh agent SDK — zero-config, binary bundled, works on every platform",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"ws": "^8.18.0"
|
|
13
13
|
},
|
|
14
14
|
"optionalDependencies": {
|
|
15
|
-
"@zerox1/sdk-darwin-arm64": "0.1.
|
|
16
|
-
"@zerox1/sdk-darwin-x64": "0.1.
|
|
17
|
-
"@zerox1/sdk-linux-x64": "0.1.
|
|
18
|
-
"@zerox1/sdk-windows-x64": "0.1.
|
|
15
|
+
"@zerox1/sdk-darwin-arm64": "0.1.16",
|
|
16
|
+
"@zerox1/sdk-darwin-x64": "0.1.16",
|
|
17
|
+
"@zerox1/sdk-linux-x64": "0.1.16",
|
|
18
|
+
"@zerox1/sdk-windows-x64": "0.1.16"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^22.0.0",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as fs
|
|
2
|
-
import * as net
|
|
3
|
-
import * as os
|
|
4
|
-
import * as path
|
|
1
|
+
import * as fs from 'fs'
|
|
2
|
+
import * as net from 'net'
|
|
3
|
+
import * as os from 'os'
|
|
4
|
+
import * as path from 'path'
|
|
5
5
|
import { spawn, ChildProcess } from 'child_process'
|
|
6
|
-
import WebSocket
|
|
6
|
+
import WebSocket from 'ws'
|
|
7
7
|
|
|
8
8
|
// ============================================================================
|
|
9
9
|
// Public config / types
|
|
@@ -15,25 +15,25 @@ export interface Zerox1AgentConfig {
|
|
|
15
15
|
* key file (raw 32 bytes). If the path does not exist, the node
|
|
16
16
|
* generates a new key and writes it there.
|
|
17
17
|
*/
|
|
18
|
-
keypair:
|
|
18
|
+
keypair: Uint8Array | string
|
|
19
19
|
/** Display name broadcast in BEACON/ADVERTISE. Default: 'zerox1-agent'. */
|
|
20
|
-
name?:
|
|
20
|
+
name?: string
|
|
21
21
|
/**
|
|
22
22
|
* SATI mint address as hex (32 bytes). Required for mainnet.
|
|
23
23
|
* Omit to run in dev mode (SATI checks are advisory only).
|
|
24
24
|
*/
|
|
25
25
|
satiMint?: string
|
|
26
26
|
/** Solana RPC URL. Default: mainnet-beta. */
|
|
27
|
-
rpcUrl?:
|
|
27
|
+
rpcUrl?: string
|
|
28
28
|
/** Directory for per-epoch envelope logs. Default: current dir. */
|
|
29
|
-
logDir?:
|
|
29
|
+
logDir?: string
|
|
30
30
|
/** Additional bootstrap peer multiaddrs. */
|
|
31
31
|
bootstrap?: string[]
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export type MsgType =
|
|
35
35
|
| 'ADVERTISE' | 'DISCOVER'
|
|
36
|
-
| 'PROPOSE'
|
|
36
|
+
| 'PROPOSE' | 'COUNTER' | 'ACCEPT' | 'REJECT'
|
|
37
37
|
| 'DELIVER'
|
|
38
38
|
| 'NOTARIZE_BID' | 'NOTARIZE_ASSIGN'
|
|
39
39
|
| 'VERDICT'
|
|
@@ -41,53 +41,53 @@ export type MsgType =
|
|
|
41
41
|
| 'DISPUTE'
|
|
42
42
|
|
|
43
43
|
export interface SendParams {
|
|
44
|
-
msgType:
|
|
44
|
+
msgType: MsgType
|
|
45
45
|
/** Hex-encoded 32-byte agent ID. Omit for broadcast types. */
|
|
46
|
-
recipient?:
|
|
46
|
+
recipient?: string
|
|
47
47
|
/** Hex-encoded 16-byte conversation ID. */
|
|
48
48
|
conversationId: string
|
|
49
|
-
payload:
|
|
49
|
+
payload: Buffer | Uint8Array
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export interface SentConfirmation {
|
|
53
|
-
nonce:
|
|
53
|
+
nonce: number
|
|
54
54
|
payloadHash: string
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export interface FeedbackPayload {
|
|
58
58
|
conversationId: string
|
|
59
|
-
targetAgent:
|
|
60
|
-
score:
|
|
61
|
-
outcome:
|
|
62
|
-
isDispute:
|
|
63
|
-
role:
|
|
59
|
+
targetAgent: string
|
|
60
|
+
score: number
|
|
61
|
+
outcome: number
|
|
62
|
+
isDispute: boolean
|
|
63
|
+
role: number
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
export interface NotarizeBidPayload {
|
|
67
|
-
bidType:
|
|
67
|
+
bidType: number
|
|
68
68
|
conversationId: string
|
|
69
|
-
opaqueB64:
|
|
69
|
+
opaqueB64: string
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export interface InboundEnvelope {
|
|
73
|
-
msgType:
|
|
74
|
-
sender:
|
|
75
|
-
recipient:
|
|
73
|
+
msgType: MsgType
|
|
74
|
+
sender: string
|
|
75
|
+
recipient: string
|
|
76
76
|
conversationId: string
|
|
77
|
-
slot:
|
|
78
|
-
nonce:
|
|
79
|
-
payloadB64:
|
|
80
|
-
feedback?:
|
|
81
|
-
notarizeBid?:
|
|
77
|
+
slot: number
|
|
78
|
+
nonce: number
|
|
79
|
+
payloadB64: string
|
|
80
|
+
feedback?: FeedbackPayload
|
|
81
|
+
notarizeBid?: NotarizeBidPayload
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
export interface SendFeedbackParams {
|
|
85
85
|
conversationId: string
|
|
86
|
-
targetAgent:
|
|
86
|
+
targetAgent: string
|
|
87
87
|
/** -100 to +100 */
|
|
88
|
-
score:
|
|
89
|
-
outcome:
|
|
90
|
-
role:
|
|
88
|
+
score: number
|
|
89
|
+
outcome: 'negative' | 'neutral' | 'positive'
|
|
90
|
+
role: 'participant' | 'notary'
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// ============================================================================
|
|
@@ -108,23 +108,23 @@ export interface SendFeedbackParams {
|
|
|
108
108
|
|
|
109
109
|
function cborInt(n: number): Buffer {
|
|
110
110
|
n = Math.trunc(n)
|
|
111
|
-
if (n >= 0
|
|
112
|
-
if (n >= 24
|
|
113
|
-
if (n >= -24 && n <
|
|
111
|
+
if (n >= 0 && n <= 23) return Buffer.from([n])
|
|
112
|
+
if (n >= 24 && n <= 255) return Buffer.from([0x18, n])
|
|
113
|
+
if (n >= -24 && n < 0) return Buffer.from([0x20 + (-n - 1)])
|
|
114
114
|
if (n >= -256 && n < -24) return Buffer.from([0x38, -n - 1])
|
|
115
115
|
throw new RangeError(`CBOR int out of range: ${n}`)
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
function encodeFeedbackCbor(
|
|
119
119
|
conversationIdHex: string,
|
|
120
|
-
targetAgentHex:
|
|
121
|
-
score:
|
|
122
|
-
outcome:
|
|
123
|
-
isDispute:
|
|
124
|
-
role:
|
|
120
|
+
targetAgentHex: string,
|
|
121
|
+
score: number,
|
|
122
|
+
outcome: number,
|
|
123
|
+
isDispute: boolean,
|
|
124
|
+
role: number,
|
|
125
125
|
): Buffer {
|
|
126
|
-
const convId
|
|
127
|
-
const targetAgent = Buffer.from(targetAgentHex,
|
|
126
|
+
const convId = Buffer.from(conversationIdHex, 'hex') // 16 bytes
|
|
127
|
+
const targetAgent = Buffer.from(targetAgentHex, 'hex') // 32 bytes
|
|
128
128
|
return Buffer.concat([
|
|
129
129
|
Buffer.from([0x86]), // array(6)
|
|
130
130
|
Buffer.from([0x50]), convId, // bytes(16)
|
|
@@ -142,9 +142,9 @@ function encodeFeedbackCbor(
|
|
|
142
142
|
|
|
143
143
|
function getBinaryPath(): string {
|
|
144
144
|
const platform = process.platform // 'win32' | 'darwin' | 'linux'
|
|
145
|
-
const arch
|
|
146
|
-
const binName
|
|
147
|
-
const pkgName
|
|
145
|
+
const arch = process.arch // 'x64' | 'arm64'
|
|
146
|
+
const binName = platform === 'win32' ? 'zerox1-node.exe' : 'zerox1-node'
|
|
147
|
+
const pkgName = `@zerox1/sdk-${platform}-${arch}`
|
|
148
148
|
|
|
149
149
|
try {
|
|
150
150
|
const pkgJson = require.resolve(`${pkgName}/package.json`)
|
|
@@ -208,14 +208,14 @@ async function waitForReady(port: number, timeoutMs = 15_000): Promise<void> {
|
|
|
208
208
|
type Handler = (env: InboundEnvelope) => void | Promise<void>
|
|
209
209
|
|
|
210
210
|
export class Zerox1Agent {
|
|
211
|
-
private proc:
|
|
212
|
-
private ws:
|
|
213
|
-
private handlers:
|
|
214
|
-
private port:
|
|
215
|
-
private nodeUrl:
|
|
211
|
+
private proc: ChildProcess | null = null
|
|
212
|
+
private ws: WebSocket | null = null
|
|
213
|
+
private handlers: Map<string, Handler[]> = new Map()
|
|
214
|
+
private port: number = 0
|
|
215
|
+
private nodeUrl: string = ''
|
|
216
216
|
private _reconnectDelay: number = 1000
|
|
217
217
|
|
|
218
|
-
private constructor() {}
|
|
218
|
+
private constructor() { }
|
|
219
219
|
|
|
220
220
|
// ── Factory ───────────────────────────────────────────────────────────────
|
|
221
221
|
|
|
@@ -239,21 +239,21 @@ export class Zerox1Agent {
|
|
|
239
239
|
* Safe to await — resolves once the agent is live on the mesh.
|
|
240
240
|
*/
|
|
241
241
|
async start(): Promise<void> {
|
|
242
|
-
this.port
|
|
242
|
+
this.port = await getFreePort()
|
|
243
243
|
this.nodeUrl = `http://127.0.0.1:${this.port}`
|
|
244
244
|
|
|
245
245
|
const keypairPath = resolveKeypairPath(this._config.keypair)
|
|
246
|
-
const binaryPath
|
|
246
|
+
const binaryPath = getBinaryPath()
|
|
247
247
|
|
|
248
248
|
const args: string[] = [
|
|
249
249
|
'--keypair-path', keypairPath,
|
|
250
|
-
'--api-addr',
|
|
251
|
-
'--agent-name',
|
|
250
|
+
'--api-addr', `127.0.0.1:${this.port}`,
|
|
251
|
+
'--agent-name', this._config.name ?? 'zerox1-agent',
|
|
252
252
|
]
|
|
253
253
|
|
|
254
254
|
if (this._config.satiMint) args.push('--sati-mint', this._config.satiMint)
|
|
255
|
-
if (this._config.rpcUrl)
|
|
256
|
-
if (this._config.logDir)
|
|
255
|
+
if (this._config.rpcUrl) args.push('--rpc-url', this._config.rpcUrl)
|
|
256
|
+
if (this._config.logDir) args.push('--log-dir', this._config.logDir)
|
|
257
257
|
for (const b of this._config.bootstrap ?? []) {
|
|
258
258
|
args.push('--bootstrap', b)
|
|
259
259
|
}
|
|
@@ -297,7 +297,7 @@ export class Zerox1Agent {
|
|
|
297
297
|
* Chain multiple `.on()` calls — all handlers for a type are called in order.
|
|
298
298
|
*/
|
|
299
299
|
on(msgType: MsgType | '*', handler: Handler): this {
|
|
300
|
-
const key
|
|
300
|
+
const key = msgType === '*' ? '__all__' : msgType
|
|
301
301
|
const list = this.handlers.get(key) ?? []
|
|
302
302
|
list.push(handler)
|
|
303
303
|
this.handlers.set(key, list)
|
|
@@ -320,25 +320,31 @@ export class Zerox1Agent {
|
|
|
320
320
|
*/
|
|
321
321
|
async send(params: SendParams): Promise<SentConfirmation> {
|
|
322
322
|
const body = {
|
|
323
|
-
msg_type:
|
|
324
|
-
recipient:
|
|
323
|
+
msg_type: params.msgType,
|
|
324
|
+
recipient: params.recipient ?? null,
|
|
325
325
|
conversation_id: params.conversationId,
|
|
326
|
-
payload_b64:
|
|
326
|
+
payload_b64: Buffer.from(params.payload).toString('base64'),
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
const res
|
|
330
|
-
method:
|
|
329
|
+
const res = await fetch(`${this.nodeUrl}/envelopes/send`, {
|
|
330
|
+
method: 'POST',
|
|
331
331
|
headers: { 'Content-Type': 'application/json' },
|
|
332
|
-
body:
|
|
332
|
+
body: JSON.stringify(body),
|
|
333
333
|
})
|
|
334
|
-
const
|
|
335
|
-
|
|
334
|
+
const isJson = res.headers.get('content-type')?.includes('application/json')
|
|
336
335
|
if (!res.ok) {
|
|
337
|
-
|
|
336
|
+
if (isJson) {
|
|
337
|
+
const errJson = await res.json() as Record<string, unknown>
|
|
338
|
+
throw new Error((errJson['error'] as string) ?? `HTTP ${res.status}`)
|
|
339
|
+
} else {
|
|
340
|
+
const text = await res.text()
|
|
341
|
+
throw new Error(text || `HTTP ${res.status}`)
|
|
342
|
+
}
|
|
338
343
|
}
|
|
339
344
|
|
|
345
|
+
const json = await res.json() as Record<string, unknown>
|
|
340
346
|
return {
|
|
341
|
-
nonce:
|
|
347
|
+
nonce: json['nonce'] as number,
|
|
342
348
|
payloadHash: json['payload_hash'] as string,
|
|
343
349
|
}
|
|
344
350
|
}
|
|
@@ -352,7 +358,7 @@ export class Zerox1Agent {
|
|
|
352
358
|
throw new RangeError(`score must be in [-100, 100], got ${params.score}`)
|
|
353
359
|
|
|
354
360
|
const outcomeMap = { negative: 0, neutral: 1, positive: 2 } as const
|
|
355
|
-
const roleMap
|
|
361
|
+
const roleMap = { participant: 0, notary: 1 } as const
|
|
356
362
|
|
|
357
363
|
const payload = encodeFeedbackCbor(
|
|
358
364
|
params.conversationId,
|
|
@@ -364,7 +370,7 @@ export class Zerox1Agent {
|
|
|
364
370
|
)
|
|
365
371
|
|
|
366
372
|
return this.send({
|
|
367
|
-
msgType:
|
|
373
|
+
msgType: 'FEEDBACK',
|
|
368
374
|
conversationId: params.conversationId,
|
|
369
375
|
payload,
|
|
370
376
|
})
|
|
@@ -394,8 +400,8 @@ export class Zerox1Agent {
|
|
|
394
400
|
|
|
395
401
|
private _connectInbox(): void {
|
|
396
402
|
const wsUrl = `ws://127.0.0.1:${this.port}/ws/inbox`
|
|
397
|
-
const ws
|
|
398
|
-
this.ws
|
|
403
|
+
const ws = new WebSocket(wsUrl)
|
|
404
|
+
this.ws = ws
|
|
399
405
|
|
|
400
406
|
ws.on('open', () => { this._reconnectDelay = 1000 })
|
|
401
407
|
|
|
@@ -403,25 +409,25 @@ export class Zerox1Agent {
|
|
|
403
409
|
try {
|
|
404
410
|
const raw = JSON.parse(data.toString())
|
|
405
411
|
const env: InboundEnvelope = {
|
|
406
|
-
msgType:
|
|
407
|
-
sender:
|
|
408
|
-
recipient:
|
|
412
|
+
msgType: raw.msg_type,
|
|
413
|
+
sender: raw.sender,
|
|
414
|
+
recipient: raw.recipient,
|
|
409
415
|
conversationId: raw.conversation_id,
|
|
410
|
-
slot:
|
|
411
|
-
nonce:
|
|
412
|
-
payloadB64:
|
|
416
|
+
slot: raw.slot,
|
|
417
|
+
nonce: raw.nonce,
|
|
418
|
+
payloadB64: raw.payload_b64,
|
|
413
419
|
feedback: raw.feedback ? {
|
|
414
420
|
conversationId: raw.feedback.conversation_id,
|
|
415
|
-
targetAgent:
|
|
416
|
-
score:
|
|
417
|
-
outcome:
|
|
418
|
-
isDispute:
|
|
419
|
-
role:
|
|
421
|
+
targetAgent: raw.feedback.target_agent,
|
|
422
|
+
score: raw.feedback.score,
|
|
423
|
+
outcome: raw.feedback.outcome,
|
|
424
|
+
isDispute: raw.feedback.is_dispute,
|
|
425
|
+
role: raw.feedback.role,
|
|
420
426
|
} : undefined,
|
|
421
427
|
notarizeBid: raw.notarize_bid ? {
|
|
422
|
-
bidType:
|
|
428
|
+
bidType: raw.notarize_bid.bid_type,
|
|
423
429
|
conversationId: raw.notarize_bid.conversation_id,
|
|
424
|
-
opaqueB64:
|
|
430
|
+
opaqueB64: raw.notarize_bid.opaque_b64,
|
|
425
431
|
} : undefined,
|
|
426
432
|
}
|
|
427
433
|
this._dispatch(env)
|