@nevermined-io/openclaw-plugin 1.0.11-rc.1 → 1.0.12
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 +26 -3
- package/dist/auth.d.ts +13 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +98 -0
- package/dist/auth.js.map +1 -0
- package/dist/config.d.ts +4 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -2
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +22 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +79 -4
- package/dist/index.js.map +1 -1
- package/docs/commands.md +164 -0
- package/docs/getting-started.md +71 -0
- package/docs/links.md +38 -0
- package/docs/setup.md +64 -0
- package/openclaw.plugin.json +15 -3
- package/package.json +7 -1
- package/skills/nevermined/SKILL.md +17 -1
package/README.md
CHANGED
|
@@ -8,9 +8,23 @@ OpenClaw plugin for [Nevermined](https://nevermined.io) — exposes AI agent pay
|
|
|
8
8
|
openclaw plugin install @nevermined-io/openclaw-plugin
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Authentication
|
|
12
|
+
|
|
13
|
+
The plugin supports two ways to provide your Nevermined API key:
|
|
14
|
+
|
|
15
|
+
### Option A: Browser login (recommended)
|
|
16
|
+
|
|
17
|
+
Use the `/nvm-login` command from any chat channel, or call the `nevermined.login` gateway method. This opens a browser window where you authenticate with Nevermined, and the API key is captured automatically.
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
/nvm-login # Login to sandbox (default)
|
|
21
|
+
/nvm-login live # Login to live environment
|
|
22
|
+
/nvm-logout # Remove stored API key
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Option B: Manual configuration
|
|
12
26
|
|
|
13
|
-
Add
|
|
27
|
+
Add your API key directly to `openclaw.json`:
|
|
14
28
|
|
|
15
29
|
```json
|
|
16
30
|
{
|
|
@@ -26,9 +40,11 @@ Add the Nevermined plugin config to your `openclaw.json`:
|
|
|
26
40
|
}
|
|
27
41
|
```
|
|
28
42
|
|
|
43
|
+
## Configuration
|
|
44
|
+
|
|
29
45
|
| Field | Required | Default | Description |
|
|
30
46
|
|-------|----------|---------|-------------|
|
|
31
|
-
| `nvmApiKey` |
|
|
47
|
+
| `nvmApiKey` | No | — | Your Nevermined API key (or use `/nvm-login`) |
|
|
32
48
|
| `environment` | No | `sandbox` | `sandbox` or `live` |
|
|
33
49
|
| `planId` | No | — | Default plan ID for subscriber tools |
|
|
34
50
|
| `agentId` | No | — | Default agent ID for multi-agent plans |
|
|
@@ -36,6 +52,13 @@ Add the Nevermined plugin config to your `openclaw.json`:
|
|
|
36
52
|
|
|
37
53
|
## Available Tools
|
|
38
54
|
|
|
55
|
+
### Authentication
|
|
56
|
+
|
|
57
|
+
| Tool / Command | Description |
|
|
58
|
+
|----------------|-------------|
|
|
59
|
+
| `nevermined.login` / `/nvm-login` | Authenticate via browser login |
|
|
60
|
+
| `nevermined.logout` / `/nvm-logout` | Remove stored API key |
|
|
61
|
+
|
|
39
62
|
### Subscriber Tools
|
|
40
63
|
|
|
41
64
|
| Tool | Description | Key Params |
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { EnvironmentName } from '@nevermined-io/payments';
|
|
2
|
+
export interface LoginResult {
|
|
3
|
+
nvmApiKey: string;
|
|
4
|
+
environment: string;
|
|
5
|
+
loginUrl: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Starts a one-shot HTTP server, opens the Nevermined login page in the browser,
|
|
9
|
+
* and resolves with the API key once the callback is received.
|
|
10
|
+
*/
|
|
11
|
+
export declare function startLoginFlow(environment: EnvironmentName, openBrowserFn?: (url: string) => Promise<void>): Promise<LoginResult>;
|
|
12
|
+
export declare function openBrowser(url: string): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAa9D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,eAAe,EAC5B,aAAa,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAe,GAC1D,OAAO,CAAC,WAAW,CAAC,CAiEtB;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBtD"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createServer } from 'http';
|
|
2
|
+
import { execFile } from 'child_process';
|
|
3
|
+
import { Environments } from '@nevermined-io/payments';
|
|
4
|
+
const LOGIN_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
5
|
+
const SUCCESS_HTML = `
|
|
6
|
+
<html><body style="font-family: system-ui, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #f8f9fa;">
|
|
7
|
+
<div style="text-align: center;">
|
|
8
|
+
<h2>Authentication successful!</h2>
|
|
9
|
+
<p>You can close this tab and return to your application.</p>
|
|
10
|
+
</div>
|
|
11
|
+
</body></html>
|
|
12
|
+
`;
|
|
13
|
+
/**
|
|
14
|
+
* Starts a one-shot HTTP server, opens the Nevermined login page in the browser,
|
|
15
|
+
* and resolves with the API key once the callback is received.
|
|
16
|
+
*/
|
|
17
|
+
export async function startLoginFlow(environment, openBrowserFn = openBrowser) {
|
|
18
|
+
const envInfo = Environments[environment];
|
|
19
|
+
if (!envInfo?.frontend) {
|
|
20
|
+
throw new Error(`Unknown environment: ${environment}`);
|
|
21
|
+
}
|
|
22
|
+
const frontendUrl = envInfo.frontend;
|
|
23
|
+
const nvmApiKey = await new Promise((resolve, reject) => {
|
|
24
|
+
const server = createServer((req, res) => {
|
|
25
|
+
const url = new URL(req.url || '/', 'http://localhost');
|
|
26
|
+
if (url.pathname !== '/callback') {
|
|
27
|
+
res.writeHead(404);
|
|
28
|
+
res.end('Not found');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const key = url.searchParams.get('nvm_api_key');
|
|
32
|
+
if (!key) {
|
|
33
|
+
res.writeHead(400);
|
|
34
|
+
res.end('Missing nvm_api_key parameter');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
38
|
+
res.end(SUCCESS_HTML);
|
|
39
|
+
clearTimeout(timeout);
|
|
40
|
+
server.close();
|
|
41
|
+
resolve(key);
|
|
42
|
+
});
|
|
43
|
+
const timeout = setTimeout(() => {
|
|
44
|
+
server.close();
|
|
45
|
+
reject(new Error('Login timed out after 5 minutes. Please try again.'));
|
|
46
|
+
}, LOGIN_TIMEOUT_MS);
|
|
47
|
+
server.listen(0, '127.0.0.1', () => {
|
|
48
|
+
const addr = server.address();
|
|
49
|
+
if (!addr || typeof addr === 'string') {
|
|
50
|
+
clearTimeout(timeout);
|
|
51
|
+
server.close();
|
|
52
|
+
reject(new Error('Failed to start local server'));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const port = addr.port;
|
|
56
|
+
const callbackUrl = encodeURIComponent(`http://localhost:${port}/callback`);
|
|
57
|
+
const loginUrl = `${frontendUrl}/auth/cli?callback_url=${callbackUrl}`;
|
|
58
|
+
openBrowserFn(loginUrl).catch(() => {
|
|
59
|
+
// Browser open failed — the caller should provide the URL to the user
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
server.on('error', (err) => {
|
|
63
|
+
clearTimeout(timeout);
|
|
64
|
+
reject(new Error(`Failed to start local server: ${err.message}`));
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
nvmApiKey,
|
|
69
|
+
environment,
|
|
70
|
+
loginUrl: `${frontendUrl}/auth/cli`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function openBrowser(url) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
const platform = process.platform;
|
|
76
|
+
let cmd;
|
|
77
|
+
let args;
|
|
78
|
+
if (platform === 'darwin') {
|
|
79
|
+
cmd = 'open';
|
|
80
|
+
args = [url];
|
|
81
|
+
}
|
|
82
|
+
else if (platform === 'win32') {
|
|
83
|
+
cmd = 'cmd';
|
|
84
|
+
args = ['/c', 'start', '""', url];
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
cmd = 'xdg-open';
|
|
88
|
+
args = [url];
|
|
89
|
+
}
|
|
90
|
+
execFile(cmd, args, (err) => {
|
|
91
|
+
if (err)
|
|
92
|
+
reject(err);
|
|
93
|
+
else
|
|
94
|
+
resolve();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAGtD,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,YAAY;AAEnD,MAAM,YAAY,GAAG;;;;;;;CAOpB,CAAA;AAQD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAA4B,EAC5B,gBAAgD,WAAW;IAE3D,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;IACzC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,WAAW,EAAE,CAAC,CAAA;IACxD,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAA;IAEpC,MAAM,SAAS,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC9D,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAoB,EAAE,GAAmB,EAAE,EAAE;YACxE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAA;YACvD,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACjC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;gBAClB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;gBACpB,OAAM;YACR,CAAC;YAED,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;YAC/C,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;gBAClB,GAAG,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;gBACxC,OAAM;YACR,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAA;YACnD,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YAErB,YAAY,CAAC,OAAO,CAAC,CAAA;YACrB,MAAM,CAAC,KAAK,EAAE,CAAA;YACd,OAAO,CAAC,GAAG,CAAC,CAAA;QACd,CAAC,CAAC,CAAA;QAEF,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,MAAM,CAAC,KAAK,EAAE,CAAA;YACd,MAAM,CAAC,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAA;QACzE,CAAC,EAAE,gBAAgB,CAAC,CAAA;QAEpB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;YAC7B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtC,YAAY,CAAC,OAAO,CAAC,CAAA;gBACrB,MAAM,CAAC,KAAK,EAAE,CAAA;gBACd,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAA;gBACjD,OAAM;YACR,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;YACtB,MAAM,WAAW,GAAG,kBAAkB,CAAC,oBAAoB,IAAI,WAAW,CAAC,CAAA;YAC3E,MAAM,QAAQ,GAAG,GAAG,WAAW,0BAA0B,WAAW,EAAE,CAAA;YAEtE,aAAa,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBACjC,sEAAsE;YACxE,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,YAAY,CAAC,OAAO,CAAC,CAAA;YACrB,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACnE,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,SAAS;QACT,WAAW;QACX,QAAQ,EAAE,GAAG,WAAW,WAAW;KACpC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QACjC,IAAI,GAAW,CAAA;QACf,IAAI,IAAc,CAAA;QAClB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,GAAG,GAAG,MAAM,CAAA;YACZ,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACd,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAChC,GAAG,GAAG,KAAK,CAAA;YACX,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;QACnC,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,UAAU,CAAA;YAChB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACd,CAAC;QACD,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;YAC1B,IAAI,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAA;;gBACf,OAAO,EAAE,CAAA;QAChB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { Payments } from '@nevermined-io/payments';
|
|
3
3
|
export declare const NeverminedPluginConfigSchema: z.ZodObject<{
|
|
4
|
-
nvmApiKey: z.ZodString
|
|
4
|
+
nvmApiKey: z.ZodOptional<z.ZodString>;
|
|
5
5
|
environment: z.ZodDefault<z.ZodEnum<["sandbox", "live"]>>;
|
|
6
6
|
planId: z.ZodOptional<z.ZodString>;
|
|
7
7
|
agentId: z.ZodOptional<z.ZodString>;
|
|
8
8
|
creditsPerRequest: z.ZodDefault<z.ZodNumber>;
|
|
9
9
|
}, "strip", z.ZodTypeAny, {
|
|
10
|
-
nvmApiKey: string;
|
|
11
10
|
environment: "sandbox" | "live";
|
|
12
11
|
creditsPerRequest: number;
|
|
12
|
+
nvmApiKey?: string | undefined;
|
|
13
13
|
planId?: string | undefined;
|
|
14
14
|
agentId?: string | undefined;
|
|
15
15
|
}, {
|
|
16
|
-
nvmApiKey
|
|
16
|
+
nvmApiKey?: string | undefined;
|
|
17
17
|
environment?: "sandbox" | "live" | undefined;
|
|
18
18
|
planId?: string | undefined;
|
|
19
19
|
agentId?: string | undefined;
|
|
@@ -21,5 +21,6 @@ export declare const NeverminedPluginConfigSchema: z.ZodObject<{
|
|
|
21
21
|
}>;
|
|
22
22
|
export type NeverminedPluginConfig = z.infer<typeof NeverminedPluginConfigSchema>;
|
|
23
23
|
export declare function validateConfig(raw: unknown): NeverminedPluginConfig;
|
|
24
|
+
export declare function requireApiKey(config: NeverminedPluginConfig): string;
|
|
24
25
|
export declare function createPaymentsFromConfig(config: NeverminedPluginConfig): Payments;
|
|
25
26
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAGlD,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;EAMvC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,sBAAsB,CAEnE;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,sBAAsB,GAAG,QAAQ,CAKjF"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAGlD,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;EAMvC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEjF,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,sBAAsB,CAEnE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAKpE;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,sBAAsB,GAAG,QAAQ,CAKjF"}
|
package/dist/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { Payments } from '@nevermined-io/payments';
|
|
3
3
|
export const NeverminedPluginConfigSchema = z.object({
|
|
4
|
-
nvmApiKey: z.string().
|
|
4
|
+
nvmApiKey: z.string().optional(),
|
|
5
5
|
environment: z.enum(['sandbox', 'live']).default('sandbox'),
|
|
6
6
|
planId: z.string().optional(),
|
|
7
7
|
agentId: z.string().optional(),
|
|
@@ -10,9 +10,15 @@ export const NeverminedPluginConfigSchema = z.object({
|
|
|
10
10
|
export function validateConfig(raw) {
|
|
11
11
|
return NeverminedPluginConfigSchema.parse(raw);
|
|
12
12
|
}
|
|
13
|
+
export function requireApiKey(config) {
|
|
14
|
+
if (!config.nvmApiKey) {
|
|
15
|
+
throw new Error('Not authenticated. Run nevermined.login or /nvm-login first.');
|
|
16
|
+
}
|
|
17
|
+
return config.nvmApiKey;
|
|
18
|
+
}
|
|
13
19
|
export function createPaymentsFromConfig(config) {
|
|
14
20
|
return Payments.getInstance({
|
|
15
|
-
nvmApiKey: config
|
|
21
|
+
nvmApiKey: requireApiKey(config),
|
|
16
22
|
environment: config.environment,
|
|
17
23
|
});
|
|
18
24
|
}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAGlD,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAGlD,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAC3D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;CAC1D,CAAC,CAAA;AAIF,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,OAAO,4BAA4B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAA8B;IAC1D,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IACjF,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAA8B;IACrE,OAAO,QAAQ,CAAC,WAAW,CAAC;QAC1B,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC;QAChC,WAAW,EAAE,MAAM,CAAC,WAA8B;KACnD,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { validateConfig, createPaymentsFromConfig } from './config.js';
|
|
1
|
+
import { validateConfig, createPaymentsFromConfig, requireApiKey } from './config.js';
|
|
2
2
|
import { allTools } from './tools.js';
|
|
3
|
-
import
|
|
3
|
+
import { Payments } from '@nevermined-io/payments';
|
|
4
4
|
import type { NeverminedPluginConfig } from './config.js';
|
|
5
5
|
import type { ToolDefinition } from './tools.js';
|
|
6
6
|
export type { NeverminedPluginConfig, ToolDefinition };
|
|
7
|
-
export { validateConfig, createPaymentsFromConfig, allTools };
|
|
7
|
+
export { validateConfig, createPaymentsFromConfig, requireApiKey, allTools };
|
|
8
|
+
export { startLoginFlow, openBrowser } from './auth.js';
|
|
8
9
|
export interface OpenClawPluginAPI {
|
|
9
10
|
getConfig(namespace: string): unknown;
|
|
11
|
+
setConfig(namespace: string, key: string, value: unknown): void;
|
|
10
12
|
registerGatewayMethod(name: string, options: {
|
|
11
13
|
description: string;
|
|
12
14
|
params: Array<{
|
|
@@ -17,6 +19,23 @@ export interface OpenClawPluginAPI {
|
|
|
17
19
|
}>;
|
|
18
20
|
handler: (params: Record<string, unknown>) => Promise<unknown>;
|
|
19
21
|
}): void;
|
|
22
|
+
registerCommand(options: {
|
|
23
|
+
name: string;
|
|
24
|
+
description: string;
|
|
25
|
+
acceptsArgs?: boolean;
|
|
26
|
+
requireAuth?: boolean;
|
|
27
|
+
handler: (ctx: CommandContext) => Promise<{
|
|
28
|
+
text: string;
|
|
29
|
+
}>;
|
|
30
|
+
}): void;
|
|
31
|
+
}
|
|
32
|
+
export interface CommandContext {
|
|
33
|
+
senderId: string;
|
|
34
|
+
channel: string;
|
|
35
|
+
isAuthorizedSender: boolean;
|
|
36
|
+
args: string;
|
|
37
|
+
commandBody: string;
|
|
38
|
+
config: Record<string, unknown>;
|
|
20
39
|
}
|
|
21
40
|
export interface RegisterOptions {
|
|
22
41
|
paymentsFactory?: (config: NeverminedPluginConfig) => Payments;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,QAAQ,EAAgB,MAAM,yBAAyB,CAAA;AAEhE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAA;AAC5E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvD,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAA;IACrC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IAC/D,qBAAqB,CACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAA;QACnB,MAAM,EAAE,KAAK,CAAC;YACZ,IAAI,EAAE,MAAM,CAAA;YACZ,IAAI,EAAE,MAAM,CAAA;YACZ,WAAW,EAAE,MAAM,CAAA;YACnB,QAAQ,EAAE,OAAO,CAAA;SAClB,CAAC,CAAA;QACF,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;KAC/D,GACA,IAAI,CAAA;IACP,eAAe,CAAC,OAAO,EAAE;QACvB,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAC5D,GAAG,IAAI,CAAA;CACT;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB,EAAE,OAAO,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,QAAQ,CAAA;CAC/D;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,CA+GhF"}
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,93 @@
|
|
|
1
|
-
import { validateConfig, createPaymentsFromConfig } from './config.js';
|
|
1
|
+
import { validateConfig, createPaymentsFromConfig, requireApiKey } from './config.js';
|
|
2
2
|
import { allTools } from './tools.js';
|
|
3
|
-
|
|
3
|
+
import { startLoginFlow } from './auth.js';
|
|
4
|
+
export { validateConfig, createPaymentsFromConfig, requireApiKey, allTools };
|
|
5
|
+
export { startLoginFlow, openBrowser } from './auth.js';
|
|
4
6
|
export function register(api, options) {
|
|
5
7
|
const rawConfig = api.getConfig('nevermined');
|
|
6
8
|
const config = validateConfig(rawConfig);
|
|
9
|
+
// Lazy Payments instance — created on first use after authentication
|
|
10
|
+
let payments = null;
|
|
7
11
|
const factory = options?.paymentsFactory ?? createPaymentsFromConfig;
|
|
8
|
-
|
|
12
|
+
function getPayments() {
|
|
13
|
+
if (!payments) {
|
|
14
|
+
requireApiKey(config);
|
|
15
|
+
payments = factory(config);
|
|
16
|
+
}
|
|
17
|
+
return payments;
|
|
18
|
+
}
|
|
19
|
+
// --- Login/Logout gateway tools ---
|
|
20
|
+
api.registerGatewayMethod('nevermined.login', {
|
|
21
|
+
description: 'Authenticate with Nevermined via browser login to obtain an API key',
|
|
22
|
+
params: [
|
|
23
|
+
{ name: 'environment', type: 'string', description: 'Target environment: sandbox or live (default: from config)', required: false },
|
|
24
|
+
],
|
|
25
|
+
handler: async (params) => {
|
|
26
|
+
const env = params.environment || config.environment || 'sandbox';
|
|
27
|
+
const result = await startLoginFlow(env);
|
|
28
|
+
config.nvmApiKey = result.nvmApiKey;
|
|
29
|
+
config.environment = result.environment;
|
|
30
|
+
payments = null; // Reset so next call creates a fresh instance
|
|
31
|
+
api.setConfig('nevermined', 'nvmApiKey', result.nvmApiKey);
|
|
32
|
+
api.setConfig('nevermined', 'environment', result.environment);
|
|
33
|
+
return {
|
|
34
|
+
authenticated: true,
|
|
35
|
+
environment: result.environment,
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
api.registerGatewayMethod('nevermined.logout', {
|
|
40
|
+
description: 'Log out from Nevermined by removing the stored API key',
|
|
41
|
+
params: [],
|
|
42
|
+
handler: async () => {
|
|
43
|
+
config.nvmApiKey = undefined;
|
|
44
|
+
payments = null;
|
|
45
|
+
api.setConfig('nevermined', 'nvmApiKey', '');
|
|
46
|
+
return { authenticated: false };
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
// --- Slash commands for chat channels ---
|
|
50
|
+
api.registerCommand({
|
|
51
|
+
name: 'nvm-login',
|
|
52
|
+
description: 'Authenticate with Nevermined via browser login',
|
|
53
|
+
acceptsArgs: true,
|
|
54
|
+
requireAuth: true,
|
|
55
|
+
handler: async (ctx) => {
|
|
56
|
+
try {
|
|
57
|
+
const env = (ctx.args?.trim() || config.environment || 'sandbox');
|
|
58
|
+
const result = await startLoginFlow(env);
|
|
59
|
+
config.nvmApiKey = result.nvmApiKey;
|
|
60
|
+
config.environment = result.environment;
|
|
61
|
+
payments = null;
|
|
62
|
+
api.setConfig('nevermined', 'nvmApiKey', result.nvmApiKey);
|
|
63
|
+
api.setConfig('nevermined', 'environment', result.environment);
|
|
64
|
+
return { text: `Authenticated with Nevermined (${result.environment}). You can now use payment tools.` };
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
68
|
+
return { text: `Login failed: ${message}` };
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
api.registerCommand({
|
|
73
|
+
name: 'nvm-logout',
|
|
74
|
+
description: 'Log out from Nevermined',
|
|
75
|
+
requireAuth: true,
|
|
76
|
+
handler: async () => {
|
|
77
|
+
config.nvmApiKey = undefined;
|
|
78
|
+
payments = null;
|
|
79
|
+
api.setConfig('nevermined', 'nvmApiKey', '');
|
|
80
|
+
return { text: 'Logged out from Nevermined. API key has been removed.' };
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
// --- Payment tools (require authentication) ---
|
|
9
84
|
for (const tool of allTools) {
|
|
10
85
|
api.registerGatewayMethod(tool.name, {
|
|
11
86
|
description: tool.description,
|
|
12
87
|
params: tool.params,
|
|
13
88
|
handler: async (params) => {
|
|
14
89
|
try {
|
|
15
|
-
return await tool.handler(
|
|
90
|
+
return await tool.handler(getPayments(), config, params);
|
|
16
91
|
}
|
|
17
92
|
catch (err) {
|
|
18
93
|
const message = err instanceof Error ? err.message : String(err);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/docs/commands.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Commands"
|
|
3
|
+
description: "All available tools and slash commands in the Nevermined OpenClaw plugin"
|
|
4
|
+
icon: "terminal"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Commands
|
|
8
|
+
|
|
9
|
+
The plugin provides slash commands for chat channels and gateway methods for programmatic access. Each command is available in both forms.
|
|
10
|
+
|
|
11
|
+
## Authentication
|
|
12
|
+
|
|
13
|
+
### `/nvm-login [environment]`
|
|
14
|
+
|
|
15
|
+
Authenticate with Nevermined via browser login.
|
|
16
|
+
|
|
17
|
+
| Parameter | Type | Required | Default | Description |
|
|
18
|
+
|-----------|------|----------|---------|-------------|
|
|
19
|
+
| `environment` | string | No | `sandbox` | `sandbox` or `live` |
|
|
20
|
+
|
|
21
|
+
**Gateway method:** `nevermined.login`
|
|
22
|
+
|
|
23
|
+
**Example:**
|
|
24
|
+
```
|
|
25
|
+
/nvm-login
|
|
26
|
+
/nvm-login live
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### `/nvm-logout`
|
|
32
|
+
|
|
33
|
+
Log out from Nevermined and remove the stored API key.
|
|
34
|
+
|
|
35
|
+
**Gateway method:** `nevermined.logout`
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Subscriber Tools
|
|
40
|
+
|
|
41
|
+
These tools are for users who want to subscribe to plans, check balances, and query agents.
|
|
42
|
+
|
|
43
|
+
### `nevermined.checkBalance`
|
|
44
|
+
|
|
45
|
+
Check the credit balance for a payment plan.
|
|
46
|
+
|
|
47
|
+
| Parameter | Type | Required | Default | Description |
|
|
48
|
+
|-----------|------|----------|---------|-------------|
|
|
49
|
+
| `planId` | string | No | Config `planId` | The payment plan ID to check |
|
|
50
|
+
|
|
51
|
+
**Returns:**
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"planId": "did:nv:abc123...",
|
|
55
|
+
"planName": "Basic Plan",
|
|
56
|
+
"balance": "95",
|
|
57
|
+
"isSubscriber": true
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### `nevermined.getAccessToken`
|
|
64
|
+
|
|
65
|
+
Get an x402 access token for authenticating requests to a Nevermined agent.
|
|
66
|
+
|
|
67
|
+
| Parameter | Type | Required | Default | Description |
|
|
68
|
+
|-----------|------|----------|---------|-------------|
|
|
69
|
+
| `planId` | string | No | Config `planId` | The payment plan ID |
|
|
70
|
+
| `agentId` | string | No | Config `agentId` | The agent ID |
|
|
71
|
+
|
|
72
|
+
**Returns:**
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"accessToken": "eyJhbG..."
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
### `nevermined.orderPlan`
|
|
82
|
+
|
|
83
|
+
Purchase (order) a Nevermined payment plan.
|
|
84
|
+
|
|
85
|
+
| Parameter | Type | Required | Default | Description |
|
|
86
|
+
|-----------|------|----------|---------|-------------|
|
|
87
|
+
| `planId` | string | No | Config `planId` | The plan ID to purchase |
|
|
88
|
+
|
|
89
|
+
**Returns:** Order confirmation with transaction hash.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### `nevermined.queryAgent`
|
|
94
|
+
|
|
95
|
+
End-to-end agent query: acquires an x402 access token, sends the prompt to the agent URL with the `PAYMENT-SIGNATURE` header, and returns the response.
|
|
96
|
+
|
|
97
|
+
| Parameter | Type | Required | Default | Description |
|
|
98
|
+
|-----------|------|----------|---------|-------------|
|
|
99
|
+
| `agentUrl` | string | **Yes** | — | The URL of the agent to query |
|
|
100
|
+
| `prompt` | string | **Yes** | — | The prompt to send to the agent |
|
|
101
|
+
| `planId` | string | No | Config `planId` | The payment plan ID |
|
|
102
|
+
| `agentId` | string | No | Config `agentId` | The agent ID |
|
|
103
|
+
| `method` | string | No | `POST` | HTTP method |
|
|
104
|
+
|
|
105
|
+
If the agent returns a 402 (Payment Required) response, the tool returns an error indicating insufficient credits.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Builder Tools
|
|
110
|
+
|
|
111
|
+
These tools are for agent builders who want to register agents and create payment plans.
|
|
112
|
+
|
|
113
|
+
### `nevermined.registerAgent`
|
|
114
|
+
|
|
115
|
+
Register a new AI agent with an associated payment plan.
|
|
116
|
+
|
|
117
|
+
| Parameter | Type | Required | Description |
|
|
118
|
+
|-----------|------|----------|-------------|
|
|
119
|
+
| `name` | string | **Yes** | Agent name |
|
|
120
|
+
| `description` | string | No | Agent description |
|
|
121
|
+
| `agentUrl` | string | **Yes** | The endpoint URL for the agent |
|
|
122
|
+
| `planName` | string | **Yes** | Name for the payment plan |
|
|
123
|
+
| `priceAmounts` | string | **Yes** | Comma-separated price amounts in wei |
|
|
124
|
+
| `priceReceivers` | string | **Yes** | Comma-separated receiver addresses |
|
|
125
|
+
| `creditsAmount` | number | **Yes** | Number of credits in the plan |
|
|
126
|
+
|
|
127
|
+
**Returns:**
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"agentId": "did:nv:...",
|
|
131
|
+
"planId": "did:nv:...",
|
|
132
|
+
"txHash": "0x..."
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### `nevermined.createPlan`
|
|
139
|
+
|
|
140
|
+
Create a standalone payment plan (without an agent).
|
|
141
|
+
|
|
142
|
+
| Parameter | Type | Required | Description |
|
|
143
|
+
|-----------|------|----------|-------------|
|
|
144
|
+
| `name` | string | **Yes** | Plan name |
|
|
145
|
+
| `description` | string | No | Plan description |
|
|
146
|
+
| `priceAmounts` | string | **Yes** | Comma-separated price amounts in wei |
|
|
147
|
+
| `priceReceivers` | string | **Yes** | Comma-separated receiver addresses |
|
|
148
|
+
| `creditsAmount` | number | **Yes** | Number of credits in the plan |
|
|
149
|
+
| `accessLimit` | string | No | `"credits"` (default) or `"time"` |
|
|
150
|
+
|
|
151
|
+
**Returns:**
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"planId": "did:nv:..."
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### `nevermined.listPlans`
|
|
161
|
+
|
|
162
|
+
List the builder's payment plans. No parameters required.
|
|
163
|
+
|
|
164
|
+
**Returns:** Array of plan objects.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Getting Started"
|
|
3
|
+
description: "Install and configure the Nevermined OpenClaw plugin in minutes"
|
|
4
|
+
icon: "rocket"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Getting Started
|
|
8
|
+
|
|
9
|
+
The Nevermined OpenClaw plugin exposes AI agent payment operations as gateway tools callable from any OpenClaw channel — Telegram, Discord, WhatsApp, and more.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
- An [OpenClaw](https://openclaw.ai) gateway instance
|
|
14
|
+
- Node.js >= 18.0.0
|
|
15
|
+
- A [Nevermined account](https://nevermined.app) (free to create)
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
Install the plugin from your OpenClaw gateway:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
openclaw plugin install @nevermined-io/openclaw-plugin
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Authentication
|
|
26
|
+
|
|
27
|
+
### Option A: Browser login (recommended)
|
|
28
|
+
|
|
29
|
+
Use the `/nvm-login` command from any connected chat channel:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
/nvm-login
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This opens a browser window where you authenticate with Nevermined. The API key is captured automatically and stored in your gateway config.
|
|
36
|
+
|
|
37
|
+
To target the live environment:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
/nvm-login live
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Option B: Manual configuration
|
|
44
|
+
|
|
45
|
+
Add your API key directly to `openclaw.json`:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"plugins": {
|
|
50
|
+
"nevermined": {
|
|
51
|
+
"nvmApiKey": "sandbox:eyJhbG...",
|
|
52
|
+
"environment": "sandbox"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
You can obtain an API key from the [Nevermined App](https://nevermined.app) under Settings > API Keys. See the [Get Your API Key](/docs/getting-started/get-your-api-key) guide for details.
|
|
59
|
+
|
|
60
|
+
## Quick Test
|
|
61
|
+
|
|
62
|
+
After authenticating, verify the plugin is working:
|
|
63
|
+
|
|
64
|
+
1. **Check your balance** — from any chat channel, the agent can call `nevermined.checkBalance` to verify connectivity.
|
|
65
|
+
|
|
66
|
+
2. **List plans** — call `nevermined.listPlans` to see available payment plans.
|
|
67
|
+
|
|
68
|
+
## Next Steps
|
|
69
|
+
|
|
70
|
+
- [Setup](/docs/api-reference/openclaw-plugin/setup) — full configuration reference
|
|
71
|
+
- [Commands](/docs/api-reference/openclaw-plugin/commands) — all available tools and slash commands
|
package/docs/links.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Resources"
|
|
3
|
+
description: "Links to Nevermined documentation, SDKs, and community resources"
|
|
4
|
+
icon: "book"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Resources
|
|
8
|
+
|
|
9
|
+
## Nevermined Documentation
|
|
10
|
+
|
|
11
|
+
| Resource | Description |
|
|
12
|
+
|----------|-------------|
|
|
13
|
+
| [Nevermined Docs](https://docs.nevermined.app) | Full platform documentation |
|
|
14
|
+
| [Get Your API Key](https://docs.nevermined.app/docs/getting-started/get-your-api-key) | How to create a Nevermined account and obtain an API key |
|
|
15
|
+
| [Payment Plans](https://docs.nevermined.app/docs/api-reference/typescript/payment-plans-and-agents) | Creating and managing payment plans |
|
|
16
|
+
| [Querying Agents](https://docs.nevermined.app/docs/api-reference/typescript/querying-an-agent) | How to query agents using x402 access tokens |
|
|
17
|
+
| [x402 Protocol](https://docs.nevermined.app/docs/api-reference/typescript/x402-protocol) | The HTTP payment protocol specification |
|
|
18
|
+
|
|
19
|
+
## SDKs
|
|
20
|
+
|
|
21
|
+
| SDK | Language | Package |
|
|
22
|
+
|-----|----------|---------|
|
|
23
|
+
| [Payments SDK](https://github.com/nevermined-io/payments) | TypeScript | `@nevermined-io/payments` |
|
|
24
|
+
| [Payments SDK (Python)](https://github.com/nevermined-io/payments-py) | Python | `payments-py` |
|
|
25
|
+
| [Nevermined CLI](https://www.npmjs.com/package/@nevermined-io/cli) | TypeScript | `@nevermined-io/cli` |
|
|
26
|
+
|
|
27
|
+
## OpenClaw
|
|
28
|
+
|
|
29
|
+
| Resource | Description |
|
|
30
|
+
|----------|-------------|
|
|
31
|
+
| [OpenClaw Docs](https://docs.openclaw.ai) | OpenClaw gateway documentation |
|
|
32
|
+
| [Plugin Development](https://docs.openclaw.ai/tools/plugin) | How to build OpenClaw plugins |
|
|
33
|
+
|
|
34
|
+
## Support
|
|
35
|
+
|
|
36
|
+
- [GitHub Issues](https://github.com/nevermined-io/payments/issues) — report bugs or request features
|
|
37
|
+
- [Nevermined Discord](https://discord.gg/nevermined) — community support
|
|
38
|
+
- [Nevermined App](https://nevermined.app) — manage your account, plans, and agents
|
package/docs/setup.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Setup"
|
|
3
|
+
description: "Full configuration reference for the Nevermined OpenClaw plugin"
|
|
4
|
+
icon: "gear"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Setup
|
|
8
|
+
|
|
9
|
+
## Configuration
|
|
10
|
+
|
|
11
|
+
The plugin reads its configuration from the `plugins.nevermined` section of your `openclaw.json`:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"plugins": {
|
|
16
|
+
"nevermined": {
|
|
17
|
+
"nvmApiKey": "sandbox:eyJhbG...",
|
|
18
|
+
"environment": "sandbox",
|
|
19
|
+
"planId": "did:nv:abc123...",
|
|
20
|
+
"agentId": "did:nv:def456...",
|
|
21
|
+
"creditsPerRequest": 1
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Configuration Fields
|
|
28
|
+
|
|
29
|
+
| Field | Required | Default | Description |
|
|
30
|
+
|-------|----------|---------|-------------|
|
|
31
|
+
| `nvmApiKey` | No | — | Your Nevermined API key. Can be set via `/nvm-login` instead. |
|
|
32
|
+
| `environment` | No | `sandbox` | Target environment: `sandbox` for testing, `live` for production. |
|
|
33
|
+
| `planId` | No | — | Default payment plan ID. When set, subscriber tools use this plan automatically. |
|
|
34
|
+
| `agentId` | No | — | Default agent ID. Required for plans with multiple agents. |
|
|
35
|
+
| `creditsPerRequest` | No | `1` | Number of credits consumed per request. |
|
|
36
|
+
|
|
37
|
+
### Environment Details
|
|
38
|
+
|
|
39
|
+
| Environment | Description | Use Case |
|
|
40
|
+
|-------------|-------------|----------|
|
|
41
|
+
| `sandbox` | Test environment on Arbitrum Sepolia | Development, testing, integration |
|
|
42
|
+
| `live` | Production environment on Arbitrum One | Live deployments with real payments |
|
|
43
|
+
|
|
44
|
+
## Authentication Flow
|
|
45
|
+
|
|
46
|
+
The plugin supports a browser-based login flow identical to the [Nevermined CLI](/docs/api-reference/cli/getting-started):
|
|
47
|
+
|
|
48
|
+
1. User sends `/nvm-login` in any chat channel (or calls `nevermined.login`)
|
|
49
|
+
2. The plugin starts a local HTTP server on a random port
|
|
50
|
+
3. A browser window opens to the Nevermined login page
|
|
51
|
+
4. After authentication, Nevermined redirects back with the API key
|
|
52
|
+
5. The key is stored in the gateway config via `api.setConfig()`
|
|
53
|
+
|
|
54
|
+
The login times out after 5 minutes if no authentication is received.
|
|
55
|
+
|
|
56
|
+
### Logging Out
|
|
57
|
+
|
|
58
|
+
Send `/nvm-logout` or call `nevermined.logout` to remove the stored API key. All payment tools will require re-authentication after logout.
|
|
59
|
+
|
|
60
|
+
## Default Values
|
|
61
|
+
|
|
62
|
+
When `planId` and `agentId` are set in the config, all subscriber tools (`checkBalance`, `getAccessToken`, `orderPlan`, `queryAgent`) use them as defaults. You can always override them per-call by passing the parameter explicitly.
|
|
63
|
+
|
|
64
|
+
This is useful for gateways that serve a single plan — configure it once and all tools work without extra parameters.
|
package/openclaw.plugin.json
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
"configSchema": {
|
|
6
6
|
"nvmApiKey": {
|
|
7
7
|
"type": "string",
|
|
8
|
-
"required":
|
|
9
|
-
"description": "Your Nevermined API key"
|
|
8
|
+
"required": false,
|
|
9
|
+
"description": "Your Nevermined API key (optional — use /nvm-login to authenticate via browser)"
|
|
10
10
|
},
|
|
11
11
|
"environment": {
|
|
12
12
|
"type": "string",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"nvmApiKey": {
|
|
35
35
|
"sensitive": true,
|
|
36
36
|
"label": "Nevermined API Key",
|
|
37
|
-
"placeholder": "sandbox:eyJhbG..."
|
|
37
|
+
"placeholder": "sandbox:eyJhbG... (or use /nvm-login)"
|
|
38
38
|
},
|
|
39
39
|
"environment": {
|
|
40
40
|
"label": "Environment"
|
|
@@ -48,9 +48,21 @@
|
|
|
48
48
|
"placeholder": "did:nv:..."
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
|
+
"commands": [
|
|
52
|
+
{
|
|
53
|
+
"name": "nvm-login",
|
|
54
|
+
"description": "Authenticate with Nevermined via browser login"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "nvm-logout",
|
|
58
|
+
"description": "Log out from Nevermined"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
51
61
|
"skills": ["skills/nevermined/SKILL.md"],
|
|
52
62
|
"gateway": {
|
|
53
63
|
"methods": [
|
|
64
|
+
"nevermined.login",
|
|
65
|
+
"nevermined.logout",
|
|
54
66
|
"nevermined.checkBalance",
|
|
55
67
|
"nevermined.getAccessToken",
|
|
56
68
|
"nevermined.orderPlan",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nevermined-io/openclaw-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "OpenClaw plugin for Nevermined — exposes subscriber and builder tools as gateway methods",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"dist/",
|
|
16
16
|
"openclaw.plugin.json",
|
|
17
17
|
"skills/",
|
|
18
|
+
"docs/",
|
|
18
19
|
"README.md"
|
|
19
20
|
],
|
|
20
21
|
"scripts": {
|
|
@@ -45,6 +46,11 @@
|
|
|
45
46
|
"url": "https://github.com/nevermined-io/payments.git",
|
|
46
47
|
"directory": "openclaw"
|
|
47
48
|
},
|
|
49
|
+
"openclaw": {
|
|
50
|
+
"extensions": [
|
|
51
|
+
"./dist/index.js"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
48
54
|
"keywords": [
|
|
49
55
|
"nevermined",
|
|
50
56
|
"openclaw",
|
|
@@ -2,13 +2,29 @@
|
|
|
2
2
|
metadata:
|
|
3
3
|
openclaw:
|
|
4
4
|
requires:
|
|
5
|
-
config: ["plugins.nevermined
|
|
5
|
+
config: ["plugins.nevermined"]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Nevermined Tools
|
|
9
9
|
|
|
10
10
|
This plugin provides gateway tools for interacting with Nevermined AI agent payments.
|
|
11
11
|
|
|
12
|
+
## Authentication
|
|
13
|
+
|
|
14
|
+
### `/nvm-login [environment]`
|
|
15
|
+
Authenticate with Nevermined via browser login. Opens a browser window to obtain an API key.
|
|
16
|
+
- `environment` (optional) — `sandbox` or `live` (default: from config)
|
|
17
|
+
|
|
18
|
+
### `/nvm-logout`
|
|
19
|
+
Log out from Nevermined and remove the stored API key.
|
|
20
|
+
|
|
21
|
+
### `nevermined.login`
|
|
22
|
+
Gateway method equivalent of `/nvm-login`.
|
|
23
|
+
- `environment` (optional)
|
|
24
|
+
|
|
25
|
+
### `nevermined.logout`
|
|
26
|
+
Gateway method equivalent of `/nvm-logout`.
|
|
27
|
+
|
|
12
28
|
## Subscriber Tools
|
|
13
29
|
|
|
14
30
|
### `nevermined.checkBalance`
|