otto-intel-mcp 0.1.2 → 0.1.4
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 +76 -18
- package/dist/account-userop-policy-definition.d.ts +14 -0
- package/dist/account-userop-policy-definition.js +12 -0
- package/dist/account-userop-policy-relation.d.ts +371 -0
- package/dist/account-userop-policy-relation.js +87 -0
- package/dist/adapter/cdp-signer.d.ts +76 -9
- package/dist/adapter/cdp-signer.js +274 -33
- package/dist/adapter/evm-call-failure.d.ts +29 -0
- package/dist/adapter/evm-call-failure.js +109 -0
- package/dist/adapter/refusal.d.ts +1 -1
- package/dist/adapter/refusal.js +13 -0
- package/dist/adapter/route-simulator.d.ts +91 -0
- package/dist/adapter/route-simulator.js +143 -0
- package/dist/adapter-cdp-index.d.ts +1 -1
- package/dist/executable-equities.d.ts +55 -0
- package/dist/executable-equities.js +116 -0
- package/dist/executable-yield-markets.d.ts +261 -0
- package/dist/executable-yield-markets.js +154 -0
- package/dist/execution-account-gas-quote.d.ts +141 -0
- package/dist/execution-account-gas-quote.js +443 -0
- package/dist/execution-account-gas-review.d.ts +123 -0
- package/dist/execution-account-gas-review.js +104 -0
- package/dist/execution-account-gas-runtime.d.ts +33 -0
- package/dist/execution-account-gas-runtime.js +131 -0
- package/dist/execution-account-gas-view.d.ts +936 -0
- package/dist/execution-account-gas-view.js +56 -0
- package/dist/execution-config.d.ts +3 -0
- package/dist/execution-config.js +4 -0
- package/dist/execution-delegated-definition.d.ts +7 -6
- package/dist/execution-delegated-definition.js +13 -2
- package/dist/execution-delegation-admin-definition.d.ts +127 -5
- package/dist/execution-delegation-admin-definition.js +155 -5
- package/dist/execution-delegation-admin.d.ts +48 -2
- package/dist/execution-delegation-admin.js +422 -12
- package/dist/execution-delegation-cap-store.d.ts +386 -0
- package/dist/execution-delegation-cap-store.js +1150 -0
- package/dist/execution-delegation-exit-definition.d.ts +309 -0
- package/dist/execution-delegation-exit-definition.js +204 -0
- package/dist/execution-delegation-exit-store.d.ts +114 -0
- package/dist/execution-delegation-exit-store.js +671 -0
- package/dist/execution-delegation-exit.d.ts +4 -0
- package/dist/execution-delegation-exit.js +614 -0
- package/dist/execution-delegation-finality.d.ts +22 -0
- package/dist/execution-delegation-finality.js +90 -0
- package/dist/execution-delegation-operation-store.d.ts +129 -0
- package/dist/execution-delegation-operation-store.js +1107 -0
- package/dist/execution-delegation-operations-definition.d.ts +282 -0
- package/dist/execution-delegation-operations-definition.js +117 -0
- package/dist/execution-delegation-operations.d.ts +6 -0
- package/dist/execution-delegation-operations.js +282 -0
- package/dist/execution-delegation-policy.d.ts +154 -8
- package/dist/execution-delegation-policy.js +273 -40
- package/dist/execution-delegation.d.ts +51 -0
- package/dist/execution-delegation.js +441 -31
- package/dist/execution-errors.d.ts +1 -1
- package/dist/execution-errors.js +122 -0
- package/dist/execution-index.d.ts +7 -2
- package/dist/execution-index.js +7 -2
- package/dist/execution-journal-schema.d.ts +96 -0
- package/dist/execution-journal-schema.js +368 -0
- package/dist/execution-journal-tables.d.ts +14 -0
- package/dist/execution-journal-tables.js +227 -0
- package/dist/execution-policy-compatibility.d.ts +34 -0
- package/dist/execution-policy-compatibility.js +76 -0
- package/dist/execution-registration.d.ts +54 -2
- package/dist/execution-registration.js +151 -5
- package/dist/execution-sponsored-account-profile.d.ts +32 -0
- package/dist/execution-sponsored-account-profile.js +59 -0
- package/dist/execution-sponsored-account.d.ts +1519 -0
- package/dist/execution-sponsored-account.js +222 -0
- package/dist/execution-sponsored-definition.d.ts +1713 -0
- package/dist/execution-sponsored-definition.js +185 -0
- package/dist/execution-sponsored-gas-policy.d.ts +27 -0
- package/dist/execution-sponsored-gas-policy.js +110 -0
- package/dist/execution-sponsored-hosted.d.ts +3 -0
- package/dist/execution-sponsored-hosted.js +71 -0
- package/dist/execution-sponsored-index.d.ts +1322 -0
- package/dist/execution-sponsored-index.js +102 -0
- package/dist/execution-sponsored-mcp-definition.d.ts +1662 -0
- package/dist/execution-sponsored-mcp-definition.js +94 -0
- package/dist/execution-sponsored-receipt.d.ts +47 -0
- package/dist/execution-sponsored-receipt.js +74 -0
- package/dist/execution-sponsored-registration.d.ts +14 -0
- package/dist/execution-sponsored-registration.js +77 -0
- package/dist/execution-sponsored-runtime.d.ts +84 -0
- package/dist/execution-sponsored-runtime.js +149 -0
- package/dist/execution-sponsored-settlement.d.ts +15 -0
- package/dist/execution-sponsored-settlement.js +88 -0
- package/dist/execution-sponsored-store.d.ts +67 -0
- package/dist/execution-sponsored-store.js +517 -0
- package/dist/execution-sponsored-transport.d.ts +90 -0
- package/dist/execution-sponsored-transport.js +180 -0
- package/dist/execution-tool-definitions.d.ts +21 -21
- package/dist/execution-tool-definitions.js +0 -7
- package/dist/execution-tools.d.ts +53 -1
- package/dist/execution-tools.js +171 -13
- package/dist/execution-worker-guard.d.ts +28 -0
- package/dist/execution-worker-guard.js +124 -0
- package/dist/hybrid-yield-index.d.ts +10 -0
- package/dist/hybrid-yield-index.js +11 -0
- package/dist/hybrid-yield-markets.d.ts +96 -0
- package/dist/hybrid-yield-markets.js +124 -0
- package/dist/hybrid-yield.d.ts +411 -0
- package/dist/hybrid-yield.js +155 -0
- package/dist/hyperliquid-order-builder.js +4 -0
- package/dist/lifi-execution-client.d.ts +6 -0
- package/dist/lifi-execution-client.js +3 -0
- package/dist/lp-userop-account.d.ts +461 -0
- package/dist/lp-userop-account.js +417 -0
- package/dist/lp-userop-authority.d.ts +49 -0
- package/dist/lp-userop-authority.js +211 -0
- package/dist/lp-userop-definition.d.ts +233 -0
- package/dist/lp-userop-definition.js +85 -0
- package/dist/lp-userop-hosted.d.ts +3 -0
- package/dist/lp-userop-hosted.js +73 -0
- package/dist/lp-userop-index.d.ts +1569 -0
- package/dist/lp-userop-index.js +112 -0
- package/dist/lp-userop-mcp-definition.d.ts +1220 -0
- package/dist/lp-userop-mcp-definition.js +46 -0
- package/dist/lp-userop-operation.d.ts +1230 -0
- package/dist/lp-userop-operation.js +140 -0
- package/dist/lp-userop-registration.d.ts +14 -0
- package/dist/lp-userop-registration.js +70 -0
- package/dist/lp-userop-settlement.d.ts +89 -0
- package/dist/lp-userop-settlement.js +184 -0
- package/dist/lp-userop.d.ts +643 -0
- package/dist/lp-userop.js +343 -0
- package/dist/native-yield-account-definition.d.ts +1192 -0
- package/dist/native-yield-account-definition.js +232 -0
- package/dist/native-yield-account-gas.d.ts +58 -0
- package/dist/native-yield-account-gas.js +228 -0
- package/dist/native-yield-account-index.d.ts +23 -0
- package/dist/native-yield-account-index.js +28 -0
- package/dist/native-yield-account-policy.d.ts +168 -0
- package/dist/native-yield-account-policy.js +525 -0
- package/dist/native-yield-account-rpc.d.ts +8 -0
- package/dist/native-yield-account-rpc.js +128 -0
- package/dist/native-yield-account-runtime.d.ts +71 -0
- package/dist/native-yield-account-runtime.js +125 -0
- package/dist/native-yield-account-store.d.ts +40 -0
- package/dist/native-yield-account-store.js +307 -0
- package/dist/native-yield-account.d.ts +662 -0
- package/dist/native-yield-account.js +371 -0
- package/dist/native-yield-consent-store.d.ts +20 -0
- package/dist/native-yield-consent-store.js +317 -0
- package/dist/native-yield-definition.d.ts +288 -0
- package/dist/native-yield-definition.js +105 -0
- package/dist/native-yield-reader.d.ts +4 -0
- package/dist/native-yield-reader.js +137 -0
- package/dist/native-yield-settlement.d.ts +48 -0
- package/dist/native-yield-settlement.js +167 -0
- package/dist/native-yield-simulation.d.ts +18 -0
- package/dist/native-yield-simulation.js +45 -0
- package/dist/native-yield-userop-account.d.ts +675 -0
- package/dist/native-yield-userop-account.js +357 -0
- package/dist/native-yield-userop-authority.d.ts +214 -0
- package/dist/native-yield-userop-authority.js +296 -0
- package/dist/native-yield-userop-definition.d.ts +331 -0
- package/dist/native-yield-userop-definition.js +105 -0
- package/dist/native-yield-userop-hosted.d.ts +3 -0
- package/dist/native-yield-userop-hosted.js +71 -0
- package/dist/native-yield-userop-index.d.ts +1522 -0
- package/dist/native-yield-userop-index.js +142 -0
- package/dist/native-yield-userop-mcp-definition.d.ts +1356 -0
- package/dist/native-yield-userop-mcp-definition.js +50 -0
- package/dist/native-yield-userop-operation.d.ts +845 -0
- package/dist/native-yield-userop-operation.js +127 -0
- package/dist/native-yield-userop-policy.d.ts +23 -0
- package/dist/native-yield-userop-policy.js +25 -0
- package/dist/native-yield-userop-registration.d.ts +17 -0
- package/dist/native-yield-userop-registration.js +76 -0
- package/dist/native-yield-userop-settlement.d.ts +8 -0
- package/dist/native-yield-userop-settlement.js +79 -0
- package/dist/native-yield-userop-simulation.d.ts +18 -0
- package/dist/native-yield-userop-simulation.js +34 -0
- package/dist/native-yield-userop.d.ts +35 -0
- package/dist/native-yield-userop.js +156 -0
- package/dist/native-yield-verify.d.ts +30 -0
- package/dist/native-yield-verify.js +141 -0
- package/dist/native-yield.d.ts +17 -0
- package/dist/native-yield.js +119 -0
- package/dist/stdio-main.js +0 -0
- package/dist/stock-buy-definition.d.ts +338 -0
- package/dist/stock-buy-definition.js +127 -0
- package/dist/stock-buy-oracle.d.ts +8 -0
- package/dist/stock-buy-oracle.js +22 -0
- package/dist/stock-buy.d.ts +17 -0
- package/dist/stock-buy.js +164 -0
- package/dist/tool-definitions.d.ts +3 -1
- package/dist/tool-definitions.js +55 -2
- package/dist/vendor/lp-v3/lp-v3-atomic-contract.d.ts +445 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-contract.js +90 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-evidence.d.ts +14 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-evidence.js +82 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-index.d.ts +80 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-index.js +19 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-plan.d.ts +43 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-plan.js +112 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-read-contract.d.ts +312 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-read-contract.js +41 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-read-index.d.ts +3 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-read-index.js +3 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-read-rpc.d.ts +49 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-read-rpc.js +88 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-read.d.ts +17 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-read.js +232 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-settlement.d.ts +105 -0
- package/dist/vendor/lp-v3/lp-v3-atomic-settlement.js +162 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-contract.d.ts +606 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-contract.js +59 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-index.d.ts +168 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-index.js +23 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-observation.d.ts +32 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-observation.js +228 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-plan.d.ts +11 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-plan.js +91 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-reconcile.d.ts +9 -0
- package/dist/vendor/lp-v3/lp-v3-collect-protocol-reconcile.js +124 -0
- package/dist/vendor/lp-v3/lp-v3-contract.d.ts +538 -0
- package/dist/vendor/lp-v3/lp-v3-contract.js +137 -0
- package/dist/vendor/lp-v3/lp-v3-evidence.d.ts +25 -0
- package/dist/vendor/lp-v3/lp-v3-evidence.js +168 -0
- package/dist/vendor/lp-v3/lp-v3-plan.d.ts +22 -0
- package/dist/vendor/lp-v3/lp-v3-plan.js +135 -0
- package/dist/vendor/lp-v3/types.d.ts +131 -0
- package/dist/vendor/lp-v3/types.js +6 -0
- package/dist/vendor/lp-v3/v4-math.d.ts +18 -0
- package/dist/vendor/lp-v3/v4-math.js +90 -0
- package/dist/yield-deposit-definition.d.ts +374 -0
- package/dist/yield-deposit-definition.js +123 -0
- package/dist/yield-deposit.d.ts +16 -0
- package/dist/yield-deposit.js +149 -0
- package/dist/yield-route-semantics.d.ts +27 -0
- package/dist/yield-route-semantics.js +71 -0
- package/dist/yield-withdraw-definition.d.ts +357 -0
- package/dist/yield-withdraw-definition.js +90 -0
- package/dist/yield-withdraw.d.ts +11 -0
- package/dist/yield-withdraw.js +122 -0
- package/package.json +239 -7
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import { LP_USEROP_ACCOUNT_GAS_CONFIRMATION } from './lp-userop-definition.js';
|
|
2
|
+
import { SPONSORED_GAS_REVIEW_INPUT } from './execution-sponsored-definition.js';
|
|
3
|
+
import { accountGasBudgetPublicSchema, accountGasView, accountGasViewMatches, accountGasFailure, AccountGasConfirmationRefusal } from './execution-account-gas-view.js';
|
|
4
|
+
/** One manually reviewed guarded collection on the shared sponsored execution rail. */
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { freezeHybridValue, hybridYieldCommitment } from './hybrid-yield-markets.js';
|
|
8
|
+
import { LP_USEROP_CONFIRMATION, LP_USEROP_INPUT_SCHEMA } from './lp-userop-definition.js';
|
|
9
|
+
import { assertFreshVerifiedLpUserOp, assertLpUserOpEnvelope, lpUserOpCalls, lpUserOpRecordedCalls, lpUserOpVerificationEvidence, prepareLpUserOp, verifyLpUserOp, simulateLpUserOp, } from './lp-userop.js';
|
|
10
|
+
import { readLpUserOpSettlement, LP_USEROP_SETTLEMENT_SCHEMA } from './lp-userop-settlement.js';
|
|
11
|
+
import { assertLpUserOpContext, LP_USEROP_CONTEXT_SCHEMA, } from './lp-userop-operation.js';
|
|
12
|
+
import { readConfirmedSponsoredReceipt, SponsoredReceiptUnconfirmedError, } from './execution-sponsored-receipt.js';
|
|
13
|
+
const token = z.string().min(1).max(16_384), hash = z.string().regex(/^0x[0-9a-fA-F]{64}$/);
|
|
14
|
+
const address = z.string().regex(/^0x[0-9a-fA-F]{40}$/), digest = z.string().regex(/^[0-9a-f]{64}$/);
|
|
15
|
+
const commitment = z.string().regex(/^sha256:[0-9a-f]{64}$/), time = z.number().int().nonnegative().safe();
|
|
16
|
+
const pattern = /^(0|[1-9][0-9]{0,77})$/;
|
|
17
|
+
const uint = (bits = 256) => z
|
|
18
|
+
.string()
|
|
19
|
+
.max(78)
|
|
20
|
+
.regex(pattern)
|
|
21
|
+
.refine((value) => pattern.test(value) && BigInt(value) < 1n << BigInt(bits));
|
|
22
|
+
const operationId = z
|
|
23
|
+
.string()
|
|
24
|
+
.regex(/^sp_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
|
|
25
|
+
/** The canonical protocol operation ID is generated by this service, never accepted from the caller. */
|
|
26
|
+
export const LP_USEROP_PUBLIC_INTENT_SCHEMA = LP_USEROP_INPUT_SCHEMA.omit({ operationId: true })
|
|
27
|
+
.extend({
|
|
28
|
+
tokenId: uint(),
|
|
29
|
+
amountMax: z.tuple([uint(128), uint(128)]),
|
|
30
|
+
amountMin: z.tuple([uint(), uint()]),
|
|
31
|
+
})
|
|
32
|
+
.strict();
|
|
33
|
+
export const LP_USEROP_ACCOUNT_PREPARE_INPUT = z
|
|
34
|
+
.object({ accessToken: token, input: LP_USEROP_PUBLIC_INTENT_SCHEMA })
|
|
35
|
+
.strict();
|
|
36
|
+
export const LP_USEROP_ACCOUNT_READ_INPUT = z.object({ accessToken: token, operationId }).strict();
|
|
37
|
+
export const LP_USEROP_ACCOUNT_SUBMIT_INPUT = LP_USEROP_ACCOUNT_READ_INPUT.extend({
|
|
38
|
+
envelopeCommitment: commitment,
|
|
39
|
+
reviewCommitment: digest,
|
|
40
|
+
confirmation: z.enum([LP_USEROP_CONFIRMATION, LP_USEROP_ACCOUNT_GAS_CONFIRMATION]),
|
|
41
|
+
}).strict();
|
|
42
|
+
const pair = z.tuple([uint(), uint()]);
|
|
43
|
+
export const LP_USEROP_ACCOUNT_OPERATION_RESULT = z
|
|
44
|
+
.object({
|
|
45
|
+
schemaVersion: z.literal('1'),
|
|
46
|
+
kind: z.literal('lp-collect-userop'),
|
|
47
|
+
operationId,
|
|
48
|
+
account: address,
|
|
49
|
+
chainId: z.literal(8453),
|
|
50
|
+
protocol: z.literal('uniswap-v3'),
|
|
51
|
+
action: z.literal('guarded-collect'),
|
|
52
|
+
pool: address,
|
|
53
|
+
tokenId: uint(),
|
|
54
|
+
state: z.enum(['review', 'active', 'unknown', 'submitted', 'completed', 'failed']),
|
|
55
|
+
reviewConsumed: z.boolean(),
|
|
56
|
+
envelopeCommitment: commitment,
|
|
57
|
+
reviewCommitment: digest,
|
|
58
|
+
validUntilMs: time,
|
|
59
|
+
collection: z
|
|
60
|
+
.object({
|
|
61
|
+
tokens: z.tuple([address, address]),
|
|
62
|
+
maximum: pair,
|
|
63
|
+
minimum: pair,
|
|
64
|
+
tokensOwedAtReview: pair,
|
|
65
|
+
maximumAuthorized: pair,
|
|
66
|
+
mayIncludeOwedPrincipal: z.literal(true),
|
|
67
|
+
profitClassification: z.literal('UNKNOWN'),
|
|
68
|
+
distributableProfitRaw: z.null(),
|
|
69
|
+
})
|
|
70
|
+
.strict(),
|
|
71
|
+
gas: accountGasBudgetPublicSchema(uint()),
|
|
72
|
+
requiresOperationReview: z.boolean(),
|
|
73
|
+
confirmation: z.enum([LP_USEROP_CONFIRMATION, LP_USEROP_ACCOUNT_GAS_CONFIRMATION]),
|
|
74
|
+
protocolActionVerified: z.boolean(),
|
|
75
|
+
userOpHash: hash.optional(),
|
|
76
|
+
transactionHash: hash.optional(),
|
|
77
|
+
settlement: LP_USEROP_SETTLEMENT_SCHEMA.optional(),
|
|
78
|
+
failureCode: z
|
|
79
|
+
.enum([
|
|
80
|
+
'SPONSOR_NOT_SUBMITTED',
|
|
81
|
+
'SPONSOR_USER_OPERATION_REVERTED',
|
|
82
|
+
'SPONSOR_GAS_CAP_EXCEEDED',
|
|
83
|
+
])
|
|
84
|
+
.optional(),
|
|
85
|
+
attention: z
|
|
86
|
+
.literal('The original provider request is unresolved. Read or reconcile this operation; do not submit a replacement.')
|
|
87
|
+
.optional(),
|
|
88
|
+
automaticExecutionEnabled: z.literal(false),
|
|
89
|
+
walletAuthorityChangeIncluded: z.literal(false),
|
|
90
|
+
retrySafe: z.literal(false),
|
|
91
|
+
})
|
|
92
|
+
.strict()
|
|
93
|
+
.refine((value) => accountGasViewMatches(value) && value.confirmation === (value.gas.payer === 'account' ? LP_USEROP_ACCOUNT_GAS_CONFIRMATION : LP_USEROP_CONFIRMATION) && value.requiresOperationReview === (value.state === 'review') &&
|
|
94
|
+
value.reviewConsumed === (value.state !== 'review') &&
|
|
95
|
+
value.protocolActionVerified === (value.settlement?.status === 'completed') &&
|
|
96
|
+
(value.state !== 'completed' || value.settlement?.status === 'completed') &&
|
|
97
|
+
(!value.settlement ||
|
|
98
|
+
(value.settlement.status === 'completed'
|
|
99
|
+
? value.state === 'completed'
|
|
100
|
+
: value.settlement.status === 'reverted' && value.state === 'failed')) &&
|
|
101
|
+
(!value.transactionHash || !!value.userOpHash) &&
|
|
102
|
+
(value.gas.payer !== 'sponsor' || !value.gas.activationChainHalted ||
|
|
103
|
+
(value.state === 'submitted' && value.failureCode === 'SPONSOR_GAS_CAP_EXCEEDED')), 'LP state must agree with the reviewed operation and canonical accounting proof');
|
|
104
|
+
export function lpUserOpAccountView(operation) {
|
|
105
|
+
const { context } = operation, { input, baseline, terms } = assertLpUserOpEnvelope(context.envelope);
|
|
106
|
+
return freezeHybridValue(LP_USEROP_ACCOUNT_OPERATION_RESULT.parse({
|
|
107
|
+
schemaVersion: '1',
|
|
108
|
+
kind: 'lp-collect-userop',
|
|
109
|
+
operationId: operation.operationId,
|
|
110
|
+
account: context.account,
|
|
111
|
+
chainId: terms.chainId,
|
|
112
|
+
protocol: 'uniswap-v3',
|
|
113
|
+
action: 'guarded-collect',
|
|
114
|
+
pool: input.pool,
|
|
115
|
+
tokenId: input.tokenId,
|
|
116
|
+
state: operation.state,
|
|
117
|
+
reviewConsumed: operation.reviewConsumed,
|
|
118
|
+
envelopeCommitment: context.envelope.commitment,
|
|
119
|
+
reviewCommitment: operation.reviewCommitment,
|
|
120
|
+
validUntilMs: context.validUntilMs,
|
|
121
|
+
collection: {
|
|
122
|
+
tokens: [input.token0, input.token1],
|
|
123
|
+
maximum: input.amountMax,
|
|
124
|
+
minimum: input.amountMin,
|
|
125
|
+
tokensOwedAtReview: baseline.position.tokensOwed,
|
|
126
|
+
maximumAuthorized: terms.maximumCollectAtomic,
|
|
127
|
+
mayIncludeOwedPrincipal: true,
|
|
128
|
+
profitClassification: 'UNKNOWN',
|
|
129
|
+
distributableProfitRaw: null,
|
|
130
|
+
},
|
|
131
|
+
gas: accountGasView(operation, { maximumCostWei: terms.maxGasCostWei,
|
|
132
|
+
maximumUserCostWei: terms.maxUserGasCostWei, maximumActivationCostWei: terms.maxTotalGasCostWei }),
|
|
133
|
+
requiresOperationReview: operation.state === 'review',
|
|
134
|
+
confirmation: operation.gasReview?.payer === 'account' ? LP_USEROP_ACCOUNT_GAS_CONFIRMATION : LP_USEROP_CONFIRMATION,
|
|
135
|
+
protocolActionVerified: operation.settlement?.status === 'completed',
|
|
136
|
+
...(operation.userOpHash ? { userOpHash: operation.userOpHash } : {}),
|
|
137
|
+
...(operation.transactionHash ? { transactionHash: operation.transactionHash } : {}),
|
|
138
|
+
...(operation.settlement ? { settlement: operation.settlement } : {}),
|
|
139
|
+
...(operation.failureCode ? { failureCode: operation.failureCode } : {}),
|
|
140
|
+
...(operation.state === 'unknown' && !operation.userOpHash
|
|
141
|
+
? {
|
|
142
|
+
attention: 'The original provider request is unresolved. Read or reconcile this operation; do not submit a replacement.',
|
|
143
|
+
}
|
|
144
|
+
: {}),
|
|
145
|
+
automaticExecutionEnabled: false,
|
|
146
|
+
walletAuthorityChangeIncluded: false,
|
|
147
|
+
retrySafe: false,
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
const equal = (left, right) => hybridYieldCommitment(left) === hybridYieldCommitment(right);
|
|
151
|
+
function refuse(code) {
|
|
152
|
+
throw new Error(code);
|
|
153
|
+
}
|
|
154
|
+
/** Current invocation was refused before its provider callback ran; says nothing about older attempts. */
|
|
155
|
+
export class LpUserOpPreHandoffRefusal extends Error {
|
|
156
|
+
constructor() {
|
|
157
|
+
super('LP_USEROP_REQUEST_REFUSED');
|
|
158
|
+
this.name = 'LpUserOpPreHandoffRefusal';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
export class LpUserOpAccountService {
|
|
162
|
+
issuer;
|
|
163
|
+
protocol;
|
|
164
|
+
runtime;
|
|
165
|
+
store;
|
|
166
|
+
guards;
|
|
167
|
+
transport;
|
|
168
|
+
gasRuntime;
|
|
169
|
+
constructor(issuer, protocol, runtime, store, guards, transport, gasRuntime) {
|
|
170
|
+
this.issuer = issuer;
|
|
171
|
+
this.protocol = protocol;
|
|
172
|
+
this.runtime = runtime;
|
|
173
|
+
this.store = store;
|
|
174
|
+
this.guards = guards;
|
|
175
|
+
this.transport = transport;
|
|
176
|
+
this.gasRuntime = gasRuntime;
|
|
177
|
+
}
|
|
178
|
+
requireProtocol() {
|
|
179
|
+
return this.protocol ?? refuse('LP_USEROP_CHAIN_UNAVAILABLE');
|
|
180
|
+
}
|
|
181
|
+
async owned(accessToken, id) {
|
|
182
|
+
let userId;
|
|
183
|
+
try {
|
|
184
|
+
userId = (await this.runtime.cdp.endUser.validateAccessToken({ accessToken })).userId;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return refuse('LP_USEROP_SESSION_INVALID');
|
|
188
|
+
}
|
|
189
|
+
if (!/^[a-zA-Z0-9-]{1,100}$/.test(userId))
|
|
190
|
+
return refuse('LP_USEROP_SESSION_INVALID');
|
|
191
|
+
const operation = this.store.read(userId, id), who = await this.runtime.identity(accessToken, operation.context.account);
|
|
192
|
+
if (who.userId !== operation.userId)
|
|
193
|
+
return refuse('LP_USEROP_OWNER_MISMATCH');
|
|
194
|
+
return operation;
|
|
195
|
+
}
|
|
196
|
+
async prepare(raw) {
|
|
197
|
+
const request = LP_USEROP_ACCOUNT_PREPARE_INPUT.parse(raw);
|
|
198
|
+
this.store.assertReadyForNewOperations();
|
|
199
|
+
const input = LP_USEROP_INPUT_SCHEMA.parse({
|
|
200
|
+
...request.input,
|
|
201
|
+
operationId: `lp_${randomUUID()}`,
|
|
202
|
+
});
|
|
203
|
+
let authority = await this.issuer.mint(request.accessToken, input);
|
|
204
|
+
const envelope = await prepareLpUserOp(this.requireProtocol(), input, this.issuer.terms(authority));
|
|
205
|
+
authority = await this.issuer.refresh(request.accessToken, authority);
|
|
206
|
+
const context = LP_USEROP_CONTEXT_SCHEMA.parse({
|
|
207
|
+
kind: 'lp-collect-userop',
|
|
208
|
+
account: envelope.terms.account,
|
|
209
|
+
chainId: envelope.terms.chainId,
|
|
210
|
+
envelope,
|
|
211
|
+
review: this.issuer.reviewRecord(authority),
|
|
212
|
+
authority: this.issuer.sponsorship(authority),
|
|
213
|
+
activation: this.issuer.activation(authority),
|
|
214
|
+
reviewedAtMs: envelope.preparedAtMs,
|
|
215
|
+
validUntilMs: envelope.validUntilMs,
|
|
216
|
+
});
|
|
217
|
+
const operation = this.store.transaction(() => {
|
|
218
|
+
this.issuer.assertCurrent(authority);
|
|
219
|
+
assertLpUserOpContext(context, true, this.runtime.now());
|
|
220
|
+
return this.store.create(context);
|
|
221
|
+
});
|
|
222
|
+
const guard = await this.guards.acquire('sponsored', operation.operationId, true);
|
|
223
|
+
guard.release();
|
|
224
|
+
if (context.activation.gasPaymentReviewEnabled) {
|
|
225
|
+
try {
|
|
226
|
+
return await this.reviewGas({ accessToken: request.accessToken,
|
|
227
|
+
operationId: operation.operationId, reviewCommitment: operation.reviewCommitment, preference: 'auto' });
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
return lpUserOpAccountView(this.store.recordGasReviewFailure(operation.userId, operation.operationId, accountGasFailure(error) ?? 'ACCOUNT_GAS_QUOTE_UNAVAILABLE'));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return lpUserOpAccountView(operation);
|
|
234
|
+
}
|
|
235
|
+
async reviewGas(raw) {
|
|
236
|
+
const input = SPONSORED_GAS_REVIEW_INPUT.extend({ operationId: LP_USEROP_ACCOUNT_READ_INPUT.shape.operationId }).parse(raw), owned = await this.owned(input.accessToken, input.operationId);
|
|
237
|
+
const guard = await this.guards.acquire('sponsored', owned.operationId, false);
|
|
238
|
+
try {
|
|
239
|
+
const operation = this.store.read(owned.userId, owned.operationId);
|
|
240
|
+
if (!this.gasRuntime || (operation.state !== 'review' && !(operation.state === 'failed' && !operation.handoffAttempted && operation.failureCode === 'SPONSOR_NOT_SUBMITTED')))
|
|
241
|
+
return refuse('ACCOUNT_GAS_REVIEW_UNAVAILABLE');
|
|
242
|
+
const authority = await this.issuer.restoreFromTrustedReview(input.accessToken, operation.context.review);
|
|
243
|
+
this.assertCurrentReview(operation, authority);
|
|
244
|
+
const gasReview = await this.gasRuntime.review(operation, lpUserOpRecordedCalls(operation.context.envelope), input.preference);
|
|
245
|
+
return lpUserOpAccountView(this.store.reviewGas(operation.userId, operation.operationId, input.reviewCommitment, gasReview));
|
|
246
|
+
}
|
|
247
|
+
finally {
|
|
248
|
+
guard.release();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
async read(raw) {
|
|
252
|
+
const input = LP_USEROP_ACCOUNT_READ_INPUT.parse(raw);
|
|
253
|
+
return lpUserOpAccountView(await this.owned(input.accessToken, input.operationId));
|
|
254
|
+
}
|
|
255
|
+
assertCurrentReview(operation, authority) {
|
|
256
|
+
if (!equal(this.issuer.reviewRecord(authority), operation.context.review) ||
|
|
257
|
+
!equal(this.issuer.terms(authority), operation.context.envelope.terms))
|
|
258
|
+
return refuse('LP_USEROP_REVIEW_CHANGED');
|
|
259
|
+
assertLpUserOpContext(operation.context, true, this.runtime.now());
|
|
260
|
+
}
|
|
261
|
+
async submit(raw) {
|
|
262
|
+
let providerInvoked = false;
|
|
263
|
+
try {
|
|
264
|
+
return await this.submitOnce(raw, () => {
|
|
265
|
+
providerInvoked = true;
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
if (!providerInvoked)
|
|
270
|
+
throw new LpUserOpPreHandoffRefusal();
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
async submitOnce(raw, providerStarted) {
|
|
275
|
+
const input = LP_USEROP_ACCOUNT_SUBMIT_INPUT.parse(raw), owned = await this.owned(input.accessToken, input.operationId);
|
|
276
|
+
if (owned.state !== 'review' ||
|
|
277
|
+
owned.reviewConsumed ||
|
|
278
|
+
input.reviewCommitment !== owned.reviewCommitment ||
|
|
279
|
+
input.envelopeCommitment !== owned.context.envelope.commitment)
|
|
280
|
+
return refuse('LP_USEROP_REVIEW_REQUIRED');
|
|
281
|
+
if (input.confirmation !== (owned.gasReview?.payer === 'account' ? LP_USEROP_ACCOUNT_GAS_CONFIRMATION : LP_USEROP_CONFIRMATION))
|
|
282
|
+
throw new AccountGasConfirmationRefusal();
|
|
283
|
+
const guard = await this.guards.acquire('sponsored', owned.operationId, false);
|
|
284
|
+
try {
|
|
285
|
+
let authority = await this.issuer.restoreFromTrustedReview(input.accessToken, owned.context.review);
|
|
286
|
+
this.assertCurrentReview(owned, authority);
|
|
287
|
+
const simulation = await simulateLpUserOp(this.requireProtocol(), owned.context.envelope, this.issuer.terms(authority));
|
|
288
|
+
authority = await this.issuer.refresh(input.accessToken, authority);
|
|
289
|
+
this.assertCurrentReview(owned, authority);
|
|
290
|
+
this.store.transaction(() => {
|
|
291
|
+
this.store.begin(owned.userId, owned.operationId, input.reviewCommitment, this.issuer.sponsorship(authority));
|
|
292
|
+
this.issuer.assertCurrent(authority);
|
|
293
|
+
});
|
|
294
|
+
let handoffProof;
|
|
295
|
+
let unattemptedRecordCommitment;
|
|
296
|
+
try {
|
|
297
|
+
const operation = this.store.read(owned.userId, owned.operationId);
|
|
298
|
+
unattemptedRecordCommitment = hybridYieldCommitment(operation);
|
|
299
|
+
const request = this.transport.prepare({
|
|
300
|
+
userId: operation.userId,
|
|
301
|
+
account: operation.context.account,
|
|
302
|
+
chainId: operation.context.chainId,
|
|
303
|
+
idempotencyKey: operation.operationId.slice(3),
|
|
304
|
+
}, lpUserOpCalls(simulation), operation.gasReview?.payer ?? 'sponsor');
|
|
305
|
+
unattemptedRecordCommitment = hybridYieldCommitment(this.store.prepare(operation.userId, operation.operationId, request));
|
|
306
|
+
let verified;
|
|
307
|
+
let checkedGas;
|
|
308
|
+
const result = await this.transport.send(request, async () => {
|
|
309
|
+
if (operation.context.activation.gasPaymentReviewEnabled && !this.gasRuntime)
|
|
310
|
+
return refuse('ACCOUNT_GAS_REVIEW_UNAVAILABLE');
|
|
311
|
+
checkedGas = await this.gasRuntime?.revalidate(operation, lpUserOpRecordedCalls(operation.context.envelope));
|
|
312
|
+
// Finish all asynchronous protocol/profile and authority reads before the attempted stamp.
|
|
313
|
+
verified = await verifyLpUserOp(this.requireProtocol(), operation.context.envelope, this.issuer.terms(authority));
|
|
314
|
+
authority = await this.issuer.refresh(input.accessToken, authority);
|
|
315
|
+
this.assertCurrentReview(operation, authority);
|
|
316
|
+
assertFreshVerifiedLpUserOp(verified, this.runtime.now());
|
|
317
|
+
unattemptedRecordCommitment = hybridYieldCommitment(this.store.recordLpVerification(operation.userId, operation.operationId, lpUserOpVerificationEvidence(verified)));
|
|
318
|
+
}, (start) => {
|
|
319
|
+
handoffProof = this.store.attemptedWithProof(operation.userId, operation.operationId);
|
|
320
|
+
return this.store.handoff(operation.userId, operation.operationId, () => {
|
|
321
|
+
// Preserve journal -> caps ordering, including the shared gas circuit. No await follows the stamp.
|
|
322
|
+
this.issuer.assertCurrent(authority);
|
|
323
|
+
this.assertCurrentReview(operation, authority);
|
|
324
|
+
return this.issuer.withCurrentCap(authority, () => {
|
|
325
|
+
this.assertCurrentReview(operation, authority);
|
|
326
|
+
if (!verified || !handoffProof)
|
|
327
|
+
return refuse('LP_USEROP_HANDOFF_UNVERIFIED');
|
|
328
|
+
assertFreshVerifiedLpUserOp(verified, this.runtime.now());
|
|
329
|
+
return start((gasPolicy) => {
|
|
330
|
+
this.gasRuntime?.assertFresh(operation, lpUserOpRecordedCalls(operation.context.envelope), checkedGas, gasPolicy);
|
|
331
|
+
this.store.consumeHandoffProof(handoffProof);
|
|
332
|
+
providerStarted();
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
this.store.acknowledged(operation.userId, operation.operationId, result);
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
const current = this.store.read(owned.userId, owned.operationId);
|
|
341
|
+
if (current.state === 'active' &&
|
|
342
|
+
!current.handoffAttempted &&
|
|
343
|
+
!current.userOpHash &&
|
|
344
|
+
!current.transactionHash &&
|
|
345
|
+
unattemptedRecordCommitment === hybridYieldCommitment(current))
|
|
346
|
+
this.store.failBeforeHandoff(owned.userId, owned.operationId);
|
|
347
|
+
else if (handoffProof) {
|
|
348
|
+
try {
|
|
349
|
+
this.store.failUninvokedHandoff(handoffProof);
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
/* Invoked, changed, restarted or uncertain journal state retains the original claim. */
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const gasFailure = accountGasFailure(error);
|
|
356
|
+
if (gasFailure)
|
|
357
|
+
this.store.recordGasReviewFailure(owned.userId, owned.operationId, gasFailure);
|
|
358
|
+
return lpUserOpAccountView(this.store.read(owned.userId, owned.operationId));
|
|
359
|
+
}
|
|
360
|
+
return await this.reconcileOwned(this.store.read(owned.userId, owned.operationId));
|
|
361
|
+
}
|
|
362
|
+
finally {
|
|
363
|
+
guard.release();
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/** Owned reconciliation survives expired review, Stop and removed delegation; it grants no new send authority. */
|
|
367
|
+
async reconcile(raw) {
|
|
368
|
+
const input = LP_USEROP_ACCOUNT_READ_INPUT.parse(raw), operation = await this.owned(input.accessToken, input.operationId);
|
|
369
|
+
if (['review', 'completed', 'failed'].includes(operation.state))
|
|
370
|
+
return lpUserOpAccountView(operation);
|
|
371
|
+
const guard = await this.guards.acquire('sponsored', operation.operationId, false);
|
|
372
|
+
try {
|
|
373
|
+
return await this.reconcileOwned(this.store.read(operation.userId, operation.operationId));
|
|
374
|
+
}
|
|
375
|
+
finally {
|
|
376
|
+
guard.release();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
async reconcileOwned(operation) {
|
|
380
|
+
if (!operation.handoffAttempted)
|
|
381
|
+
return lpUserOpAccountView(this.store.failBeforeHandoff(operation.userId, operation.operationId));
|
|
382
|
+
if (!operation.userOpHash || !operation.submitEvidence)
|
|
383
|
+
return lpUserOpAccountView(operation);
|
|
384
|
+
try {
|
|
385
|
+
const acknowledgement = await this.runtime.readAcknowledgement(operation, lpUserOpRecordedCalls(operation.context.envelope));
|
|
386
|
+
operation = this.store.acknowledged(operation.userId, operation.operationId, acknowledgement);
|
|
387
|
+
if (!operation.transactionHash || !operation.submitEvidence)
|
|
388
|
+
return lpUserOpAccountView(operation);
|
|
389
|
+
const { terms } = operation.context.envelope;
|
|
390
|
+
const binding = {
|
|
391
|
+
userOpHash: operation.userOpHash,
|
|
392
|
+
transactionHash: operation.transactionHash,
|
|
393
|
+
};
|
|
394
|
+
const receipt = await readConfirmedSponsoredReceipt({
|
|
395
|
+
...binding,
|
|
396
|
+
chainId: terms.chainId,
|
|
397
|
+
account: terms.account,
|
|
398
|
+
entryPoint: terms.entryPoint,
|
|
399
|
+
payer: operation.gasReview?.payer ?? 'sponsor',
|
|
400
|
+
paymaster: operation.gasReview?.payer === 'account' ? '0x0000000000000000000000000000000000000000' : terms.paymaster,
|
|
401
|
+
maxGasCostWei: BigInt(terms.maxGasCostWei),
|
|
402
|
+
}, this.runtime.client(terms.chainId));
|
|
403
|
+
const settlement = await readLpUserOpSettlement(operation.context.envelope, binding, this.requireProtocol(), operation.submitEvidence, operation.gasReview?.payer ?? 'sponsor');
|
|
404
|
+
if (!settlement.releaseClaim)
|
|
405
|
+
return lpUserOpAccountView(this.store.read(operation.userId, operation.operationId));
|
|
406
|
+
return lpUserOpAccountView(this.store.finish(operation.userId, operation.operationId, receipt, settlement));
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
if (error instanceof SponsoredReceiptUnconfirmedError &&
|
|
410
|
+
error.code === 'SPONSOR_GAS_CAP_EXCEEDED' &&
|
|
411
|
+
error.breachedReceipt)
|
|
412
|
+
return lpUserOpAccountView(this.store.recordGasCapBreach(operation.userId, operation.operationId, error.breachedReceipt));
|
|
413
|
+
return lpUserOpAccountView(this.store.read(operation.userId, operation.operationId));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
//# sourceMappingURL=lp-userop-account.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type SponsoredActivation, type SponsoredAuthority } from './execution-sponsored-definition.js';
|
|
2
|
+
import { SponsoredAccountRuntime } from './execution-sponsored-runtime.js';
|
|
3
|
+
import { type NativeYieldAccountActivation } from './native-yield-account-definition.js';
|
|
4
|
+
import { type LpUserOpActivation, type LpUserOpReviewRecord, type LpUserOpTerms } from './lp-userop-definition.js';
|
|
5
|
+
export declare class LpUserOpAuthorityRefusal extends Error {
|
|
6
|
+
readonly code: string;
|
|
7
|
+
constructor(code: string);
|
|
8
|
+
}
|
|
9
|
+
declare const brand: unique symbol;
|
|
10
|
+
/** Only this issuer can turn fresh authenticated facts into an operation authority. */
|
|
11
|
+
export interface LpUserOpAuthority {
|
|
12
|
+
readonly [brand]: true;
|
|
13
|
+
}
|
|
14
|
+
export declare class LpUserOpAuthorityIssuer {
|
|
15
|
+
private readonly sponsor;
|
|
16
|
+
private readonly issued;
|
|
17
|
+
private readonly capLocked;
|
|
18
|
+
private readonly nativeActivations;
|
|
19
|
+
private readonly sponsorActivations;
|
|
20
|
+
private readonly lpActivations;
|
|
21
|
+
constructor(sponsor: SponsoredAccountRuntime,
|
|
22
|
+
/** Internal fixtures only; the production constructor reads three empty reviewed source arrays. */
|
|
23
|
+
fixtures?: {
|
|
24
|
+
nativeActivations: readonly NativeYieldAccountActivation[];
|
|
25
|
+
sponsoredActivations: readonly SponsoredActivation[];
|
|
26
|
+
lpActivations: readonly LpUserOpActivation[];
|
|
27
|
+
});
|
|
28
|
+
private now;
|
|
29
|
+
private sources;
|
|
30
|
+
private window;
|
|
31
|
+
private derivedTerms;
|
|
32
|
+
private facts;
|
|
33
|
+
private issue;
|
|
34
|
+
mint(accessToken: string, rawInput: unknown): Promise<LpUserOpAuthority>;
|
|
35
|
+
private read;
|
|
36
|
+
refresh(accessToken: string, authority: LpUserOpAuthority): Promise<LpUserOpAuthority>;
|
|
37
|
+
/** Only immutable trusted journal context may enter here; never caller-supplied terms. */
|
|
38
|
+
restoreFromTrustedReview(accessToken: string, rawReview: unknown): Promise<LpUserOpAuthority>;
|
|
39
|
+
private assertScope;
|
|
40
|
+
/** Synchronous source/time and Stop check, including inside the caller's shared-journal stamp. */
|
|
41
|
+
assertCurrent(authority: LpUserOpAuthority): void;
|
|
42
|
+
/** The existing cap writer lock orders Stop against the synchronous provider POST invocation. */
|
|
43
|
+
withCurrentCap<T>(authority: LpUserOpAuthority, start: () => T): T;
|
|
44
|
+
terms(authority: LpUserOpAuthority): LpUserOpTerms;
|
|
45
|
+
reviewRecord(authority: LpUserOpAuthority): LpUserOpReviewRecord;
|
|
46
|
+
sponsorship(authority: LpUserOpAuthority): SponsoredAuthority;
|
|
47
|
+
activation(authority: LpUserOpAuthority): SponsoredActivation;
|
|
48
|
+
}
|
|
49
|
+
export {};
|