@edge-protocol/sdk 0.5.3 → 0.5.6
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 +170 -152
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,80 +2,61 @@
|
|
|
2
2
|
|
|
3
3
|
# @edge-protocol/sdk
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Bounded Financial Authority for Autonomous AI Agents on Sui
|
|
6
6
|
|
|
7
7
|
[](https://npmjs.com/package/@edge-protocol/sdk)
|
|
8
8
|
[](https://npmjs.com/package/@edge-protocol/sdk)
|
|
9
|
-
[](src/test.ts)
|
|
10
10
|
[](https://sui.io)
|
|
11
11
|
[](LICENSE)
|
|
12
12
|
|
|
13
13
|
**Give agents your rules, not your keys.**
|
|
14
14
|
|
|
15
|
-
[Live Demo](https://edge-web-
|
|
15
|
+
[Live Demo](https://edge-web-cyan.vercel.app) · [Full Docs](https://github.com/fluturecode/edge/blob/main/packages/sdk/DOCS.md) · [GitHub](https://github.com/fluturecode/edge)
|
|
16
16
|
|
|
17
17
|
</div>
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Giving an AI agent raw private keys is a security nightmare. Requiring human approval for every transaction defeats the purpose of automation. Edge provides an **on-chain policy layer** that issues scoped, programmatic spend authority (`EdgePass`) directly to agent runtimes — with cryptographic guardrails enforced by the Sui VM.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
Option A: Give the agent full wallet access → catastrophic risk
|
|
25
|
-
Option B: Human approves every transaction → defeats the purpose
|
|
26
|
-
Option C: Build custom policy logic → 6-8 weeks of work
|
|
27
|
-
```
|
|
23
|
+
---
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
## ⚡ Quickstart — 3 Lines of Code
|
|
30
26
|
|
|
31
|
-
|
|
27
|
+
```typescript
|
|
28
|
+
import { EdgePass, MIST_PER_SUI } from '@edge-protocol/sdk';
|
|
32
29
|
|
|
33
|
-
|
|
30
|
+
const sdk = new EdgePass({ network: 'mainnet', enokiApiKey: 'YOUR_KEY' });
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
// 1. Issue a 5-dimensional spend authorization (once)
|
|
33
|
+
const pass = await sdk.create(EdgePass.fromTemplate('festival', { owner: userAddress }), signer);
|
|
34
|
+
|
|
35
|
+
// 2. Agent executes autonomously within policy boundaries (many times)
|
|
36
|
+
const outcome = await sdk.execute(pass, { merchant: 'Shuttle Express', amount: 18n * MIST_PER_SUI }, signer);
|
|
37
|
+
|
|
38
|
+
console.log(outcome.status); // 'approved' | 'escalated' | 'blocked'
|
|
41
39
|
```
|
|
42
40
|
|
|
43
41
|
---
|
|
44
42
|
|
|
45
|
-
##
|
|
43
|
+
## 🛠 The 5-Dimensional Trust Primitive
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
import { EdgePass, MIST_PER_SUI } from '@edge-protocol/sdk';
|
|
45
|
+
Every EdgePass is a native Sui Move object encoding five distinct governance dimensions:
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}),
|
|
58
|
-
signer
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
// 2. Execute autonomously (many times)
|
|
62
|
-
const outcome = await sdk.execute(pass, {
|
|
63
|
-
merchant: 'Shuttle Express',
|
|
64
|
-
amount: 18_500_000_000n, // 18.5 SUI in MIST
|
|
65
|
-
}, signer);
|
|
66
|
-
|
|
67
|
-
switch (outcome.status) {
|
|
68
|
-
case 'approved': // ✅ executed on-chain, digest on Walrus
|
|
69
|
-
case 'escalated': // ⚠️ notify user, await approval
|
|
70
|
-
case 'blocked': // 🚫 policy rejected, reason logged
|
|
71
|
-
}
|
|
72
|
-
```
|
|
47
|
+
| Dimension | What it controls |
|
|
48
|
+
|-----------|-----------------|
|
|
49
|
+
| **BUDGET** | Maximum global spending ceiling |
|
|
50
|
+
| **VELOCITY** | Auto-approve threshold before escalation fires |
|
|
51
|
+
| **SCOPE** | Explicit allowlist of approved merchants / contracts |
|
|
52
|
+
| **TIME** | Hard cryptographic expiration date |
|
|
53
|
+
| **ESCALATION** | Programmatic fallback when a limit is exceeded |
|
|
73
54
|
|
|
74
55
|
---
|
|
75
56
|
|
|
76
|
-
## Templates
|
|
57
|
+
## 📋 Templates
|
|
77
58
|
|
|
78
|
-
Pre-configured
|
|
59
|
+
Pre-configured for common use cases — override any field:
|
|
79
60
|
|
|
80
61
|
```typescript
|
|
81
62
|
EdgePass.fromTemplate('festival', { owner }) // $300 · auto <$50 · escalate >$100 · 48h
|
|
@@ -85,179 +66,213 @@ EdgePass.fromTemplate('defi', { owner }) // $10k · auto <$500 · escal
|
|
|
85
66
|
EdgePass.fromTemplate('enterprise', { owner }) // $50k · auto <$1k · escalate >$5k · 30d
|
|
86
67
|
```
|
|
87
68
|
|
|
88
|
-
Override any field:
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
91
|
-
const pass = await sdk.create(
|
|
92
|
-
EdgePass.fromTemplate('defi', {
|
|
93
|
-
budget: 25_000n * MIST_PER_SUI,
|
|
94
|
-
approvedMerchants: ['DeepBook', 'Cetus'],
|
|
95
|
-
owner: userAddress,
|
|
96
|
-
}),
|
|
97
|
-
signer
|
|
98
|
-
);
|
|
99
|
-
```
|
|
100
|
-
|
|
101
69
|
---
|
|
102
70
|
|
|
103
|
-
##
|
|
71
|
+
## 🤖 Agent Framework Integration
|
|
72
|
+
|
|
73
|
+
### Vercel AI SDK / Mastra
|
|
104
74
|
|
|
105
|
-
|
|
75
|
+
Integrate Edge directly into your agent's tool declaration to enforce policy boundaries before any transaction touches the network:
|
|
106
76
|
|
|
107
77
|
```typescript
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
78
|
+
import { tool } from 'ai';
|
|
79
|
+
import { z } from 'zod';
|
|
80
|
+
import { EdgePass, MIST_PER_SUI } from '@edge-protocol/sdk';
|
|
81
|
+
|
|
82
|
+
export const autonomousPurchaseTool = tool({
|
|
83
|
+
description: 'Purchase assets or services autonomously within policy boundaries.',
|
|
84
|
+
parameters: z.object({
|
|
85
|
+
merchant: z.string(),
|
|
86
|
+
amountSUI: z.number(),
|
|
87
|
+
}),
|
|
88
|
+
execute: async ({ merchant, amountSUI }) => {
|
|
89
|
+
// Edge validates BEFORE the transaction touches the network
|
|
90
|
+
const outcome = await sdk.execute(currentPass, {
|
|
91
|
+
merchant,
|
|
92
|
+
amount: BigInt(Math.floor(amountSUI * 1e9)),
|
|
93
|
+
}, agentSigner);
|
|
94
|
+
|
|
95
|
+
if (outcome.status === 'blocked') {
|
|
96
|
+
return { success: false, error: `Blocked by EdgePass policy: ${outcome.reason}` };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (outcome.status === 'escalated') {
|
|
100
|
+
return { success: false, error: `Paused — human approval required: ${outcome.reason}` };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { success: true, digest: outcome.digest };
|
|
104
|
+
}
|
|
111
105
|
});
|
|
112
106
|
```
|
|
113
107
|
|
|
114
|
-
###
|
|
108
|
+
### Native Agent System Prompt
|
|
115
109
|
|
|
116
|
-
|
|
110
|
+
Include this in your LLM initialization to teach the agent how to handle EdgePass responses:
|
|
117
111
|
|
|
118
112
|
```typescript
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
autoThreshold: 50n * MIST_PER_SUI,
|
|
122
|
-
escalateThreshold: 100n * MIST_PER_SUI,
|
|
123
|
-
maxPerTransaction: 200n * MIST_PER_SUI, // optional
|
|
124
|
-
approvedMerchants: ['Shuttle Express'],
|
|
125
|
-
expiryMs: 48 * 60 * 60 * 1000,
|
|
126
|
-
owner: userAddress,
|
|
127
|
-
}, signer);
|
|
128
|
-
|
|
129
|
-
console.log(pass.id); // Sui object ID — verifiable on Suiscan
|
|
130
|
-
```
|
|
113
|
+
const systemPrompt = `
|
|
114
|
+
You are an autonomous agent operating with bounded financial authority via Edge Protocol.
|
|
131
115
|
|
|
132
|
-
|
|
116
|
+
When a financial tool returns 'escalated': do NOT retry the operation.
|
|
117
|
+
Inform the user that manual approval is required and await confirmation.
|
|
133
118
|
|
|
134
|
-
|
|
119
|
+
When a tool returns 'blocked': the transaction violates policy.
|
|
120
|
+
Explain the constraint to the user and suggest an alternative within limits.
|
|
135
121
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
amount: 18_500_000_000n,
|
|
140
|
-
}, signer);
|
|
141
|
-
|
|
142
|
-
// outcome.status → 'approved' | 'escalated' | 'blocked'
|
|
143
|
-
// outcome.digest → tx digest (if approved)
|
|
144
|
-
// outcome.reason → explanation (if escalated or blocked)
|
|
122
|
+
When a tool returns 'approved': proceed normally.
|
|
123
|
+
The transaction was executed on-chain and logged to Walrus.
|
|
124
|
+
`;
|
|
145
125
|
```
|
|
146
126
|
|
|
147
|
-
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 📊 Execution Results
|
|
148
130
|
|
|
149
|
-
|
|
131
|
+
Every `sdk.execute()` returns a structured outcome — not a flat string:
|
|
150
132
|
|
|
151
133
|
```typescript
|
|
152
|
-
|
|
153
|
-
|
|
134
|
+
type TransactionOutcome =
|
|
135
|
+
| { status: 'approved'; digest: string; auto: true; }
|
|
136
|
+
| { status: 'escalated'; reason: string; auto: false; }
|
|
137
|
+
| { status: 'blocked'; reason: string; auto: false; }
|
|
138
|
+
|
|
139
|
+
// Example approved outcome
|
|
140
|
+
{
|
|
141
|
+
status: 'approved',
|
|
142
|
+
digest: '0xabc123...txdigest',
|
|
143
|
+
auto: true,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Example blocked outcome
|
|
147
|
+
{
|
|
148
|
+
status: 'blocked',
|
|
149
|
+
reason: 'Merchant "ShadyTokens.xyz" is not approved',
|
|
150
|
+
auto: false,
|
|
151
|
+
}
|
|
154
152
|
```
|
|
155
153
|
|
|
156
|
-
|
|
154
|
+
---
|
|
157
155
|
|
|
158
|
-
|
|
156
|
+
## 🔔 Events System
|
|
159
157
|
|
|
160
|
-
|
|
158
|
+
React to decisions without polling:
|
|
161
159
|
|
|
162
|
-
|
|
160
|
+
```typescript
|
|
161
|
+
sdk
|
|
162
|
+
.on('approved', ({ outcome, pass, request }) => {
|
|
163
|
+
updateBudgetUI(pass);
|
|
164
|
+
console.log('executed:', outcome.digest);
|
|
165
|
+
})
|
|
166
|
+
.on('escalated', ({ outcome, request }) => {
|
|
167
|
+
sendPushNotification(`Approve $${request.amount} at ${request.merchant}?`);
|
|
168
|
+
})
|
|
169
|
+
.on('blocked', ({ outcome }) => {
|
|
170
|
+
logger.warn('blocked:', outcome.reason);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Events fire automatically on execute
|
|
174
|
+
await sdk.execute(pass, request, signer);
|
|
175
|
+
```
|
|
163
176
|
|
|
164
|
-
|
|
177
|
+
---
|
|
165
178
|
|
|
166
|
-
|
|
179
|
+
## 🔌 Pluggable Escalation Handlers
|
|
167
180
|
|
|
168
|
-
|
|
181
|
+
Route escalation alerts to dashboards, Slack, or Telegram:
|
|
169
182
|
|
|
170
|
-
|
|
183
|
+
```typescript
|
|
184
|
+
sdk.on('escalated', async ({ outcome, request }) => {
|
|
185
|
+
// Slack webhook
|
|
186
|
+
await fetch('https://hooks.slack.com/your-webhook', {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
body: JSON.stringify({
|
|
189
|
+
text: `⚠️ Agent escalation: $${request.amount} at ${request.merchant}\n${outcome.reason}`,
|
|
190
|
+
}),
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
```
|
|
171
194
|
|
|
172
195
|
---
|
|
173
196
|
|
|
174
|
-
##
|
|
197
|
+
## 📜 Cryptographic Audit Trail
|
|
175
198
|
|
|
176
|
-
|
|
199
|
+
Every execution writes an immutable receipt to Walrus — decentralized, tamper-evident, permanent. No database. No server. Cryptographically committed.
|
|
177
200
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
7. If amount ≤ `autoThreshold` → auto-approve
|
|
201
|
+
```typescript
|
|
202
|
+
// After execution, the Walrus blob ID is available
|
|
203
|
+
const outcome = await sdk.execute(pass, request, signer);
|
|
204
|
+
// audit receipt automatically written to Walrus
|
|
205
|
+
// verifiable at walruscan.com/testnet/blob/{blobId}
|
|
206
|
+
```
|
|
185
207
|
|
|
186
208
|
---
|
|
187
209
|
|
|
188
|
-
##
|
|
210
|
+
## 🔍 Preview Without Executing
|
|
189
211
|
|
|
190
|
-
|
|
212
|
+
Zero network calls. Sub-millisecond. Use for UI previews:
|
|
191
213
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
214
|
+
```typescript
|
|
215
|
+
const preview = sdk.validate(pass, { merchant, amount });
|
|
216
|
+
// { allowed: boolean, requiresEscalation: boolean, reason: string }
|
|
217
|
+
|
|
218
|
+
if (!preview.allowed) showBlockedUI(preview.reason);
|
|
219
|
+
if (preview.requiresEscalation) showEscalationModal(preview.reason);
|
|
220
|
+
```
|
|
197
221
|
|
|
198
222
|
---
|
|
199
223
|
|
|
200
|
-
##
|
|
224
|
+
## 🔒 Security Model
|
|
201
225
|
|
|
202
|
-
|
|
226
|
+
Edge has two enforcement layers:
|
|
203
227
|
|
|
204
|
-
|
|
205
|
-
🧠 Claude: "Shuttle from parking — $18.50"
|
|
206
|
-
⚙️ PolicyEngine: ✅ auto-approved · trusted merchant
|
|
207
|
-
⛓ Sui: execute_transaction · Success · Suiscan verified
|
|
228
|
+
**Layer 1 — TypeScript PolicyEngine** — pre-flight, zero network calls, under 1ms. Can be bypassed by a compromised agent. Treat as a UX convenience, not a security boundary.
|
|
208
229
|
|
|
209
|
-
|
|
210
|
-
⚙️ PolicyEngine: ⚠️ escalated · exceeds $100 threshold
|
|
211
|
-
👤 User: approves via modal
|
|
230
|
+
**Layer 2 — Sui Move Contract** — on-chain enforcement by the Sui VM. Cannot be bypassed. The EdgePass object validates all policy dimensions independently. This is the source of truth.
|
|
212
231
|
|
|
213
|
-
|
|
232
|
+
```
|
|
233
|
+
sdk.validate() → TypeScript (instant preview, saves gas)
|
|
234
|
+
sdk.execute() → TypeScript + Move contract (atomic, tamper-proof)
|
|
214
235
|
```
|
|
215
236
|
|
|
216
|
-
|
|
237
|
+
For production: always execute via the Move contract. The TypeScript layer is a preview — the chain is the guarantee.
|
|
217
238
|
|
|
218
239
|
---
|
|
219
240
|
|
|
220
|
-
## Testing
|
|
241
|
+
## 🧪 Testing
|
|
221
242
|
|
|
222
243
|
```bash
|
|
223
244
|
pnpm test
|
|
224
245
|
```
|
|
225
246
|
|
|
226
247
|
```
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
✓ blocks when inactive
|
|
233
|
-
34/34 passing ✅
|
|
234
|
-
```
|
|
248
|
+
📋 PolicyEngine.validate() 10 tests ✓
|
|
249
|
+
📋 PolicyEngine helpers 5 tests ✓
|
|
250
|
+
📋 EdgePass.fromTemplate() 7 tests ✓
|
|
251
|
+
📋 Constants 5 tests ✓
|
|
252
|
+
📋 Events system 7 tests ✓
|
|
235
253
|
|
|
254
|
+
34 passed · 0 failed ✅
|
|
255
|
+
```
|
|
236
256
|
|
|
237
257
|
---
|
|
238
258
|
|
|
239
|
-
##
|
|
240
|
-
|
|
241
|
-
Edge has two enforcement layers:
|
|
242
|
-
|
|
243
|
-
**Layer 1 — TypeScript PolicyEngine** — pre-flight validation, zero network calls, under 1ms. Can be bypassed by a malicious agent runtime. Use as a UX convenience, not a security boundary.
|
|
244
|
-
|
|
245
|
-
**Layer 2 — Sui Move Contract** — on-chain enforcement by the Sui VM. Cannot be bypassed. The EdgePass object validates budget, expiry, and merchant allowlist independently. This is the source of truth.
|
|
259
|
+
## ⛓ Move Contract
|
|
246
260
|
|
|
247
261
|
```
|
|
248
|
-
|
|
249
|
-
|
|
262
|
+
Package: 0x9f4065009494aa5acd92a5c72a6c22ce80939b2bddae3b34345459bc98d2501d
|
|
263
|
+
Network: Sui Testnet (Mainnet coming)
|
|
250
264
|
```
|
|
251
265
|
|
|
252
|
-
For production: always execute via the Move contract. The TypeScript layer is a preview — the chain is the guarantee.
|
|
253
|
-
|
|
254
266
|
---
|
|
255
267
|
|
|
256
|
-
##
|
|
268
|
+
## 📦 Install
|
|
257
269
|
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
|
|
270
|
+
```bash
|
|
271
|
+
npm install @edge-protocol/sdk
|
|
272
|
+
# or
|
|
273
|
+
pnpm add @edge-protocol/sdk
|
|
274
|
+
# or
|
|
275
|
+
yarn add @edge-protocol/sdk
|
|
261
276
|
```
|
|
262
277
|
|
|
263
278
|
---
|
|
@@ -268,4 +283,7 @@ Network: Sui Testnet (Mainnet coming)
|
|
|
268
283
|
|
|
269
284
|
Built for [Sui Overflow 2026](https://overflow.sui.io) · MIT License
|
|
270
285
|
|
|
286
|
+
[](https://github.com/fluturecode/edge)
|
|
287
|
+
[](https://npmjs.com/package/@edge-protocol/sdk)
|
|
288
|
+
|
|
271
289
|
</div>
|
package/package.json
CHANGED