@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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/dist/account/balance.d.ts +41 -0
  4. package/dist/account/balance.d.ts.map +1 -0
  5. package/dist/account/balance.js +264 -0
  6. package/dist/account/balance.js.map +1 -0
  7. package/dist/account/create.d.ts +27 -0
  8. package/dist/account/create.d.ts.map +1 -0
  9. package/dist/account/create.js +116 -0
  10. package/dist/account/create.js.map +1 -0
  11. package/dist/account/deposit.d.ts +34 -0
  12. package/dist/account/deposit.d.ts.map +1 -0
  13. package/dist/account/deposit.js +88 -0
  14. package/dist/account/deposit.js.map +1 -0
  15. package/dist/account/guardian-approval.d.ts +111 -0
  16. package/dist/account/guardian-approval.d.ts.map +1 -0
  17. package/dist/account/guardian-approval.js +223 -0
  18. package/dist/account/guardian-approval.js.map +1 -0
  19. package/dist/account/guardian.d.ts +27 -0
  20. package/dist/account/guardian.d.ts.map +1 -0
  21. package/dist/account/guardian.js +67 -0
  22. package/dist/account/guardian.js.map +1 -0
  23. package/dist/account/history.d.ts +22 -0
  24. package/dist/account/history.d.ts.map +1 -0
  25. package/dist/account/history.js +144 -0
  26. package/dist/account/history.js.map +1 -0
  27. package/dist/account/transfer.d.ts +28 -0
  28. package/dist/account/transfer.d.ts.map +1 -0
  29. package/dist/account/transfer.js +137 -0
  30. package/dist/account/transfer.js.map +1 -0
  31. package/dist/auth/erc8128.d.ts +14 -0
  32. package/dist/auth/erc8128.d.ts.map +1 -0
  33. package/dist/auth/erc8128.js +92 -0
  34. package/dist/auth/erc8128.js.map +1 -0
  35. package/dist/client.d.ts +394 -0
  36. package/dist/client.d.ts.map +1 -0
  37. package/dist/client.js +970 -0
  38. package/dist/client.js.map +1 -0
  39. package/dist/events/emitter.d.ts +96 -0
  40. package/dist/events/emitter.d.ts.map +1 -0
  41. package/dist/events/emitter.js +90 -0
  42. package/dist/events/emitter.js.map +1 -0
  43. package/dist/index.d.ts +29 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +33 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/messaging/message-router.d.ts +69 -0
  48. package/dist/messaging/message-router.d.ts.map +1 -0
  49. package/dist/messaging/message-router.js +307 -0
  50. package/dist/messaging/message-router.js.map +1 -0
  51. package/dist/messaging/rate-limiter.d.ts +31 -0
  52. package/dist/messaging/rate-limiter.d.ts.map +1 -0
  53. package/dist/messaging/rate-limiter.js +74 -0
  54. package/dist/messaging/rate-limiter.js.map +1 -0
  55. package/dist/messaging/xmtp.d.ts +144 -0
  56. package/dist/messaging/xmtp.d.ts.map +1 -0
  57. package/dist/messaging/xmtp.js +473 -0
  58. package/dist/messaging/xmtp.js.map +1 -0
  59. package/dist/payments/agreements.d.ts +87 -0
  60. package/dist/payments/agreements.d.ts.map +1 -0
  61. package/dist/payments/agreements.js +337 -0
  62. package/dist/payments/agreements.js.map +1 -0
  63. package/dist/payments/budget.d.ts +118 -0
  64. package/dist/payments/budget.d.ts.map +1 -0
  65. package/dist/payments/budget.js +176 -0
  66. package/dist/payments/budget.js.map +1 -0
  67. package/dist/payments/smart-fetch.d.ts +65 -0
  68. package/dist/payments/smart-fetch.d.ts.map +1 -0
  69. package/dist/payments/smart-fetch.js +115 -0
  70. package/dist/payments/smart-fetch.js.map +1 -0
  71. package/dist/payments/x402.d.ts +89 -0
  72. package/dist/payments/x402.d.ts.map +1 -0
  73. package/dist/payments/x402.js +620 -0
  74. package/dist/payments/x402.js.map +1 -0
  75. package/dist/registry/discover.d.ts +43 -0
  76. package/dist/registry/discover.d.ts.map +1 -0
  77. package/dist/registry/discover.js +272 -0
  78. package/dist/registry/discover.js.map +1 -0
  79. package/dist/registry/register.d.ts +44 -0
  80. package/dist/registry/register.d.ts.map +1 -0
  81. package/dist/registry/register.js +126 -0
  82. package/dist/registry/register.js.map +1 -0
  83. package/dist/reputation/opinion.d.ts +52 -0
  84. package/dist/reputation/opinion.d.ts.map +1 -0
  85. package/dist/reputation/opinion.js +198 -0
  86. package/dist/reputation/opinion.js.map +1 -0
  87. package/dist/utils/addresses.d.ts +6 -0
  88. package/dist/utils/addresses.d.ts.map +1 -0
  89. package/dist/utils/addresses.js +53 -0
  90. package/dist/utils/addresses.js.map +1 -0
  91. package/dist/utils/errors.d.ts +23 -0
  92. package/dist/utils/errors.d.ts.map +1 -0
  93. package/dist/utils/errors.js +188 -0
  94. package/dist/utils/errors.js.map +1 -0
  95. package/dist/utils/execution.d.ts +20 -0
  96. package/dist/utils/execution.d.ts.map +1 -0
  97. package/dist/utils/execution.js +28 -0
  98. package/dist/utils/execution.js.map +1 -0
  99. package/dist/utils/paymaster.d.ts +35 -0
  100. package/dist/utils/paymaster.d.ts.map +1 -0
  101. package/dist/utils/paymaster.js +115 -0
  102. package/dist/utils/paymaster.js.map +1 -0
  103. package/dist/utils/retry.d.ts +19 -0
  104. package/dist/utils/retry.d.ts.map +1 -0
  105. package/dist/utils/retry.js +68 -0
  106. package/dist/utils/retry.js.map +1 -0
  107. package/dist/utils/userop.d.ts +55 -0
  108. package/dist/utils/userop.d.ts.map +1 -0
  109. package/dist/utils/userop.js +201 -0
  110. package/dist/utils/userop.js.map +1 -0
  111. package/dist/utils/validation.d.ts +8 -0
  112. package/dist/utils/validation.d.ts.map +1 -0
  113. package/dist/utils/validation.js +35 -0
  114. package/dist/utils/validation.js.map +1 -0
  115. package/package.json +63 -0
