@azeth/sdk 0.2.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/LICENSE +21 -0
- package/README.md +139 -0
- package/dist/account/balance.d.ts +41 -0
- package/dist/account/balance.d.ts.map +1 -0
- package/dist/account/balance.js +264 -0
- package/dist/account/balance.js.map +1 -0
- package/dist/account/create.d.ts +27 -0
- package/dist/account/create.d.ts.map +1 -0
- package/dist/account/create.js +116 -0
- package/dist/account/create.js.map +1 -0
- package/dist/account/deposit.d.ts +34 -0
- package/dist/account/deposit.d.ts.map +1 -0
- package/dist/account/deposit.js +88 -0
- package/dist/account/deposit.js.map +1 -0
- package/dist/account/guardian-approval.d.ts +111 -0
- package/dist/account/guardian-approval.d.ts.map +1 -0
- package/dist/account/guardian-approval.js +223 -0
- package/dist/account/guardian-approval.js.map +1 -0
- package/dist/account/guardian.d.ts +27 -0
- package/dist/account/guardian.d.ts.map +1 -0
- package/dist/account/guardian.js +67 -0
- package/dist/account/guardian.js.map +1 -0
- package/dist/account/history.d.ts +22 -0
- package/dist/account/history.d.ts.map +1 -0
- package/dist/account/history.js +144 -0
- package/dist/account/history.js.map +1 -0
- package/dist/account/transfer.d.ts +28 -0
- package/dist/account/transfer.d.ts.map +1 -0
- package/dist/account/transfer.js +137 -0
- package/dist/account/transfer.js.map +1 -0
- package/dist/auth/erc8128.d.ts +14 -0
- package/dist/auth/erc8128.d.ts.map +1 -0
- package/dist/auth/erc8128.js +92 -0
- package/dist/auth/erc8128.js.map +1 -0
- package/dist/client.d.ts +394 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +970 -0
- package/dist/client.js.map +1 -0
- package/dist/events/emitter.d.ts +96 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +90 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/messaging/message-router.d.ts +69 -0
- package/dist/messaging/message-router.d.ts.map +1 -0
- package/dist/messaging/message-router.js +307 -0
- package/dist/messaging/message-router.js.map +1 -0
- package/dist/messaging/rate-limiter.d.ts +31 -0
- package/dist/messaging/rate-limiter.d.ts.map +1 -0
- package/dist/messaging/rate-limiter.js +74 -0
- package/dist/messaging/rate-limiter.js.map +1 -0
- package/dist/messaging/xmtp.d.ts +144 -0
- package/dist/messaging/xmtp.d.ts.map +1 -0
- package/dist/messaging/xmtp.js +473 -0
- package/dist/messaging/xmtp.js.map +1 -0
- package/dist/payments/agreements.d.ts +87 -0
- package/dist/payments/agreements.d.ts.map +1 -0
- package/dist/payments/agreements.js +337 -0
- package/dist/payments/agreements.js.map +1 -0
- package/dist/payments/budget.d.ts +118 -0
- package/dist/payments/budget.d.ts.map +1 -0
- package/dist/payments/budget.js +176 -0
- package/dist/payments/budget.js.map +1 -0
- package/dist/payments/smart-fetch.d.ts +65 -0
- package/dist/payments/smart-fetch.d.ts.map +1 -0
- package/dist/payments/smart-fetch.js +115 -0
- package/dist/payments/smart-fetch.js.map +1 -0
- package/dist/payments/x402.d.ts +89 -0
- package/dist/payments/x402.d.ts.map +1 -0
- package/dist/payments/x402.js +620 -0
- package/dist/payments/x402.js.map +1 -0
- package/dist/registry/discover.d.ts +43 -0
- package/dist/registry/discover.d.ts.map +1 -0
- package/dist/registry/discover.js +272 -0
- package/dist/registry/discover.js.map +1 -0
- package/dist/registry/register.d.ts +44 -0
- package/dist/registry/register.d.ts.map +1 -0
- package/dist/registry/register.js +126 -0
- package/dist/registry/register.js.map +1 -0
- package/dist/reputation/opinion.d.ts +52 -0
- package/dist/reputation/opinion.d.ts.map +1 -0
- package/dist/reputation/opinion.js +198 -0
- package/dist/reputation/opinion.js.map +1 -0
- package/dist/utils/addresses.d.ts +6 -0
- package/dist/utils/addresses.d.ts.map +1 -0
- package/dist/utils/addresses.js +53 -0
- package/dist/utils/addresses.js.map +1 -0
- package/dist/utils/errors.d.ts +23 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +188 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/execution.d.ts +20 -0
- package/dist/utils/execution.d.ts.map +1 -0
- package/dist/utils/execution.js +28 -0
- package/dist/utils/execution.js.map +1 -0
- package/dist/utils/paymaster.d.ts +35 -0
- package/dist/utils/paymaster.d.ts.map +1 -0
- package/dist/utils/paymaster.js +115 -0
- package/dist/utils/paymaster.js.map +1 -0
- package/dist/utils/retry.d.ts +19 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +68 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/userop.d.ts +55 -0
- package/dist/utils/userop.d.ts.map +1 -0
- package/dist/utils/userop.js +201 -0
- package/dist/utils/userop.js.map +1 -0
- package/dist/utils/validation.d.ts +8 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +35 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { keccak256, toBytes, encodeFunctionData, } from 'viem';
|
|
2
|
+
import { PaymentAgreementModuleAbi } from '@azeth/common/abis';
|
|
3
|
+
import { AzethError } from '@azeth/common';
|
|
4
|
+
import { requireAddress } from '../utils/addresses.js';
|
|
5
|
+
import { wrapContractError } from '../utils/errors.js';
|
|
6
|
+
import { withRetry } from '../utils/retry.js';
|
|
7
|
+
// AgreementCreated(address indexed account, uint256 indexed agreementId, address indexed payee, address token, uint256 amount, uint256 interval, uint256 endTime)
|
|
8
|
+
const AGREEMENT_CREATED_TOPIC = keccak256(toBytes('AgreementCreated(address,uint256,address,address,uint256,uint256,uint256)'));
|
|
9
|
+
/** Create a recurring payment agreement via ERC-4337 UserOperation.
|
|
10
|
+
*
|
|
11
|
+
* Routes the call through the smart account so msg.sender = smart account address.
|
|
12
|
+
* The SmartAccountClient wraps the PaymentAgreementModule.createAgreement() call
|
|
13
|
+
* inside AzethAccount.execute() via a UserOp submitted to EntryPoint v0.7.
|
|
14
|
+
*/
|
|
15
|
+
export async function createPaymentAgreement(publicClient, smartAccountClient, addresses, account, params) {
|
|
16
|
+
if (!/^0x[a-fA-F0-9]{40}$/.test(params.payee)) {
|
|
17
|
+
throw new AzethError('Invalid payee address format', 'INVALID_INPUT', { field: 'payee' });
|
|
18
|
+
}
|
|
19
|
+
if (!/^0x[a-fA-F0-9]{40}$/.test(params.token)) {
|
|
20
|
+
throw new AzethError('Invalid token address format', 'INVALID_INPUT', { field: 'token' });
|
|
21
|
+
}
|
|
22
|
+
if (params.amount <= 0n) {
|
|
23
|
+
throw new AzethError('Payment amount must be positive', 'INVALID_INPUT', { field: 'amount' });
|
|
24
|
+
}
|
|
25
|
+
if (!Number.isInteger(params.interval) || params.interval < 1) {
|
|
26
|
+
throw new AzethError('Interval must be a positive integer (seconds)', 'INVALID_INPUT', { field: 'interval' });
|
|
27
|
+
}
|
|
28
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
29
|
+
let txHash;
|
|
30
|
+
try {
|
|
31
|
+
const data = encodeFunctionData({
|
|
32
|
+
abi: PaymentAgreementModuleAbi,
|
|
33
|
+
functionName: 'createAgreement',
|
|
34
|
+
args: [
|
|
35
|
+
params.payee,
|
|
36
|
+
params.token,
|
|
37
|
+
params.amount,
|
|
38
|
+
BigInt(params.interval),
|
|
39
|
+
params.endTime ?? 0n,
|
|
40
|
+
BigInt(params.maxExecutions ?? 0),
|
|
41
|
+
params.totalCap ?? (params.maxExecutions ? params.amount * BigInt(params.maxExecutions) : params.amount * 365n),
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
txHash = await smartAccountClient.sendTransaction({
|
|
45
|
+
to: moduleAddress,
|
|
46
|
+
value: 0n,
|
|
47
|
+
data,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
throw wrapContractError(err, 'PAYMENT_FAILED');
|
|
52
|
+
}
|
|
53
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash, timeout: 120_000 });
|
|
54
|
+
if (receipt.status === 'reverted') {
|
|
55
|
+
throw new AzethError('Transaction reverted', 'CONTRACT_ERROR', { txHash });
|
|
56
|
+
}
|
|
57
|
+
// Parse AgreementCreated event for agreementId — filter by module address and event signature
|
|
58
|
+
let agreementId = 0n;
|
|
59
|
+
for (const log of receipt.logs) {
|
|
60
|
+
if (log.address?.toLowerCase() === moduleAddress.toLowerCase() && log.topics[0] === AGREEMENT_CREATED_TOPIC && log.topics.length >= 3) {
|
|
61
|
+
agreementId = BigInt(log.topics[2] ?? '0x0');
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { agreementId, txHash };
|
|
66
|
+
}
|
|
67
|
+
/** Get agreement details */
|
|
68
|
+
export async function getAgreement(publicClient, addresses, account, agreementId) {
|
|
69
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
70
|
+
const result = await withRetry(() => publicClient.readContract({
|
|
71
|
+
address: moduleAddress,
|
|
72
|
+
abi: PaymentAgreementModuleAbi,
|
|
73
|
+
functionName: 'getAgreement',
|
|
74
|
+
args: [account, agreementId],
|
|
75
|
+
}));
|
|
76
|
+
return {
|
|
77
|
+
id: agreementId,
|
|
78
|
+
payee: result.payee,
|
|
79
|
+
token: result.token,
|
|
80
|
+
amount: result.amount,
|
|
81
|
+
interval: result.interval,
|
|
82
|
+
endTime: result.endTime,
|
|
83
|
+
lastExecuted: result.lastExecuted,
|
|
84
|
+
maxExecutions: result.maxExecutions,
|
|
85
|
+
executionCount: result.executionCount,
|
|
86
|
+
totalCap: result.totalCap,
|
|
87
|
+
totalPaid: result.totalPaid,
|
|
88
|
+
active: result.active,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/** Audit #13 M-14 fix: Cap the number of agreements scanned to prevent RPC flooding */
|
|
92
|
+
const MAX_AGREEMENT_SCAN = 100;
|
|
93
|
+
/** Find an active agreement from a given account to a specific payee.
|
|
94
|
+
* Iterates from newest to oldest (newest more likely active).
|
|
95
|
+
* Scans at most MAX_AGREEMENT_SCAN agreements to prevent O(n) RPC calls.
|
|
96
|
+
*
|
|
97
|
+
* @param publicClient - viem public client for on-chain reads
|
|
98
|
+
* @param addresses - Contract addresses containing paymentAgreementModule
|
|
99
|
+
* @param account - The payer's smart account address
|
|
100
|
+
* @param payee - The payee address to match
|
|
101
|
+
* @param token - Optional token address to filter by
|
|
102
|
+
* @returns The first matching active agreement, or null
|
|
103
|
+
*/
|
|
104
|
+
export async function findAgreementWithPayee(publicClient, addresses, account, payee, token) {
|
|
105
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
106
|
+
// Get agreement count
|
|
107
|
+
let count;
|
|
108
|
+
try {
|
|
109
|
+
count = await withRetry(() => publicClient.readContract({
|
|
110
|
+
address: moduleAddress,
|
|
111
|
+
abi: PaymentAgreementModuleAbi,
|
|
112
|
+
functionName: 'getAgreementCount',
|
|
113
|
+
args: [account],
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
if (count === 0n)
|
|
120
|
+
return null;
|
|
121
|
+
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
122
|
+
// Cap scan to most recent MAX_AGREEMENT_SCAN agreements to prevent RPC flooding
|
|
123
|
+
const scanLimit = count < BigInt(MAX_AGREEMENT_SCAN) ? count : BigInt(MAX_AGREEMENT_SCAN);
|
|
124
|
+
const startIndex = count - 1n;
|
|
125
|
+
const endIndex = count - scanLimit;
|
|
126
|
+
// Iterate from newest to oldest (most recent agreements are most likely active)
|
|
127
|
+
for (let i = startIndex; i >= endIndex; i--) {
|
|
128
|
+
let agreement;
|
|
129
|
+
try {
|
|
130
|
+
agreement = await getAgreement(publicClient, addresses, account, i);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (!agreement.active)
|
|
136
|
+
continue;
|
|
137
|
+
if (agreement.payee.toLowerCase() !== payee.toLowerCase())
|
|
138
|
+
continue;
|
|
139
|
+
if (token && agreement.token.toLowerCase() !== token.toLowerCase())
|
|
140
|
+
continue;
|
|
141
|
+
if (agreement.endTime !== 0n && agreement.endTime <= now)
|
|
142
|
+
continue;
|
|
143
|
+
if (agreement.maxExecutions !== 0n && agreement.executionCount >= agreement.maxExecutions)
|
|
144
|
+
continue;
|
|
145
|
+
return agreement;
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
/** Execute a due payment agreement via ERC-4337 UserOperation.
|
|
150
|
+
*
|
|
151
|
+
* Routes the call through the smart account so msg.sender = smart account address.
|
|
152
|
+
*/
|
|
153
|
+
export async function executeAgreement(publicClient, smartAccountClient, addresses, account, agreementId) {
|
|
154
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
155
|
+
let txHash;
|
|
156
|
+
try {
|
|
157
|
+
const data = encodeFunctionData({
|
|
158
|
+
abi: PaymentAgreementModuleAbi,
|
|
159
|
+
functionName: 'executeAgreement',
|
|
160
|
+
args: [account, agreementId],
|
|
161
|
+
});
|
|
162
|
+
txHash = await smartAccountClient.sendTransaction({
|
|
163
|
+
to: moduleAddress,
|
|
164
|
+
value: 0n,
|
|
165
|
+
data,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
if (err instanceof AzethError)
|
|
170
|
+
throw err;
|
|
171
|
+
throw new AzethError(err instanceof Error ? err.message : 'Failed to execute agreement', 'PAYMENT_FAILED', { operation: 'agreement_execution', originalError: err instanceof Error ? err.name : undefined });
|
|
172
|
+
}
|
|
173
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash, timeout: 120_000 });
|
|
174
|
+
if (receipt.status === 'reverted') {
|
|
175
|
+
throw new AzethError('Transaction reverted', 'CONTRACT_ERROR', { txHash });
|
|
176
|
+
}
|
|
177
|
+
return txHash;
|
|
178
|
+
}
|
|
179
|
+
/** Execute a payment agreement as a third-party keeper.
|
|
180
|
+
*
|
|
181
|
+
* The contract's executeAgreement() is permissionless — any msg.sender can trigger it.
|
|
182
|
+
* When the caller is NOT the payer (i.e., it's a keeper or payee), we cannot build a
|
|
183
|
+
* UserOp for the payer's smart account (AA24 signature mismatch). Instead:
|
|
184
|
+
*
|
|
185
|
+
* - If the keeper has their own smart account: route via the keeper's SmartAccountClient
|
|
186
|
+
* (the keeper's smart account calls the module, which executes on the payer's account)
|
|
187
|
+
* - If the keeper has no smart account: call the module directly from the keeper's EOA
|
|
188
|
+
* via walletClient.writeContract()
|
|
189
|
+
*/
|
|
190
|
+
export async function executeAgreementAsKeeper(publicClient, keeperSmartAccountClient, walletClient, addresses, payerAccount, agreementId) {
|
|
191
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
192
|
+
let txHash;
|
|
193
|
+
try {
|
|
194
|
+
const data = encodeFunctionData({
|
|
195
|
+
abi: PaymentAgreementModuleAbi,
|
|
196
|
+
functionName: 'executeAgreement',
|
|
197
|
+
args: [payerAccount, agreementId],
|
|
198
|
+
});
|
|
199
|
+
if (keeperSmartAccountClient) {
|
|
200
|
+
// Route via keeper's own smart account (UserOp from keeper's account)
|
|
201
|
+
txHash = await keeperSmartAccountClient.sendTransaction({
|
|
202
|
+
to: moduleAddress,
|
|
203
|
+
value: 0n,
|
|
204
|
+
data,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
// Direct EOA call — keeper has no smart account
|
|
209
|
+
txHash = await walletClient.writeContract({
|
|
210
|
+
address: moduleAddress,
|
|
211
|
+
abi: PaymentAgreementModuleAbi,
|
|
212
|
+
functionName: 'executeAgreement',
|
|
213
|
+
args: [payerAccount, agreementId],
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
if (err instanceof AzethError)
|
|
219
|
+
throw err;
|
|
220
|
+
throw new AzethError(err instanceof Error ? err.message : 'Failed to execute agreement as keeper', 'PAYMENT_FAILED', { operation: 'agreement_execution', originalError: err instanceof Error ? err.name : undefined });
|
|
221
|
+
}
|
|
222
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash, timeout: 120_000 });
|
|
223
|
+
if (receipt.status === 'reverted') {
|
|
224
|
+
throw new AzethError('Transaction reverted', 'CONTRACT_ERROR', { txHash });
|
|
225
|
+
}
|
|
226
|
+
return txHash;
|
|
227
|
+
}
|
|
228
|
+
/** Cancel an active payment agreement via ERC-4337 UserOperation.
|
|
229
|
+
*
|
|
230
|
+
* Routes the call through the smart account so msg.sender = smart account address.
|
|
231
|
+
* Only the payer (agreement creator) can cancel. Immediate effect, no timelock.
|
|
232
|
+
*/
|
|
233
|
+
export async function cancelAgreement(publicClient, smartAccountClient, addresses, agreementId) {
|
|
234
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
235
|
+
let txHash;
|
|
236
|
+
try {
|
|
237
|
+
const data = encodeFunctionData({
|
|
238
|
+
abi: PaymentAgreementModuleAbi,
|
|
239
|
+
functionName: 'cancelAgreement',
|
|
240
|
+
args: [agreementId],
|
|
241
|
+
});
|
|
242
|
+
txHash = await smartAccountClient.sendTransaction({
|
|
243
|
+
to: moduleAddress,
|
|
244
|
+
value: 0n,
|
|
245
|
+
data,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
if (err instanceof AzethError)
|
|
250
|
+
throw err;
|
|
251
|
+
throw new AzethError(err instanceof Error ? err.message : 'Failed to cancel agreement', 'PAYMENT_FAILED', { operation: 'agreement_cancel', originalError: err instanceof Error ? err.name : undefined });
|
|
252
|
+
}
|
|
253
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash, timeout: 120_000 });
|
|
254
|
+
if (receipt.status === 'reverted') {
|
|
255
|
+
throw new AzethError('Transaction reverted', 'CONTRACT_ERROR', { txHash });
|
|
256
|
+
}
|
|
257
|
+
return txHash;
|
|
258
|
+
}
|
|
259
|
+
/** Get the total number of agreements for an account */
|
|
260
|
+
export async function getAgreementCount(publicClient, addresses, account) {
|
|
261
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
262
|
+
return await withRetry(() => publicClient.readContract({
|
|
263
|
+
address: moduleAddress,
|
|
264
|
+
abi: PaymentAgreementModuleAbi,
|
|
265
|
+
functionName: 'getAgreementCount',
|
|
266
|
+
args: [account],
|
|
267
|
+
}));
|
|
268
|
+
}
|
|
269
|
+
/** Check if a payment agreement can be executed right now.
|
|
270
|
+
* Returns [executable, reason] — reason explains why if not executable.
|
|
271
|
+
*/
|
|
272
|
+
export async function canExecutePayment(publicClient, addresses, account, agreementId) {
|
|
273
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
274
|
+
const result = await withRetry(() => publicClient.readContract({
|
|
275
|
+
address: moduleAddress,
|
|
276
|
+
abi: PaymentAgreementModuleAbi,
|
|
277
|
+
functionName: 'canExecutePayment',
|
|
278
|
+
args: [account, agreementId],
|
|
279
|
+
}));
|
|
280
|
+
return { executable: result[0], reason: result[1] };
|
|
281
|
+
}
|
|
282
|
+
/** Check if a payment agreement is executable (ignoring interval timing).
|
|
283
|
+
* Checks: active, not expired, not maxed, not capped, guardian whitelist,
|
|
284
|
+
* guardian limits, and payer balance >= accrued amount. */
|
|
285
|
+
export async function isAgreementExecutable(publicClient, addresses, account, agreementId) {
|
|
286
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
287
|
+
return await withRetry(() => publicClient.readContract({
|
|
288
|
+
address: moduleAddress,
|
|
289
|
+
abi: PaymentAgreementModuleAbi,
|
|
290
|
+
functionName: 'isAgreementExecutable',
|
|
291
|
+
args: [account, agreementId],
|
|
292
|
+
}));
|
|
293
|
+
}
|
|
294
|
+
/** Get comprehensive agreement data in a single RPC call.
|
|
295
|
+
* Combines getAgreement + isAgreementExecutable + isAgreementDue +
|
|
296
|
+
* getNextExecutionTime + getAgreementCount. */
|
|
297
|
+
export async function getAgreementData(publicClient, addresses, account, agreementId) {
|
|
298
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
299
|
+
const result = await withRetry(() => publicClient.readContract({
|
|
300
|
+
address: moduleAddress,
|
|
301
|
+
abi: PaymentAgreementModuleAbi,
|
|
302
|
+
functionName: 'getAgreementData',
|
|
303
|
+
args: [account, agreementId],
|
|
304
|
+
}));
|
|
305
|
+
return {
|
|
306
|
+
agreement: {
|
|
307
|
+
id: agreementId,
|
|
308
|
+
payee: result[0].payee,
|
|
309
|
+
token: result[0].token,
|
|
310
|
+
amount: result[0].amount,
|
|
311
|
+
interval: result[0].interval,
|
|
312
|
+
endTime: result[0].endTime,
|
|
313
|
+
lastExecuted: result[0].lastExecuted,
|
|
314
|
+
maxExecutions: result[0].maxExecutions,
|
|
315
|
+
executionCount: result[0].executionCount,
|
|
316
|
+
totalCap: result[0].totalCap,
|
|
317
|
+
totalPaid: result[0].totalPaid,
|
|
318
|
+
active: result[0].active,
|
|
319
|
+
},
|
|
320
|
+
executable: result[1],
|
|
321
|
+
reason: result[2],
|
|
322
|
+
isDue: result[3],
|
|
323
|
+
nextExecutionTime: result[4],
|
|
324
|
+
count: result[5],
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/** Get the next execution timestamp for a payment agreement */
|
|
328
|
+
export async function getNextExecutionTime(publicClient, addresses, account, agreementId) {
|
|
329
|
+
const moduleAddress = requireAddress(addresses, 'paymentAgreementModule');
|
|
330
|
+
return await withRetry(() => publicClient.readContract({
|
|
331
|
+
address: moduleAddress,
|
|
332
|
+
abi: PaymentAgreementModuleAbi,
|
|
333
|
+
functionName: 'getNextExecutionTime',
|
|
334
|
+
args: [account, agreementId],
|
|
335
|
+
}));
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=agreements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agreements.js","sourceRoot":"","sources":["../../src/payments/agreements.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/** Reputation-aware budget manager for x402 payments.
|
|
2
|
+
*
|
|
3
|
+
* Provides per-transaction and per-session spending limits that scale
|
|
4
|
+
* with the target service's on-chain reputation. Higher reputation =
|
|
5
|
+
* higher trust = higher allowed spending.
|
|
6
|
+
*
|
|
7
|
+
* Budget tiers are configurable and layer ON TOP of the Guardian Module's
|
|
8
|
+
* on-chain dailySpendLimitUSD (which is the hard ceiling that can't be bypassed).
|
|
9
|
+
* This is a client-side soft limit for convenience and safety.
|
|
10
|
+
*/
|
|
11
|
+
/** A single budget tier: reputation threshold → per-transaction limit */
|
|
12
|
+
export interface BudgetTier {
|
|
13
|
+
/** Minimum reputation score to qualify for this tier (0-100) */
|
|
14
|
+
minReputation: number;
|
|
15
|
+
/** Maximum payment per transaction in token smallest unit (e.g., USDC 6 decimals) */
|
|
16
|
+
maxPerTransaction: bigint;
|
|
17
|
+
/** Tier label for display/logging */
|
|
18
|
+
label: string;
|
|
19
|
+
}
|
|
20
|
+
/** Default budget tiers (ordered highest reputation first) */
|
|
21
|
+
export declare const DEFAULT_BUDGET_TIERS: readonly BudgetTier[];
|
|
22
|
+
/** Budget manager configuration */
|
|
23
|
+
export interface BudgetConfig {
|
|
24
|
+
/** Custom budget tiers (overrides defaults). Must be sorted by minReputation descending. */
|
|
25
|
+
tiers?: BudgetTier[];
|
|
26
|
+
/** Maximum spending per session across all services (in token smallest unit).
|
|
27
|
+
* Default: 10,000,000 (10 USDC) */
|
|
28
|
+
maxPerSession?: bigint;
|
|
29
|
+
/** Whether to enforce budget checks (default: true).
|
|
30
|
+
* When false, budget is tracked but not enforced. */
|
|
31
|
+
enforce?: boolean;
|
|
32
|
+
/** Fallback per-tx limit when reputation is unknown (default: bronze tier) */
|
|
33
|
+
unknownReputationLimit?: bigint;
|
|
34
|
+
}
|
|
35
|
+
/** Result of a budget check */
|
|
36
|
+
export interface BudgetCheckResult {
|
|
37
|
+
allowed: boolean;
|
|
38
|
+
reason?: string;
|
|
39
|
+
/** The tier that was matched */
|
|
40
|
+
tier?: string;
|
|
41
|
+
/** Maximum allowed for this transaction */
|
|
42
|
+
maxAllowed?: bigint;
|
|
43
|
+
/** Remaining session budget */
|
|
44
|
+
sessionRemaining?: bigint;
|
|
45
|
+
}
|
|
46
|
+
/** Record of a completed payment for budget tracking */
|
|
47
|
+
interface SpendRecord {
|
|
48
|
+
amount: bigint;
|
|
49
|
+
service: string;
|
|
50
|
+
timestamp: number;
|
|
51
|
+
}
|
|
52
|
+
/** Manages spending limits based on service reputation.
|
|
53
|
+
*
|
|
54
|
+
* Usage:
|
|
55
|
+
* ```ts
|
|
56
|
+
* const budget = new BudgetManager({ maxPerSession: 10_000_000n });
|
|
57
|
+
* const check = budget.checkBudget(amount, serviceReputation);
|
|
58
|
+
* if (!check.allowed) throw new Error(check.reason);
|
|
59
|
+
* // ... make payment ...
|
|
60
|
+
* budget.recordSpend(amount, serviceUrl);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare class BudgetManager {
|
|
64
|
+
private static readonly MAX_HISTORY;
|
|
65
|
+
private readonly _tiers;
|
|
66
|
+
private readonly _maxPerSession;
|
|
67
|
+
private readonly _enforce;
|
|
68
|
+
private readonly _unknownLimit;
|
|
69
|
+
private _sessionSpent;
|
|
70
|
+
private _history;
|
|
71
|
+
/** Promise-based mutex for atomic check-and-spend operations (C-1 fix) */
|
|
72
|
+
private _lock;
|
|
73
|
+
constructor(config?: BudgetConfig);
|
|
74
|
+
/** Acquire exclusive budget access for atomic check-and-spend.
|
|
75
|
+
*
|
|
76
|
+
* Serializes concurrent async operations so that checkBudget + recordSpend
|
|
77
|
+
* cannot be interleaved by parallel payment flows (TOCTOU prevention).
|
|
78
|
+
*
|
|
79
|
+
* Audit #10: Timeout prevents permanent deadlock if fn() never resolves.
|
|
80
|
+
* 120s allows for full smart_pay cycle: discovery + on-chain settlement +
|
|
81
|
+
* UserOp bundling + retries + reputation feedback.
|
|
82
|
+
*
|
|
83
|
+
* @param fn - The async function to execute while holding the lock
|
|
84
|
+
* @returns The return value of fn
|
|
85
|
+
*/
|
|
86
|
+
acquireBudgetLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
87
|
+
/** Check if a payment is within budget.
|
|
88
|
+
*
|
|
89
|
+
* @param amount - Payment amount in token smallest unit
|
|
90
|
+
* @param serviceReputation - Service's reputation score (0-100), or undefined if unknown
|
|
91
|
+
* @returns Budget check result with allowed/denied and reason
|
|
92
|
+
*/
|
|
93
|
+
checkBudget(amount: bigint, serviceReputation?: number): BudgetCheckResult;
|
|
94
|
+
/** Record a completed payment.
|
|
95
|
+
*
|
|
96
|
+
* History is capped at MAX_HISTORY entries (M-1 fix) to prevent unbounded growth.
|
|
97
|
+
*/
|
|
98
|
+
recordSpend(amount: bigint, service: string): void;
|
|
99
|
+
/** Get total spent this session */
|
|
100
|
+
getSessionSpent(): bigint;
|
|
101
|
+
/** Get remaining session budget */
|
|
102
|
+
getRemaining(): bigint;
|
|
103
|
+
/** Get spending history */
|
|
104
|
+
getHistory(): readonly SpendRecord[];
|
|
105
|
+
/** Reset session spending (e.g., for a new session) */
|
|
106
|
+
reset(): void;
|
|
107
|
+
/** Get the per-transaction limit for a given reputation score */
|
|
108
|
+
getLimitForReputation(reputation?: number): bigint;
|
|
109
|
+
private _findTier;
|
|
110
|
+
}
|
|
111
|
+
/** Compute a reputation score (0-100) from on-chain summary data.
|
|
112
|
+
*
|
|
113
|
+
* Converts the raw summaryValue/summaryValueDecimals from the ERC-8004
|
|
114
|
+
* Reputation Registry into a 0-100 integer score suitable for budget tier lookup.
|
|
115
|
+
*/
|
|
116
|
+
export declare function reputationToScore(summaryValue: bigint, summaryValueDecimals: number): number;
|
|
117
|
+
export {};
|
|
118
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/payments/budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,yEAAyE;AACzE,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,EAAE,SAAS,UAAU,EAK5C,CAAC;AAEX,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,4FAA4F;IAC5F,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB;wCACoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;0DACsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,+BAA+B;AAC/B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wDAAwD;AACxD,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAU;IAE7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAqB;IAErC,0EAA0E;IAC1E,OAAO,CAAC,KAAK,CAAoC;gBAErC,MAAM,CAAC,EAAE,YAAY;IAOjC;;;;;;;;;;;OAWG;IACG,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAwB5D;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAsC1E;;;OAGG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAQlD,mCAAmC;IACnC,eAAe,IAAI,MAAM;IAIzB,mCAAmC;IACnC,YAAY,IAAI,MAAM;IAKtB,2BAA2B;IAC3B,UAAU,IAAI,SAAS,WAAW,EAAE;IAIpC,uDAAuD;IACvD,KAAK,IAAI,IAAI;IAKb,iEAAiE;IACjE,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;IAIlD,OAAO,CAAC,SAAS;CAUlB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAQ5F"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/** Reputation-aware budget manager for x402 payments.
|
|
2
|
+
*
|
|
3
|
+
* Provides per-transaction and per-session spending limits that scale
|
|
4
|
+
* with the target service's on-chain reputation. Higher reputation =
|
|
5
|
+
* higher trust = higher allowed spending.
|
|
6
|
+
*
|
|
7
|
+
* Budget tiers are configurable and layer ON TOP of the Guardian Module's
|
|
8
|
+
* on-chain dailySpendLimitUSD (which is the hard ceiling that can't be bypassed).
|
|
9
|
+
* This is a client-side soft limit for convenience and safety.
|
|
10
|
+
*/
|
|
11
|
+
import { AzethError } from '@azeth/common';
|
|
12
|
+
/** Default budget tiers (ordered highest reputation first) */
|
|
13
|
+
export const DEFAULT_BUDGET_TIERS = [
|
|
14
|
+
{ minReputation: 90, maxPerTransaction: 5000000n, label: 'diamond' }, // $5.00 USDC
|
|
15
|
+
{ minReputation: 70, maxPerTransaction: 1000000n, label: 'gold' }, // $1.00 USDC
|
|
16
|
+
{ minReputation: 50, maxPerTransaction: 500000n, label: 'silver' }, // $0.50 USDC
|
|
17
|
+
{ minReputation: 0, maxPerTransaction: 100000n, label: 'bronze' }, // $0.10 USDC
|
|
18
|
+
];
|
|
19
|
+
/** Manages spending limits based on service reputation.
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* ```ts
|
|
23
|
+
* const budget = new BudgetManager({ maxPerSession: 10_000_000n });
|
|
24
|
+
* const check = budget.checkBudget(amount, serviceReputation);
|
|
25
|
+
* if (!check.allowed) throw new Error(check.reason);
|
|
26
|
+
* // ... make payment ...
|
|
27
|
+
* budget.recordSpend(amount, serviceUrl);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class BudgetManager {
|
|
31
|
+
static MAX_HISTORY = 10_000;
|
|
32
|
+
_tiers;
|
|
33
|
+
_maxPerSession;
|
|
34
|
+
_enforce;
|
|
35
|
+
_unknownLimit;
|
|
36
|
+
_sessionSpent = 0n;
|
|
37
|
+
_history = [];
|
|
38
|
+
/** Promise-based mutex for atomic check-and-spend operations (C-1 fix) */
|
|
39
|
+
_lock = Promise.resolve();
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this._tiers = config?.tiers ?? DEFAULT_BUDGET_TIERS;
|
|
42
|
+
this._maxPerSession = config?.maxPerSession ?? 10000000n;
|
|
43
|
+
this._enforce = config?.enforce ?? true;
|
|
44
|
+
this._unknownLimit = config?.unknownReputationLimit ?? 100000n; // $0.10 USDC
|
|
45
|
+
}
|
|
46
|
+
/** Acquire exclusive budget access for atomic check-and-spend.
|
|
47
|
+
*
|
|
48
|
+
* Serializes concurrent async operations so that checkBudget + recordSpend
|
|
49
|
+
* cannot be interleaved by parallel payment flows (TOCTOU prevention).
|
|
50
|
+
*
|
|
51
|
+
* Audit #10: Timeout prevents permanent deadlock if fn() never resolves.
|
|
52
|
+
* 120s allows for full smart_pay cycle: discovery + on-chain settlement +
|
|
53
|
+
* UserOp bundling + retries + reputation feedback.
|
|
54
|
+
*
|
|
55
|
+
* @param fn - The async function to execute while holding the lock
|
|
56
|
+
* @returns The return value of fn
|
|
57
|
+
*/
|
|
58
|
+
async acquireBudgetLock(fn) {
|
|
59
|
+
const LOCK_TIMEOUT_MS = 120_000;
|
|
60
|
+
let release;
|
|
61
|
+
const next = new Promise(resolve => { release = resolve; });
|
|
62
|
+
const prev = this._lock;
|
|
63
|
+
this._lock = next;
|
|
64
|
+
let timer;
|
|
65
|
+
const timeout = new Promise((_, reject) => {
|
|
66
|
+
timer = setTimeout(() => reject(new AzethError('Budget lock timeout', 'NETWORK_ERROR')), LOCK_TIMEOUT_MS);
|
|
67
|
+
});
|
|
68
|
+
try {
|
|
69
|
+
await Promise.race([prev, timeout]);
|
|
70
|
+
return await Promise.race([fn(), timeout]);
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
if (timer)
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
release();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Check if a payment is within budget.
|
|
79
|
+
*
|
|
80
|
+
* @param amount - Payment amount in token smallest unit
|
|
81
|
+
* @param serviceReputation - Service's reputation score (0-100), or undefined if unknown
|
|
82
|
+
* @returns Budget check result with allowed/denied and reason
|
|
83
|
+
*/
|
|
84
|
+
checkBudget(amount, serviceReputation) {
|
|
85
|
+
const sessionRemaining = this._maxPerSession - this._sessionSpent;
|
|
86
|
+
// Check session limit
|
|
87
|
+
if (amount > sessionRemaining) {
|
|
88
|
+
const result = {
|
|
89
|
+
allowed: false,
|
|
90
|
+
reason: `Session budget exceeded: ${amount} requested, ${sessionRemaining} remaining of ${this._maxPerSession} total`,
|
|
91
|
+
sessionRemaining,
|
|
92
|
+
};
|
|
93
|
+
return this._enforce ? result : { ...result, allowed: true };
|
|
94
|
+
}
|
|
95
|
+
// Find matching tier
|
|
96
|
+
const tier = this._findTier(serviceReputation);
|
|
97
|
+
const maxAllowed = tier?.maxPerTransaction ?? this._unknownLimit;
|
|
98
|
+
const tierLabel = tier?.label ?? 'unknown';
|
|
99
|
+
// Check per-transaction limit
|
|
100
|
+
if (amount > maxAllowed) {
|
|
101
|
+
const result = {
|
|
102
|
+
allowed: false,
|
|
103
|
+
reason: `Amount ${amount} exceeds ${tierLabel} tier limit of ${maxAllowed} (reputation: ${serviceReputation ?? 'unknown'})`,
|
|
104
|
+
tier: tierLabel,
|
|
105
|
+
maxAllowed,
|
|
106
|
+
sessionRemaining,
|
|
107
|
+
};
|
|
108
|
+
return this._enforce ? result : { ...result, allowed: true };
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
allowed: true,
|
|
112
|
+
tier: tierLabel,
|
|
113
|
+
maxAllowed,
|
|
114
|
+
sessionRemaining,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/** Record a completed payment.
|
|
118
|
+
*
|
|
119
|
+
* History is capped at MAX_HISTORY entries (M-1 fix) to prevent unbounded growth.
|
|
120
|
+
*/
|
|
121
|
+
recordSpend(amount, service) {
|
|
122
|
+
this._sessionSpent += amount;
|
|
123
|
+
this._history.push({ amount, service, timestamp: Date.now() });
|
|
124
|
+
if (this._history.length > BudgetManager.MAX_HISTORY) {
|
|
125
|
+
this._history = this._history.slice(-BudgetManager.MAX_HISTORY);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** Get total spent this session */
|
|
129
|
+
getSessionSpent() {
|
|
130
|
+
return this._sessionSpent;
|
|
131
|
+
}
|
|
132
|
+
/** Get remaining session budget */
|
|
133
|
+
getRemaining() {
|
|
134
|
+
const remaining = this._maxPerSession - this._sessionSpent;
|
|
135
|
+
return remaining > 0n ? remaining : 0n;
|
|
136
|
+
}
|
|
137
|
+
/** Get spending history */
|
|
138
|
+
getHistory() {
|
|
139
|
+
return this._history;
|
|
140
|
+
}
|
|
141
|
+
/** Reset session spending (e.g., for a new session) */
|
|
142
|
+
reset() {
|
|
143
|
+
this._sessionSpent = 0n;
|
|
144
|
+
this._history = [];
|
|
145
|
+
}
|
|
146
|
+
/** Get the per-transaction limit for a given reputation score */
|
|
147
|
+
getLimitForReputation(reputation) {
|
|
148
|
+
return this._findTier(reputation)?.maxPerTransaction ?? this._unknownLimit;
|
|
149
|
+
}
|
|
150
|
+
_findTier(reputation) {
|
|
151
|
+
if (reputation === undefined || reputation === null)
|
|
152
|
+
return undefined;
|
|
153
|
+
// Tiers are sorted by minReputation descending — first match wins
|
|
154
|
+
for (const tier of this._tiers) {
|
|
155
|
+
if (reputation >= tier.minReputation) {
|
|
156
|
+
return tier;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** Compute a reputation score (0-100) from on-chain summary data.
|
|
163
|
+
*
|
|
164
|
+
* Converts the raw summaryValue/summaryValueDecimals from the ERC-8004
|
|
165
|
+
* Reputation Registry into a 0-100 integer score suitable for budget tier lookup.
|
|
166
|
+
*/
|
|
167
|
+
export function reputationToScore(summaryValue, summaryValueDecimals) {
|
|
168
|
+
if (summaryValueDecimals === 0) {
|
|
169
|
+
const val = Number(summaryValue);
|
|
170
|
+
return Math.max(0, Math.min(100, val));
|
|
171
|
+
}
|
|
172
|
+
const divisor = 10n ** BigInt(summaryValueDecimals);
|
|
173
|
+
const score = Number(summaryValue) / Number(divisor);
|
|
174
|
+
return Math.max(0, Math.min(100, Math.round(score)));
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/payments/budget.ts"],"names":[],"mappings":"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"}
|