@brninpay/core 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/.turbo/turbo-build.log +4 -0
- package/LICENSE +203 -0
- package/README.md +7 -0
- package/dist/decision-resolver.d.ts +5 -0
- package/dist/decision-resolver.d.ts.map +1 -0
- package/dist/decision-resolver.js +20 -0
- package/dist/decision-resolver.js.map +1 -0
- package/dist/errors.d.ts +3 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +2 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/policies/allowlist.d.ts +3 -0
- package/dist/policies/allowlist.d.ts.map +1 -0
- package/dist/policies/allowlist.js +21 -0
- package/dist/policies/allowlist.js.map +1 -0
- package/dist/policies/budget-check.d.ts +3 -0
- package/dist/policies/budget-check.d.ts.map +1 -0
- package/dist/policies/budget-check.js +22 -0
- package/dist/policies/budget-check.js.map +1 -0
- package/dist/policies/index.d.ts +5 -0
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +5 -0
- package/dist/policies/index.js.map +1 -0
- package/dist/policies/max-per-call.d.ts +3 -0
- package/dist/policies/max-per-call.d.ts.map +1 -0
- package/dist/policies/max-per-call.js +20 -0
- package/dist/policies/max-per-call.js.map +1 -0
- package/dist/policies/rate-limit.d.ts +3 -0
- package/dist/policies/rate-limit.d.ts.map +1 -0
- package/dist/policies/rate-limit.js +33 -0
- package/dist/policies/rate-limit.js.map +1 -0
- package/dist/policy-engine.d.ts +8 -0
- package/dist/policy-engine.d.ts.map +1 -0
- package/dist/policy-engine.js +39 -0
- package/dist/policy-engine.js.map +1 -0
- package/dist/types/errors.d.ts +80 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +150 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/payment.d.ts +55 -0
- package/dist/types/payment.d.ts.map +1 -0
- package/dist/types/payment.js +188 -0
- package/dist/types/payment.js.map +1 -0
- package/dist/types/policy.d.ts +58 -0
- package/dist/types/policy.d.ts.map +1 -0
- package/dist/types/policy.js +194 -0
- package/dist/types/policy.js.map +1 -0
- package/dist/types/wallet.d.ts +66 -0
- package/dist/types/wallet.d.ts.map +1 -0
- package/dist/types/wallet.js +13 -0
- package/dist/types/wallet.js.map +1 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/crypto.d.ts +25 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +119 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/validation/schemas.d.ts +598 -0
- package/dist/validation/schemas.d.ts.map +1 -0
- package/dist/validation/schemas.js +178 -0
- package/dist/validation/schemas.js.map +1 -0
- package/package.json +30 -0
- package/src/decision-resolver.ts +16 -0
- package/src/errors.ts +20 -0
- package/src/index.ts +139 -0
- package/src/policies/allowlist.ts +26 -0
- package/src/policies/budget-check.ts +26 -0
- package/src/policies/index.ts +4 -0
- package/src/policies/max-per-call.ts +25 -0
- package/src/policies/rate-limit.ts +40 -0
- package/src/policy-engine.ts +65 -0
- package/src/types/errors.ts +215 -0
- package/src/types/payment.ts +297 -0
- package/src/types/policy.ts +289 -0
- package/src/types/wallet.ts +84 -0
- package/src/types.ts +193 -0
- package/src/utils/crypto.ts +182 -0
- package/src/validation/schemas.ts +208 -0
- package/test/architecture/architecture-invariants.test.ts +95 -0
- package/test/authorization-pipeline.test.ts +117 -0
- package/test/crypto.test.ts +56 -0
- package/test/decision-resolver.test.ts +52 -0
- package/test/errors.test.ts +97 -0
- package/test/payment-types.test.ts +49 -0
- package/test/policies.test.ts +162 -0
- package/test/policy-engine.test.ts +96 -0
- package/test/policy-types.test.ts +93 -0
- package/test/property/auth-invariants.test.ts +110 -0
- package/test/property/policy-invariants.test.ts +241 -0
- package/test/schemas.test.ts +58 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { ValidationError } from './errors.js'
|
|
2
|
+
import type { Address } from './wallet.js'
|
|
3
|
+
|
|
4
|
+
export const POLICY_DECISIONS = ['allow', 'deny', 'review'] as const
|
|
5
|
+
|
|
6
|
+
export type PolicyDecision = (typeof POLICY_DECISIONS)[number]
|
|
7
|
+
|
|
8
|
+
export interface PolicyReason {
|
|
9
|
+
code: string
|
|
10
|
+
message: string
|
|
11
|
+
detail?: Record<string, unknown>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface BasePolicy {
|
|
15
|
+
id: string
|
|
16
|
+
name: string
|
|
17
|
+
enabled: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface BudgetPolicy extends BasePolicy {
|
|
21
|
+
kind: 'budget'
|
|
22
|
+
currency: 'USDC'
|
|
23
|
+
limit: bigint
|
|
24
|
+
softLimit?: bigint
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface AllowlistPolicy extends BasePolicy {
|
|
28
|
+
kind: 'allowlist'
|
|
29
|
+
addresses: readonly Address[]
|
|
30
|
+
chains?: readonly number[]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface RateLimitPolicy extends BasePolicy {
|
|
34
|
+
kind: 'rate_limit'
|
|
35
|
+
maxRequests: number
|
|
36
|
+
intervalMs: number
|
|
37
|
+
burst?: number
|
|
38
|
+
scope: 'actor' | 'workspace' | 'ip'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type PolicyDefinition = BudgetPolicy | AllowlistPolicy | RateLimitPolicy
|
|
42
|
+
|
|
43
|
+
export interface PolicyEvaluationContext {
|
|
44
|
+
actorId: string
|
|
45
|
+
workspaceId: string
|
|
46
|
+
recipient: Address
|
|
47
|
+
chainId: number
|
|
48
|
+
amount: bigint
|
|
49
|
+
currency: 'USDC'
|
|
50
|
+
timestampMs: number
|
|
51
|
+
spentAmount: bigint
|
|
52
|
+
requestCount: number
|
|
53
|
+
sourceIp?: string
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface PolicyEvaluationResult {
|
|
57
|
+
policyId: string
|
|
58
|
+
decision: PolicyDecision
|
|
59
|
+
reason: PolicyReason
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface AggregatedPolicyDecision {
|
|
63
|
+
decision: PolicyDecision
|
|
64
|
+
reasons: PolicyReason[]
|
|
65
|
+
evaluations: PolicyEvaluationResult[]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function assertBasePolicy(policy: BasePolicy): void {
|
|
69
|
+
if (!policy.id.trim()) {
|
|
70
|
+
throw new ValidationError('Policy id is required', { field: 'id' })
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!policy.name.trim()) {
|
|
74
|
+
throw new ValidationError('Policy name is required', { field: 'name' })
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function normalizeAddress(address: Address): string {
|
|
79
|
+
return address.toLowerCase()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function evaluatePolicy(
|
|
83
|
+
policy: PolicyDefinition,
|
|
84
|
+
context: PolicyEvaluationContext
|
|
85
|
+
): PolicyEvaluationResult {
|
|
86
|
+
assertBasePolicy(policy)
|
|
87
|
+
|
|
88
|
+
if (!policy.enabled) {
|
|
89
|
+
return {
|
|
90
|
+
policyId: policy.id,
|
|
91
|
+
decision: 'allow',
|
|
92
|
+
reason: {
|
|
93
|
+
code: 'policy_disabled',
|
|
94
|
+
message: `Policy ${policy.name} is disabled`,
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
switch (policy.kind) {
|
|
100
|
+
case 'budget': {
|
|
101
|
+
if (policy.currency !== context.currency) {
|
|
102
|
+
return {
|
|
103
|
+
policyId: policy.id,
|
|
104
|
+
decision: 'deny',
|
|
105
|
+
reason: {
|
|
106
|
+
code: 'budget_currency_mismatch',
|
|
107
|
+
message: `Budget policy ${policy.name} only allows ${policy.currency}`,
|
|
108
|
+
},
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const nextSpend = context.spentAmount + context.amount
|
|
113
|
+
if (nextSpend > policy.limit) {
|
|
114
|
+
return {
|
|
115
|
+
policyId: policy.id,
|
|
116
|
+
decision: 'deny',
|
|
117
|
+
reason: {
|
|
118
|
+
code: 'budget_limit_exceeded',
|
|
119
|
+
message: `Budget policy ${policy.name} would exceed its hard limit`,
|
|
120
|
+
detail: {
|
|
121
|
+
limit: policy.limit.toString(),
|
|
122
|
+
spentAmount: context.spentAmount.toString(),
|
|
123
|
+
requestedAmount: context.amount.toString(),
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (policy.softLimit !== undefined && nextSpend > policy.softLimit) {
|
|
130
|
+
return {
|
|
131
|
+
policyId: policy.id,
|
|
132
|
+
decision: 'review',
|
|
133
|
+
reason: {
|
|
134
|
+
code: 'budget_soft_limit_exceeded',
|
|
135
|
+
message: `Budget policy ${policy.name} exceeded its soft limit`,
|
|
136
|
+
detail: {
|
|
137
|
+
softLimit: policy.softLimit.toString(),
|
|
138
|
+
nextSpend: nextSpend.toString(),
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
policyId: policy.id,
|
|
146
|
+
decision: 'allow',
|
|
147
|
+
reason: {
|
|
148
|
+
code: 'budget_ok',
|
|
149
|
+
message: `Budget policy ${policy.name} approved the request`,
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
case 'allowlist': {
|
|
155
|
+
const addressAllowed = policy.addresses
|
|
156
|
+
.map((address) => normalizeAddress(address))
|
|
157
|
+
.includes(normalizeAddress(context.recipient))
|
|
158
|
+
|
|
159
|
+
if (!addressAllowed) {
|
|
160
|
+
return {
|
|
161
|
+
policyId: policy.id,
|
|
162
|
+
decision: 'deny',
|
|
163
|
+
reason: {
|
|
164
|
+
code: 'recipient_not_allowlisted',
|
|
165
|
+
message: `Recipient ${context.recipient} is not allowlisted by ${policy.name}`,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (policy.chains && !policy.chains.includes(context.chainId)) {
|
|
171
|
+
return {
|
|
172
|
+
policyId: policy.id,
|
|
173
|
+
decision: 'deny',
|
|
174
|
+
reason: {
|
|
175
|
+
code: 'chain_not_allowlisted',
|
|
176
|
+
message: `Chain ${context.chainId} is not allowlisted by ${policy.name}`,
|
|
177
|
+
},
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
policyId: policy.id,
|
|
183
|
+
decision: 'allow',
|
|
184
|
+
reason: {
|
|
185
|
+
code: 'allowlist_ok',
|
|
186
|
+
message: `Allowlist policy ${policy.name} approved the request`,
|
|
187
|
+
},
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
case 'rate_limit': {
|
|
192
|
+
if (!Number.isInteger(policy.maxRequests) || policy.maxRequests <= 0) {
|
|
193
|
+
throw new ValidationError('Rate limit maxRequests must be a positive integer', {
|
|
194
|
+
field: 'maxRequests',
|
|
195
|
+
value: policy.maxRequests,
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (!Number.isInteger(policy.intervalMs) || policy.intervalMs <= 0) {
|
|
200
|
+
throw new ValidationError('Rate limit intervalMs must be a positive integer', {
|
|
201
|
+
field: 'intervalMs',
|
|
202
|
+
value: policy.intervalMs,
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const nextCount = context.requestCount + 1
|
|
207
|
+
if (nextCount > policy.maxRequests) {
|
|
208
|
+
return {
|
|
209
|
+
policyId: policy.id,
|
|
210
|
+
decision: 'deny',
|
|
211
|
+
reason: {
|
|
212
|
+
code: 'rate_limit_exceeded',
|
|
213
|
+
message: `Rate limit policy ${policy.name} denied the request`,
|
|
214
|
+
detail: {
|
|
215
|
+
scope: policy.scope,
|
|
216
|
+
maxRequests: policy.maxRequests,
|
|
217
|
+
requestCount: context.requestCount,
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (policy.burst !== undefined && nextCount > policy.burst) {
|
|
224
|
+
return {
|
|
225
|
+
policyId: policy.id,
|
|
226
|
+
decision: 'review',
|
|
227
|
+
reason: {
|
|
228
|
+
code: 'rate_limit_burst_review',
|
|
229
|
+
message: `Rate limit policy ${policy.name} exceeded its preferred burst`,
|
|
230
|
+
detail: {
|
|
231
|
+
burst: policy.burst,
|
|
232
|
+
requestCount: nextCount,
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
policyId: policy.id,
|
|
240
|
+
decision: 'allow',
|
|
241
|
+
reason: {
|
|
242
|
+
code: 'rate_limit_ok',
|
|
243
|
+
message: `Rate limit policy ${policy.name} approved the request`,
|
|
244
|
+
},
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function aggregatePolicyDecisions(
|
|
251
|
+
evaluations: readonly PolicyEvaluationResult[]
|
|
252
|
+
): AggregatedPolicyDecision {
|
|
253
|
+
const denyResult = evaluations.find((evaluation) => evaluation.decision === 'deny')
|
|
254
|
+
if (denyResult) {
|
|
255
|
+
return {
|
|
256
|
+
decision: 'deny',
|
|
257
|
+
reasons: evaluations
|
|
258
|
+
.filter((evaluation) => evaluation.decision === 'deny')
|
|
259
|
+
.map((evaluation) => evaluation.reason),
|
|
260
|
+
evaluations: [...evaluations],
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const reviewResult = evaluations.find((evaluation) => evaluation.decision === 'review')
|
|
265
|
+
if (reviewResult) {
|
|
266
|
+
return {
|
|
267
|
+
decision: 'review',
|
|
268
|
+
reasons: evaluations
|
|
269
|
+
.filter((evaluation) => evaluation.decision === 'review')
|
|
270
|
+
.map((evaluation) => evaluation.reason),
|
|
271
|
+
evaluations: [...evaluations],
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
decision: 'allow',
|
|
277
|
+
reasons: evaluations.map((evaluation) => evaluation.reason),
|
|
278
|
+
evaluations: [...evaluations],
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function evaluatePolicies(
|
|
283
|
+
policies: readonly PolicyDefinition[],
|
|
284
|
+
context: PolicyEvaluationContext
|
|
285
|
+
): AggregatedPolicyDecision {
|
|
286
|
+
return aggregatePolicyDecisions(
|
|
287
|
+
policies.map((policy) => evaluatePolicy(policy, context))
|
|
288
|
+
)
|
|
289
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export type Hex = `0x${string}`
|
|
2
|
+
export type Address = `0x${string}`
|
|
3
|
+
|
|
4
|
+
export type SmartWalletProvider = 'safe' | 'kernel' | 'circle'
|
|
5
|
+
export type EntryPointVersion = 'v0.6' | 'v0.7'
|
|
6
|
+
|
|
7
|
+
export interface SmartWallet {
|
|
8
|
+
address: Address
|
|
9
|
+
ownerAddress: Address
|
|
10
|
+
chainId: number
|
|
11
|
+
provider: SmartWalletProvider
|
|
12
|
+
entryPointAddress: Address
|
|
13
|
+
entryPointVersion: EntryPointVersion
|
|
14
|
+
factoryAddress?: Address
|
|
15
|
+
deployed: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface UserOperationCall {
|
|
19
|
+
to: Address
|
|
20
|
+
value: bigint
|
|
21
|
+
data: Hex
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface GasEstimate {
|
|
25
|
+
callGasLimit: bigint
|
|
26
|
+
verificationGasLimit: bigint
|
|
27
|
+
preVerificationGas: bigint
|
|
28
|
+
maxFeePerGas: bigint
|
|
29
|
+
maxPriorityFeePerGas: bigint
|
|
30
|
+
paymasterVerificationGasLimit?: bigint
|
|
31
|
+
paymasterPostOpGasLimit?: bigint
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface UserOperationV06 {
|
|
35
|
+
version: 'v0.6'
|
|
36
|
+
sender: Address
|
|
37
|
+
nonce: bigint
|
|
38
|
+
initCode: Hex
|
|
39
|
+
callData: Hex
|
|
40
|
+
callGasLimit: bigint
|
|
41
|
+
verificationGasLimit: bigint
|
|
42
|
+
preVerificationGas: bigint
|
|
43
|
+
maxFeePerGas: bigint
|
|
44
|
+
maxPriorityFeePerGas: bigint
|
|
45
|
+
paymasterAndData: Hex
|
|
46
|
+
signature: Hex
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface UserOperationV07 {
|
|
50
|
+
version: 'v0.7'
|
|
51
|
+
sender: Address
|
|
52
|
+
nonce: bigint
|
|
53
|
+
factory: Address | Hex
|
|
54
|
+
factoryData: Hex
|
|
55
|
+
callData: Hex
|
|
56
|
+
callGasLimit: bigint
|
|
57
|
+
verificationGasLimit: bigint
|
|
58
|
+
preVerificationGas: bigint
|
|
59
|
+
maxFeePerGas: bigint
|
|
60
|
+
maxPriorityFeePerGas: bigint
|
|
61
|
+
paymaster: Address | Hex
|
|
62
|
+
paymasterVerificationGasLimit: bigint
|
|
63
|
+
paymasterPostOpGasLimit: bigint
|
|
64
|
+
paymasterData: Hex
|
|
65
|
+
signature: Hex
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type UserOperation = UserOperationV06 | UserOperationV07
|
|
69
|
+
|
|
70
|
+
export function isUserOperationV06(value: UserOperation): value is UserOperationV06 {
|
|
71
|
+
return value.version === 'v0.6'
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function isUserOperationV07(value: UserOperation): value is UserOperationV07 {
|
|
75
|
+
return value.version === 'v0.7'
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function getUserOperationSender(value: UserOperation): Address {
|
|
79
|
+
return value.sender
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function getUserOperationNonce(value: UserOperation): bigint {
|
|
83
|
+
return value.nonce
|
|
84
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
export interface Actor {
|
|
2
|
+
id: string
|
|
3
|
+
name: string
|
|
4
|
+
status: 'active' | 'frozen' | 'depleted'
|
|
5
|
+
createdAt: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface Budget {
|
|
9
|
+
id: string
|
|
10
|
+
actorId: string
|
|
11
|
+
amount: bigint
|
|
12
|
+
used: bigint
|
|
13
|
+
currency: 'USDC'
|
|
14
|
+
period: 'monthly' | 'total'
|
|
15
|
+
resetAt: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface Policy {
|
|
19
|
+
id: string
|
|
20
|
+
actorId: string
|
|
21
|
+
type: string
|
|
22
|
+
version: string
|
|
23
|
+
config: Record<string, unknown>
|
|
24
|
+
priority: number
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SettlementDescriptor {
|
|
28
|
+
address: string
|
|
29
|
+
chain: string
|
|
30
|
+
asset: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Target {
|
|
34
|
+
id: string
|
|
35
|
+
actorId: string
|
|
36
|
+
name: string
|
|
37
|
+
settlement: SettlementDescriptor
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface Purpose {
|
|
41
|
+
type: string
|
|
42
|
+
id: string
|
|
43
|
+
description?: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface Intent {
|
|
47
|
+
target: string
|
|
48
|
+
amount: bigint
|
|
49
|
+
purpose: Purpose
|
|
50
|
+
idempotencyKey?: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface BudgetState {
|
|
54
|
+
total: bigint
|
|
55
|
+
used: bigint
|
|
56
|
+
remaining: bigint
|
|
57
|
+
period: string
|
|
58
|
+
currency: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface PolicyResult {
|
|
62
|
+
policyId: string
|
|
63
|
+
policyType: string
|
|
64
|
+
version: string
|
|
65
|
+
decision: 'pass' | 'deny' | 'review'
|
|
66
|
+
reason: { code: string; message: string }
|
|
67
|
+
evaluatedAt: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type AuthorizationDecision = 'approved' | 'denied' | 'pending-review'
|
|
71
|
+
|
|
72
|
+
export interface Authorization {
|
|
73
|
+
intent: Intent
|
|
74
|
+
policyResults: PolicyResult[]
|
|
75
|
+
decision: AuthorizationDecision
|
|
76
|
+
evaluatedAt: string
|
|
77
|
+
actorVersion: string
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface SettlementHint {
|
|
81
|
+
preferredChain?: string
|
|
82
|
+
deadline?: string
|
|
83
|
+
gasStrategy?: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface ExecutionPlan {
|
|
87
|
+
authorization: Authorization
|
|
88
|
+
settlementHints: SettlementHint
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface PolicyContext {
|
|
92
|
+
actor: Actor
|
|
93
|
+
intent: Intent
|
|
94
|
+
budget: BudgetState
|
|
95
|
+
evaluatedPolicies: PolicyResult[]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type PolicyMiddleware = (
|
|
99
|
+
ctx: PolicyContext,
|
|
100
|
+
next: () => Promise<PolicyResult>
|
|
101
|
+
) => Promise<PolicyResult>
|
|
102
|
+
|
|
103
|
+
export interface PolicyEvaluator {
|
|
104
|
+
id: string
|
|
105
|
+
type: string
|
|
106
|
+
version: string
|
|
107
|
+
middleware: PolicyMiddleware
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface SimulationResult {
|
|
111
|
+
decision: AuthorizationDecision
|
|
112
|
+
policyResults: PolicyResult[]
|
|
113
|
+
estimatedGas?: bigint
|
|
114
|
+
estimatedCost?: bigint
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface SignedTransaction {
|
|
118
|
+
serialized: `0x${string}`
|
|
119
|
+
hash: `0x${string}`
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface Receipt {
|
|
123
|
+
txHash: `0x${string}`
|
|
124
|
+
status: 'confirmed' | 'failed'
|
|
125
|
+
blockNumber: bigint
|
|
126
|
+
gasUsed: bigint
|
|
127
|
+
effectiveGasPrice: bigint
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type {
|
|
131
|
+
PaymentIntentStatus,
|
|
132
|
+
PaymentAmount,
|
|
133
|
+
PaymentRecipient,
|
|
134
|
+
PaymentIntentFailure,
|
|
135
|
+
PaymentMetadataValue,
|
|
136
|
+
PaymentIntent,
|
|
137
|
+
SerializedBigInt,
|
|
138
|
+
} from './types/payment.js'
|
|
139
|
+
|
|
140
|
+
export {
|
|
141
|
+
PAYMENT_INTENT_STATUSES,
|
|
142
|
+
PAYMENT_INTENT_TERMINAL_STATUSES,
|
|
143
|
+
PAYMENT_INTENT_TRANSITIONS,
|
|
144
|
+
validatePaymentAmount,
|
|
145
|
+
isPaymentIntentTerminalStatus,
|
|
146
|
+
canTransitionPaymentIntentStatus,
|
|
147
|
+
assertValidPaymentIntentTransition,
|
|
148
|
+
assertPaymentIntent,
|
|
149
|
+
serializeBigInts,
|
|
150
|
+
deserializeBigInts,
|
|
151
|
+
serializePaymentIntent,
|
|
152
|
+
deserializePaymentIntent,
|
|
153
|
+
} from './types/payment.js'
|
|
154
|
+
|
|
155
|
+
export type {
|
|
156
|
+
PolicyDecision,
|
|
157
|
+
PolicyReason,
|
|
158
|
+
BasePolicy,
|
|
159
|
+
BudgetPolicy,
|
|
160
|
+
AllowlistPolicy,
|
|
161
|
+
RateLimitPolicy,
|
|
162
|
+
PolicyDefinition,
|
|
163
|
+
PolicyEvaluationContext,
|
|
164
|
+
PolicyEvaluationResult,
|
|
165
|
+
AggregatedPolicyDecision,
|
|
166
|
+
} from './types/policy.js'
|
|
167
|
+
|
|
168
|
+
export {
|
|
169
|
+
POLICY_DECISIONS,
|
|
170
|
+
evaluatePolicy,
|
|
171
|
+
aggregatePolicyDecisions,
|
|
172
|
+
evaluatePolicies,
|
|
173
|
+
} from './types/policy.js'
|
|
174
|
+
|
|
175
|
+
export type {
|
|
176
|
+
Hex,
|
|
177
|
+
Address,
|
|
178
|
+
SmartWalletProvider,
|
|
179
|
+
EntryPointVersion,
|
|
180
|
+
SmartWallet,
|
|
181
|
+
UserOperationCall,
|
|
182
|
+
GasEstimate,
|
|
183
|
+
UserOperationV06,
|
|
184
|
+
UserOperationV07,
|
|
185
|
+
UserOperation,
|
|
186
|
+
} from './types/wallet.js'
|
|
187
|
+
|
|
188
|
+
export {
|
|
189
|
+
isUserOperationV06,
|
|
190
|
+
isUserOperationV07,
|
|
191
|
+
getUserOperationSender,
|
|
192
|
+
getUserOperationNonce,
|
|
193
|
+
} from './types/wallet.js'
|