fangorn-sdk 2026.2.24 → 2026.2.27
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 +44 -22
- package/lib/{cli.js → cli/cli.js} +34 -40
- package/lib/cli/index.d.ts +700 -0
- package/lib/cli/index.js +36 -0
- package/lib/cli/registry.d.ts +29 -0
- package/lib/cli/registry.js +53 -0
- package/lib/config.d.ts +1 -1
- package/lib/deployContract.js +2 -2
- package/lib/fangorn.d.ts +1 -1
- package/lib/fangorn.js +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +4 -4
- package/lib/interface/datasource-registry/dataSourceRegistry.d.ts +2 -2
- package/lib/interface/settlement-tracker/settlementTracker.d.ts +2 -2
- package/lib/modules/encryption/lit.js +1 -1
- package/lib/modules/gadgets/payment.d.ts +1 -0
- package/lib/modules/gadgets/payment.js +1 -3
- package/lib/test/testbed.d.ts +1 -1
- package/lib/test/testbed.js +5 -4
- package/lib/utils/index.d.ts +2 -5
- package/lib/utils/index.js +15 -34
- package/package.json +8 -17
- package/lib/circuits/poseiden1_hash/target/poseiden1_hash.js +0 -45
- package/lib/circuits/poseiden2_hash/target/poseiden2_hash.js +0 -49
- /package/lib/{cli.d.ts → cli/cli.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -10,44 +10,62 @@ Fangorn is a programmable data framework that lets you **register datasources**
|
|
|
10
10
|
|
|
11
11
|
Fangorn can be deployed on any EVM chain that has a brige to Lit protocol. Currently, contracts are deployed to both Arbitrum Sepolia and Base Sepolia. See the [contracts](#contracts) section for more info.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Usage
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Fangorn is a programmable data framework. It provides tools to register data sources that can be accessed based on owner-defined conditions, like payment.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
## CLI/Quickstart
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
To install the fangorn-sdk from NPM, run:
|
|
20
|
+
|
|
21
|
+
```shell
|
|
22
|
+
npm i -g fangorn-sdk
|
|
23
|
+
```
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
### Register a Datasource
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
First register a datasource
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
fangorn register name-of-your-datasource-agent
|
|
25
31
|
```
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
### Upload Data
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
On upload, data is encrypted under a user-specified **gadget**. For now, the CLI only supports the payment gadget, which is used by specifying the argument `-g "Payment(amount)"`. The minimum amount is `0.000001`.
|
|
36
|
+
|
|
37
|
+
For `-c`, the CLI supports both arbitrumSepolia and baseSepolia.
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
fangorn upload name-of-your-datasource-agent file-to-upload.ext -c arbitrumSepolia -g "Payment(0.0001)"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Decrypt and Download
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
fangorn decrypt [owner] [datasourceName] [tag] -c arbitrumSepolia
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Full Guide
|
|
50
|
+
|
|
51
|
+
### Build
|
|
52
|
+
|
|
53
|
+
`pnpm i`
|
|
54
|
+
|
|
55
|
+
### Setup
|
|
30
56
|
|
|
31
57
|
```js
|
|
32
58
|
// provide the account, rpcurl, and chain externally
|
|
33
59
|
// Initalize a wallet client
|
|
34
60
|
const walletClient = createWalletClient({
|
|
35
|
-
account
|
|
61
|
+
account,
|
|
36
62
|
transport: http(rpcUrl),
|
|
37
63
|
chain,
|
|
38
64
|
});
|
|
39
|
-
|
|
40
65
|
// For ArbSep, also supports BaseSepolia (wallet client must match)
|
|
41
66
|
const config: AppConfig = FangornConfig.ArbitrumSepolia;
|
|
42
|
-
|
|
43
|
-
// setup the Lit client (for encryption)
|
|
44
|
-
const litClient = await createLitClient({
|
|
45
|
-
network: nagaDev,
|
|
46
|
-
});
|
|
47
67
|
// and the encryption service
|
|
48
|
-
const encryptionService = new LitEncryptionService(
|
|
49
|
-
chainName: chain,
|
|
50
|
-
});
|
|
68
|
+
const encryptionService = new LitEncryptionService(chain);
|
|
51
69
|
|
|
52
70
|
// setup the storage client
|
|
53
71
|
const pinata = new PinataSDK({
|
|
@@ -69,7 +87,7 @@ const fangorn = await Fangorn.init(
|
|
|
69
87
|
);
|
|
70
88
|
```
|
|
71
89
|
|
|
72
|
-
|
|
90
|
+
### Datasource Registration
|
|
73
91
|
|
|
74
92
|
Now that you have a Fangorn client, you can create a _datasource_. A datasource is an on-chain asset that stores a commitment to its storage root along with an optional `agentId` field for associating the datasource with an ERC-8004 identity.
|
|
75
93
|
|
|
@@ -79,7 +97,7 @@ const name = "demo";
|
|
|
79
97
|
const id = await this.delegatorFangorn.registerDataSource(name, "");
|
|
80
98
|
```
|
|
81
99
|
|
|
82
|
-
|
|
100
|
+
### Encryption
|
|
83
101
|
|
|
84
102
|
Once a datasource exists, the owner can update its storage root to point it to data. Fangorn leverages Lit protocol for encryption and access control.
|
|
85
103
|
|
|
@@ -229,7 +247,7 @@ The tests will:
|
|
|
229
247
|
To install locally:
|
|
230
248
|
|
|
231
249
|
```sh
|
|
232
|
-
chmod +x
|
|
250
|
+
chmod +x update_cli.sh
|
|
233
251
|
./update_cli.sh
|
|
234
252
|
```
|
|
235
253
|
|
|
@@ -243,8 +261,12 @@ Options:
|
|
|
243
261
|
-h, --help display help for command
|
|
244
262
|
|
|
245
263
|
Commands:
|
|
264
|
+
init Configure your Fangorn credentials
|
|
246
265
|
register [options] <name> Register a new datasource as an agent.
|
|
247
266
|
upload [options] <name> <files...> Upload file(s) to a data source
|
|
267
|
+
list [options] <name> List contents (index) of a data source
|
|
268
|
+
info [options] <name> Get data source info from contract
|
|
269
|
+
entry [options] <name> <tag> Get info about a specific entry
|
|
248
270
|
decrypt [options] <owner> <name> <tag> Decrypt a file from a vault
|
|
249
271
|
help [command] display help for command
|
|
250
272
|
```
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import { Fangorn } from "
|
|
4
|
-
import { PinataStorage } from "
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
2
|
+
import { FangornConfig, SupportedNetworks } from "../config.js";
|
|
3
|
+
import { Fangorn } from "../fangorn.js";
|
|
4
|
+
import { PinataStorage } from "../providers/storage/pinata/index.js";
|
|
5
|
+
import { computeTagCommitment, fieldToHex } from "../utils/index.js";
|
|
6
|
+
import { LitEncryptionService } from "../modules/encryption/lit.js";
|
|
7
|
+
import { agentCardBuilder } from "../builders/a2aCardBuilder.js";
|
|
8
|
+
import { getChain, handleCancel, parseGadgetArg, selectChain } from "./index.js";
|
|
9
|
+
import { GADGET_REGISTRY, selectGadget } from "./registry.js";
|
|
10
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
11
|
+
import { basename, extname, join } from "path";
|
|
11
12
|
import { createWalletClient, http } from "viem";
|
|
13
|
+
import { Command } from "commander";
|
|
14
|
+
import { confirm, intro, multiselect, note, outro, select, spinner, text } from "@clack/prompts";
|
|
12
15
|
import { privateKeyToAccount } from "viem/accounts";
|
|
13
16
|
import "dotenv/config";
|
|
14
17
|
import { PinataSDK } from "pinata";
|
|
15
18
|
import { SDK } from "agent0-sdk";
|
|
16
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
17
|
-
import { basename, extname, join } from "path";
|
|
18
19
|
import { homedir } from "os";
|
|
19
20
|
|
|
20
|
-
//#region src/cli.ts
|
|
21
|
+
//#region src/cli/cli.ts
|
|
21
22
|
const CONFIG_DIR = join(homedir(), ".fangorn");
|
|
22
23
|
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
23
24
|
let _config = null;
|
|
@@ -78,26 +79,6 @@ async function getFangorn(chain) {
|
|
|
78
79
|
_fangorn = await Fangorn.init(walletClient, storage, encryptionService, domain, appConfig);
|
|
79
80
|
return _fangorn;
|
|
80
81
|
}
|
|
81
|
-
const getChain = (chainStr) => {
|
|
82
|
-
return getNetwork(chainStr);
|
|
83
|
-
};
|
|
84
|
-
const handleCancel = (value) => {
|
|
85
|
-
if (isCancel(value)) process.exit(0);
|
|
86
|
-
};
|
|
87
|
-
const selectChain = async () => {
|
|
88
|
-
const chainChoice = await select({
|
|
89
|
-
message: "Pick your chain.",
|
|
90
|
-
options: [{
|
|
91
|
-
value: "arbitrumSepolia",
|
|
92
|
-
label: "Arbitrum Sepolia"
|
|
93
|
-
}, {
|
|
94
|
-
value: "baseSepolia",
|
|
95
|
-
label: "Base Sepolia"
|
|
96
|
-
}]
|
|
97
|
-
});
|
|
98
|
-
handleCancel(chainChoice);
|
|
99
|
-
return getNetwork(chainChoice.toString());
|
|
100
|
-
};
|
|
101
82
|
const program = new Command();
|
|
102
83
|
program.name("Fangorn").description("CLI for Fangorn").version("0.0.1");
|
|
103
84
|
program.command("init").description("Configure your Fangorn credentials").action(async () => {
|
|
@@ -395,7 +376,7 @@ program.command("register").description("Register a new datasource as an agent."
|
|
|
395
376
|
process.exit(1);
|
|
396
377
|
}
|
|
397
378
|
});
|
|
398
|
-
program.command("upload").description("Upload file(s) to a data source").argument("<name>", "Data source name").argument("<files...>", "File path(s) to upload").option("-c, --chain <chain>", "The chain to use as the backend (arbitrumSepolia or baseSepolia)").option("-
|
|
379
|
+
program.command("upload").description("Upload file(s) to a data source").argument("<name>", "Data source name").argument("<files...>", "File path(s) to upload").option("-c, --chain <chain>", "The chain to use as the backend (arbitrumSepolia or baseSepolia)").option("-g, --gadget <type(args)>", "Gadget to use (e.g. Payment(0.000001))").option("-o --overwrite", "Overwrite existing data source contents").action(async (name, files, options) => {
|
|
399
380
|
try {
|
|
400
381
|
const owner = getAccount().address;
|
|
401
382
|
const fangorn = await getFangorn(getChain(options.chain));
|
|
@@ -412,12 +393,21 @@ program.command("upload").description("Upload file(s) to a data source").argumen
|
|
|
412
393
|
};
|
|
413
394
|
});
|
|
414
395
|
const cid = await fangorn.upload(name, filedata, async (file) => {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
396
|
+
if (options.gadget) {
|
|
397
|
+
const { type, args } = parseGadgetArg(options.gadget);
|
|
398
|
+
const def = GADGET_REGISTRY[type];
|
|
399
|
+
if (!def) throw new Error(`Unknown gadget type: ${type}`);
|
|
400
|
+
const params = {};
|
|
401
|
+
def.argSchema.forEach((key, i) => {
|
|
402
|
+
params[key] = args[i];
|
|
403
|
+
});
|
|
404
|
+
params.commitment = fieldToHex(await computeTagCommitment(owner, name, file.tag, options.price));
|
|
405
|
+
params.chainName = options.chain;
|
|
406
|
+
params.settlementTrackerContractAddress = options.chain === "arbitrumSepolia" ? "0x7c6ae9eb3398234eb69b2f3acfae69065505ff69" : "0x708751829f5f5f584da4142b62cd5cc9235c8a18";
|
|
407
|
+
params.pinataJwt = loadConfig().jwt;
|
|
408
|
+
return def.build(params);
|
|
409
|
+
}
|
|
410
|
+
return selectGadget(owner, name, file.tag, options.price);
|
|
421
411
|
}, options.overwrite);
|
|
422
412
|
console.log(`Upload complete! Manifest CID: ${cid}`);
|
|
423
413
|
process.exit(0);
|
|
@@ -476,7 +466,11 @@ program.command("decrypt").description("Decrypt a file from a vault").argument("
|
|
|
476
466
|
if (options.output) {
|
|
477
467
|
writeFileSync(options.output, Buffer.from(decrypted));
|
|
478
468
|
console.log(`Decrypted file saved to: ${options.output}`);
|
|
479
|
-
} else
|
|
469
|
+
} else {
|
|
470
|
+
const buf = Buffer.from(decrypted);
|
|
471
|
+
process.stdout.write(atob(buf.toString()));
|
|
472
|
+
process.stdout.write("\n");
|
|
473
|
+
}
|
|
480
474
|
process.exit(0);
|
|
481
475
|
} catch (err) {
|
|
482
476
|
console.error("Failed to decrypt:", err.message);
|