@zerox1/sdk 0.2.1 → 0.2.3
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.d.ts +21 -0
- package/dist/index.js +65 -0
- package/package.json +6 -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/bin/zerox1-node.exe +0 -0
- package/packages/win32-x64/package.json +1 -1
- package/src/index.ts +79 -0
package/dist/index.d.ts
CHANGED
|
@@ -205,6 +205,27 @@ export declare class Zerox1Agent {
|
|
|
205
205
|
*/
|
|
206
206
|
encodeBidValue(value: bigint, rest?: Buffer): Buffer;
|
|
207
207
|
private _connectInbox;
|
|
208
|
+
/**
|
|
209
|
+
* Upload a media blob to the aggregator.
|
|
210
|
+
* Enforces reputation-based size limits:
|
|
211
|
+
* - Claimed/Rep 100+: 10 MB
|
|
212
|
+
* - Rep 50-99: 2 MB
|
|
213
|
+
* - Rep 10-49: 512 KB
|
|
214
|
+
*
|
|
215
|
+
* Every upload is signed by the agent's keypair for authentication.
|
|
216
|
+
*
|
|
217
|
+
* @param data - Buffer or Uint8Array of the media.
|
|
218
|
+
* @param aggregatorUrl - Aggregator base URL.
|
|
219
|
+
* @returns Hex-encoded CID (Keccak-256 hash).
|
|
220
|
+
*/
|
|
221
|
+
uploadBlob(data: Buffer | Uint8Array, aggregatorUrl?: string): Promise<string>;
|
|
222
|
+
/**
|
|
223
|
+
* Download a media blob from the aggregator.
|
|
224
|
+
*
|
|
225
|
+
* @param cid - Hex-encoded CID.
|
|
226
|
+
* @param aggregatorUrl - Aggregator base URL.
|
|
227
|
+
*/
|
|
228
|
+
downloadBlob(cid: string, aggregatorUrl?: string): Promise<Buffer>;
|
|
208
229
|
}
|
|
209
230
|
/**
|
|
210
231
|
* A hosted agent that delegates signing and routing to a host node.
|
package/dist/index.js
CHANGED
|
@@ -43,6 +43,7 @@ const os = __importStar(require("os"));
|
|
|
43
43
|
const path = __importStar(require("path"));
|
|
44
44
|
const child_process_1 = require("child_process");
|
|
45
45
|
const ws_1 = __importDefault(require("ws"));
|
|
46
|
+
const ed = __importStar(require("@noble/ed25519"));
|
|
46
47
|
// ============================================================================
|
|
47
48
|
// CBOR encoding for FEEDBACK payload
|
|
48
49
|
//
|
|
@@ -458,6 +459,70 @@ class Zerox1Agent {
|
|
|
458
459
|
});
|
|
459
460
|
ws.on('error', () => { });
|
|
460
461
|
}
|
|
462
|
+
// ── Blobs (Media Relay) ───────────────────────────────────────────────────
|
|
463
|
+
/**
|
|
464
|
+
* Upload a media blob to the aggregator.
|
|
465
|
+
* Enforces reputation-based size limits:
|
|
466
|
+
* - Claimed/Rep 100+: 10 MB
|
|
467
|
+
* - Rep 50-99: 2 MB
|
|
468
|
+
* - Rep 10-49: 512 KB
|
|
469
|
+
*
|
|
470
|
+
* Every upload is signed by the agent's keypair for authentication.
|
|
471
|
+
*
|
|
472
|
+
* @param data - Buffer or Uint8Array of the media.
|
|
473
|
+
* @param aggregatorUrl - Aggregator base URL.
|
|
474
|
+
* @returns Hex-encoded CID (Keccak-256 hash).
|
|
475
|
+
*/
|
|
476
|
+
async uploadBlob(data, aggregatorUrl = 'https://api.0x01.world') {
|
|
477
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
478
|
+
const body = Buffer.from(data);
|
|
479
|
+
// Signing payload: body + timestamp (8-byte Little Endian)
|
|
480
|
+
const tsBuf = Buffer.alloc(8);
|
|
481
|
+
tsBuf.writeBigUInt64LE(BigInt(timestamp), 0);
|
|
482
|
+
const msg = Buffer.concat([body, tsBuf]);
|
|
483
|
+
const secretKeyHex = fs.readFileSync(resolveKeypairPath(this._config.keypair), 'hex');
|
|
484
|
+
const secretKey = Buffer.from(secretKeyHex, 'hex').slice(0, 32);
|
|
485
|
+
const pubKey = await ed.getPublicKey(secretKey);
|
|
486
|
+
const signature = await ed.sign(msg, secretKey);
|
|
487
|
+
// In dev mode agent_id == verifying key (same hex).
|
|
488
|
+
// In SATI mode agent_id is the SATI mint address (different key).
|
|
489
|
+
// The aggregator uses X-0x01-Agent-Id for reputation lookup and
|
|
490
|
+
// X-0x01-Signer for signature verification — always the Ed25519 key.
|
|
491
|
+
const signerHex = Buffer.from(pubKey).toString('hex');
|
|
492
|
+
const agentIdHex = this._config.satiMint ?? signerHex;
|
|
493
|
+
const res = await fetch(`${aggregatorUrl}/blobs`, {
|
|
494
|
+
method: 'POST',
|
|
495
|
+
headers: {
|
|
496
|
+
'Content-Type': 'application/octet-stream',
|
|
497
|
+
'X-0x01-Agent-Id': agentIdHex,
|
|
498
|
+
'X-0x01-Signer': signerHex,
|
|
499
|
+
'X-0x01-Timestamp': timestamp.toString(),
|
|
500
|
+
'X-0x01-Signature': Buffer.from(signature).toString('hex'),
|
|
501
|
+
},
|
|
502
|
+
body: body,
|
|
503
|
+
});
|
|
504
|
+
if (!res.ok) {
|
|
505
|
+
const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
506
|
+
throw new Error(`uploadBlob failed: ${err.error ?? res.status}`);
|
|
507
|
+
}
|
|
508
|
+
const { cid } = await res.json();
|
|
509
|
+
return cid;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Download a media blob from the aggregator.
|
|
513
|
+
*
|
|
514
|
+
* @param cid - Hex-encoded CID.
|
|
515
|
+
* @param aggregatorUrl - Aggregator base URL.
|
|
516
|
+
*/
|
|
517
|
+
async downloadBlob(cid, aggregatorUrl = 'https://api.0x01.world') {
|
|
518
|
+
const res = await fetch(`${aggregatorUrl}/blobs/${cid}`);
|
|
519
|
+
if (res.status === 404)
|
|
520
|
+
throw new Error('Blob not found');
|
|
521
|
+
if (!res.ok)
|
|
522
|
+
throw new Error(`downloadBlob failed: HTTP ${res.status}`);
|
|
523
|
+
const arrayBuffer = await res.arrayBuffer();
|
|
524
|
+
return Buffer.from(arrayBuffer);
|
|
525
|
+
}
|
|
461
526
|
}
|
|
462
527
|
exports.Zerox1Agent = Zerox1Agent;
|
|
463
528
|
// ============================================================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerox1/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "0x01 mesh agent SDK — zero-config, binary bundled, works on every platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,13 +10,14 @@
|
|
|
10
10
|
"dev": "tsc --watch"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
+
"@noble/ed25519": "^3.0.0",
|
|
13
14
|
"ws": "^8.18.0"
|
|
14
15
|
},
|
|
15
16
|
"optionalDependencies": {
|
|
16
|
-
"@zerox1/sdk-darwin-arm64": "0.2.
|
|
17
|
-
"@zerox1/sdk-darwin-x64": "0.2.
|
|
18
|
-
"@zerox1/sdk-linux-x64": "0.2.
|
|
19
|
-
"@zerox1/sdk-win32-x64": "0.2.
|
|
17
|
+
"@zerox1/sdk-darwin-arm64": "0.2.3",
|
|
18
|
+
"@zerox1/sdk-darwin-x64": "0.2.3",
|
|
19
|
+
"@zerox1/sdk-linux-x64": "0.2.3",
|
|
20
|
+
"@zerox1/sdk-win32-x64": "0.2.3"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"@types/node": "^22.0.0",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import * as os from 'os'
|
|
|
4
4
|
import * as path from 'path'
|
|
5
5
|
import { spawn, ChildProcess } from 'child_process'
|
|
6
6
|
import WebSocket from 'ws'
|
|
7
|
+
import * as ed from '@noble/ed25519'
|
|
7
8
|
|
|
8
9
|
// ============================================================================
|
|
9
10
|
// Public config / types
|
|
@@ -623,6 +624,84 @@ export class Zerox1Agent {
|
|
|
623
624
|
|
|
624
625
|
ws.on('error', () => { /* close event handles reconnect */ })
|
|
625
626
|
}
|
|
627
|
+
|
|
628
|
+
// ── Blobs (Media Relay) ───────────────────────────────────────────────────
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Upload a media blob to the aggregator.
|
|
632
|
+
* Enforces reputation-based size limits:
|
|
633
|
+
* - Claimed/Rep 100+: 10 MB
|
|
634
|
+
* - Rep 50-99: 2 MB
|
|
635
|
+
* - Rep 10-49: 512 KB
|
|
636
|
+
*
|
|
637
|
+
* Every upload is signed by the agent's keypair for authentication.
|
|
638
|
+
*
|
|
639
|
+
* @param data - Buffer or Uint8Array of the media.
|
|
640
|
+
* @param aggregatorUrl - Aggregator base URL.
|
|
641
|
+
* @returns Hex-encoded CID (Keccak-256 hash).
|
|
642
|
+
*/
|
|
643
|
+
async uploadBlob(
|
|
644
|
+
data: Buffer | Uint8Array,
|
|
645
|
+
aggregatorUrl = 'https://api.0x01.world'
|
|
646
|
+
): Promise<string> {
|
|
647
|
+
const timestamp = Math.floor(Date.now() / 1000)
|
|
648
|
+
const body = Buffer.from(data)
|
|
649
|
+
|
|
650
|
+
// Signing payload: body + timestamp (8-byte Little Endian)
|
|
651
|
+
const tsBuf = Buffer.alloc(8)
|
|
652
|
+
tsBuf.writeBigUInt64LE(BigInt(timestamp), 0)
|
|
653
|
+
const msg = Buffer.concat([body, tsBuf])
|
|
654
|
+
|
|
655
|
+
const secretKeyHex = fs.readFileSync(resolveKeypairPath(this._config.keypair), 'hex')
|
|
656
|
+
const secretKey = Buffer.from(secretKeyHex, 'hex').slice(0, 32)
|
|
657
|
+
const pubKey = await ed.getPublicKey(secretKey)
|
|
658
|
+
const signature = await ed.sign(msg, secretKey)
|
|
659
|
+
|
|
660
|
+
// In dev mode agent_id == verifying key (same hex).
|
|
661
|
+
// In SATI mode agent_id is the SATI mint address (different key).
|
|
662
|
+
// The aggregator uses X-0x01-Agent-Id for reputation lookup and
|
|
663
|
+
// X-0x01-Signer for signature verification — always the Ed25519 key.
|
|
664
|
+
const signerHex = Buffer.from(pubKey).toString('hex')
|
|
665
|
+
const agentIdHex = this._config.satiMint ?? signerHex
|
|
666
|
+
|
|
667
|
+
const res = await fetch(`${aggregatorUrl}/blobs`, {
|
|
668
|
+
method: 'POST',
|
|
669
|
+
headers: {
|
|
670
|
+
'Content-Type': 'application/octet-stream',
|
|
671
|
+
'X-0x01-Agent-Id': agentIdHex,
|
|
672
|
+
'X-0x01-Signer': signerHex,
|
|
673
|
+
'X-0x01-Timestamp': timestamp.toString(),
|
|
674
|
+
'X-0x01-Signature': Buffer.from(signature).toString('hex'),
|
|
675
|
+
},
|
|
676
|
+
body: body,
|
|
677
|
+
})
|
|
678
|
+
|
|
679
|
+
if (!res.ok) {
|
|
680
|
+
const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }))
|
|
681
|
+
throw new Error(`uploadBlob failed: ${(err as { error?: string }).error ?? res.status}`)
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
const { cid } = await res.json() as { cid: string }
|
|
685
|
+
return cid
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Download a media blob from the aggregator.
|
|
690
|
+
*
|
|
691
|
+
* @param cid - Hex-encoded CID.
|
|
692
|
+
* @param aggregatorUrl - Aggregator base URL.
|
|
693
|
+
*/
|
|
694
|
+
async downloadBlob(
|
|
695
|
+
cid: string,
|
|
696
|
+
aggregatorUrl = 'https://api.0x01.world'
|
|
697
|
+
): Promise<Buffer> {
|
|
698
|
+
const res = await fetch(`${aggregatorUrl}/blobs/${cid}`)
|
|
699
|
+
if (res.status === 404) throw new Error('Blob not found')
|
|
700
|
+
if (!res.ok) throw new Error(`downloadBlob failed: HTTP ${res.status}`)
|
|
701
|
+
|
|
702
|
+
const arrayBuffer = await res.arrayBuffer()
|
|
703
|
+
return Buffer.from(arrayBuffer)
|
|
704
|
+
}
|
|
626
705
|
}
|
|
627
706
|
|
|
628
707
|
// ============================================================================
|