@x1scroll/agent-sdk 1.0.2 → 1.0.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/README.md +15 -5
- package/package.json +1 -1
- package/src/index.js +46 -21
package/README.md
CHANGED
|
@@ -122,28 +122,38 @@ const { txSig, memoryEntryPDA } = await client.storeMemory(
|
|
|
122
122
|
|
|
123
123
|
**Fee:** 0.001 XNT (same as `storeMemory`)
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
By default, content is pinned to the **x1scroll validator network** — no API key, no configuration needed. Pinata is available as an alternative for production workloads requiring independent pinning.
|
|
126
126
|
|
|
127
127
|
```js
|
|
128
|
+
// Default: pinned to x1scroll validator network (zero config)
|
|
128
129
|
const { txSig, cid } = await client.uploadMemory(
|
|
129
130
|
agentKeypair,
|
|
130
131
|
humanWallet.publicKey.toBase58(),
|
|
131
132
|
'session-2026-04-06',
|
|
132
133
|
{ summary: 'Discussed SDK launch', decisions: ['publish to npm', 'BSL license'] },
|
|
133
|
-
{
|
|
134
|
+
{ tags: ['session', 'daily'] }
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
// Alternative: Pinata (bring your own key)
|
|
138
|
+
const { txSig, cid } = await client.uploadMemory(
|
|
139
|
+
agentKeypair,
|
|
140
|
+
humanWallet.publicKey.toBase58(),
|
|
141
|
+
'session-2026-04-06',
|
|
142
|
+
{ summary: 'Discussed SDK launch' },
|
|
143
|
+
{ provider: 'pinata', pinataJwt: process.env.PINATA_JWT }
|
|
134
144
|
);
|
|
135
|
-
// Content is pinned on IPFS, CID stored on X1. Done.
|
|
136
145
|
```
|
|
137
146
|
|
|
138
147
|
| Option | Type | Default | Description |
|
|
139
148
|
|--------|------|---------|-------------|
|
|
140
|
-
| `
|
|
149
|
+
| `provider` | `string` | `'x1scroll'` | `'x1scroll'` (validator network) or `'pinata'` |
|
|
150
|
+
| `pinataJwt` | `string` | — | Required only if provider is `'pinata'` |
|
|
141
151
|
| `tags` | `string[]` | `[]` | Up to 5 tags |
|
|
142
152
|
| `encrypted` | `boolean` | `false` | Whether content is encrypted |
|
|
143
153
|
|
|
144
154
|
**Returns:** `Promise<{ txSig: string, memoryEntryPDA: string, cid: string }>`
|
|
145
155
|
|
|
146
|
-
> **Use `uploadMemory()`
|
|
156
|
+
> **Use `uploadMemory()` for zero-config IPFS pinning.** Content is pinned to x1scroll validator infrastructure — as long as X1 runs, your agent remembers. Use `storeMemory()` directly if you manage your own pinning.
|
|
147
157
|
|
|
148
158
|
---
|
|
149
159
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -551,38 +551,63 @@ class AgentClient {
|
|
|
551
551
|
*/
|
|
552
552
|
async uploadMemory(agentKeypair, agentRecordHuman, topic, content, options = {}) {
|
|
553
553
|
const {
|
|
554
|
+
provider = 'x1scroll',
|
|
554
555
|
pinataJwt = null,
|
|
555
556
|
tags = [],
|
|
556
557
|
encrypted = false,
|
|
557
558
|
} = options;
|
|
558
559
|
|
|
559
|
-
if (!pinataJwt) {
|
|
560
|
-
throw new AgentSDKError(
|
|
561
|
-
'pinataJwt is required for uploadMemory(). Get a free API key at https://pinata.cloud (free tier: 100 pins, 1GB). Pass it as options.pinataJwt.',
|
|
562
|
-
'MISSING_PINATA_JWT'
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
560
|
// Serialize content
|
|
567
561
|
const body = (typeof content === 'string') ? content : JSON.stringify(content);
|
|
568
562
|
|
|
569
563
|
let cid;
|
|
570
564
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
'Content-Type':
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
565
|
+
if (provider === 'x1scroll' || !provider) {
|
|
566
|
+
// Upload to x1scroll validator network — pinned across X1 infrastructure
|
|
567
|
+
const res = await fetch('https://x1scroll.io/api/ipfs/upload', {
|
|
568
|
+
method: 'POST',
|
|
569
|
+
headers: { 'Content-Type': 'application/json' },
|
|
570
|
+
body: JSON.stringify({
|
|
571
|
+
content: body,
|
|
572
|
+
topic,
|
|
573
|
+
agentPubkey: agentKeypair.publicKey.toBase58(),
|
|
574
|
+
}),
|
|
575
|
+
});
|
|
576
|
+
if (!res.ok) {
|
|
577
|
+
const err = await res.text();
|
|
578
|
+
throw new AgentSDKError(`x1scroll IPFS upload failed (${res.status}): ${err}`, 'X1SCROLL_IPFS_ERROR');
|
|
579
|
+
}
|
|
580
|
+
const json = await res.json();
|
|
581
|
+
cid = json.cid;
|
|
582
|
+
|
|
583
|
+
} else if (provider === 'pinata') {
|
|
584
|
+
if (!pinataJwt) {
|
|
585
|
+
throw new AgentSDKError(
|
|
586
|
+
'pinataJwt is required when provider is "pinata". Get one at https://pinata.cloud',
|
|
587
|
+
'MISSING_PINATA_JWT'
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
const res = await fetch('https://api.pinata.cloud/pinning/pinJSONToIPFS', {
|
|
591
|
+
method: 'POST',
|
|
592
|
+
headers: {
|
|
593
|
+
'Content-Type': 'application/json',
|
|
594
|
+
'Authorization': `Bearer ${pinataJwt}`,
|
|
595
|
+
},
|
|
596
|
+
body: JSON.stringify({ pinataContent: body, pinataMetadata: { name: topic } }),
|
|
597
|
+
});
|
|
598
|
+
if (!res.ok) {
|
|
599
|
+
const err = await res.text();
|
|
600
|
+
throw new AgentSDKError(`Pinata upload failed: ${err}`, 'PINATA_ERROR');
|
|
601
|
+
}
|
|
602
|
+
const json = await res.json();
|
|
603
|
+
cid = json.IpfsHash;
|
|
604
|
+
|
|
605
|
+
} else {
|
|
606
|
+
throw new AgentSDKError(
|
|
607
|
+
`Unknown provider "${provider}". Supported: 'x1scroll' (default), 'pinata'`,
|
|
608
|
+
'INVALID_PROVIDER'
|
|
609
|
+
);
|
|
583
610
|
}
|
|
584
|
-
const json = await res.json();
|
|
585
|
-
cid = json.IpfsHash;
|
|
586
611
|
|
|
587
612
|
if (!cid) {
|
|
588
613
|
throw new AgentSDKError('IPFS upload returned no CID', 'NO_CID');
|