agentwallet-sdk 3.0.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -10
- package/dist/fiat/index.d.ts +10 -0
- package/dist/fiat/index.d.ts.map +1 -0
- package/dist/fiat/index.js +9 -0
- package/dist/fiat/index.js.map +1 -0
- package/dist/fiat/onramp.d.ts +101 -0
- package/dist/fiat/onramp.d.ts.map +1 -0
- package/dist/fiat/onramp.js +155 -0
- package/dist/fiat/onramp.js.map +1 -0
- package/dist/fiat/providers/index.d.ts +16 -0
- package/dist/fiat/providers/index.d.ts.map +1 -0
- package/dist/fiat/providers/index.js +30 -0
- package/dist/fiat/providers/index.js.map +1 -0
- package/dist/fiat/providers/moonpay.d.ts +22 -0
- package/dist/fiat/providers/moonpay.d.ts.map +1 -0
- package/dist/fiat/providers/moonpay.js +107 -0
- package/dist/fiat/providers/moonpay.js.map +1 -0
- package/dist/fiat/providers/stripe.d.ts +26 -0
- package/dist/fiat/providers/stripe.d.ts.map +1 -0
- package/dist/fiat/providers/stripe.js +135 -0
- package/dist/fiat/providers/stripe.js.map +1 -0
- package/dist/fiat/providers/transak.d.ts +26 -0
- package/dist/fiat/providers/transak.d.ts.map +1 -0
- package/dist/fiat/providers/transak.js +119 -0
- package/dist/fiat/providers/transak.js.map +1 -0
- package/dist/fiat/types.d.ts +106 -0
- package/dist/fiat/types.d.ts.map +1 -0
- package/dist/fiat/types.js +13 -0
- package/dist/fiat/types.js.map +1 -0
- package/dist/flash/executor.d.ts +119 -0
- package/dist/flash/executor.d.ts.map +1 -0
- package/dist/flash/executor.js +195 -0
- package/dist/flash/executor.js.map +1 -0
- package/dist/flash/index.d.ts +28 -0
- package/dist/flash/index.d.ts.map +1 -0
- package/dist/flash/index.js +25 -0
- package/dist/flash/index.js.map +1 -0
- package/dist/flash/scanner.d.ts +133 -0
- package/dist/flash/scanner.d.ts.map +1 -0
- package/dist/flash/scanner.js +212 -0
- package/dist/flash/scanner.js.map +1 -0
- package/dist/flash/types.d.ts +136 -0
- package/dist/flash/types.d.ts.map +1 -0
- package/dist/flash/types.js +23 -0
- package/dist/flash/types.js.map +1 -0
- package/dist/gas/index.d.ts +4 -0
- package/dist/gas/index.d.ts.map +1 -0
- package/dist/gas/index.js +3 -0
- package/dist/gas/index.js.map +1 -0
- package/dist/gas/sponsor.d.ts +70 -0
- package/dist/gas/sponsor.d.ts.map +1 -0
- package/dist/gas/sponsor.js +193 -0
- package/dist/gas/sponsor.js.map +1 -0
- package/dist/gas/types.d.ts +76 -0
- package/dist/gas/types.d.ts.map +1 -0
- package/dist/gas/types.js +21 -0
- package/dist/gas/types.js.map +1 -0
- package/dist/index.d.ts +84 -62
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/mev/index.d.ts +4 -0
- package/dist/mev/index.d.ts.map +1 -0
- package/dist/mev/index.js +4 -0
- package/dist/mev/index.js.map +1 -0
- package/dist/mev/protection.d.ts +54 -0
- package/dist/mev/protection.d.ts.map +1 -0
- package/dist/mev/protection.js +185 -0
- package/dist/mev/protection.js.map +1 -0
- package/dist/mev/risk.d.ts +19 -0
- package/dist/mev/risk.d.ts.map +1 -0
- package/dist/mev/risk.js +95 -0
- package/dist/mev/risk.js.map +1 -0
- package/dist/mev/types.d.ts +49 -0
- package/dist/mev/types.d.ts.map +1 -0
- package/dist/mev/types.js +2 -0
- package/dist/mev/types.js.map +1 -0
- package/dist/settlement/index.d.ts +4 -0
- package/dist/settlement/index.d.ts.map +1 -0
- package/dist/settlement/index.js +3 -0
- package/dist/settlement/index.js.map +1 -0
- package/dist/settlement/types.d.ts +66 -0
- package/dist/settlement/types.d.ts.map +1 -0
- package/dist/settlement/types.js +37 -0
- package/dist/settlement/types.js.map +1 -0
- package/dist/settlement/verifier.d.ts +75 -0
- package/dist/settlement/verifier.d.ts.map +1 -0
- package/dist/settlement/verifier.js +354 -0
- package/dist/settlement/verifier.js.map +1 -0
- package/dist/solver/adapter.d.ts +47 -0
- package/dist/solver/adapter.d.ts.map +1 -0
- package/dist/solver/adapter.js +138 -0
- package/dist/solver/adapter.js.map +1 -0
- package/dist/solver/analyzer.d.ts +48 -0
- package/dist/solver/analyzer.d.ts.map +1 -0
- package/dist/solver/analyzer.js +89 -0
- package/dist/solver/analyzer.js.map +1 -0
- package/dist/solver/builder.d.ts +31 -0
- package/dist/solver/builder.d.ts.map +1 -0
- package/dist/solver/builder.js +60 -0
- package/dist/solver/builder.js.map +1 -0
- package/dist/solver/index.d.ts +22 -0
- package/dist/solver/index.d.ts.map +1 -0
- package/dist/solver/index.js +21 -0
- package/dist/solver/index.js.map +1 -0
- package/dist/solver/types.d.ts +115 -0
- package/dist/solver/types.d.ts.map +1 -0
- package/dist/solver/types.js +10 -0
- package/dist/solver/types.js.map +1 -0
- package/dist/swap/index.d.ts +1 -0
- package/dist/swap/index.d.ts.map +1 -1
- package/dist/swap/index.js +2 -0
- package/dist/swap/index.js.map +1 -1
- package/dist/swap/router/cache.d.ts +13 -0
- package/dist/swap/router/cache.d.ts.map +1 -0
- package/dist/swap/router/cache.js +30 -0
- package/dist/swap/router/cache.js.map +1 -0
- package/dist/swap/router/flashbots.d.ts +10 -0
- package/dist/swap/router/flashbots.d.ts.map +1 -0
- package/dist/swap/router/flashbots.js +43 -0
- package/dist/swap/router/flashbots.js.map +1 -0
- package/dist/swap/router/health.d.ts +17 -0
- package/dist/swap/router/health.d.ts.map +1 -0
- package/dist/swap/router/health.js +38 -0
- package/dist/swap/router/health.js.map +1 -0
- package/dist/swap/router/index.d.ts +10 -0
- package/dist/swap/router/index.d.ts.map +1 -0
- package/dist/swap/router/index.js +10 -0
- package/dist/swap/router/index.js.map +1 -0
- package/dist/swap/router/providers/cowswap.d.ts +11 -0
- package/dist/swap/router/providers/cowswap.d.ts.map +1 -0
- package/dist/swap/router/providers/cowswap.js +79 -0
- package/dist/swap/router/providers/cowswap.js.map +1 -0
- package/dist/swap/router/providers/index.d.ts +20 -0
- package/dist/swap/router/providers/index.d.ts.map +1 -0
- package/dist/swap/router/providers/index.js +32 -0
- package/dist/swap/router/providers/index.js.map +1 -0
- package/dist/swap/router/providers/jupiter.d.ts +12 -0
- package/dist/swap/router/providers/jupiter.d.ts.map +1 -0
- package/dist/swap/router/providers/jupiter.js +73 -0
- package/dist/swap/router/providers/jupiter.js.map +1 -0
- package/dist/swap/router/providers/lifi.d.ts +11 -0
- package/dist/swap/router/providers/lifi.d.ts.map +1 -0
- package/dist/swap/router/providers/lifi.js +123 -0
- package/dist/swap/router/providers/lifi.js.map +1 -0
- package/dist/swap/router/providers/oneinch.d.ts +13 -0
- package/dist/swap/router/providers/oneinch.d.ts.map +1 -0
- package/dist/swap/router/providers/oneinch.js +71 -0
- package/dist/swap/router/providers/oneinch.js.map +1 -0
- package/dist/swap/router/providers/paraswap.d.ts +11 -0
- package/dist/swap/router/providers/paraswap.d.ts.map +1 -0
- package/dist/swap/router/providers/paraswap.js +73 -0
- package/dist/swap/router/providers/paraswap.js.map +1 -0
- package/dist/swap/router/providers/uniswap.d.ts +31 -0
- package/dist/swap/router/providers/uniswap.d.ts.map +1 -0
- package/dist/swap/router/providers/uniswap.js +116 -0
- package/dist/swap/router/providers/uniswap.js.map +1 -0
- package/dist/swap/router/providers/zerox.d.ts +13 -0
- package/dist/swap/router/providers/zerox.d.ts.map +1 -0
- package/dist/swap/router/providers/zerox.js +94 -0
- package/dist/swap/router/providers/zerox.js.map +1 -0
- package/dist/swap/router/router.d.ts +86 -0
- package/dist/swap/router/router.d.ts.map +1 -0
- package/dist/swap/router/router.js +224 -0
- package/dist/swap/router/router.js.map +1 -0
- package/dist/swap/router/rsi/engine.d.ts +60 -0
- package/dist/swap/router/rsi/engine.d.ts.map +1 -0
- package/dist/swap/router/rsi/engine.js +483 -0
- package/dist/swap/router/rsi/engine.js.map +1 -0
- package/dist/swap/router/rsi/index.d.ts +3 -0
- package/dist/swap/router/rsi/index.d.ts.map +1 -0
- package/dist/swap/router/rsi/index.js +3 -0
- package/dist/swap/router/rsi/index.js.map +1 -0
- package/dist/swap/router/rsi/types.d.ts +106 -0
- package/dist/swap/router/rsi/types.d.ts.map +1 -0
- package/dist/swap/router/rsi/types.js +3 -0
- package/dist/swap/router/rsi/types.js.map +1 -0
- package/dist/swap/router/types.d.ts +120 -0
- package/dist/swap/router/types.d.ts.map +1 -0
- package/dist/swap/router/types.js +16 -0
- package/dist/swap/router/types.js.map +1 -0
- package/dist/tax/engine.d.ts +131 -0
- package/dist/tax/engine.d.ts.map +1 -0
- package/dist/tax/engine.js +307 -0
- package/dist/tax/engine.js.map +1 -0
- package/dist/tax/index.d.ts +9 -0
- package/dist/tax/index.d.ts.map +1 -0
- package/dist/tax/index.js +8 -0
- package/dist/tax/index.js.map +1 -0
- package/dist/tax/lots.d.ts +60 -0
- package/dist/tax/lots.d.ts.map +1 -0
- package/dist/tax/lots.js +129 -0
- package/dist/tax/lots.js.map +1 -0
- package/dist/tax/types.d.ts +113 -0
- package/dist/tax/types.d.ts.map +1 -0
- package/dist/tax/types.js +18 -0
- package/dist/tax/types.js.map +1 -0
- package/dist/yield/index.d.ts +26 -0
- package/dist/yield/index.d.ts.map +1 -0
- package/dist/yield/index.js +25 -0
- package/dist/yield/index.js.map +1 -0
- package/dist/yield/rates.d.ts +114 -0
- package/dist/yield/rates.d.ts.map +1 -0
- package/dist/yield/rates.js +351 -0
- package/dist/yield/rates.js.map +1 -0
- package/dist/yield/types.d.ts +134 -0
- package/dist/yield/types.d.ts.map +1 -0
- package/dist/yield/types.js +24 -0
- package/dist/yield/types.js.map +1 -0
- package/dist/yield/vault.d.ts +112 -0
- package/dist/yield/vault.d.ts.map +1 -0
- package/dist/yield/vault.js +264 -0
- package/dist/yield/vault.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
// SettlementVerifier — On-chain settlement verification for agent transactions
|
|
2
|
+
//
|
|
3
|
+
// Verifies that bridge transfers, x402 payments, and regular transactions actually
|
|
4
|
+
// settled on-chain. Uses Alchemy RPC for supported chains, public RPCs as fallback.
|
|
5
|
+
//
|
|
6
|
+
// Supported verification types:
|
|
7
|
+
// - EVM transaction receipts (any EVM chain)
|
|
8
|
+
// - Solana transaction confirmation
|
|
9
|
+
// - CCTP bridge transfers end-to-end (source burn + attestation + dest mint)
|
|
10
|
+
// - x402 ERC20 payment verification (payee + amount from event logs)
|
|
11
|
+
import { SETTLEMENT_ALCHEMY_NETWORKS, SETTLEMENT_PUBLIC_RPCS, CIRCLE_ATTESTATION_API, ERC20_TRANSFER_TOPIC, SOLANA_RPC_URL, } from './types.js';
|
|
12
|
+
export class SettlementVerifier {
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
this.alchemyApiKey = config.alchemyApiKey;
|
|
15
|
+
}
|
|
16
|
+
// ─── EVM Transaction Verification ───
|
|
17
|
+
/**
|
|
18
|
+
* Verify that an EVM transaction settled on-chain.
|
|
19
|
+
*
|
|
20
|
+
* Uses Alchemy RPC if apiKey is configured and chain is supported,
|
|
21
|
+
* otherwise falls back to public RPCs.
|
|
22
|
+
*
|
|
23
|
+
* @param params.chain - SDK chain name (e.g. 'base', 'arbitrum')
|
|
24
|
+
* @param params.txHash - Transaction hash to verify
|
|
25
|
+
* @param params.confirmations - Minimum confirmations required (default: 1)
|
|
26
|
+
*/
|
|
27
|
+
async verifyEvmTransaction(params) {
|
|
28
|
+
const requiredConfirmations = params.confirmations ?? 1;
|
|
29
|
+
const rpcUrl = this._getRpcUrl(params.chain);
|
|
30
|
+
try {
|
|
31
|
+
// Get receipt
|
|
32
|
+
const receiptResp = await this._evmRpc(rpcUrl, 'eth_getTransactionReceipt', [params.txHash]);
|
|
33
|
+
const receipt = receiptResp.result;
|
|
34
|
+
if (!receipt) {
|
|
35
|
+
// Not mined yet — check if it's in the mempool
|
|
36
|
+
return {
|
|
37
|
+
status: 'pending',
|
|
38
|
+
txHash: params.txHash,
|
|
39
|
+
blockNumber: 0n,
|
|
40
|
+
confirmations: 0,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Get current block number to compute confirmations
|
|
44
|
+
const blockResp = await this._evmRpc(rpcUrl, 'eth_blockNumber', []);
|
|
45
|
+
const currentBlock = BigInt(blockResp.result);
|
|
46
|
+
const txBlock = BigInt(receipt.blockNumber);
|
|
47
|
+
const confirmationCount = Number(currentBlock - txBlock) + 1;
|
|
48
|
+
const success = receipt.status === '0x1';
|
|
49
|
+
if (!success) {
|
|
50
|
+
return {
|
|
51
|
+
status: 'failed',
|
|
52
|
+
txHash: params.txHash,
|
|
53
|
+
blockNumber: txBlock,
|
|
54
|
+
confirmations: confirmationCount,
|
|
55
|
+
gasUsed: BigInt(receipt.gasUsed),
|
|
56
|
+
success: false,
|
|
57
|
+
error: 'Transaction reverted (status=0)',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (confirmationCount < requiredConfirmations) {
|
|
61
|
+
return {
|
|
62
|
+
status: 'pending',
|
|
63
|
+
txHash: params.txHash,
|
|
64
|
+
blockNumber: txBlock,
|
|
65
|
+
confirmations: confirmationCount,
|
|
66
|
+
gasUsed: BigInt(receipt.gasUsed),
|
|
67
|
+
success: true,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
status: 'confirmed',
|
|
72
|
+
txHash: params.txHash,
|
|
73
|
+
blockNumber: txBlock,
|
|
74
|
+
confirmations: confirmationCount,
|
|
75
|
+
gasUsed: BigInt(receipt.gasUsed),
|
|
76
|
+
success: true,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
return {
|
|
81
|
+
status: 'not_found',
|
|
82
|
+
txHash: params.txHash,
|
|
83
|
+
blockNumber: 0n,
|
|
84
|
+
confirmations: 0,
|
|
85
|
+
error: err instanceof Error ? err.message : String(err),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// ─── Solana Transaction Verification ───
|
|
90
|
+
/**
|
|
91
|
+
* Verify that a Solana transaction settled on-chain.
|
|
92
|
+
*
|
|
93
|
+
* @param params.signature - Solana transaction signature (base58)
|
|
94
|
+
* @param params.commitment - Commitment level: 'confirmed' or 'finalized' (default: 'confirmed')
|
|
95
|
+
*/
|
|
96
|
+
async verifySolanaTransaction(params) {
|
|
97
|
+
const commitment = params.commitment ?? 'confirmed';
|
|
98
|
+
try {
|
|
99
|
+
const resp = await this._solanaRpc('getTransaction', [
|
|
100
|
+
params.signature,
|
|
101
|
+
{ encoding: 'json', commitment, maxSupportedTransactionVersion: 0 },
|
|
102
|
+
]);
|
|
103
|
+
const tx = resp.result;
|
|
104
|
+
if (!tx) {
|
|
105
|
+
return {
|
|
106
|
+
status: 'not_found',
|
|
107
|
+
txHash: params.signature,
|
|
108
|
+
blockNumber: 0n,
|
|
109
|
+
confirmations: 0,
|
|
110
|
+
error: 'Transaction not found or not yet confirmed',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const success = tx.meta.err === null;
|
|
114
|
+
// Get current slot for confirmation count approximation
|
|
115
|
+
const slotResp = await this._solanaRpc('getSlot', [{ commitment }]);
|
|
116
|
+
const currentSlot = slotResp.result;
|
|
117
|
+
const confirmations = currentSlot - tx.slot;
|
|
118
|
+
return {
|
|
119
|
+
status: success ? 'confirmed' : 'failed',
|
|
120
|
+
txHash: params.signature,
|
|
121
|
+
blockNumber: BigInt(tx.slot),
|
|
122
|
+
confirmations,
|
|
123
|
+
success,
|
|
124
|
+
error: !success ? `Solana transaction error: ${JSON.stringify(tx.meta.err)}` : undefined,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
return {
|
|
129
|
+
status: 'not_found',
|
|
130
|
+
txHash: params.signature,
|
|
131
|
+
blockNumber: 0n,
|
|
132
|
+
confirmations: 0,
|
|
133
|
+
error: err instanceof Error ? err.message : String(err),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ─── CCTP Bridge Settlement ───
|
|
138
|
+
/**
|
|
139
|
+
* Verify a CCTP bridge transfer settled end-to-end:
|
|
140
|
+
* 1. Verifies source chain burn tx succeeded
|
|
141
|
+
* 2. Checks Circle attestation API for the message hash
|
|
142
|
+
* 3. Attempts to find destination mint tx (if attestation is complete)
|
|
143
|
+
*
|
|
144
|
+
* @param params.sourceTxHash - Burn tx hash on source chain
|
|
145
|
+
* @param params.sourceChain - Source chain name (e.g. 'solana', 'base')
|
|
146
|
+
* @param params.destinationChain - Destination chain name
|
|
147
|
+
* @param params.expectedAmount - Expected USDC amount in base units (6 decimals)
|
|
148
|
+
*/
|
|
149
|
+
async verifyBridgeSettlement(params) {
|
|
150
|
+
// Step 1: verify source tx
|
|
151
|
+
let sourceTx;
|
|
152
|
+
if (params.sourceChain === 'solana') {
|
|
153
|
+
sourceTx = await this.verifySolanaTransaction({ signature: params.sourceTxHash });
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
sourceTx = await this.verifyEvmTransaction({
|
|
157
|
+
chain: params.sourceChain,
|
|
158
|
+
txHash: params.sourceTxHash,
|
|
159
|
+
confirmations: params.sourceChain === 'ethereum' ? 65 : 1, // Ethereum needs more for CCTP
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
if (sourceTx.status === 'failed') {
|
|
163
|
+
return {
|
|
164
|
+
status: 'source_failed',
|
|
165
|
+
sourceTx,
|
|
166
|
+
error: 'Source chain burn transaction failed or reverted',
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (sourceTx.status === 'pending' || sourceTx.status === 'not_found') {
|
|
170
|
+
return {
|
|
171
|
+
status: 'source_pending',
|
|
172
|
+
sourceTx,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Step 2: check Circle attestation API
|
|
176
|
+
let attestationStatus;
|
|
177
|
+
try {
|
|
178
|
+
attestationStatus = await this._checkCircleAttestation(params.sourceTxHash);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
attestationStatus = 'error';
|
|
182
|
+
}
|
|
183
|
+
if (attestationStatus === 'pending_confirmations') {
|
|
184
|
+
return {
|
|
185
|
+
status: 'source_confirmed_awaiting_attestation',
|
|
186
|
+
sourceTx,
|
|
187
|
+
attestationStatus,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
if (attestationStatus === 'complete') {
|
|
191
|
+
// Step 3: Try to find the destination mint tx
|
|
192
|
+
// For now, we report attestation complete and let the caller poll for mint
|
|
193
|
+
// A full implementation would index destination chain events
|
|
194
|
+
return {
|
|
195
|
+
status: 'attestation_complete_awaiting_mint',
|
|
196
|
+
sourceTx,
|
|
197
|
+
attestationStatus,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// If we can verify source + attestation but not destination, return partial
|
|
201
|
+
return {
|
|
202
|
+
status: 'error',
|
|
203
|
+
sourceTx,
|
|
204
|
+
attestationStatus,
|
|
205
|
+
error: 'Could not determine attestation status',
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// ─── x402 Payment Verification ───
|
|
209
|
+
/**
|
|
210
|
+
* Verify an x402 payment settled on-chain by inspecting ERC20 Transfer event logs.
|
|
211
|
+
*
|
|
212
|
+
* Checks that the tx:
|
|
213
|
+
* - Succeeded (status=1)
|
|
214
|
+
* - Emitted an ERC20 Transfer event to expectedPayee
|
|
215
|
+
* - The transferred amount matches expectedAmount
|
|
216
|
+
*
|
|
217
|
+
* @param params.chain - EVM chain name
|
|
218
|
+
* @param params.txHash - Transaction hash
|
|
219
|
+
* @param params.expectedPayee - Address that should have received the payment
|
|
220
|
+
* @param params.expectedAmount - Amount in USDC base units (6 decimals)
|
|
221
|
+
*/
|
|
222
|
+
async verifyX402Payment(params) {
|
|
223
|
+
const rpcUrl = this._getRpcUrl(params.chain);
|
|
224
|
+
try {
|
|
225
|
+
const receiptResp = await this._evmRpc(rpcUrl, 'eth_getTransactionReceipt', [params.txHash]);
|
|
226
|
+
const receipt = receiptResp.result;
|
|
227
|
+
if (!receipt) {
|
|
228
|
+
return {
|
|
229
|
+
status: 'pending',
|
|
230
|
+
txHash: params.txHash,
|
|
231
|
+
payeeVerified: false,
|
|
232
|
+
amountVerified: false,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
if (receipt.status !== '0x1') {
|
|
236
|
+
return {
|
|
237
|
+
status: 'failed',
|
|
238
|
+
txHash: params.txHash,
|
|
239
|
+
payeeVerified: false,
|
|
240
|
+
amountVerified: false,
|
|
241
|
+
error: 'Transaction reverted',
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
// Find ERC20 Transfer events — topic[0] = Transfer sig, topic[2] = to address
|
|
245
|
+
const expectedPayeeHex = params.expectedPayee.toLowerCase().replace('0x', '').padStart(64, '0');
|
|
246
|
+
const transferLog = receipt.logs.find((log) => {
|
|
247
|
+
return (log.topics[0]?.toLowerCase() === ERC20_TRANSFER_TOPIC &&
|
|
248
|
+
log.topics[2]?.toLowerCase() === `0x${expectedPayeeHex}`);
|
|
249
|
+
});
|
|
250
|
+
if (!transferLog) {
|
|
251
|
+
return {
|
|
252
|
+
status: 'confirmed',
|
|
253
|
+
txHash: params.txHash,
|
|
254
|
+
payeeVerified: false,
|
|
255
|
+
amountVerified: false,
|
|
256
|
+
error: `No ERC20 Transfer found to payee ${params.expectedPayee}`,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
// Decode amount from log.data (ABI-encoded uint256)
|
|
260
|
+
const actualAmount = BigInt(transferLog.data);
|
|
261
|
+
const amountVerified = actualAmount === params.expectedAmount;
|
|
262
|
+
const actualPayee = `0x${transferLog.topics[2]?.slice(-40)}`;
|
|
263
|
+
const tokenAddress = transferLog.address;
|
|
264
|
+
return {
|
|
265
|
+
status: 'confirmed',
|
|
266
|
+
txHash: params.txHash,
|
|
267
|
+
payeeVerified: true,
|
|
268
|
+
amountVerified,
|
|
269
|
+
actualAmount,
|
|
270
|
+
actualPayee,
|
|
271
|
+
tokenAddress,
|
|
272
|
+
error: amountVerified
|
|
273
|
+
? undefined
|
|
274
|
+
: `Amount mismatch: expected ${params.expectedAmount}, got ${actualAmount}`,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
return {
|
|
279
|
+
status: 'not_found',
|
|
280
|
+
txHash: params.txHash,
|
|
281
|
+
payeeVerified: false,
|
|
282
|
+
amountVerified: false,
|
|
283
|
+
error: err instanceof Error ? err.message : String(err),
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// ─── Internal Helpers ───
|
|
288
|
+
/** Get the RPC URL for a chain, preferring Alchemy over public RPCs */
|
|
289
|
+
_getRpcUrl(chain) {
|
|
290
|
+
if (this.alchemyApiKey && chain in SETTLEMENT_ALCHEMY_NETWORKS) {
|
|
291
|
+
const slug = SETTLEMENT_ALCHEMY_NETWORKS[chain];
|
|
292
|
+
return `https://${slug}.g.alchemy.com/v2/${this.alchemyApiKey}`;
|
|
293
|
+
}
|
|
294
|
+
const publicRpc = SETTLEMENT_PUBLIC_RPCS[chain];
|
|
295
|
+
if (!publicRpc) {
|
|
296
|
+
throw new Error(`No RPC URL available for chain "${chain}"`);
|
|
297
|
+
}
|
|
298
|
+
return publicRpc;
|
|
299
|
+
}
|
|
300
|
+
/** Make an EVM JSON-RPC call */
|
|
301
|
+
async _evmRpc(url, method, params) {
|
|
302
|
+
const resp = await fetch(url, {
|
|
303
|
+
method: 'POST',
|
|
304
|
+
headers: { 'Content-Type': 'application/json' },
|
|
305
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
|
|
306
|
+
});
|
|
307
|
+
if (!resp.ok) {
|
|
308
|
+
throw new Error(`EVM RPC error: HTTP ${resp.status}`);
|
|
309
|
+
}
|
|
310
|
+
const json = (await resp.json());
|
|
311
|
+
if (json.error)
|
|
312
|
+
throw new Error(`EVM RPC error: ${json.error.message}`);
|
|
313
|
+
return json;
|
|
314
|
+
}
|
|
315
|
+
/** Make a Solana JSON-RPC call */
|
|
316
|
+
async _solanaRpc(method, params) {
|
|
317
|
+
const resp = await fetch(SOLANA_RPC_URL, {
|
|
318
|
+
method: 'POST',
|
|
319
|
+
headers: { 'Content-Type': 'application/json' },
|
|
320
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
|
|
321
|
+
});
|
|
322
|
+
if (!resp.ok) {
|
|
323
|
+
throw new Error(`Solana RPC error: HTTP ${resp.status}`);
|
|
324
|
+
}
|
|
325
|
+
const json = (await resp.json());
|
|
326
|
+
if (json.error)
|
|
327
|
+
throw new Error(`Solana RPC error: ${json.error.message}`);
|
|
328
|
+
return json;
|
|
329
|
+
}
|
|
330
|
+
/** Check Circle attestation API for a CCTP burn message */
|
|
331
|
+
async _checkCircleAttestation(burnTxHash) {
|
|
332
|
+
// Circle attestation API: GET /attestations/{messageHash}
|
|
333
|
+
// For CCTP, the messageHash is derived from the MessageSent event in the burn tx.
|
|
334
|
+
// Since we don't have the full event parsing here, we query by tx hash pattern.
|
|
335
|
+
// In production, callers should provide the message hash from the burn tx receipt.
|
|
336
|
+
const url = `${CIRCLE_ATTESTATION_API}/${burnTxHash}`;
|
|
337
|
+
const resp = await fetch(url, {
|
|
338
|
+
headers: { Accept: 'application/json' },
|
|
339
|
+
});
|
|
340
|
+
if (resp.status === 404) {
|
|
341
|
+
return 'pending_confirmations';
|
|
342
|
+
}
|
|
343
|
+
if (!resp.ok) {
|
|
344
|
+
return 'error';
|
|
345
|
+
}
|
|
346
|
+
const json = (await resp.json());
|
|
347
|
+
if (json.status === 'complete')
|
|
348
|
+
return 'complete';
|
|
349
|
+
if (json.status === 'pending_confirmations')
|
|
350
|
+
return 'pending_confirmations';
|
|
351
|
+
return 'error';
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
//# sourceMappingURL=verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../src/settlement/verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CowSolverAdapter — Main entry point for the CowSwap solver integration.
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ IMPORTANT: Shadow competition is FREE and requires no registration or KYC.
|
|
5
|
+
* Production solver requires CowSwap DAO bonding pool approval and KYC.
|
|
6
|
+
* This adapter defaults to 'shadow' mode — never assume production credentials.
|
|
7
|
+
*
|
|
8
|
+
* Flow:
|
|
9
|
+
* 1. CowSwap broadcasts an auction batch to all registered solvers.
|
|
10
|
+
* 2. We call processAuction() — must return within ~30 seconds.
|
|
11
|
+
* 3. We detect CoW (Coincidence of Wants) first — zero DEX fees.
|
|
12
|
+
* 4. Remaining orders are routed through SmartSwapRouter (7 DEXes in parallel).
|
|
13
|
+
* 5. We call submitSolution() with the best settlement we can construct.
|
|
14
|
+
* 6. If we win, we earn the surplus above user limit prices.
|
|
15
|
+
*/
|
|
16
|
+
import type { SmartSwapRouter } from '../swap/router/router.js';
|
|
17
|
+
import type { CowAuctionBatch, SolverConfig, SolverSolution, SolverStats, SolutionSubmissionResult } from './types.js';
|
|
18
|
+
export declare class CowSolverAdapter {
|
|
19
|
+
private config;
|
|
20
|
+
private analyzer;
|
|
21
|
+
private builder;
|
|
22
|
+
private stats;
|
|
23
|
+
/** CowSwap competition API endpoints */
|
|
24
|
+
private readonly ENDPOINTS;
|
|
25
|
+
constructor(config: SolverConfig, router?: SmartSwapRouter);
|
|
26
|
+
/**
|
|
27
|
+
* Process an auction batch and return our best settlement solution.
|
|
28
|
+
*
|
|
29
|
+
* Called when CowSwap sends us an auction. Must respond within 30 seconds.
|
|
30
|
+
* Returns null if we have nothing viable to submit.
|
|
31
|
+
*/
|
|
32
|
+
processAuction(batch: CowAuctionBatch): Promise<SolverSolution | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Submit a solution to CowSwap.
|
|
35
|
+
*
|
|
36
|
+
* In shadow mode, the solution is evaluated but never executed on-chain —
|
|
37
|
+
* useful for measuring competitiveness before applying for the production
|
|
38
|
+
* bonding pool.
|
|
39
|
+
*/
|
|
40
|
+
submitSolution(solution: SolverSolution): Promise<SolutionSubmissionResult>;
|
|
41
|
+
/** Get current solver performance statistics */
|
|
42
|
+
getStats(): SolverStats;
|
|
43
|
+
/** Get the CowSwap API base URL for the configured environment */
|
|
44
|
+
getApiUrl(): string;
|
|
45
|
+
private getChainId;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/solver/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,cAAc,EACd,WAAW,EACX,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAIpB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAAc;IAE3B,wCAAwC;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAIxB;gBAEU,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,eAAe;IAyB1D;;;;;OAKG;IACG,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAmD5E;;;;;;OAMG;IACG,cAAc,CAClB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,wBAAwB,CAAC;IAgDpC,gDAAgD;IAChD,QAAQ,IAAI,WAAW;IAIvB,kEAAkE;IAClE,SAAS,IAAI,MAAM;IAInB,OAAO,CAAC,UAAU;CASnB"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { AuctionAnalyzer } from './analyzer.js';
|
|
2
|
+
import { SolutionBuilder } from './builder.js';
|
|
3
|
+
export class CowSolverAdapter {
|
|
4
|
+
constructor(config, router) {
|
|
5
|
+
/** CowSwap competition API endpoints */
|
|
6
|
+
this.ENDPOINTS = {
|
|
7
|
+
shadow: 'https://api.cow.fi/mainnet/api/v1/solver_competition',
|
|
8
|
+
staging: 'https://barn.api.cow.fi/mainnet/api/v1/solver_competition',
|
|
9
|
+
mainnet: 'https://api.cow.fi/mainnet/api/v1/solver_competition',
|
|
10
|
+
};
|
|
11
|
+
this.config = {
|
|
12
|
+
environment: 'shadow',
|
|
13
|
+
solverName: 'AgentWallet',
|
|
14
|
+
maxGasGwei: 50,
|
|
15
|
+
minSurplusUsd: 0.5,
|
|
16
|
+
responseTimeoutMs: 20000,
|
|
17
|
+
submissionUrl: '',
|
|
18
|
+
...config,
|
|
19
|
+
};
|
|
20
|
+
this.analyzer = new AuctionAnalyzer(router);
|
|
21
|
+
this.builder = new SolutionBuilder();
|
|
22
|
+
this.stats = {
|
|
23
|
+
auctionsProcessed: 0,
|
|
24
|
+
auctionsWon: 0,
|
|
25
|
+
auctionsLost: 0,
|
|
26
|
+
totalSurplusGenerated: '0',
|
|
27
|
+
winRate: 0,
|
|
28
|
+
avgResponseTimeMs: 0,
|
|
29
|
+
lastAuctionAt: undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Process an auction batch and return our best settlement solution.
|
|
34
|
+
*
|
|
35
|
+
* Called when CowSwap sends us an auction. Must respond within 30 seconds.
|
|
36
|
+
* Returns null if we have nothing viable to submit.
|
|
37
|
+
*/
|
|
38
|
+
async processAuction(batch) {
|
|
39
|
+
const startTime = Date.now();
|
|
40
|
+
this.stats.auctionsProcessed++;
|
|
41
|
+
this.stats.lastAuctionAt = startTime;
|
|
42
|
+
const orders = Object.values(batch.instance.orders);
|
|
43
|
+
if (orders.length === 0)
|
|
44
|
+
return null;
|
|
45
|
+
// Step 1: Find Coincidence of Wants — best outcome for users, no DEX fees
|
|
46
|
+
const cowMatches = this.analyzer.findCoincidenceOfWants(orders);
|
|
47
|
+
// Step 2: Route remaining orders through SmartSwapRouter
|
|
48
|
+
const matchedOrderIds = new Set(cowMatches.flatMap((m) => [m.orderA.uid, m.orderB.uid]));
|
|
49
|
+
const remainingOrders = orders.filter((o) => !matchedOrderIds.has(o.uid));
|
|
50
|
+
const analysisPromises = remainingOrders.map((order) => this.analyzer
|
|
51
|
+
.analyzeOrder(order, this.getChainId())
|
|
52
|
+
.then((result) => result ? { order, route: result.bestRoute } : { order, route: null }));
|
|
53
|
+
const routes = await Promise.all(analysisPromises);
|
|
54
|
+
// Step 3: Only keep orders we can actually fill
|
|
55
|
+
const viableRoutes = routes.filter((r) => r.route !== null);
|
|
56
|
+
// Step 4: Nothing to submit?
|
|
57
|
+
if (viableRoutes.length === 0 && cowMatches.length === 0)
|
|
58
|
+
return null;
|
|
59
|
+
// Step 5: Assemble the solution
|
|
60
|
+
const solution = this.builder.buildSolution({
|
|
61
|
+
auctionId: batch.id,
|
|
62
|
+
orders,
|
|
63
|
+
routes: viableRoutes,
|
|
64
|
+
cowMatches,
|
|
65
|
+
});
|
|
66
|
+
// Step 6: Update timing stats
|
|
67
|
+
const elapsed = Date.now() - startTime;
|
|
68
|
+
this.stats.avgResponseTimeMs =
|
|
69
|
+
(this.stats.avgResponseTimeMs * (this.stats.auctionsProcessed - 1) +
|
|
70
|
+
elapsed) /
|
|
71
|
+
this.stats.auctionsProcessed;
|
|
72
|
+
return solution;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Submit a solution to CowSwap.
|
|
76
|
+
*
|
|
77
|
+
* In shadow mode, the solution is evaluated but never executed on-chain —
|
|
78
|
+
* useful for measuring competitiveness before applying for the production
|
|
79
|
+
* bonding pool.
|
|
80
|
+
*/
|
|
81
|
+
async submitSolution(solution) {
|
|
82
|
+
const endpoint = this.config.submissionUrl ||
|
|
83
|
+
this.ENDPOINTS[this.config.environment];
|
|
84
|
+
try {
|
|
85
|
+
const response = await fetch(`${endpoint}/solutions`, {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: { 'Content-Type': 'application/json' },
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
auctionId: solution.auctionId,
|
|
90
|
+
trades: solution.trades,
|
|
91
|
+
interactions: solution.interactions,
|
|
92
|
+
prices: solution.prices,
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
const text = await response.text();
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
auctionId: solution.auctionId,
|
|
100
|
+
error: text,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const result = (await response.json());
|
|
104
|
+
return {
|
|
105
|
+
success: true,
|
|
106
|
+
auctionId: solution.auctionId,
|
|
107
|
+
solutionId: result.id,
|
|
108
|
+
won: result.winner === this.config.solverName,
|
|
109
|
+
surplus: result.surplus,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
return {
|
|
114
|
+
success: false,
|
|
115
|
+
auctionId: solution.auctionId,
|
|
116
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Get current solver performance statistics */
|
|
121
|
+
getStats() {
|
|
122
|
+
return { ...this.stats };
|
|
123
|
+
}
|
|
124
|
+
/** Get the CowSwap API base URL for the configured environment */
|
|
125
|
+
getApiUrl() {
|
|
126
|
+
return this.ENDPOINTS[this.config.environment];
|
|
127
|
+
}
|
|
128
|
+
getChainId() {
|
|
129
|
+
const map = {
|
|
130
|
+
ethereum: 1,
|
|
131
|
+
base: 8453,
|
|
132
|
+
arbitrum: 42161,
|
|
133
|
+
gnosis: 100,
|
|
134
|
+
};
|
|
135
|
+
return map[this.config.chain] ?? 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/solver/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuctionAnalyzer — Core intelligence for CowSwap solver.
|
|
3
|
+
*
|
|
4
|
+
* Given an auction batch, finds the best execution route for each order
|
|
5
|
+
* by leveraging SmartSwapRouter (7 DEX aggregators queried in parallel).
|
|
6
|
+
*
|
|
7
|
+
* Also detects Coincidence of Wants (CoW): orders that can settle directly
|
|
8
|
+
* without any DEX, saving gas and maximising user surplus.
|
|
9
|
+
*/
|
|
10
|
+
import type { SmartSwapRouter } from '../swap/router/router.js';
|
|
11
|
+
import type { AggregatorQuote } from '../swap/router/types.js';
|
|
12
|
+
import type { CowOrder } from './types.js';
|
|
13
|
+
export declare class AuctionAnalyzer {
|
|
14
|
+
private router?;
|
|
15
|
+
constructor(router?: SmartSwapRouter | undefined);
|
|
16
|
+
/**
|
|
17
|
+
* Analyse a single order — find the best execution route.
|
|
18
|
+
* Returns null if no router is configured or no viable quotes exist.
|
|
19
|
+
*
|
|
20
|
+
* NOTE: analyzeOrder is intentionally graceful — it never throws.
|
|
21
|
+
* A missing router or empty quote list simply returns null.
|
|
22
|
+
*/
|
|
23
|
+
analyzeOrder(order: CowOrder, chainId: number): Promise<{
|
|
24
|
+
order: CowOrder;
|
|
25
|
+
bestRoute: AggregatorQuote | null;
|
|
26
|
+
/** Surplus vs the order's limit price in buy-token units */
|
|
27
|
+
surplusBuyToken: bigint;
|
|
28
|
+
/** Surplus in USD (simplified) */
|
|
29
|
+
surplusUsd: number;
|
|
30
|
+
viable: boolean;
|
|
31
|
+
} | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Find Coincidence of Wants (CoW) — orders that can trade directly.
|
|
34
|
+
*
|
|
35
|
+
* If user A wants to sell ETH for USDC and user B wants to sell USDC for
|
|
36
|
+
* ETH, they can settle directly with ZERO DEX fees. This is CowSwap's core
|
|
37
|
+
* innovation and is the primary edge for any competitive solver.
|
|
38
|
+
*/
|
|
39
|
+
findCoincidenceOfWants(orders: CowOrder[]): Array<{
|
|
40
|
+
orderA: CowOrder;
|
|
41
|
+
orderB: CowOrder;
|
|
42
|
+
matchedAmount: bigint;
|
|
43
|
+
estimatedGasSaved: bigint;
|
|
44
|
+
}>;
|
|
45
|
+
private calculateCoWMatch;
|
|
46
|
+
private chainIdToName;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/solver/analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,eAAe;IACd,OAAO,CAAC,MAAM,CAAC;gBAAP,MAAM,CAAC,6BAAiB;IAE5C;;;;;;OAMG;IACG,YAAY,CAChB,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QACT,KAAK,EAAE,QAAQ,CAAC;QAChB,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;QAClC,4DAA4D;QAC5D,eAAe,EAAE,MAAM,CAAC;QACxB,kCAAkC;QAClC,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,OAAO,CAAC;KACjB,GAAG,IAAI,CAAC;IAqCT;;;;;;OAMG;IACH,sBAAsB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;QAChD,MAAM,EAAE,QAAQ,CAAC;QACjB,MAAM,EAAE,QAAQ,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IA+BF,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,aAAa;CAStB"}
|