@@ -0,0 +1,34 @@
1
+ import { type PublicClient, type WalletClient, type Chain, type Transport, type Account } from 'viem';
2
+ import { type AzethContractAddresses } from '@azeth/common';
3
+ export interface DepositParams {
4
+ /** The smart account to deposit into (must be owned by the caller) */
5
+ to: `0x${string}`;
6
+ /** Amount to deposit (in smallest unit) */
7
+ amount: bigint;
8
+ /** ERC-20 token address. Omit for native ETH deposit. */
9
+ token?: `0x${string}`;
10
+ }
11
+ export interface DepositResult {
12
+ txHash: `0x${string}`;
13
+ from: `0x${string}`;
14
+ to: `0x${string}`;
15
+ amount: bigint;
16
+ token: `0x${string}` | 'ETH';
17
+ }
18
+ /** Validate that a target address is an Azeth smart account owned by the depositor.
19
+ *
20
+ * SECURITY CRITICAL: Both checks are on-chain reads and cannot be spoofed.
21
+ * 1. factory.isAzethAccount(target) — confirms it's a real Azeth account
22
+ * 2. factory.getOwnerOf(target) == depositor — confirms ownership
23
+ *
24
+ * No TOCTOU risk: AzethAccount has no transferOwnership(), so ownership is immutable.
25
+ */
26
+ export declare function validateDepositTarget(publicClient: PublicClient<Transport, Chain>, addresses: AzethContractAddresses, depositor: `0x${string}`, target: `0x${string}`): Promise<void>;
27
+ /** Deposit ETH or ERC-20 tokens from the EOA to a self-owned smart account.
28
+ *
29
+ * SECURITY: Validates on-chain that the target is:
30
+ * 1. A real Azeth smart account (via factory.isAzethAccount)
31
+ * 2. Owned by the depositor (via factory.getOwnerOf)
32
+ */
33
+ export declare function deposit(publicClient: PublicClient<Transport, Chain>, walletClient: WalletClient<Transport, Chain, Account>, addresses: AzethContractAddresses, depositor: `0x${string}`, params: DepositParams): Promise<DepositResult>;
34
+ //# sourceMappingURL=deposit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deposit.d.ts","sourceRoot":"","sources":["../../src/account/deposit.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,OAAO,EAEb,MAAM,MAAM,CAAC;AACd,OAAO,EAAc,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAKxE,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,EAAE,EAAE,KAAK,MAAM,EAAE,CAAC;IAClB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,KAAK,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,EAAE,EAAE,KAAK,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,SAAS,EAAE,sBAAsB,EACjC,SAAS,EAAE,KAAK,MAAM,EAAE,EACxB,MAAM,EAAE,KAAK,MAAM,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAC3B,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EACrD,SAAS,EAAE,sBAAsB,EACjC,SAAS,EAAE,KAAK,MAAM,EAAE,EACxB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CAmDxB"}
@@ -0,0 +1,88 @@
1
+ import { erc20Abi, } from 'viem';
2
+ import { AzethError } from '@azeth/common';
3
+ import { AzethFactoryAbi } from '@azeth/common/abis';
4
+ import { requireAddress } from '../utils/addresses.js';
5
+ import { withRetry } from '../utils/retry.js';
6
+ /** Validate that a target address is an Azeth smart account owned by the depositor.
7
+ *
8
+ * SECURITY CRITICAL: Both checks are on-chain reads and cannot be spoofed.
9
+ * 1. factory.isAzethAccount(target) — confirms it's a real Azeth account
10
+ * 2. factory.getOwnerOf(target) == depositor — confirms ownership
11
+ *
12
+ * No TOCTOU risk: AzethAccount has no transferOwnership(), so ownership is immutable.
13
+ */
14
+ export async function validateDepositTarget(publicClient, addresses, depositor, target) {
15
+ const factoryAddress = requireAddress(addresses, 'factory');
16
+ // Check 1: Is this a real Azeth account?
17
+ const isAzethAccount = await withRetry(() => publicClient.readContract({
18
+ address: factoryAddress,
19
+ abi: AzethFactoryAbi,
20
+ functionName: 'isAzethAccount',
21
+ args: [target],
22
+ }));
23
+ if (!isAzethAccount) {
24
+ throw new AzethError('Target is not a valid Azeth smart account', 'INVALID_INPUT', { target, factory: factoryAddress });
25
+ }
26
+ // Check 2: Does the depositor own this account?
27
+ const owner = await withRetry(() => publicClient.readContract({
28
+ address: factoryAddress,
29
+ abi: AzethFactoryAbi,
30
+ functionName: 'getOwnerOf',
31
+ args: [target],
32
+ }));
33
+ if (owner.toLowerCase() !== depositor.toLowerCase()) {
34
+ throw new AzethError('Cannot deposit to a smart account you do not own', 'UNAUTHORIZED', { target, owner, depositor });
35
+ }
36
+ }
37
+ /** Deposit ETH or ERC-20 tokens from the EOA to a self-owned smart account.
38
+ *
39
+ * SECURITY: Validates on-chain that the target is:
40
+ * 1. A real Azeth smart account (via factory.isAzethAccount)
41
+ * 2. Owned by the depositor (via factory.getOwnerOf)
42
+ */
43
+ export async function deposit(publicClient, walletClient, addresses, depositor, params) {
44
+ if (params.amount <= 0n) {
45
+ throw new AzethError('Deposit amount must be positive', 'INVALID_INPUT', { field: 'amount' });
46
+ }
47
+ // SECURITY: On-chain ownership verification
48
+ await validateDepositTarget(publicClient, addresses, depositor, params.to);
49
+ let txHash;
50
+ try {
51
+ if (!params.token) {
52
+ // ETH deposit: simple value transfer to the smart account
53
+ txHash = await walletClient.sendTransaction({
54
+ to: params.to,
55
+ value: params.amount,
56
+ });
57
+ }
58
+ else {
59
+ // ERC-20 deposit: transfer tokens to the smart account
60
+ txHash = await walletClient.writeContract({
61
+ address: params.token,
62
+ abi: erc20Abi,
63
+ functionName: 'transfer',
64
+ args: [params.to, params.amount],
65
+ });
66
+ }
67
+ }
68
+ catch (err) {
69
+ if (err instanceof AzethError)
70
+ throw err;
71
+ const message = err instanceof Error ? err.message : 'Deposit failed';
72
+ const isInsufficientFunds = message.toLowerCase().includes('insufficient') ||
73
+ message.toLowerCase().includes('exceeds balance');
74
+ throw new AzethError(message, isInsufficientFunds ? 'INSUFFICIENT_BALANCE' : 'NETWORK_ERROR', { originalError: err instanceof Error ? err.name : undefined });
75
+ }
76
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash, timeout: 120_000 });
77
+ if (receipt.status === 'reverted') {
78
+ throw new AzethError('Deposit transaction reverted', 'NETWORK_ERROR', { txHash });
79
+ }
80
+ return {
81
+ txHash,
82
+ from: depositor,
83
+ to: params.to,
84
+ amount: params.amount,
85
+ token: params.token ?? 'ETH',
86
+ };
87
+ }
88
+ //# sourceMappingURL=deposit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deposit.js","sourceRoot":"","sources":["../../src/account/deposit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import type { XMTPClient } from '../messaging/xmtp.js';
2
+ /** Structured XMTP message sent from agent to guardian requesting co-signature */
3
+ export interface GuardianApprovalRequest {
4
+ type: 'azeth:guardian_request';
5
+ version: '1.0';
6
+ requestId: string;
7
+ chainId: number;
8
+ account: `0x${string}`;
9
+ userOpHash: `0x${string}`;
10
+ operation: {
11
+ type: 'transfer' | 'whitelist_add' | 'agreement' | 'payment' | 'other';
12
+ description: string;
13
+ to?: string;
14
+ amount?: string;
15
+ usdValue?: string;
16
+ };
17
+ reason: string;
18
+ limits: {
19
+ maxTxAmountUSD: string;
20
+ dailySpendLimitUSD: string;
21
+ guardianMaxTxAmountUSD: string;
22
+ guardianDailySpendLimitUSD: string;
23
+ dailySpentUSD: string;
24
+ };
25
+ expiresAt: string;
26
+ }
27
+ /** Structured XMTP message sent from guardian back to agent with decision */
28
+ export interface GuardianApprovalResponse {
29
+ type: 'azeth:guardian_response';
30
+ version: '1.0';
31
+ requestId: string;
32
+ decision: 'approved' | 'rejected';
33
+ signature?: `0x${string}`;
34
+ reason?: string;
35
+ }
36
+ /** In-memory record of a pending guardian approval request */
37
+ export interface PendingApproval {
38
+ requestId: string;
39
+ userOpHash: `0x${string}`;
40
+ ownerSignature: `0x${string}`;
41
+ guardianAddress: `0x${string}`;
42
+ operation: GuardianApprovalRequest['operation'];
43
+ reason: string;
44
+ status: 'pending' | 'approved' | 'rejected' | 'expired';
45
+ guardianSignature?: `0x${string}`;
46
+ rejectionReason?: string;
47
+ createdAt: number;
48
+ expiresAt: number;
49
+ }
50
+ /** Result of a guardian approval request */
51
+ export type GuardianApprovalResult = {
52
+ status: 'approved';
53
+ signature: `0x${string}`;
54
+ combinedSignature: `0x${string}`;
55
+ } | {
56
+ status: 'rejected';
57
+ reason?: string;
58
+ } | {
59
+ status: 'timeout';
60
+ requestId: string;
61
+ } | {
62
+ status: 'error';
63
+ message: string;
64
+ };
65
+ /** Retrieve a pending approval by request ID. Auto-expires if past deadline. */
66
+ export declare function getPendingApproval(requestId: string): PendingApproval | undefined;
67
+ /** Get all non-expired pending approvals. */
68
+ export declare function getAllPendingApprovals(): PendingApproval[];
69
+ /** Remove all expired approvals from the store. */
70
+ export declare function clearExpiredApprovals(): void;
71
+ /**
72
+ * Send a guardian approval request via XMTP and poll for the response.
73
+ *
74
+ * The agent sends a structured JSON message to the guardian's address,
75
+ * then polls XMTP for a response until timeout. On approval, the guardian's
76
+ * signature is combined with the owner's signature (owner 65 bytes + guardian 65 bytes).
77
+ *
78
+ * @param xmtpClient - Initialized XMTPClient instance
79
+ * @param guardianAddress - Ethereum address of the guardian
80
+ * @param userOpHash - The UserOperation hash that needs co-signing
81
+ * @param ownerSignature - The owner's EIP-191 signature of the userOpHash
82
+ * @param chainId - The chain ID for the operation
83
+ * @param account - The smart account address
84
+ * @param operation - Human-readable operation details
85
+ * @param reason - Why guardian approval is needed (e.g., EXCEEDS_TX_LIMIT)
86
+ * @param limits - Current guardrail limits for context
87
+ * @param options - Polling options (timeoutMs, pollIntervalMs)
88
+ * @returns The approval result with combined signature, rejection reason, or timeout
89
+ */
90
+ export declare function requestGuardianApproval(xmtpClient: XMTPClient, guardianAddress: `0x${string}`, userOpHash: `0x${string}`, ownerSignature: `0x${string}`, chainId: number, account: `0x${string}`, operation: GuardianApprovalRequest['operation'], reason: string, limits: GuardianApprovalRequest['limits'], options?: {
91
+ timeoutMs?: number;
92
+ pollIntervalMs?: number;
93
+ }): Promise<GuardianApprovalResult>;
94
+ /**
95
+ * Check XMTP messages from the guardian for a response to a specific request.
96
+ *
97
+ * Reads recent messages from the guardian's conversation and looks for a
98
+ * matching `azeth:guardian_response` message.
99
+ *
100
+ * @param xmtpClient - Initialized XMTPClient instance
101
+ * @param guardianAddress - Guardian's Ethereum address
102
+ * @param requestId - The approval request ID to match
103
+ * @param afterTimestamp - Only consider messages after this timestamp (ms)
104
+ * @returns The parsed response, or null if no matching response found
105
+ */
106
+ export declare function checkForGuardianResponse(xmtpClient: XMTPClient, guardianAddress: `0x${string}`, requestId: string, afterTimestamp?: number): Promise<GuardianApprovalResponse | null>;
107
+ /** Try to parse a message string as a GuardianApprovalResponse. Returns null if not a valid response. */
108
+ export declare function tryParseGuardianResponse(content: string): GuardianApprovalResponse | null;
109
+ /** Try to parse a message string as a GuardianApprovalRequest. Returns null if not a valid request. */
110
+ export declare function tryParseGuardianRequest(content: string): GuardianApprovalRequest | null;
111
+ //# sourceMappingURL=guardian-approval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardian-approval.d.ts","sourceRoot":"","sources":["../../src/account/guardian-approval.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAIvD,kFAAkF;AAClF,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,OAAO,EAAE,KAAK,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE;QACT,IAAI,EAAE,UAAU,GAAG,eAAe,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;QACvE,WAAW,EAAE,MAAM,CAAC;QACpB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QACN,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,0BAA0B,EAAE,MAAM,CAAC;QACnC,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,6EAA6E;AAC7E,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,KAAK,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,UAAU,GAAG,UAAU,CAAC;IAClC,SAAS,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,KAAK,MAAM,EAAE,CAAC;IAC9B,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;IAC/B,SAAS,EAAE,uBAAuB,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IACxD,iBAAiB,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,4CAA4C;AAC5C,MAAM,MAAM,sBAAsB,GAC9B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,iBAAiB,EAAE,KAAK,MAAM,EAAE,CAAA;CAAE,GAClF;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AASzC,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAMjF;AAED,6CAA6C;AAC7C,wBAAgB,sBAAsB,IAAI,eAAe,EAAE,CAO1D;AAED,mDAAmD;AACnD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,KAAK,MAAM,EAAE,EAC9B,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,cAAc,EAAE,KAAK,MAAM,EAAE,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,KAAK,MAAM,EAAE,EACtB,SAAS,EAAE,uBAAuB,CAAC,WAAW,CAAC,EAC/C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,uBAAuB,CAAC,QAAQ,CAAC,EACzC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,OAAO,CAAC,sBAAsB,CAAC,CAsFjC;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,KAAK,MAAM,EAAE,EAC9B,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAkB1C;AAID,yGAAyG;AACzG,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,wBAAwB,GAAG,IAAI,CAsBzF;AAID,uGAAuG;AACvG,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI,CAkBvF"}
@@ -0,0 +1,223 @@
1
+ import crypto from 'node:crypto';
2
+ import { AzethError } from '@azeth/common';
3
+ // ── Pending Approvals Store (in-memory, per-process) ──
4
+ /** Audit #13 M-11 fix: Cap pending approvals to prevent unbounded memory growth */
5
+ const MAX_PENDING_APPROVALS = 1000;
6
+ const pendingApprovals = new Map();
7
+ /** Retrieve a pending approval by request ID. Auto-expires if past deadline. */
8
+ export function getPendingApproval(requestId) {
9
+ const approval = pendingApprovals.get(requestId);
10
+ if (approval && approval.status === 'pending' && Date.now() > approval.expiresAt) {
11
+ approval.status = 'expired';
12
+ }
13
+ return approval;
14
+ }
15
+ /** Get all non-expired pending approvals. */
16
+ export function getAllPendingApprovals() {
17
+ return Array.from(pendingApprovals.values())
18
+ .map(a => {
19
+ if (a.status === 'pending' && Date.now() > a.expiresAt)
20
+ a.status = 'expired';
21
+ return a;
22
+ })
23
+ .filter(a => a.status === 'pending');
24
+ }
25
+ /** Remove all expired approvals from the store. */
26
+ export function clearExpiredApprovals() {
27
+ for (const [id, approval] of pendingApprovals) {
28
+ if (Date.now() > approval.expiresAt)
29
+ pendingApprovals.delete(id);
30
+ }
31
+ }
32
+ // ── Request Guardian Approval ──────────────────────────
33
+ /**
34
+ * Send a guardian approval request via XMTP and poll for the response.
35
+ *
36
+ * The agent sends a structured JSON message to the guardian's address,
37
+ * then polls XMTP for a response until timeout. On approval, the guardian's
38
+ * signature is combined with the owner's signature (owner 65 bytes + guardian 65 bytes).
39
+ *
40
+ * @param xmtpClient - Initialized XMTPClient instance
41
+ * @param guardianAddress - Ethereum address of the guardian
42
+ * @param userOpHash - The UserOperation hash that needs co-signing
43
+ * @param ownerSignature - The owner's EIP-191 signature of the userOpHash
44
+ * @param chainId - The chain ID for the operation
45
+ * @param account - The smart account address
46
+ * @param operation - Human-readable operation details
47
+ * @param reason - Why guardian approval is needed (e.g., EXCEEDS_TX_LIMIT)
48
+ * @param limits - Current guardrail limits for context
49
+ * @param options - Polling options (timeoutMs, pollIntervalMs)
50
+ * @returns The approval result with combined signature, rejection reason, or timeout
51
+ */
52
+ export async function requestGuardianApproval(xmtpClient, guardianAddress, userOpHash, ownerSignature, chainId, account, operation, reason, limits, options) {
53
+ const timeoutMs = options?.timeoutMs ?? 30_000;
54
+ const pollIntervalMs = options?.pollIntervalMs ?? 2_000;
55
+ const requestId = crypto.randomUUID();
56
+ const expiresAt = Date.now() + 5 * 60 * 1000; // 5 min expiry
57
+ // Audit #13 M-11 fix: Auto-cleanup expired entries and enforce size cap
58
+ clearExpiredApprovals();
59
+ if (pendingApprovals.size >= MAX_PENDING_APPROVALS) {
60
+ // Evict oldest entries (Map iterates in insertion order)
61
+ const evictCount = Math.ceil(MAX_PENDING_APPROVALS * 0.1);
62
+ let removed = 0;
63
+ for (const key of pendingApprovals.keys()) {
64
+ if (removed >= evictCount)
65
+ break;
66
+ pendingApprovals.delete(key);
67
+ removed++;
68
+ }
69
+ }
70
+ // Store pending approval
71
+ const pending = {
72
+ requestId,
73
+ userOpHash,
74
+ ownerSignature,
75
+ guardianAddress,
76
+ operation,
77
+ reason,
78
+ status: 'pending',
79
+ createdAt: Date.now(),
80
+ expiresAt,
81
+ };
82
+ pendingApprovals.set(requestId, pending);
83
+ // Build request message
84
+ const request = {
85
+ type: 'azeth:guardian_request',
86
+ version: '1.0',
87
+ requestId,
88
+ chainId,
89
+ account,
90
+ userOpHash,
91
+ operation,
92
+ reason,
93
+ limits,
94
+ expiresAt: new Date(expiresAt).toISOString(),
95
+ };
96
+ // Send via XMTP
97
+ try {
98
+ await xmtpClient.sendMessage({
99
+ to: guardianAddress,
100
+ content: JSON.stringify(request),
101
+ });
102
+ }
103
+ catch (err) {
104
+ pendingApprovals.delete(requestId);
105
+ throw new AzethError(`Failed to send guardian approval request via XMTP: ${err instanceof Error ? err.message : String(err)}`, 'NETWORK_ERROR');
106
+ }
107
+ // Poll for response
108
+ const startTime = Date.now();
109
+ const deadline = startTime + timeoutMs;
110
+ while (Date.now() < deadline) {
111
+ await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
112
+ const result = await checkForGuardianResponse(xmtpClient, guardianAddress, requestId, startTime);
113
+ if (result) {
114
+ if (result.decision === 'approved' && result.signature) {
115
+ pending.status = 'approved';
116
+ pending.guardianSignature = result.signature;
117
+ // Combine: owner signature (65 bytes) + guardian signature (65 bytes)
118
+ const combinedSignature = (ownerSignature + result.signature.slice(2));
119
+ return { status: 'approved', signature: result.signature, combinedSignature };
120
+ }
121
+ else {
122
+ pending.status = 'rejected';
123
+ pending.rejectionReason = result.reason;
124
+ return { status: 'rejected', reason: result.reason };
125
+ }
126
+ }
127
+ }
128
+ // Timeout — approval stays pending for later retrieval via azeth_guardian_status
129
+ return { status: 'timeout', requestId };
130
+ }
131
+ // ── Check for Response ─────────────────────────────────
132
+ /**
133
+ * Check XMTP messages from the guardian for a response to a specific request.
134
+ *
135
+ * Reads recent messages from the guardian's conversation and looks for a
136
+ * matching `azeth:guardian_response` message.
137
+ *
138
+ * @param xmtpClient - Initialized XMTPClient instance
139
+ * @param guardianAddress - Guardian's Ethereum address
140
+ * @param requestId - The approval request ID to match
141
+ * @param afterTimestamp - Only consider messages after this timestamp (ms)
142
+ * @returns The parsed response, or null if no matching response found
143
+ */
144
+ export async function checkForGuardianResponse(xmtpClient, guardianAddress, requestId, afterTimestamp) {
145
+ try {
146
+ // Use getMessagesByPeer to read messages from the guardian
147
+ const messages = await xmtpClient.getMessagesByPeer(guardianAddress, 20);
148
+ for (const msg of messages) {
149
+ // Skip messages from before our request
150
+ if (afterTimestamp && msg.timestamp < afterTimestamp)
151
+ continue;
152
+ const parsed = tryParseGuardianResponse(msg.content);
153
+ if (parsed && parsed.requestId === requestId) {
154
+ return parsed;
155
+ }
156
+ }
157
+ }
158
+ catch {
159
+ // XMTP read failure — non-fatal, will retry on next poll
160
+ }
161
+ return null;
162
+ }
163
+ // ── Parse Guardian Response ────────────────────────────
164
+ /** Try to parse a message string as a GuardianApprovalResponse. Returns null if not a valid response. */
165
+ export function tryParseGuardianResponse(content) {
166
+ try {
167
+ const parsed = JSON.parse(content);
168
+ if (parsed.type !== 'azeth:guardian_response')
169
+ return null;
170
+ if (parsed.version !== '1.0')
171
+ return null;
172
+ if (typeof parsed.requestId !== 'string')
173
+ return null;
174
+ if (parsed.decision !== 'approved' && parsed.decision !== 'rejected')
175
+ return null;
176
+ return {
177
+ type: 'azeth:guardian_response',
178
+ version: '1.0',
179
+ requestId: parsed.requestId,
180
+ decision: parsed.decision,
181
+ // Audit #13 H-6 fix: Validate signature format (0x + 130 hex chars = 65 bytes)
182
+ signature: (typeof parsed.signature === 'string'
183
+ && /^0x[0-9a-fA-F]{130}$/.test(parsed.signature))
184
+ ? parsed.signature : undefined,
185
+ reason: typeof parsed.reason === 'string' ? parsed.reason : undefined,
186
+ };
187
+ }
188
+ catch {
189
+ return null;
190
+ }
191
+ }
192
+ // ── Parse Guardian Request ─────────────────────────────
193
+ /** Try to parse a message string as a GuardianApprovalRequest. Returns null if not a valid request. */
194
+ export function tryParseGuardianRequest(content) {
195
+ try {
196
+ const parsed = JSON.parse(content);
197
+ if (parsed.type !== 'azeth:guardian_request')
198
+ return null;
199
+ if (parsed.version !== '1.0')
200
+ return null;
201
+ if (typeof parsed.requestId !== 'string')
202
+ return null;
203
+ if (typeof parsed.userOpHash !== 'string')
204
+ return null;
205
+ if (typeof parsed.chainId !== 'number')
206
+ return null;
207
+ if (typeof parsed.account !== 'string')
208
+ return null;
209
+ if (typeof parsed.operation !== 'object' || parsed.operation === null)
210
+ return null;
211
+ if (typeof parsed.reason !== 'string')
212
+ return null;
213
+ if (typeof parsed.limits !== 'object' || parsed.limits === null)
214
+ return null;
215
+ if (typeof parsed.expiresAt !== 'string')
216
+ return null;
217
+ return parsed;
218
+ }
219
+ catch {
220
+ return null;
221
+ }
222
+ }
223
+ //# sourceMappingURL=guardian-approval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardian-approval.js","sourceRoot":"","sources":["../../src/account/guardian-approval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type AzethContractAddresses } from '@azeth/common';
2
+ import type { AzethSmartAccountClient } from '../utils/userop.js';
3
+ /** Update the token whitelist on the GuardianModule via ERC-4337 UserOperation.
4
+ *
5
+ * Tokens must be whitelisted for executor-module operations (e.g., PaymentAgreementModule)
6
+ * to succeed. Owner-signed transfers bypass the whitelist.
7
+ *
8
+ * @param smartAccountClient - ERC-4337 smart account client for the caller
9
+ * @param addresses - Contract addresses containing guardianModule
10
+ * @param token - Token address to whitelist/delist (use address(0) for native ETH)
11
+ * @param allowed - true to whitelist, false to remove from whitelist
12
+ * @returns Transaction hash
13
+ */
14
+ export declare function setTokenWhitelist(smartAccountClient: AzethSmartAccountClient, addresses: AzethContractAddresses, token: `0x${string}`, allowed: boolean): Promise<`0x${string}`>;
15
+ /** Update the protocol whitelist on the GuardianModule via ERC-4337 UserOperation.
16
+ *
17
+ * Protocols (contract addresses) must be whitelisted for executor-module operations
18
+ * that interact with external contracts.
19
+ *
20
+ * @param smartAccountClient - ERC-4337 smart account client for the caller
21
+ * @param addresses - Contract addresses containing guardianModule
22
+ * @param protocol - Protocol/contract address to whitelist/delist
23
+ * @param allowed - true to whitelist, false to remove from whitelist
24
+ * @returns Transaction hash
25
+ */
26
+ export declare function setProtocolWhitelist(smartAccountClient: AzethSmartAccountClient, addresses: AzethContractAddresses, protocol: `0x${string}`, allowed: boolean): Promise<`0x${string}`>;
27
+ //# sourceMappingURL=guardian.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardian.d.ts","sourceRoot":"","sources":["../../src/account/guardian.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAExE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,kBAAkB,EAAE,uBAAuB,EAC3C,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,KAAK,MAAM,EAAE,EACpB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAsBxB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,kBAAkB,EAAE,uBAAuB,EAC3C,SAAS,EAAE,sBAAsB,EACjC,QAAQ,EAAE,KAAK,MAAM,EAAE,EACvB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAsBxB"}
@@ -0,0 +1,67 @@
1
+ import { encodeFunctionData } from 'viem';
2
+ import { GuardianModuleAbi } from '@azeth/common/abis';
3
+ import { AzethError } from '@azeth/common';
4
+ import { requireAddress } from '../utils/addresses.js';
5
+ /** Update the token whitelist on the GuardianModule via ERC-4337 UserOperation.
6
+ *
7
+ * Tokens must be whitelisted for executor-module operations (e.g., PaymentAgreementModule)
8
+ * to succeed. Owner-signed transfers bypass the whitelist.
9
+ *
10
+ * @param smartAccountClient - ERC-4337 smart account client for the caller
11
+ * @param addresses - Contract addresses containing guardianModule
12
+ * @param token - Token address to whitelist/delist (use address(0) for native ETH)
13
+ * @param allowed - true to whitelist, false to remove from whitelist
14
+ * @returns Transaction hash
15
+ */
16
+ export async function setTokenWhitelist(smartAccountClient, addresses, token, allowed) {
17
+ const guardianAddress = requireAddress(addresses, 'guardianModule');
18
+ try {
19
+ const data = encodeFunctionData({
20
+ abi: GuardianModuleAbi,
21
+ functionName: 'setTokenWhitelist',
22
+ args: [token, allowed],
23
+ });
24
+ return await smartAccountClient.sendTransaction({
25
+ to: guardianAddress,
26
+ value: 0n,
27
+ data,
28
+ });
29
+ }
30
+ catch (err) {
31
+ if (err instanceof AzethError)
32
+ throw err;
33
+ throw new AzethError(err instanceof Error ? err.message : 'Failed to update token whitelist', 'CONTRACT_ERROR', { originalError: err instanceof Error ? err.name : undefined });
34
+ }
35
+ }
36
+ /** Update the protocol whitelist on the GuardianModule via ERC-4337 UserOperation.
37
+ *
38
+ * Protocols (contract addresses) must be whitelisted for executor-module operations
39
+ * that interact with external contracts.
40
+ *
41
+ * @param smartAccountClient - ERC-4337 smart account client for the caller
42
+ * @param addresses - Contract addresses containing guardianModule
43
+ * @param protocol - Protocol/contract address to whitelist/delist
44
+ * @param allowed - true to whitelist, false to remove from whitelist
45
+ * @returns Transaction hash
46
+ */
47
+ export async function setProtocolWhitelist(smartAccountClient, addresses, protocol, allowed) {
48
+ const guardianAddress = requireAddress(addresses, 'guardianModule');
49
+ try {
50
+ const data = encodeFunctionData({
51
+ abi: GuardianModuleAbi,
52
+ functionName: 'setProtocolWhitelist',
53
+ args: [protocol, allowed],
54
+ });
55
+ return await smartAccountClient.sendTransaction({
56
+ to: guardianAddress,
57
+ value: 0n,
58
+ data,
59
+ });
60
+ }
61
+ catch (err) {
62
+ if (err instanceof AzethError)
63
+ throw err;
64
+ throw new AzethError(err instanceof Error ? err.message : 'Failed to update protocol whitelist', 'CONTRACT_ERROR', { originalError: err instanceof Error ? err.name : undefined });
65
+ }
66
+ }
67
+ //# sourceMappingURL=guardian.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardian.js","sourceRoot":"","sources":["../../src/account/guardian.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAA+B,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,kBAA2C,EAC3C,SAAiC,EACjC,KAAoB,EACpB,OAAgB;IAEhB,MAAM,eAAe,GAAG,cAAc,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAEpE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,kBAAkB,CAAC;YAC9B,GAAG,EAAE,iBAAiB;YACtB,YAAY,EAAE,mBAAmB;YACjC,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,CAAC,CAAC;QACH,OAAO,MAAM,kBAAkB,CAAC,eAAe,CAAC;YAC9C,EAAE,EAAE,eAAe;YACnB,KAAK,EAAE,EAAE;YACT,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAC;QACzC,MAAM,IAAI,UAAU,CAClB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,kCAAkC,EACvE,gBAAgB,EAChB,EAAE,aAAa,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAC/D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,kBAA2C,EAC3C,SAAiC,EACjC,QAAuB,EACvB,OAAgB;IAEhB,MAAM,eAAe,GAAG,cAAc,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAEpE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,kBAAkB,CAAC;YAC9B,GAAG,EAAE,iBAAiB;YACtB,YAAY,EAAE,sBAAsB;YACpC,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;SAC1B,CAAC,CAAC;QACH,OAAO,MAAM,kBAAkB,CAAC,eAAe,CAAC;YAC9C,EAAE,EAAE,eAAe;YACnB,KAAK,EAAE,EAAE;YACT,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAC;QACzC,MAAM,IAAI,UAAU,CAClB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,qCAAqC,EAC1E,gBAAgB,EAChB,EAAE,aAAa,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAC/D,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type PublicClient, type Chain, type Transport } from 'viem';
2
+ export interface HistoryParams {
3
+ limit?: number;
4
+ offset?: number;
5
+ fromBlock?: bigint;
6
+ }
7
+ export interface TransactionRecord {
8
+ hash: `0x${string}`;
9
+ from: `0x${string}`;
10
+ to: `0x${string}` | null;
11
+ value: bigint;
12
+ /** Token contract address (null for native ETH, 0x0...0 for ETH recorded by ReputationModule) */
13
+ token: `0x${string}` | null;
14
+ blockNumber: bigint;
15
+ timestamp: number;
16
+ }
17
+ /** Get transaction history for an account
18
+ * Tries server API first, then falls back to on-chain TransferRecorded events
19
+ * from the ReputationModule (last ~1000 blocks).
20
+ */
21
+ export declare function getHistory(publicClient: PublicClient<Transport, Chain>, account: `0x${string}`, serverUrl?: string, params?: HistoryParams, reputationModuleAddress?: `0x${string}`, tokenAddresses?: `0x${string}`[]): Promise<TransactionRecord[]>;
22
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/account/history.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,SAAS,EACf,MAAM,MAAM,CAAC;AAKd,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,EAAE,EAAE,KAAK,MAAM,EAAE,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,iGAAiG;IACjG,KAAK,EAAE,KAAK,MAAM,EAAE,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,OAAO,EAAE,KAAK,MAAM,EAAE,EACtB,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,aAAa,EACtB,uBAAuB,CAAC,EAAE,KAAK,MAAM,EAAE,EACvC,cAAc,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE,GAC/B,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAiJ9B"}