@edge-protocol/sdk 0.6.7 → 0.8.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/dist/core/EdgePass.d.ts +88 -28
- package/dist/core/EdgePass.d.ts.map +1 -1
- package/dist/core/EdgePass.js +118 -63
- package/dist/core/EdgePass.js.map +1 -1
- package/dist/core/PolicyEngine.d.ts +57 -1
- package/dist/core/PolicyEngine.d.ts.map +1 -1
- package/dist/core/PolicyEngine.js +138 -35
- package/dist/core/PolicyEngine.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/types.d.ts +41 -2
- package/dist/utils/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/core/EdgePass.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Transaction } from "@mysten/sui/transactions";
|
|
2
|
-
import { EdgePassConfig, EdgePassObject, TransactionRequest, TransactionOutcome, EdgeSDKConfig } from "../utils/types";
|
|
2
|
+
import { EdgePassConfig, EdgePassObject, TransactionRequest, TransactionOutcome, EdgeSDKConfig, SimulationResult, BudgetStatus } from "../utils/types";
|
|
3
3
|
import { EdgePassTemplate } from "../utils/constants";
|
|
4
4
|
export type EdgePassEventType = 'approved' | 'escalated' | 'blocked';
|
|
5
5
|
export type EdgePassEventPayload = {
|
|
@@ -35,14 +35,13 @@ export declare class EdgePass {
|
|
|
35
35
|
constructor(config: EdgeSDKConfig);
|
|
36
36
|
/**
|
|
37
37
|
* Subscribe to transaction outcomes.
|
|
38
|
-
* Note: 'error' status (network/signing failures) does NOT fire events.
|
|
39
|
-
* Check outcome.status === 'error' in your execute() handler instead.
|
|
40
38
|
*
|
|
41
39
|
* @example
|
|
42
40
|
* sdk.on('approved', ({ outcome, pass }) => {
|
|
41
|
+
* updateBudgetUI(pass);
|
|
43
42
|
* console.log('executed:', outcome.digest);
|
|
44
43
|
* });
|
|
45
|
-
* sdk.on('escalated', ({
|
|
44
|
+
* sdk.on('escalated', ({ request }) => {
|
|
46
45
|
* notifyUser(`Approve $${request.amount} at ${request.merchant}?`);
|
|
47
46
|
* });
|
|
48
47
|
* sdk.on('blocked', ({ outcome }) => {
|
|
@@ -50,13 +49,7 @@ export declare class EdgePass {
|
|
|
50
49
|
* });
|
|
51
50
|
*/
|
|
52
51
|
on<T extends EdgePassEventType>(event: T, listener: EventListener<T>): this;
|
|
53
|
-
/**
|
|
54
|
-
* Unsubscribe a specific listener.
|
|
55
|
-
*/
|
|
56
52
|
off<T extends EdgePassEventType>(event: T, listener: EventListener<T>): this;
|
|
57
|
-
/**
|
|
58
|
-
* Remove all listeners for an event (or all events if none specified).
|
|
59
|
-
*/
|
|
60
53
|
removeAllListeners(event?: EdgePassEventType): this;
|
|
61
54
|
private emit;
|
|
62
55
|
/**
|
|
@@ -71,6 +64,30 @@ export declare class EdgePass {
|
|
|
71
64
|
static fromTemplate(template: EdgePassTemplate, overrides: Partial<EdgePassConfig> & {
|
|
72
65
|
owner: string;
|
|
73
66
|
}): EdgePassConfig;
|
|
67
|
+
/**
|
|
68
|
+
* Higher-order function — wraps any async function with EdgePass policy enforcement.
|
|
69
|
+
* The wrapped function only executes if the transaction is approved.
|
|
70
|
+
* Returns blocked/escalated outcomes without calling the wrapped function.
|
|
71
|
+
*
|
|
72
|
+
* Perfect for wrapping AI tool calls.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* const safePurchase = EdgePass.withPolicy(pass, signer, sdk, async (request) => {
|
|
76
|
+
* return await purchaseItem(request.merchant, request.amount);
|
|
77
|
+
* });
|
|
78
|
+
*
|
|
79
|
+
* // Now safePurchase enforces EdgePass policy automatically
|
|
80
|
+
* const result = await safePurchase({ merchant: 'Hydra Bar', amount: 32n * MIST_PER_SUI });
|
|
81
|
+
* // result.outcome === 'approved' | 'blocked' | 'escalated'
|
|
82
|
+
*/
|
|
83
|
+
static withPolicy<T>(pass: EdgePassObject, signer: {
|
|
84
|
+
signAndExecute: (tx: Transaction) => Promise<{
|
|
85
|
+
digest: string;
|
|
86
|
+
}>;
|
|
87
|
+
}, sdk: EdgePass, fn: (request: TransactionRequest) => Promise<T>): (request: TransactionRequest) => Promise<{
|
|
88
|
+
outcome: TransactionOutcome;
|
|
89
|
+
result?: T;
|
|
90
|
+
}>;
|
|
74
91
|
/**
|
|
75
92
|
* Mint a new EdgePass on Sui.
|
|
76
93
|
*/
|
|
@@ -88,14 +105,6 @@ export declare class EdgePass {
|
|
|
88
105
|
* - 'escalated' — exceeds threshold, needs human approval
|
|
89
106
|
* - 'blocked' — policy rejected the transaction
|
|
90
107
|
* - 'error' — network/signing failure, transaction NOT submitted
|
|
91
|
-
*
|
|
92
|
-
* Events fire for approved/escalated/blocked only.
|
|
93
|
-
* Check outcome.status === 'error' separately for infrastructure failures.
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* sdk.on('approved', ({ outcome }) => console.log('tx:', outcome.digest));
|
|
97
|
-
* const outcome = await sdk.execute(pass, { merchant, amount }, signer);
|
|
98
|
-
* if (outcome.status === 'error') handleInfrastructureFailure(outcome.reason);
|
|
99
108
|
*/
|
|
100
109
|
execute(pass: EdgePassObject, request: TransactionRequest, signer: {
|
|
101
110
|
signAndExecute: (tx: Transaction) => Promise<{
|
|
@@ -103,13 +112,72 @@ export declare class EdgePass {
|
|
|
103
112
|
}>;
|
|
104
113
|
}): Promise<TransactionOutcome>;
|
|
105
114
|
/**
|
|
106
|
-
*
|
|
115
|
+
* Simulate a sequence of transactions against an EdgePass.
|
|
116
|
+
* Zero network calls. Sub-millisecond. Returns predicted outcomes for
|
|
117
|
+
* all decisions including projected budget state after each step.
|
|
118
|
+
*
|
|
119
|
+
* Use this to show an agent its plan before executing, or to build
|
|
120
|
+
* approval UIs that show what will happen before touching the chain.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* const plan = sdk.simulate(pass, [
|
|
124
|
+
* { merchant: 'Hydra Bar', amount: 32n * MIST_PER_SUI },
|
|
125
|
+
* { merchant: 'ShadyTokens.xyz', amount: 1n },
|
|
126
|
+
* { merchant: 'Stage Access VIP', amount: 220n * MIST_PER_SUI },
|
|
127
|
+
* ]);
|
|
128
|
+
*
|
|
129
|
+
* console.log(plan.summary);
|
|
130
|
+
* // { approvedCount: 1, blockedCount: 1, escalatedCount: 1, totalDecisions: 3 }
|
|
131
|
+
*
|
|
132
|
+
* // Show plan, then execute approved decisions
|
|
133
|
+
* for (const decision of plan.approved) {
|
|
134
|
+
* await sdk.execute(pass, decision.request, signer);
|
|
135
|
+
* }
|
|
136
|
+
*/
|
|
137
|
+
simulate(pass: EdgePassObject, requests: TransactionRequest[]): SimulationResult;
|
|
138
|
+
/**
|
|
139
|
+
* Preview a single transaction outcome without executing.
|
|
140
|
+
* Zero network calls. Sub-millisecond.
|
|
107
141
|
*/
|
|
108
142
|
validate(pass: EdgePassObject, request: TransactionRequest): import("../utils/types").PolicyValidation;
|
|
143
|
+
/**
|
|
144
|
+
* Returns a complete budget status snapshot.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* const status = sdk.budgetStatus(pass);
|
|
148
|
+
* if (status.isExhausted) stopAgent();
|
|
149
|
+
* if (status.isNearLimit) warnUser(`${status.utilizationPct.toFixed(1)}% of budget used`);
|
|
150
|
+
*/
|
|
151
|
+
budgetStatus(pass: EdgePassObject, nearLimitThreshold?: number): BudgetStatus;
|
|
152
|
+
/**
|
|
153
|
+
* Returns budget utilization as a percentage (0-100).
|
|
154
|
+
*/
|
|
155
|
+
utilizationPct(pass: EdgePassObject): number;
|
|
156
|
+
/**
|
|
157
|
+
* Returns true if budget utilization exceeds the given threshold.
|
|
158
|
+
* Default threshold is 80%.
|
|
159
|
+
*/
|
|
160
|
+
isNearLimit(pass: EdgePassObject, threshold?: number): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Returns the remaining budget in MIST.
|
|
163
|
+
*/
|
|
164
|
+
remainingBudget(pass: EdgePassObject): bigint;
|
|
165
|
+
/**
|
|
166
|
+
* Returns time remaining on the pass in milliseconds. 0 if expired.
|
|
167
|
+
*/
|
|
168
|
+
timeRemaining(pass: EdgePassObject): number;
|
|
169
|
+
/**
|
|
170
|
+
* Returns true if the pass will expire within the given window.
|
|
171
|
+
* Default window is 1 hour.
|
|
172
|
+
*/
|
|
173
|
+
isExpiringSoon(pass: EdgePassObject, withinMs?: number): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Returns true if the pass is active and not expired.
|
|
176
|
+
*/
|
|
177
|
+
isValid(pass: EdgePassObject): boolean;
|
|
109
178
|
/**
|
|
110
179
|
* Fetch a live EdgePass from Sui.
|
|
111
180
|
* Returns null if not found.
|
|
112
|
-
* Throws if objectId is invalid or a network error occurs.
|
|
113
181
|
*/
|
|
114
182
|
fetch(objectId: string): Promise<EdgePassObject | null>;
|
|
115
183
|
/**
|
|
@@ -122,14 +190,6 @@ export declare class EdgePass {
|
|
|
122
190
|
}): Promise<{
|
|
123
191
|
digest: string;
|
|
124
192
|
}>;
|
|
125
|
-
/**
|
|
126
|
-
* Returns remaining budget in MIST.
|
|
127
|
-
*/
|
|
128
|
-
remainingBudget(pass: EdgePassObject): bigint;
|
|
129
|
-
/**
|
|
130
|
-
* Returns true if the pass is active and not expired.
|
|
131
|
-
*/
|
|
132
|
-
isValid(pass: EdgePassObject): boolean;
|
|
133
193
|
}
|
|
134
194
|
export {};
|
|
135
195
|
//# sourceMappingURL=EdgePass.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EdgePass.d.ts","sourceRoot":"","sources":["../../src/core/EdgePass.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EACL,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,
|
|
1
|
+
{"version":3,"file":"EdgePass.d.ts","sourceRoot":"","sources":["../../src/core/EdgePass.ts"],"names":[],"mappings":"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"}
|
package/dist/core/EdgePass.js
CHANGED
|
@@ -7,7 +7,6 @@ const utils_1 = require("@mysten/sui/utils");
|
|
|
7
7
|
const PolicyEngine_1 = require("./PolicyEngine");
|
|
8
8
|
const ExecutionEngine_1 = require("./ExecutionEngine");
|
|
9
9
|
const constants_1 = require("../utils/constants");
|
|
10
|
-
// Sui Clock object ID — shared object, always the same address
|
|
11
10
|
const SUI_CLOCK_OBJECT_ID = '0x0000000000000000000000000000000000000000000000000000000000000006';
|
|
12
11
|
// ── EdgePass class ────────────────────────────────────────────────────────────
|
|
13
12
|
class EdgePass {
|
|
@@ -17,17 +16,16 @@ class EdgePass {
|
|
|
17
16
|
this.client = new client_1.SuiClient({ url: constants_1.NETWORK_URLS[config.network] });
|
|
18
17
|
this.engine = new ExecutionEngine_1.ExecutionEngine(config.network);
|
|
19
18
|
}
|
|
20
|
-
// ── Event system
|
|
19
|
+
// ── Event system ─────────────────────────────────────────────────────────────
|
|
21
20
|
/**
|
|
22
21
|
* Subscribe to transaction outcomes.
|
|
23
|
-
* Note: 'error' status (network/signing failures) does NOT fire events.
|
|
24
|
-
* Check outcome.status === 'error' in your execute() handler instead.
|
|
25
22
|
*
|
|
26
23
|
* @example
|
|
27
24
|
* sdk.on('approved', ({ outcome, pass }) => {
|
|
25
|
+
* updateBudgetUI(pass);
|
|
28
26
|
* console.log('executed:', outcome.digest);
|
|
29
27
|
* });
|
|
30
|
-
* sdk.on('escalated', ({
|
|
28
|
+
* sdk.on('escalated', ({ request }) => {
|
|
31
29
|
* notifyUser(`Approve $${request.amount} at ${request.merchant}?`);
|
|
32
30
|
* });
|
|
33
31
|
* sdk.on('blocked', ({ outcome }) => {
|
|
@@ -35,29 +33,20 @@ class EdgePass {
|
|
|
35
33
|
* });
|
|
36
34
|
*/
|
|
37
35
|
on(event, listener) {
|
|
38
|
-
if (!this.listeners.has(event))
|
|
36
|
+
if (!this.listeners.has(event))
|
|
39
37
|
this.listeners.set(event, new Set());
|
|
40
|
-
}
|
|
41
38
|
this.listeners.get(event).add(listener);
|
|
42
39
|
return this;
|
|
43
40
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Unsubscribe a specific listener.
|
|
46
|
-
*/
|
|
47
41
|
off(event, listener) {
|
|
48
42
|
this.listeners.get(event)?.delete(listener);
|
|
49
43
|
return this;
|
|
50
44
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Remove all listeners for an event (or all events if none specified).
|
|
53
|
-
*/
|
|
54
45
|
removeAllListeners(event) {
|
|
55
|
-
if (event)
|
|
46
|
+
if (event)
|
|
56
47
|
this.listeners.delete(event);
|
|
57
|
-
|
|
58
|
-
else {
|
|
48
|
+
else
|
|
59
49
|
this.listeners.clear();
|
|
60
|
-
}
|
|
61
50
|
return this;
|
|
62
51
|
}
|
|
63
52
|
emit(payload) {
|
|
@@ -73,7 +62,7 @@ class EdgePass {
|
|
|
73
62
|
}
|
|
74
63
|
}
|
|
75
64
|
}
|
|
76
|
-
// ── Static helpers
|
|
65
|
+
// ── Static helpers ────────────────────────────────────────────────────────────
|
|
77
66
|
/**
|
|
78
67
|
* Creates an EdgePassConfig from a template with optional overrides.
|
|
79
68
|
*
|
|
@@ -91,39 +80,57 @@ class EdgePass {
|
|
|
91
80
|
approvedMerchants: overrides.approvedMerchants ?? base.approvedMerchants,
|
|
92
81
|
};
|
|
93
82
|
}
|
|
94
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Higher-order function — wraps any async function with EdgePass policy enforcement.
|
|
85
|
+
* The wrapped function only executes if the transaction is approved.
|
|
86
|
+
* Returns blocked/escalated outcomes without calling the wrapped function.
|
|
87
|
+
*
|
|
88
|
+
* Perfect for wrapping AI tool calls.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* const safePurchase = EdgePass.withPolicy(pass, signer, sdk, async (request) => {
|
|
92
|
+
* return await purchaseItem(request.merchant, request.amount);
|
|
93
|
+
* });
|
|
94
|
+
*
|
|
95
|
+
* // Now safePurchase enforces EdgePass policy automatically
|
|
96
|
+
* const result = await safePurchase({ merchant: 'Hydra Bar', amount: 32n * MIST_PER_SUI });
|
|
97
|
+
* // result.outcome === 'approved' | 'blocked' | 'escalated'
|
|
98
|
+
*/
|
|
99
|
+
static withPolicy(pass, signer, sdk, fn) {
|
|
100
|
+
return async (request) => {
|
|
101
|
+
const outcome = await sdk.execute(pass, request, signer);
|
|
102
|
+
if (outcome.status === 'blocked' || outcome.status === 'escalated' || outcome.status === 'error') {
|
|
103
|
+
return { outcome };
|
|
104
|
+
}
|
|
105
|
+
const result = await fn(request);
|
|
106
|
+
return { outcome, result };
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// ── Core API ──────────────────────────────────────────────────────────────────
|
|
95
110
|
/**
|
|
96
111
|
* Mint a new EdgePass on Sui.
|
|
97
112
|
*/
|
|
98
113
|
async create(passConfig, signer) {
|
|
99
|
-
// ── Config validation ─────────────────────────────────────────────────
|
|
100
114
|
if (passConfig.autoThreshold >= passConfig.escalateThreshold) {
|
|
101
115
|
throw new Error(`EdgePass.create: autoThreshold (${passConfig.autoThreshold}) must be less than escalateThreshold (${passConfig.escalateThreshold})`);
|
|
102
116
|
}
|
|
103
117
|
if (passConfig.escalateThreshold > passConfig.budget) {
|
|
104
118
|
throw new Error(`EdgePass.create: escalateThreshold (${passConfig.escalateThreshold}) must be less than budget (${passConfig.budget})`);
|
|
105
119
|
}
|
|
106
|
-
if (passConfig.maxPerTransaction !== undefined &&
|
|
107
|
-
passConfig.maxPerTransaction < passConfig.escalateThreshold) {
|
|
120
|
+
if (passConfig.maxPerTransaction !== undefined && passConfig.maxPerTransaction < passConfig.escalateThreshold) {
|
|
108
121
|
throw new Error(`EdgePass.create: maxPerTransaction (${passConfig.maxPerTransaction}) should be >= escalateThreshold (${passConfig.escalateThreshold}) to avoid unexpected blocking`);
|
|
109
122
|
}
|
|
110
|
-
if (passConfig.approvedMerchants.length === 0)
|
|
123
|
+
if (passConfig.approvedMerchants.length === 0)
|
|
111
124
|
throw new Error('EdgePass.create: approvedMerchants cannot be empty');
|
|
112
|
-
|
|
113
|
-
if (passConfig.expiryMs <= 0) {
|
|
125
|
+
if (passConfig.expiryMs <= 0)
|
|
114
126
|
throw new Error('EdgePass.create: expiryMs must be greater than 0');
|
|
115
|
-
|
|
116
|
-
if (passConfig.budget <= BigInt(0)) {
|
|
127
|
+
if (passConfig.budget <= BigInt(0))
|
|
117
128
|
throw new Error('EdgePass.create: budget must be greater than 0');
|
|
118
|
-
}
|
|
119
|
-
// ─────────────────────────────────────────────────────────────────────
|
|
120
129
|
const tx = new transactions_1.Transaction();
|
|
121
130
|
tx.setGasBudget(constants_1.DEFAULT_GAS_BUDGET);
|
|
122
131
|
const packageId = constants_1.EDGE_PACKAGE_ID[this.config.network];
|
|
123
|
-
if (!packageId)
|
|
124
|
-
throw new Error(`EdgePass.create: no package ID configured for network "${this.config.network}"
|
|
125
|
-
`Update EDGE_PACKAGE_ID in constants.ts after deploying the Move contract.`);
|
|
126
|
-
}
|
|
132
|
+
if (!packageId)
|
|
133
|
+
throw new Error(`EdgePass.create: no package ID configured for network "${this.config.network}".`);
|
|
127
134
|
tx.moveCall({
|
|
128
135
|
target: `${packageId}::edge_pass::create_pass`,
|
|
129
136
|
arguments: [
|
|
@@ -159,39 +166,99 @@ class EdgePass {
|
|
|
159
166
|
* - 'escalated' — exceeds threshold, needs human approval
|
|
160
167
|
* - 'blocked' — policy rejected the transaction
|
|
161
168
|
* - 'error' — network/signing failure, transaction NOT submitted
|
|
162
|
-
*
|
|
163
|
-
* Events fire for approved/escalated/blocked only.
|
|
164
|
-
* Check outcome.status === 'error' separately for infrastructure failures.
|
|
165
|
-
*
|
|
166
|
-
* @example
|
|
167
|
-
* sdk.on('approved', ({ outcome }) => console.log('tx:', outcome.digest));
|
|
168
|
-
* const outcome = await sdk.execute(pass, { merchant, amount }, signer);
|
|
169
|
-
* if (outcome.status === 'error') handleInfrastructureFailure(outcome.reason);
|
|
170
169
|
*/
|
|
171
170
|
async execute(pass, request, signer) {
|
|
172
171
|
const outcome = await this.engine.execute(pass, request, signer);
|
|
173
|
-
// Fire events for policy outcomes only
|
|
174
|
-
// 'error' status = infrastructure failure, not a policy decision
|
|
175
172
|
if (outcome.status !== 'error') {
|
|
176
|
-
this.emit({
|
|
177
|
-
type: outcome.status,
|
|
178
|
-
outcome: outcome,
|
|
179
|
-
pass,
|
|
180
|
-
request,
|
|
181
|
-
});
|
|
173
|
+
this.emit({ type: outcome.status, outcome: outcome, pass, request });
|
|
182
174
|
}
|
|
183
175
|
return outcome;
|
|
184
176
|
}
|
|
185
177
|
/**
|
|
186
|
-
*
|
|
178
|
+
* Simulate a sequence of transactions against an EdgePass.
|
|
179
|
+
* Zero network calls. Sub-millisecond. Returns predicted outcomes for
|
|
180
|
+
* all decisions including projected budget state after each step.
|
|
181
|
+
*
|
|
182
|
+
* Use this to show an agent its plan before executing, or to build
|
|
183
|
+
* approval UIs that show what will happen before touching the chain.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* const plan = sdk.simulate(pass, [
|
|
187
|
+
* { merchant: 'Hydra Bar', amount: 32n * MIST_PER_SUI },
|
|
188
|
+
* { merchant: 'ShadyTokens.xyz', amount: 1n },
|
|
189
|
+
* { merchant: 'Stage Access VIP', amount: 220n * MIST_PER_SUI },
|
|
190
|
+
* ]);
|
|
191
|
+
*
|
|
192
|
+
* console.log(plan.summary);
|
|
193
|
+
* // { approvedCount: 1, blockedCount: 1, escalatedCount: 1, totalDecisions: 3 }
|
|
194
|
+
*
|
|
195
|
+
* // Show plan, then execute approved decisions
|
|
196
|
+
* for (const decision of plan.approved) {
|
|
197
|
+
* await sdk.execute(pass, decision.request, signer);
|
|
198
|
+
* }
|
|
199
|
+
*/
|
|
200
|
+
simulate(pass, requests) {
|
|
201
|
+
return PolicyEngine_1.PolicyEngine.simulate(pass, requests);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Preview a single transaction outcome without executing.
|
|
205
|
+
* Zero network calls. Sub-millisecond.
|
|
187
206
|
*/
|
|
188
207
|
validate(pass, request) {
|
|
189
208
|
return PolicyEngine_1.PolicyEngine.validate(pass, request);
|
|
190
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Returns a complete budget status snapshot.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* const status = sdk.budgetStatus(pass);
|
|
215
|
+
* if (status.isExhausted) stopAgent();
|
|
216
|
+
* if (status.isNearLimit) warnUser(`${status.utilizationPct.toFixed(1)}% of budget used`);
|
|
217
|
+
*/
|
|
218
|
+
budgetStatus(pass, nearLimitThreshold = 0.8) {
|
|
219
|
+
return PolicyEngine_1.PolicyEngine.budgetStatus(pass, nearLimitThreshold);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Returns budget utilization as a percentage (0-100).
|
|
223
|
+
*/
|
|
224
|
+
utilizationPct(pass) {
|
|
225
|
+
return PolicyEngine_1.PolicyEngine.utilizationPct(pass);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Returns true if budget utilization exceeds the given threshold.
|
|
229
|
+
* Default threshold is 80%.
|
|
230
|
+
*/
|
|
231
|
+
isNearLimit(pass, threshold = 0.8) {
|
|
232
|
+
return PolicyEngine_1.PolicyEngine.isNearLimit(pass, threshold);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Returns the remaining budget in MIST.
|
|
236
|
+
*/
|
|
237
|
+
remainingBudget(pass) {
|
|
238
|
+
return PolicyEngine_1.PolicyEngine.remainingBudget(pass);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Returns time remaining on the pass in milliseconds. 0 if expired.
|
|
242
|
+
*/
|
|
243
|
+
timeRemaining(pass) {
|
|
244
|
+
return PolicyEngine_1.PolicyEngine.timeRemaining(pass);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Returns true if the pass will expire within the given window.
|
|
248
|
+
* Default window is 1 hour.
|
|
249
|
+
*/
|
|
250
|
+
isExpiringSoon(pass, withinMs = 60 * 60 * 1000) {
|
|
251
|
+
return PolicyEngine_1.PolicyEngine.isExpiringSoon(pass, withinMs);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Returns true if the pass is active and not expired.
|
|
255
|
+
*/
|
|
256
|
+
isValid(pass) {
|
|
257
|
+
return PolicyEngine_1.PolicyEngine.isValid(pass);
|
|
258
|
+
}
|
|
191
259
|
/**
|
|
192
260
|
* Fetch a live EdgePass from Sui.
|
|
193
261
|
* Returns null if not found.
|
|
194
|
-
* Throws if objectId is invalid or a network error occurs.
|
|
195
262
|
*/
|
|
196
263
|
async fetch(objectId) {
|
|
197
264
|
return this.engine.fetchPass(objectId);
|
|
@@ -209,18 +276,6 @@ class EdgePass {
|
|
|
209
276
|
});
|
|
210
277
|
return signer.signAndExecute(tx);
|
|
211
278
|
}
|
|
212
|
-
/**
|
|
213
|
-
* Returns remaining budget in MIST.
|
|
214
|
-
*/
|
|
215
|
-
remainingBudget(pass) {
|
|
216
|
-
return PolicyEngine_1.PolicyEngine.remainingBudget(pass);
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Returns true if the pass is active and not expired.
|
|
220
|
-
*/
|
|
221
|
-
isValid(pass) {
|
|
222
|
-
return PolicyEngine_1.PolicyEngine.isValid(pass);
|
|
223
|
-
}
|
|
224
279
|
}
|
|
225
280
|
exports.EdgePass = EdgePass;
|
|
226
281
|
//# sourceMappingURL=EdgePass.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EdgePass.js","sourceRoot":"","sources":["../../src/core/EdgePass.ts"],"names":[],"mappings":";;;AAAA,+CAA+C;AAC/C,2DAAuD;AACvD,6CAA6C;
|
|
1
|
+
{"version":3,"file":"EdgePass.js","sourceRoot":"","sources":["../../src/core/EdgePass.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EdgePassObject, TransactionRequest, PolicyValidation } from '../utils/types';
|
|
1
|
+
import { EdgePassObject, TransactionRequest, PolicyValidation, SimulationResult, BudgetStatus } from '../utils/types';
|
|
2
2
|
export declare class PolicyEngine {
|
|
3
3
|
/**
|
|
4
4
|
* Validates a transaction request against an EdgePass policy.
|
|
@@ -13,6 +13,23 @@ export declare class PolicyEngine {
|
|
|
13
13
|
* 7. If amount ≤ autoThreshold → auto-approve
|
|
14
14
|
*/
|
|
15
15
|
static validate(pass: EdgePassObject, request: TransactionRequest): PolicyValidation;
|
|
16
|
+
/**
|
|
17
|
+
* Simulate a sequence of transactions against an EdgePass.
|
|
18
|
+
* Zero network calls. Returns predicted outcomes for all decisions
|
|
19
|
+
* including projected budget state after each step.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const plan = sdk.simulate(pass, claudeDecisions);
|
|
23
|
+
* console.log(plan.approved.length); // decisions that will execute
|
|
24
|
+
* console.log(plan.blocked.length); // decisions that will be rejected
|
|
25
|
+
* console.log(plan.utilizationPct); // projected budget usage
|
|
26
|
+
*
|
|
27
|
+
* // Show plan to user, then execute approved decisions
|
|
28
|
+
* for (const decision of plan.approved) {
|
|
29
|
+
* await sdk.execute(pass, decision.request, signer);
|
|
30
|
+
* }
|
|
31
|
+
*/
|
|
32
|
+
static simulate(pass: EdgePassObject, requests: TransactionRequest[]): SimulationResult;
|
|
16
33
|
/**
|
|
17
34
|
* Returns true if the pass is active and not expired.
|
|
18
35
|
*/
|
|
@@ -21,5 +38,44 @@ export declare class PolicyEngine {
|
|
|
21
38
|
* Returns the remaining budget in MIST.
|
|
22
39
|
*/
|
|
23
40
|
static remainingBudget(pass: EdgePassObject): bigint;
|
|
41
|
+
/**
|
|
42
|
+
* Returns budget utilization as a percentage (0-100).
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* const pct = sdk.utilizationPct(pass);
|
|
46
|
+
* if (pct > 80) warnUser('Running low on budget');
|
|
47
|
+
*/
|
|
48
|
+
static utilizationPct(pass: EdgePassObject): number;
|
|
49
|
+
/**
|
|
50
|
+
* Returns true if budget utilization exceeds the given threshold.
|
|
51
|
+
* Default threshold is 80%.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* if (sdk.isNearLimit(pass)) notifyUser('Budget nearly exhausted');
|
|
55
|
+
* if (sdk.isNearLimit(pass, 0.5)) notifyUser('Halfway through budget');
|
|
56
|
+
*/
|
|
57
|
+
static isNearLimit(pass: EdgePassObject, threshold?: number): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Returns a complete budget status snapshot.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* const status = sdk.budgetStatus(pass);
|
|
63
|
+
* if (status.isExhausted) stopAgent();
|
|
64
|
+
* if (status.isNearLimit) notifyUser(`${status.utilizationPct}% spent`);
|
|
65
|
+
*/
|
|
66
|
+
static budgetStatus(pass: EdgePassObject, nearLimitThreshold?: number): BudgetStatus;
|
|
67
|
+
/**
|
|
68
|
+
* Returns the time remaining on the pass in milliseconds.
|
|
69
|
+
* Returns 0 if expired.
|
|
70
|
+
*/
|
|
71
|
+
static timeRemaining(pass: EdgePassObject): number;
|
|
72
|
+
/**
|
|
73
|
+
* Returns true if the pass will expire within the given window.
|
|
74
|
+
* Default window is 1 hour.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* if (sdk.isExpiringSoon(pass)) notifyUser('Pass expires in less than 1 hour');
|
|
78
|
+
*/
|
|
79
|
+
static isExpiringSoon(pass: EdgePassObject, withinMs?: number): boolean;
|
|
24
80
|
}
|
|
25
81
|
//# sourceMappingURL=PolicyEngine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PolicyEngine.d.ts","sourceRoot":"","sources":["../../src/core/PolicyEngine.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"PolicyEngine.d.ts","sourceRoot":"","sources":["../../src/core/PolicyEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAEhB,gBAAgB,EAChB,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB,qBAAa,YAAY;IAEvB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,QAAQ,CACb,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,kBAAkB,GAC1B,gBAAgB;IAqCnB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,QAAQ,CACb,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,kBAAkB,EAAE,GAC7B,gBAAgB;IA8DnB;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO;IAI7C;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAIpD;;;;;;OAMG;IACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAKnD;;;;;;;OAOG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,SAAM,GAAG,OAAO;IAIlE;;;;;;;OAOG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,kBAAkB,SAAM,GAAG,YAAY;IAajF;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAIlD;;;;;;OAMG;IACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,SAAiB,GAAG,OAAO;CAIhF"}
|
|
@@ -17,59 +17,101 @@ class PolicyEngine {
|
|
|
17
17
|
static validate(pass, request) {
|
|
18
18
|
// Rule 1 — pass must be active
|
|
19
19
|
if (!pass.active) {
|
|
20
|
-
return {
|
|
21
|
-
allowed: false,
|
|
22
|
-
requiresEscalation: false,
|
|
23
|
-
reason: 'EdgePass is inactive',
|
|
24
|
-
};
|
|
20
|
+
return { allowed: false, requiresEscalation: false, reason: 'EdgePass is inactive' };
|
|
25
21
|
}
|
|
26
22
|
// Rule 2 — pass must not be expired
|
|
27
23
|
if (Date.now() > pass.expiresAt) {
|
|
28
|
-
return {
|
|
29
|
-
allowed: false,
|
|
30
|
-
requiresEscalation: false,
|
|
31
|
-
reason: 'EdgePass has expired',
|
|
32
|
-
};
|
|
24
|
+
return { allowed: false, requiresEscalation: false, reason: 'EdgePass has expired' };
|
|
33
25
|
}
|
|
34
26
|
// Rule 3 — merchant must be approved
|
|
35
27
|
if (!pass.config.approvedMerchants.includes(request.merchant)) {
|
|
36
|
-
return {
|
|
37
|
-
allowed: false,
|
|
38
|
-
requiresEscalation: false,
|
|
39
|
-
reason: `Merchant "${request.merchant}" is not approved`,
|
|
40
|
-
};
|
|
28
|
+
return { allowed: false, requiresEscalation: false, reason: `Merchant "${request.merchant}" is not approved` };
|
|
41
29
|
}
|
|
42
30
|
// Rule 4 — must not exceed remaining budget
|
|
43
31
|
const remaining = pass.config.budget - pass.spent;
|
|
44
32
|
if (request.amount > remaining) {
|
|
45
|
-
return {
|
|
46
|
-
allowed: false,
|
|
47
|
-
requiresEscalation: false,
|
|
48
|
-
reason: `Insufficient budget. Remaining: ${remaining} MIST`,
|
|
49
|
-
};
|
|
33
|
+
return { allowed: false, requiresEscalation: false, reason: `Insufficient budget. Remaining: ${remaining} MIST` };
|
|
50
34
|
}
|
|
51
35
|
// Rule 5 — must not exceed per-transaction limit (if set)
|
|
52
|
-
if (pass.config.maxPerTransaction !== undefined &&
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
allowed: false,
|
|
56
|
-
requiresEscalation: false,
|
|
57
|
-
reason: `Amount exceeds per-transaction limit of ${pass.config.maxPerTransaction} MIST`,
|
|
58
|
-
};
|
|
36
|
+
if (pass.config.maxPerTransaction !== undefined && request.amount > pass.config.maxPerTransaction) {
|
|
37
|
+
return { allowed: false, requiresEscalation: false, reason: `Amount exceeds per-transaction limit of ${pass.config.maxPerTransaction} MIST` };
|
|
59
38
|
}
|
|
60
39
|
// Rule 6 — escalate if above escalation threshold
|
|
61
40
|
if (request.amount > pass.config.escalateThreshold) {
|
|
62
|
-
return {
|
|
63
|
-
allowed: true,
|
|
64
|
-
requiresEscalation: true,
|
|
65
|
-
reason: `Amount exceeds escalation threshold of ${pass.config.escalateThreshold} MIST`,
|
|
66
|
-
};
|
|
41
|
+
return { allowed: true, requiresEscalation: true, reason: `Amount exceeds escalation threshold of ${pass.config.escalateThreshold} MIST` };
|
|
67
42
|
}
|
|
68
43
|
// Rule 7 — auto-approve
|
|
44
|
+
return { allowed: true, requiresEscalation: false, reason: 'Auto-approved' };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Simulate a sequence of transactions against an EdgePass.
|
|
48
|
+
* Zero network calls. Returns predicted outcomes for all decisions
|
|
49
|
+
* including projected budget state after each step.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const plan = sdk.simulate(pass, claudeDecisions);
|
|
53
|
+
* console.log(plan.approved.length); // decisions that will execute
|
|
54
|
+
* console.log(plan.blocked.length); // decisions that will be rejected
|
|
55
|
+
* console.log(plan.utilizationPct); // projected budget usage
|
|
56
|
+
*
|
|
57
|
+
* // Show plan to user, then execute approved decisions
|
|
58
|
+
* for (const decision of plan.approved) {
|
|
59
|
+
* await sdk.execute(pass, decision.request, signer);
|
|
60
|
+
* }
|
|
61
|
+
*/
|
|
62
|
+
static simulate(pass, requests) {
|
|
63
|
+
const decisions = [];
|
|
64
|
+
let projectedSpent = pass.spent;
|
|
65
|
+
for (const request of requests) {
|
|
66
|
+
// Create a projected pass with current projected spent for validation
|
|
67
|
+
const projectedPass = {
|
|
68
|
+
...pass,
|
|
69
|
+
spent: projectedSpent,
|
|
70
|
+
};
|
|
71
|
+
const validation = PolicyEngine.validate(projectedPass, request);
|
|
72
|
+
let outcome;
|
|
73
|
+
let nextSpent = projectedSpent;
|
|
74
|
+
if (!validation.allowed) {
|
|
75
|
+
outcome = 'blocked';
|
|
76
|
+
}
|
|
77
|
+
else if (validation.requiresEscalation) {
|
|
78
|
+
outcome = 'escalated';
|
|
79
|
+
// Escalated decisions don't spend budget until approved
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
outcome = 'approved';
|
|
83
|
+
nextSpent = projectedSpent + request.amount;
|
|
84
|
+
}
|
|
85
|
+
const decision = {
|
|
86
|
+
request,
|
|
87
|
+
outcome,
|
|
88
|
+
reason: validation.reason,
|
|
89
|
+
projectedSpent: nextSpent,
|
|
90
|
+
projectedRemaining: pass.config.budget - nextSpent,
|
|
91
|
+
};
|
|
92
|
+
decisions.push(decision);
|
|
93
|
+
projectedSpent = nextSpent;
|
|
94
|
+
}
|
|
95
|
+
const approved = decisions.filter(d => d.outcome === 'approved');
|
|
96
|
+
const blocked = decisions.filter(d => d.outcome === 'blocked');
|
|
97
|
+
const escalated = decisions.filter(d => d.outcome === 'escalated');
|
|
98
|
+
const totalSpend = approved.reduce((sum, d) => sum + d.request.amount, 0n);
|
|
99
|
+
const remainingBudget = pass.config.budget - pass.spent - totalSpend;
|
|
100
|
+
const utilizationPct = Number((pass.spent + totalSpend) * 100n / pass.config.budget);
|
|
69
101
|
return {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
102
|
+
decisions,
|
|
103
|
+
approved,
|
|
104
|
+
blocked,
|
|
105
|
+
escalated,
|
|
106
|
+
totalSpend,
|
|
107
|
+
remainingBudget,
|
|
108
|
+
utilizationPct,
|
|
109
|
+
summary: {
|
|
110
|
+
approvedCount: approved.length,
|
|
111
|
+
blockedCount: blocked.length,
|
|
112
|
+
escalatedCount: escalated.length,
|
|
113
|
+
totalDecisions: decisions.length,
|
|
114
|
+
},
|
|
73
115
|
};
|
|
74
116
|
}
|
|
75
117
|
/**
|
|
@@ -84,6 +126,67 @@ class PolicyEngine {
|
|
|
84
126
|
static remainingBudget(pass) {
|
|
85
127
|
return pass.config.budget - pass.spent;
|
|
86
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns budget utilization as a percentage (0-100).
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* const pct = sdk.utilizationPct(pass);
|
|
134
|
+
* if (pct > 80) warnUser('Running low on budget');
|
|
135
|
+
*/
|
|
136
|
+
static utilizationPct(pass) {
|
|
137
|
+
if (pass.config.budget === 0n)
|
|
138
|
+
return 0;
|
|
139
|
+
return Number(pass.spent * 100n / pass.config.budget);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Returns true if budget utilization exceeds the given threshold.
|
|
143
|
+
* Default threshold is 80%.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* if (sdk.isNearLimit(pass)) notifyUser('Budget nearly exhausted');
|
|
147
|
+
* if (sdk.isNearLimit(pass, 0.5)) notifyUser('Halfway through budget');
|
|
148
|
+
*/
|
|
149
|
+
static isNearLimit(pass, threshold = 0.8) {
|
|
150
|
+
return PolicyEngine.utilizationPct(pass) >= threshold * 100;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Returns a complete budget status snapshot.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* const status = sdk.budgetStatus(pass);
|
|
157
|
+
* if (status.isExhausted) stopAgent();
|
|
158
|
+
* if (status.isNearLimit) notifyUser(`${status.utilizationPct}% spent`);
|
|
159
|
+
*/
|
|
160
|
+
static budgetStatus(pass, nearLimitThreshold = 0.8) {
|
|
161
|
+
const remaining = pass.config.budget - pass.spent;
|
|
162
|
+
const utilizationPct = PolicyEngine.utilizationPct(pass);
|
|
163
|
+
return {
|
|
164
|
+
budget: pass.config.budget,
|
|
165
|
+
spent: pass.spent,
|
|
166
|
+
remaining,
|
|
167
|
+
utilizationPct,
|
|
168
|
+
isNearLimit: utilizationPct >= nearLimitThreshold * 100,
|
|
169
|
+
isExhausted: remaining === 0n,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Returns the time remaining on the pass in milliseconds.
|
|
174
|
+
* Returns 0 if expired.
|
|
175
|
+
*/
|
|
176
|
+
static timeRemaining(pass) {
|
|
177
|
+
return Math.max(0, pass.expiresAt - Date.now());
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Returns true if the pass will expire within the given window.
|
|
181
|
+
* Default window is 1 hour.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* if (sdk.isExpiringSoon(pass)) notifyUser('Pass expires in less than 1 hour');
|
|
185
|
+
*/
|
|
186
|
+
static isExpiringSoon(pass, withinMs = 60 * 60 * 1000) {
|
|
187
|
+
const remaining = PolicyEngine.timeRemaining(pass);
|
|
188
|
+
return remaining > 0 && remaining <= withinMs;
|
|
189
|
+
}
|
|
87
190
|
}
|
|
88
191
|
exports.PolicyEngine = PolicyEngine;
|
|
89
192
|
//# sourceMappingURL=PolicyEngine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PolicyEngine.js","sourceRoot":"","sources":["../../src/core/PolicyEngine.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"PolicyEngine.js","sourceRoot":"","sources":["../../src/core/PolicyEngine.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { EdgePass } from './core/EdgePass';
|
|
2
2
|
export { PolicyEngine } from './core/PolicyEngine';
|
|
3
3
|
export { ExecutionEngine } from './core/ExecutionEngine';
|
|
4
|
-
export type { EdgePassConfig, EdgePassObject, TransactionRequest, TransactionOutcome, PolicyValidation, Network, EdgeSDKConfig, } from './utils/types';
|
|
4
|
+
export type { EdgePassConfig, EdgePassObject, TransactionRequest, TransactionOutcome, PolicyValidation, SimulatedDecision, SimulationResult, BudgetStatus, Network, EdgeSDKConfig, } from './utils/types';
|
|
5
5
|
export { MIST_PER_SUI, NETWORK_URLS, EDGE_PACKAGE_ID, EDGE_TEMPLATES, DEFAULT_GAS_BUDGET, } from './utils/constants';
|
|
6
6
|
export type { EdgePassTemplate } from './utils/constants';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
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,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,OAAO,EACP,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,OAAO,EACP,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4CAA2C;AAAlC,oGAAA,QAAQ,OAAA;AACjB,oDAAmD;AAA1C,4GAAA,YAAY,OAAA;AACrB,0DAAyD;AAAhD,kHAAA,eAAe,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4CAA2C;AAAlC,oGAAA,QAAQ,OAAA;AACjB,oDAAmD;AAA1C,4GAAA,YAAY,OAAA;AACrB,0DAAyD;AAAhD,kHAAA,eAAe,OAAA;AAaxB,+CAM2B;AALzB,yGAAA,YAAY,OAAA;AACZ,yGAAA,YAAY,OAAA;AACZ,4GAAA,eAAe,OAAA;AACf,2GAAA,cAAc,OAAA;AACd,+GAAA,kBAAkB,OAAA"}
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -25,9 +25,8 @@ export interface TransactionRequest {
|
|
|
25
25
|
*
|
|
26
26
|
* approved — transaction executed on-chain successfully
|
|
27
27
|
* escalated — transaction exceeds threshold, needs human approval
|
|
28
|
-
* blocked — transaction rejected by policy
|
|
28
|
+
* blocked — transaction rejected by policy
|
|
29
29
|
* error — network or signing failure — transaction was NOT submitted to chain
|
|
30
|
-
* Use this to distinguish infrastructure failures from policy rejections
|
|
31
30
|
*/
|
|
32
31
|
export type TransactionOutcome = {
|
|
33
32
|
status: 'approved';
|
|
@@ -53,6 +52,46 @@ export interface PolicyValidation {
|
|
|
53
52
|
requiresEscalation: boolean;
|
|
54
53
|
reason: string;
|
|
55
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* SimulatedDecision — result of sdk.simulate() for a single request.
|
|
57
|
+
* Includes the predicted outcome and the projected pass state after execution.
|
|
58
|
+
*/
|
|
59
|
+
export interface SimulatedDecision {
|
|
60
|
+
request: TransactionRequest;
|
|
61
|
+
outcome: 'approved' | 'escalated' | 'blocked';
|
|
62
|
+
reason: string;
|
|
63
|
+
projectedSpent: bigint;
|
|
64
|
+
projectedRemaining: bigint;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* SimulationResult — full plan returned by sdk.simulate()
|
|
68
|
+
*/
|
|
69
|
+
export interface SimulationResult {
|
|
70
|
+
decisions: SimulatedDecision[];
|
|
71
|
+
approved: SimulatedDecision[];
|
|
72
|
+
blocked: SimulatedDecision[];
|
|
73
|
+
escalated: SimulatedDecision[];
|
|
74
|
+
totalSpend: bigint;
|
|
75
|
+
remainingBudget: bigint;
|
|
76
|
+
utilizationPct: number;
|
|
77
|
+
summary: {
|
|
78
|
+
approvedCount: number;
|
|
79
|
+
blockedCount: number;
|
|
80
|
+
escalatedCount: number;
|
|
81
|
+
totalDecisions: number;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* BudgetStatus — snapshot of pass budget health
|
|
86
|
+
*/
|
|
87
|
+
export interface BudgetStatus {
|
|
88
|
+
budget: bigint;
|
|
89
|
+
spent: bigint;
|
|
90
|
+
remaining: bigint;
|
|
91
|
+
utilizationPct: number;
|
|
92
|
+
isNearLimit: boolean;
|
|
93
|
+
isExhausted: boolean;
|
|
94
|
+
}
|
|
56
95
|
export type Network = 'mainnet' | 'testnet' | 'devnet';
|
|
57
96
|
export interface EdgeSDKConfig {
|
|
58
97
|
network: Network;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAc,MAAM,CAAC;IAC3B,aAAa,EAAO,MAAM,CAAC;IAC3B,iBAAiB,EAAG,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAG,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAY,MAAM,CAAC;IAC3B,KAAK,EAAe,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAS,MAAM,CAAC;IAClB,MAAM,EAAK,cAAc,CAAC;IAC1B,KAAK,EAAM,MAAM,CAAC;IAClB,MAAM,EAAK,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAG,MAAM,CAAC;IAClB,MAAM,EAAK,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED