@everestan/plugin-protocol-banks 0.0.0-stage → 0.1.0
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 +47 -2
- package/dist/index.d.ts +13 -0
- package/dist/index.js +87 -0
- package/images/banner.jpg +0 -0
- package/images/logo.jpg +0 -0
- package/package.json +51 -4
package/README.md
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
-
#
|
|
1
|
+
# elizaOS plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A v1.x plugin: one provider (account + remaining policy in context) and two
|
|
4
|
+
actions — read the account, place an order. Order arguments must arrive as
|
|
5
|
+
structured `message.content` fields; this plugin deliberately does not parse
|
|
6
|
+
amounts out of prose.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install
|
|
10
|
+
npm test # vitest: shape, refusals, fill reporting, provider
|
|
11
|
+
npm run build # tsc -> dist (ESM + d.ts)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Add it to a character (the package is unscoped on npm as
|
|
15
|
+
`@everestan/plugin-protocol-banks` once published; until then `npm pack` it or
|
|
16
|
+
run from a local path):
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"name": "Trader",
|
|
21
|
+
"plugins": ["@everestan/plugin-protocol-banks"],
|
|
22
|
+
"settings": { "secrets": { "PB_KEY": "pb_…" } }
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then ask: *“What is my policy?”* or send a message whose content carries
|
|
27
|
+
`{ "coin": "BTC", "side": "long", "sizeUsd": 20 }` for `PROTOCOL_BANKS_ORDER`.
|
|
28
|
+
|
|
29
|
+
Why structured args: an action that guesses a notional from prose can silently
|
|
30
|
+
place the wrong size. The server cap still protects the account, but the plugin
|
|
31
|
+
refuses to guess.
|
|
32
|
+
|
|
33
|
+
## Publish (elizaOS registry)
|
|
34
|
+
|
|
35
|
+
The registry requires `images/logo.jpg` (400×400) and `images/banner.jpg`
|
|
36
|
+
(1280×640) — both are committed here. Then:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm run build
|
|
40
|
+
npm publish --access public
|
|
41
|
+
npx elizaos publish # creates the plugin repo + registry PR (needs gh + npm login)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`npm run build` runs on `prepublishOnly`, so the tarball always carries `dist/`.
|
|
45
|
+
|
|
46
|
+
**Tool-style host?** Use the hosted MCP server
|
|
47
|
+
(`https://protocolbanks.com/api/mcp`, in the official MCP Registry) — it
|
|
48
|
+
exposes the same account as tools.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* elizaOS plugin for the Protocol Banks Agent API (v1.x interface).
|
|
3
|
+
*
|
|
4
|
+
* The provider injects the account and the key's remaining policy into the
|
|
5
|
+
* agent's context; the actions read state and place orders. Order arguments
|
|
6
|
+
* must arrive as structured `message.content` fields (`coin`, `side`,
|
|
7
|
+
* `sizeUsd`) — this plugin deliberately does not parse amounts out of prose.
|
|
8
|
+
*
|
|
9
|
+
* PB_KEY=pb_… elizaos dev
|
|
10
|
+
*/
|
|
11
|
+
import type { Plugin } from "@elizaos/core";
|
|
12
|
+
export declare const protocolBanksPlugin: Plugin;
|
|
13
|
+
export default protocolBanksPlugin;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ProtocolBanks } from "@everestan/protocolbanks-sdk";
|
|
2
|
+
function client() {
|
|
3
|
+
const apiKey = process.env.PB_KEY;
|
|
4
|
+
if (!apiKey)
|
|
5
|
+
throw new Error("PB_KEY is not set");
|
|
6
|
+
return new ProtocolBanks({ apiKey });
|
|
7
|
+
}
|
|
8
|
+
const POLICY_NOTE = "The server enforces the key's policy; a 403 (policy) or 409 (guard) is final. Do not retry it unchanged.";
|
|
9
|
+
const stateProvider = {
|
|
10
|
+
name: "PROTOCOL_BANKS_STATE",
|
|
11
|
+
description: "Trading account, open positions and the API key's remaining policy from Protocol Banks.",
|
|
12
|
+
dynamic: true,
|
|
13
|
+
get: async () => {
|
|
14
|
+
try {
|
|
15
|
+
const state = await client().agent.state();
|
|
16
|
+
return {
|
|
17
|
+
text: `Protocol Banks account: mode=${state.mode}, equity=$${state.account?.totalEquity ?? "?"}, positions=${state.positions?.length ?? 0}, policy=${JSON.stringify(state.policy ?? {})}. ${POLICY_NOTE}`,
|
|
18
|
+
data: {
|
|
19
|
+
mode: state.mode,
|
|
20
|
+
equity: state.account?.totalEquity,
|
|
21
|
+
positions: state.positions ?? [],
|
|
22
|
+
policy: state.policy,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
return { text: `Protocol Banks is not configured: ${error instanceof Error ? error.message : String(error)}` };
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
const stateAction = {
|
|
32
|
+
name: "PROTOCOL_BANKS_STATE",
|
|
33
|
+
description: "Read the Protocol Banks account: mode, equity, open positions and the key's remaining policy.",
|
|
34
|
+
similes: ["TRADING_STATE", "CHECK_TRADING_AGENT"],
|
|
35
|
+
examples: [],
|
|
36
|
+
validate: async () => Boolean(process.env.PB_KEY),
|
|
37
|
+
handler: async () => {
|
|
38
|
+
const state = await client().agent.state();
|
|
39
|
+
if (state.status !== 200) {
|
|
40
|
+
return { success: false, text: `Refused (${state.status}): ${state.error ?? "no message"}` };
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
success: true,
|
|
44
|
+
text: `mode=${state.mode} equity=$${state.account?.totalEquity} positions=${state.positions?.length ?? 0} policy=${JSON.stringify(state.policy ?? {})}`,
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
const orderAction = {
|
|
49
|
+
name: "PROTOCOL_BANKS_ORDER",
|
|
50
|
+
description: `Place one perpetual order through the Protocol Banks agent wallet (trading-only, cannot withdraw). ${POLICY_NOTE}`,
|
|
51
|
+
similes: ["PLACE_TRADE", "OPEN_POSITION"],
|
|
52
|
+
examples: [],
|
|
53
|
+
validate: async () => Boolean(process.env.PB_KEY),
|
|
54
|
+
handler: async (_runtime, message, _state) => {
|
|
55
|
+
// Structured fields only: the host (or the model) must supply them.
|
|
56
|
+
const content = (message.content ?? {});
|
|
57
|
+
const coin = typeof content.coin === "string" ? content.coin : "";
|
|
58
|
+
const side = content.side === "long" || content.side === "short" ? content.side : null;
|
|
59
|
+
const sizeUsd = typeof content.sizeUsd === "number" ? content.sizeUsd : Number.NaN;
|
|
60
|
+
if (!coin || !side || !Number.isFinite(sizeUsd) || sizeUsd <= 0) {
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
text: `Missing structured arguments. Provide content { coin: "BTC", side: "long"|"short", sizeUsd: number } — amounts are never parsed from prose.`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const result = await client().agent.order({
|
|
67
|
+
coin,
|
|
68
|
+
side,
|
|
69
|
+
sizeUsd,
|
|
70
|
+
reason: typeof content.reason === "string" ? content.reason : undefined,
|
|
71
|
+
});
|
|
72
|
+
if (!result.ok) {
|
|
73
|
+
return { success: false, text: `Refused (${result.status}): ${result.error ?? "no message"}` };
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
success: true,
|
|
77
|
+
text: `Filled ${result.fill?.coin} ${result.fill?.side} at $${result.fill?.avgPx} (notional $${result.fill?.notional}); remaining today $${result.remainingTodayUsd}.`,
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
export const protocolBanksPlugin = {
|
|
82
|
+
name: "protocol-banks",
|
|
83
|
+
description: "Execution + policy for agents: trade through a trading-only wallet with a server-enforced cap, and read the account it belongs to.",
|
|
84
|
+
providers: [stateProvider],
|
|
85
|
+
actions: [stateAction, orderAction],
|
|
86
|
+
};
|
|
87
|
+
export default protocolBanksPlugin;
|
|
Binary file
|
package/images/logo.jpg
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@everestan/plugin-protocol-banks",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Trade through a trading-only Hyperliquid wallet with a server-enforced spend cap, and read the account it belongs to.",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"images"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"plugin",
|
|
26
|
+
"elizaos",
|
|
27
|
+
"trading",
|
|
28
|
+
"hyperliquid",
|
|
29
|
+
"payments",
|
|
30
|
+
"spend-cap",
|
|
31
|
+
"protocol-banks"
|
|
32
|
+
],
|
|
33
|
+
"author": "Protocol Banks",
|
|
34
|
+
"license": "GPL-3.0-only",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/everest-an/protocol-banks---web3.git",
|
|
38
|
+
"directory": "integrations/eliza"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://protocolbanks.com/agent-api",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@elizaos/core": "^1.7.0",
|
|
46
|
+
"@everestan/protocolbanks-sdk": "^0.2.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^22",
|
|
50
|
+
"typescript": "^5.0.0",
|
|
51
|
+
"vitest": "^5.0.0"
|
|
52
|
+
}
|
|
53
|
+
}
|