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.
Files changed (239) hide show
  1. package/README.md +76 -18
  2. package/dist/account-userop-policy-definition.d.ts +14 -0
  3. package/dist/account-userop-policy-definition.js +12 -0
  4. package/dist/account-userop-policy-relation.d.ts +371 -0
  5. package/dist/account-userop-policy-relation.js +87 -0
  6. package/dist/adapter/cdp-signer.d.ts +76 -9
  7. package/dist/adapter/cdp-signer.js +274 -33
  8. package/dist/adapter/evm-call-failure.d.ts +29 -0
  9. package/dist/adapter/evm-call-failure.js +109 -0
  10. package/dist/adapter/refusal.d.ts +1 -1
  11. package/dist/adapter/refusal.js +13 -0
  12. package/dist/adapter/route-simulator.d.ts +91 -0
  13. package/dist/adapter/route-simulator.js +143 -0
  14. package/dist/adapter-cdp-index.d.ts +1 -1
  15. package/dist/executable-equities.d.ts +55 -0
  16. package/dist/executable-equities.js +116 -0
  17. package/dist/executable-yield-markets.d.ts +261 -0
  18. package/dist/executable-yield-markets.js +154 -0
  19. package/dist/execution-account-gas-quote.d.ts +141 -0
  20. package/dist/execution-account-gas-quote.js +443 -0
  21. package/dist/execution-account-gas-review.d.ts +123 -0
  22. package/dist/execution-account-gas-review.js +104 -0
  23. package/dist/execution-account-gas-runtime.d.ts +33 -0
  24. package/dist/execution-account-gas-runtime.js +131 -0
  25. package/dist/execution-account-gas-view.d.ts +936 -0
  26. package/dist/execution-account-gas-view.js +56 -0
  27. package/dist/execution-config.d.ts +3 -0
  28. package/dist/execution-config.js +4 -0
  29. package/dist/execution-delegated-definition.d.ts +7 -6
  30. package/dist/execution-delegated-definition.js +13 -2
  31. package/dist/execution-delegation-admin-definition.d.ts +127 -5
  32. package/dist/execution-delegation-admin-definition.js +155 -5
  33. package/dist/execution-delegation-admin.d.ts +48 -2
  34. package/dist/execution-delegation-admin.js +422 -12
  35. package/dist/execution-delegation-cap-store.d.ts +386 -0
  36. package/dist/execution-delegation-cap-store.js +1150 -0
  37. package/dist/execution-delegation-exit-definition.d.ts +309 -0
  38. package/dist/execution-delegation-exit-definition.js +204 -0
  39. package/dist/execution-delegation-exit-store.d.ts +114 -0
  40. package/dist/execution-delegation-exit-store.js +671 -0
  41. package/dist/execution-delegation-exit.d.ts +4 -0
  42. package/dist/execution-delegation-exit.js +614 -0
  43. package/dist/execution-delegation-finality.d.ts +22 -0
  44. package/dist/execution-delegation-finality.js +90 -0
  45. package/dist/execution-delegation-operation-store.d.ts +129 -0
  46. package/dist/execution-delegation-operation-store.js +1107 -0
  47. package/dist/execution-delegation-operations-definition.d.ts +282 -0
  48. package/dist/execution-delegation-operations-definition.js +117 -0
  49. package/dist/execution-delegation-operations.d.ts +6 -0
  50. package/dist/execution-delegation-operations.js +282 -0
  51. package/dist/execution-delegation-policy.d.ts +154 -8
  52. package/dist/execution-delegation-policy.js +273 -40
  53. package/dist/execution-delegation.d.ts +51 -0
  54. package/dist/execution-delegation.js +441 -31
  55. package/dist/execution-errors.d.ts +1 -1
  56. package/dist/execution-errors.js +122 -0
  57. package/dist/execution-index.d.ts +7 -2
  58. package/dist/execution-index.js +7 -2
  59. package/dist/execution-journal-schema.d.ts +96 -0
  60. package/dist/execution-journal-schema.js +368 -0
  61. package/dist/execution-journal-tables.d.ts +14 -0
  62. package/dist/execution-journal-tables.js +227 -0
  63. package/dist/execution-policy-compatibility.d.ts +34 -0
  64. package/dist/execution-policy-compatibility.js +76 -0
  65. package/dist/execution-registration.d.ts +54 -2
  66. package/dist/execution-registration.js +151 -5
  67. package/dist/execution-sponsored-account-profile.d.ts +32 -0
  68. package/dist/execution-sponsored-account-profile.js +59 -0
  69. package/dist/execution-sponsored-account.d.ts +1519 -0
  70. package/dist/execution-sponsored-account.js +222 -0
  71. package/dist/execution-sponsored-definition.d.ts +1713 -0
  72. package/dist/execution-sponsored-definition.js +185 -0
  73. package/dist/execution-sponsored-gas-policy.d.ts +27 -0
  74. package/dist/execution-sponsored-gas-policy.js +110 -0
  75. package/dist/execution-sponsored-hosted.d.ts +3 -0
  76. package/dist/execution-sponsored-hosted.js +71 -0
  77. package/dist/execution-sponsored-index.d.ts +1322 -0
  78. package/dist/execution-sponsored-index.js +102 -0
  79. package/dist/execution-sponsored-mcp-definition.d.ts +1662 -0
  80. package/dist/execution-sponsored-mcp-definition.js +94 -0
  81. package/dist/execution-sponsored-receipt.d.ts +47 -0
  82. package/dist/execution-sponsored-receipt.js +74 -0
  83. package/dist/execution-sponsored-registration.d.ts +14 -0
  84. package/dist/execution-sponsored-registration.js +77 -0
  85. package/dist/execution-sponsored-runtime.d.ts +84 -0
  86. package/dist/execution-sponsored-runtime.js +149 -0
  87. package/dist/execution-sponsored-settlement.d.ts +15 -0
  88. package/dist/execution-sponsored-settlement.js +88 -0
  89. package/dist/execution-sponsored-store.d.ts +67 -0
  90. package/dist/execution-sponsored-store.js +517 -0
  91. package/dist/execution-sponsored-transport.d.ts +90 -0
  92. package/dist/execution-sponsored-transport.js +180 -0
  93. package/dist/execution-tool-definitions.d.ts +21 -21
  94. package/dist/execution-tool-definitions.js +0 -7
  95. package/dist/execution-tools.d.ts +53 -1
  96. package/dist/execution-tools.js +171 -13
  97. package/dist/execution-worker-guard.d.ts +28 -0
  98. package/dist/execution-worker-guard.js +124 -0
  99. package/dist/hybrid-yield-index.d.ts +10 -0
  100. package/dist/hybrid-yield-index.js +11 -0
  101. package/dist/hybrid-yield-markets.d.ts +96 -0
  102. package/dist/hybrid-yield-markets.js +124 -0
  103. package/dist/hybrid-yield.d.ts +411 -0
  104. package/dist/hybrid-yield.js +155 -0
  105. package/dist/hyperliquid-order-builder.js +4 -0
  106. package/dist/lifi-execution-client.d.ts +6 -0
  107. package/dist/lifi-execution-client.js +3 -0
  108. package/dist/lp-userop-account.d.ts +461 -0
  109. package/dist/lp-userop-account.js +417 -0
  110. package/dist/lp-userop-authority.d.ts +49 -0
  111. package/dist/lp-userop-authority.js +211 -0
  112. package/dist/lp-userop-definition.d.ts +233 -0
  113. package/dist/lp-userop-definition.js +85 -0
  114. package/dist/lp-userop-hosted.d.ts +3 -0
  115. package/dist/lp-userop-hosted.js +73 -0
  116. package/dist/lp-userop-index.d.ts +1569 -0
  117. package/dist/lp-userop-index.js +112 -0
  118. package/dist/lp-userop-mcp-definition.d.ts +1220 -0
  119. package/dist/lp-userop-mcp-definition.js +46 -0
  120. package/dist/lp-userop-operation.d.ts +1230 -0
  121. package/dist/lp-userop-operation.js +140 -0
  122. package/dist/lp-userop-registration.d.ts +14 -0
  123. package/dist/lp-userop-registration.js +70 -0
  124. package/dist/lp-userop-settlement.d.ts +89 -0
  125. package/dist/lp-userop-settlement.js +184 -0
  126. package/dist/lp-userop.d.ts +643 -0
  127. package/dist/lp-userop.js +343 -0
  128. package/dist/native-yield-account-definition.d.ts +1192 -0
  129. package/dist/native-yield-account-definition.js +232 -0
  130. package/dist/native-yield-account-gas.d.ts +58 -0
  131. package/dist/native-yield-account-gas.js +228 -0
  132. package/dist/native-yield-account-index.d.ts +23 -0
  133. package/dist/native-yield-account-index.js +28 -0
  134. package/dist/native-yield-account-policy.d.ts +168 -0
  135. package/dist/native-yield-account-policy.js +525 -0
  136. package/dist/native-yield-account-rpc.d.ts +8 -0
  137. package/dist/native-yield-account-rpc.js +128 -0
  138. package/dist/native-yield-account-runtime.d.ts +71 -0
  139. package/dist/native-yield-account-runtime.js +125 -0
  140. package/dist/native-yield-account-store.d.ts +40 -0
  141. package/dist/native-yield-account-store.js +307 -0
  142. package/dist/native-yield-account.d.ts +662 -0
  143. package/dist/native-yield-account.js +371 -0
  144. package/dist/native-yield-consent-store.d.ts +20 -0
  145. package/dist/native-yield-consent-store.js +317 -0
  146. package/dist/native-yield-definition.d.ts +288 -0
  147. package/dist/native-yield-definition.js +105 -0
  148. package/dist/native-yield-reader.d.ts +4 -0
  149. package/dist/native-yield-reader.js +137 -0
  150. package/dist/native-yield-settlement.d.ts +48 -0
  151. package/dist/native-yield-settlement.js +167 -0
  152. package/dist/native-yield-simulation.d.ts +18 -0
  153. package/dist/native-yield-simulation.js +45 -0
  154. package/dist/native-yield-userop-account.d.ts +675 -0
  155. package/dist/native-yield-userop-account.js +357 -0
  156. package/dist/native-yield-userop-authority.d.ts +214 -0
  157. package/dist/native-yield-userop-authority.js +296 -0
  158. package/dist/native-yield-userop-definition.d.ts +331 -0
  159. package/dist/native-yield-userop-definition.js +105 -0
  160. package/dist/native-yield-userop-hosted.d.ts +3 -0
  161. package/dist/native-yield-userop-hosted.js +71 -0
  162. package/dist/native-yield-userop-index.d.ts +1522 -0
  163. package/dist/native-yield-userop-index.js +142 -0
  164. package/dist/native-yield-userop-mcp-definition.d.ts +1356 -0
  165. package/dist/native-yield-userop-mcp-definition.js +50 -0
  166. package/dist/native-yield-userop-operation.d.ts +845 -0
  167. package/dist/native-yield-userop-operation.js +127 -0
  168. package/dist/native-yield-userop-policy.d.ts +23 -0
  169. package/dist/native-yield-userop-policy.js +25 -0
  170. package/dist/native-yield-userop-registration.d.ts +17 -0
  171. package/dist/native-yield-userop-registration.js +76 -0
  172. package/dist/native-yield-userop-settlement.d.ts +8 -0
  173. package/dist/native-yield-userop-settlement.js +79 -0
  174. package/dist/native-yield-userop-simulation.d.ts +18 -0
  175. package/dist/native-yield-userop-simulation.js +34 -0
  176. package/dist/native-yield-userop.d.ts +35 -0
  177. package/dist/native-yield-userop.js +156 -0
  178. package/dist/native-yield-verify.d.ts +30 -0
  179. package/dist/native-yield-verify.js +141 -0
  180. package/dist/native-yield.d.ts +17 -0
  181. package/dist/native-yield.js +119 -0
  182. package/dist/stdio-main.js +0 -0
  183. package/dist/stock-buy-definition.d.ts +338 -0
  184. package/dist/stock-buy-definition.js +127 -0
  185. package/dist/stock-buy-oracle.d.ts +8 -0
  186. package/dist/stock-buy-oracle.js +22 -0
  187. package/dist/stock-buy.d.ts +17 -0
  188. package/dist/stock-buy.js +164 -0
  189. package/dist/tool-definitions.d.ts +3 -1
  190. package/dist/tool-definitions.js +55 -2
  191. package/dist/vendor/lp-v3/lp-v3-atomic-contract.d.ts +445 -0
  192. package/dist/vendor/lp-v3/lp-v3-atomic-contract.js +90 -0
  193. package/dist/vendor/lp-v3/lp-v3-atomic-evidence.d.ts +14 -0
  194. package/dist/vendor/lp-v3/lp-v3-atomic-evidence.js +82 -0
  195. package/dist/vendor/lp-v3/lp-v3-atomic-index.d.ts +80 -0
  196. package/dist/vendor/lp-v3/lp-v3-atomic-index.js +19 -0
  197. package/dist/vendor/lp-v3/lp-v3-atomic-plan.d.ts +43 -0
  198. package/dist/vendor/lp-v3/lp-v3-atomic-plan.js +112 -0
  199. package/dist/vendor/lp-v3/lp-v3-atomic-read-contract.d.ts +312 -0
  200. package/dist/vendor/lp-v3/lp-v3-atomic-read-contract.js +41 -0
  201. package/dist/vendor/lp-v3/lp-v3-atomic-read-index.d.ts +3 -0
  202. package/dist/vendor/lp-v3/lp-v3-atomic-read-index.js +3 -0
  203. package/dist/vendor/lp-v3/lp-v3-atomic-read-rpc.d.ts +49 -0
  204. package/dist/vendor/lp-v3/lp-v3-atomic-read-rpc.js +88 -0
  205. package/dist/vendor/lp-v3/lp-v3-atomic-read.d.ts +17 -0
  206. package/dist/vendor/lp-v3/lp-v3-atomic-read.js +232 -0
  207. package/dist/vendor/lp-v3/lp-v3-atomic-settlement.d.ts +105 -0
  208. package/dist/vendor/lp-v3/lp-v3-atomic-settlement.js +162 -0
  209. package/dist/vendor/lp-v3/lp-v3-collect-protocol-contract.d.ts +606 -0
  210. package/dist/vendor/lp-v3/lp-v3-collect-protocol-contract.js +59 -0
  211. package/dist/vendor/lp-v3/lp-v3-collect-protocol-index.d.ts +168 -0
  212. package/dist/vendor/lp-v3/lp-v3-collect-protocol-index.js +23 -0
  213. package/dist/vendor/lp-v3/lp-v3-collect-protocol-observation.d.ts +32 -0
  214. package/dist/vendor/lp-v3/lp-v3-collect-protocol-observation.js +228 -0
  215. package/dist/vendor/lp-v3/lp-v3-collect-protocol-plan.d.ts +11 -0
  216. package/dist/vendor/lp-v3/lp-v3-collect-protocol-plan.js +91 -0
  217. package/dist/vendor/lp-v3/lp-v3-collect-protocol-reconcile.d.ts +9 -0
  218. package/dist/vendor/lp-v3/lp-v3-collect-protocol-reconcile.js +124 -0
  219. package/dist/vendor/lp-v3/lp-v3-contract.d.ts +538 -0
  220. package/dist/vendor/lp-v3/lp-v3-contract.js +137 -0
  221. package/dist/vendor/lp-v3/lp-v3-evidence.d.ts +25 -0
  222. package/dist/vendor/lp-v3/lp-v3-evidence.js +168 -0
  223. package/dist/vendor/lp-v3/lp-v3-plan.d.ts +22 -0
  224. package/dist/vendor/lp-v3/lp-v3-plan.js +135 -0
  225. package/dist/vendor/lp-v3/types.d.ts +131 -0
  226. package/dist/vendor/lp-v3/types.js +6 -0
  227. package/dist/vendor/lp-v3/v4-math.d.ts +18 -0
  228. package/dist/vendor/lp-v3/v4-math.js +90 -0
  229. package/dist/yield-deposit-definition.d.ts +374 -0
  230. package/dist/yield-deposit-definition.js +123 -0
  231. package/dist/yield-deposit.d.ts +16 -0
  232. package/dist/yield-deposit.js +149 -0
  233. package/dist/yield-route-semantics.d.ts +27 -0
  234. package/dist/yield-route-semantics.js +71 -0
  235. package/dist/yield-withdraw-definition.d.ts +357 -0
  236. package/dist/yield-withdraw-definition.js +90 -0
  237. package/dist/yield-withdraw.d.ts +11 -0
  238. package/dist/yield-withdraw.js +122 -0
  239. package/package.json +239 -7
@@ -0,0 +1,127 @@
1
+ /** Native UserOps are a typed record in the existing sponsored table and gas budget. */
2
+ import { z } from 'zod';
3
+ import { hybridYieldCommitment, getHybridYieldMarket } from './hybrid-yield-markets.js';
4
+ import { nativeYieldFee } from './native-yield-definition.js';
5
+ import { SPONSORED_OPERATION_SCHEMA, SPONSORED_AUTHORITY_SCHEMA, SPONSORED_ACTIVATION_SCHEMA, SPONSORED_CHAIN_SCHEMA, sponsoredDigest, sponsoredChainTerms, sponsoredActivationSupports } from './execution-sponsored-definition.js';
6
+ import { SPONSORED_CDP_NETWORKS } from './execution-sponsored-transport.js';
7
+ import { NATIVE_YIELD_USEROP_ENVELOPE_SCHEMA, NATIVE_YIELD_USEROP_SETTLEMENT_SCHEMA } from './native-yield-userop-definition.js';
8
+ import { NATIVE_YIELD_USEROP_REVIEW_RECORD_SCHEMA } from './native-yield-userop-authority.js';
9
+ import { assertNativeYieldUserOpEnvelope, nativeYieldUserOpRecordedCalls } from './native-yield-userop.js';
10
+ const time = z.number().int().positive().safe();
11
+ export const NATIVE_USEROP_CONTEXT_SCHEMA = z.object({ kind: z.literal('native-yield-userop'),
12
+ account: SPONSORED_AUTHORITY_SCHEMA.shape.account, chainId: SPONSORED_CHAIN_SCHEMA,
13
+ envelope: NATIVE_YIELD_USEROP_ENVELOPE_SCHEMA, review: NATIVE_YIELD_USEROP_REVIEW_RECORD_SCHEMA,
14
+ authority: SPONSORED_AUTHORITY_SCHEMA, activation: SPONSORED_ACTIVATION_SCHEMA,
15
+ reviewedAtMs: time, validUntilMs: time,
16
+ }).strict();
17
+ export const NATIVE_USEROP_OPERATION_SCHEMA = SPONSORED_OPERATION_SCHEMA.extend({ version: z.literal(2),
18
+ context: NATIVE_USEROP_CONTEXT_SCHEMA, settlement: NATIVE_YIELD_USEROP_SETTLEMENT_SCHEMA.optional(),
19
+ }).strict();
20
+ export function nativeUserOpReviewCommitment(operationId, context, gasReview) {
21
+ if (gasReview)
22
+ return sponsoredDigest({ domain: 'otto-account-gas-review-v1', operationId, context, gasReview });
23
+ return sponsoredDigest({ domain: 'otto-sponsored-native-yield-review-v1', operationId, context });
24
+ }
25
+ function invalid() { throw new Error('SPONSOR_NATIVE_JOURNAL_INVALID'); }
26
+ export function assertNativeUserOpContext(context, fresh = false, nowMs = Date.now()) {
27
+ const envelope = assertNativeYieldUserOpEnvelope(context.envelope), terms = envelope.terms;
28
+ const chain = sponsoredChainTerms(context.activation, context.chainId), profile = chain.nativeYieldUserOpProfile;
29
+ if (context.account !== terms.account || context.chainId !== terms.chainId ||
30
+ context.authority.account !== context.account || context.authority.userId !== terms.userId ||
31
+ context.authority.activationDigest !== sponsoredDigest(context.activation) ||
32
+ context.authority.policyRulesDigest !== context.activation.policyRulesDigest ||
33
+ context.reviewedAtMs !== envelope.preparedAtMs || context.validUntilMs !== envelope.validUntilMs ||
34
+ context.validUntilMs > context.activation.expiresAtMs ||
35
+ context.validUntilMs > Date.parse(context.authority.grantExpiresAt) ||
36
+ hybridYieldCommitment(context.review.input) !== hybridYieldCommitment(envelope.input) ||
37
+ hybridYieldCommitment(context.review.terms) !== hybridYieldCommitment(terms) ||
38
+ !sponsoredActivationSupports(context.activation, 'native-yield-userop') ||
39
+ terms.sponsoredActivationId !== context.activation.id ||
40
+ terms.sponsoredActivationDigest !== sponsoredDigest(context.activation) ||
41
+ terms.projectId !== context.activation.projectId || terms.policyId !== context.activation.policyId ||
42
+ terms.policyRulesDigest !== context.activation.policyRulesDigest ||
43
+ terms.providerEnforcementEvidenceDigest !== context.activation.providerEnforcementEvidenceDigest ||
44
+ terms.nativeActivationCommitment !== context.activation.nativeYieldUserOpPolicyRelation?.nativeActivationCommitment ||
45
+ (context.activation.lpUserOpPolicyRelation?.compiledFullPolicyDigest ??
46
+ context.activation.nativeYieldUserOpPolicyRelation?.compiledFullPolicyDigest) !== terms.policyRulesDigest ||
47
+ !profile || terms.implementation !== profile.implementation ||
48
+ terms.implementationCodeHash !== profile.implementationCodeHash ||
49
+ terms.delegateBatchAbi !== profile.delegateBatchAbi || terms.delegateBatchReviewDigest !== profile.delegateBatchReviewDigest ||
50
+ terms.entryPointVersion !== profile.entryPointVersion ||
51
+ terms.delegate !== chain.delegate || terms.delegateCodeHash !== chain.delegateCodeHash ||
52
+ terms.entryPoint !== chain.entryPoint || terms.entryPointCodeHash !== chain.entryPointCodeHash ||
53
+ terms.paymaster !== chain.paymaster || terms.paymasterCodeHash !== chain.paymasterCodeHash ||
54
+ terms.sponsorshipPolicyId !== chain.sponsorshipPolicyId || terms.maxGasCostWei !== chain.maxGasCostWei ||
55
+ terms.maxUserGasCostWei !== chain.maxUserGasCostWei || terms.maxTotalGasCostWei !== chain.maxTotalGasCostWei)
56
+ invalid();
57
+ if (fresh && (context.activation.mode !== 'enabled' || context.activation.approvedAtMs > nowMs ||
58
+ nowMs < context.reviewedAtMs || nowMs >= context.validUntilMs))
59
+ throw new Error('SPONSOR_REVIEW_EXPIRED');
60
+ }
61
+ export function validateNativeUserOpOperation(raw) {
62
+ const op = NATIVE_USEROP_OPERATION_SCHEMA.parse(raw), context = op.context;
63
+ assertNativeUserOpContext(context);
64
+ const { plan, terms } = context.envelope;
65
+ if (op.userId !== context.authority.userId ||
66
+ op.reviewCommitment !== nativeUserOpReviewCommitment(op.operationId, context, op.gasReview) ||
67
+ (op.state === 'review') !== !op.reviewConsumed || op.updatedAtMs < op.createdAtMs ||
68
+ context.reviewedAtMs !== op.createdAtMs || context.validUntilMs <= context.reviewedAtMs)
69
+ invalid();
70
+ if (op.request) {
71
+ const expectedBody = JSON.stringify({ network: SPONSORED_CDP_NETWORKS[context.chainId],
72
+ calls: nativeYieldUserOpRecordedCalls(context.envelope), useCdpPaymaster: false,
73
+ ...(op.gasReview?.payer === 'account' ? {} : { paymasterAlias: `pimlico:${context.chainId}`,
74
+ paymasterContext: { sponsorshipPolicyId: terms.sponsorshipPolicyId } }) });
75
+ if (op.request.userId !== op.userId || op.request.account !== context.account || op.request.chainId !== context.chainId ||
76
+ op.request.idempotencyKey !== op.operationId.slice(3) ||
77
+ op.request.path !== `/platform/v2/embedded-wallet-api/end-users/${op.userId}/evm/smart-accounts/${context.account.toLowerCase()}/send` ||
78
+ op.request.body !== expectedBody)
79
+ invalid();
80
+ }
81
+ if (op.handoffAttempted && !op.request)
82
+ invalid();
83
+ if (op.state === 'review' && (op.request || op.handoffAttempted || op.userOpHash || op.transactionHash))
84
+ invalid();
85
+ if ((op.userOpHash || op.transactionHash || op.receipt) && !op.handoffAttempted)
86
+ invalid();
87
+ if (op.transactionHash && !op.userOpHash)
88
+ invalid();
89
+ const boundReceipt = (receipt) => receipt.userOpHash.toLowerCase() === op.userOpHash?.toLowerCase() &&
90
+ receipt.transactionHash.toLowerCase() === op.transactionHash?.toLowerCase() &&
91
+ receipt.chainId === context.chainId && receipt.account === context.account && receipt.paymaster === (op.gasReview?.payer === 'account' ? '0x0000000000000000000000000000000000000000' : terms.paymaster);
92
+ if (op.receipt && (!boundReceipt(op.receipt) || (op.gasReview?.payer !== 'account' && BigInt(op.receipt.actualGasCostWei) > BigInt(terms.maxGasCostWei))))
93
+ invalid();
94
+ if (op.gasCapBreach && (op.gasReview?.payer === 'account' || !boundReceipt(op.gasCapBreach) || !op.handoffAttempted || op.state !== 'submitted' ||
95
+ op.receipt || op.settlement || op.failureCode !== 'SPONSOR_GAS_CAP_EXCEEDED' ||
96
+ BigInt(op.gasCapBreach.actualGasCostWei) <= BigInt(terms.maxGasCostWei)))
97
+ invalid();
98
+ const result = op.settlement;
99
+ if (result) {
100
+ const receipt = op.receipt, market = getHybridYieldMarket(plan.marketId);
101
+ if (!receipt || result.transactionHash !== receipt.transactionHash || result.userOpHash !== receipt.userOpHash ||
102
+ result.blockHash !== receipt.blockHash || result.blockNumber !== receipt.blockNumber ||
103
+ result.owner !== context.account || result.marketId !== plan.marketId || result.action !== plan.action ||
104
+ result.actualGasCostWei !== receipt.actualGasCostWei || result.actualGasUsed !== receipt.actualGasUsed ||
105
+ result.paymaster !== receipt.paymaster)
106
+ invalid();
107
+ if (result.status === 'completed') {
108
+ if (op.state !== 'completed' || receipt.status !== 'success' || result.actualInput !== plan.amount ||
109
+ BigInt(result.actualOutput) < BigInt(plan.minimumOutput) || result.feeToken !== market.asset.address ||
110
+ BigInt(result.actualOttoFee) !== nativeYieldFee(plan.action === 'deposit' ? BigInt(plan.amount)
111
+ : BigInt(result.actualOutput) + BigInt(result.actualOttoFee)) ||
112
+ BigInt(result.routerNonceAtBlock) < BigInt(plan.nonce) + 1n)
113
+ invalid();
114
+ }
115
+ else if (op.state !== 'failed' || receipt.status !== 'reverted' ||
116
+ BigInt(result.routerNonceAtBlock) !== BigInt(plan.nonce))
117
+ invalid();
118
+ }
119
+ if (op.state === 'completed' && result?.status !== 'completed')
120
+ invalid();
121
+ if (op.state === 'failed' && op.handoffAttempted && result?.status !== 'reverted')
122
+ invalid();
123
+ if (op.state === 'submitted' && !op.userOpHash)
124
+ invalid();
125
+ return op;
126
+ }
127
+ //# sourceMappingURL=native-yield-userop-operation.js.map
@@ -0,0 +1,23 @@
1
+ import { type NativeYieldAccountActivation } from './native-yield-account-definition.js';
2
+ /**
3
+ * Installed CDP SDK SendEndUserOperationRule and official create-policy schema name the end-user
4
+ * operation sendEndUserOperation. sendUserOperation is a different server-wallet operation.
5
+ * This exact compiler adds native calls only; it does not enable sponsored LI.FI swaps.
6
+ * https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-policy
7
+ * Source review must include provider rejection of a forbidden call in the actual end-user batch.
8
+ */
9
+ export declare function compileNativeYieldEndUserOperationPolicy(activation: NativeYieldAccountActivation): {
10
+ body: {
11
+ scope: "project";
12
+ description: "OTTO model b swap fence v3";
13
+ rules: (import("./execution-delegation-policy.js").DelegationPolicyRule | {
14
+ operation: "sendEndUserOperation";
15
+ action: "accept";
16
+ criteria: readonly import("./native-yield-account-policy.js").NativeYieldAccountPolicyCriterion[];
17
+ })[];
18
+ };
19
+ nativeActivationCommitment: `sha256:${string}`;
20
+ nativeRulesDigest: string;
21
+ compiledFullPolicyDigest: string;
22
+ compiler: "legacy-v2-native-enduser-userop-v1";
23
+ };
@@ -0,0 +1,25 @@
1
+ /** Pure reviewed native policy compiler shared by native-only and explicit composite policies. */
2
+ import { freezeHybridValue } from './hybrid-yield-markets.js';
3
+ import { policyRulesDigest } from './execution-policy-compatibility.js';
4
+ import { NATIVE_ACCOUNT_POLICY_NAME } from './native-yield-account-definition.js';
5
+ import { nativeYieldAccountActivationCommitment, validateNativeYieldAccountActivation } from './native-yield-account-policy.js';
6
+ import { refuseNative } from './native-yield-definition.js';
7
+ /**
8
+ * Installed CDP SDK SendEndUserOperationRule and official create-policy schema name the end-user
9
+ * operation sendEndUserOperation. sendUserOperation is a different server-wallet operation.
10
+ * This exact compiler adds native calls only; it does not enable sponsored LI.FI swaps.
11
+ * https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-policy
12
+ * Source review must include provider rejection of a forbidden call in the actual end-user batch.
13
+ */
14
+ export function compileNativeYieldEndUserOperationPolicy(activation) {
15
+ const native = validateNativeYieldAccountActivation(activation);
16
+ const nativeRules = native.nativeRules.map(rule => ({ ...rule, operation: 'sendEndUserOperation' }));
17
+ const rules = [...native.legacyRules, ...nativeRules];
18
+ if (native.legacyRules.length !== 5 || rules.length > 10)
19
+ refuseNative('NATIVE_USEROP_POLICY_RULE_LIMIT', 'Current owner, native consent, protocol scope and sponsorship authority must agree');
20
+ return freezeHybridValue({ body: { scope: 'project', description: NATIVE_ACCOUNT_POLICY_NAME, rules },
21
+ nativeActivationCommitment: nativeYieldAccountActivationCommitment(activation),
22
+ nativeRulesDigest: native.nativeRulesDigest, compiledFullPolicyDigest: policyRulesDigest(rules),
23
+ compiler: 'legacy-v2-native-enduser-userop-v1' });
24
+ }
25
+ //# sourceMappingURL=native-yield-userop-policy.js.map
@@ -0,0 +1,17 @@
1
+ /** Header authorization precedes every input parse and optional native runtime access. */
2
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
3
+ import type { ExecutionToolRuntime } from './execution-tools.js';
4
+ import { type NativeUserOpAvailabilityResult } from './native-yield-userop-mcp-definition.js';
5
+ export interface NativeYieldUserOpBinding {
6
+ availability(): Promise<NativeUserOpAvailabilityResult>;
7
+ reviewConsent(input: unknown): Promise<unknown>;
8
+ confirmConsent(input: unknown): Promise<unknown>;
9
+ reviewGas(input: unknown): Promise<unknown>;
10
+ prepare(input: unknown): Promise<unknown>;
11
+ submit(input: unknown): Promise<unknown>;
12
+ read(input: unknown): Promise<unknown>;
13
+ reconcile(input: unknown): Promise<unknown>;
14
+ revokeConsent(input: unknown): Promise<unknown>;
15
+ }
16
+ export declare function unavailableNativeYieldUserOpBinding(reason?: NonNullable<NativeUserOpAvailabilityResult['reason']>): NativeYieldUserOpBinding;
17
+ export declare function callNativeYieldUserOp(runtime: ExecutionToolRuntime, raw: unknown, headers: Readonly<Record<string, string | string[] | undefined>> | undefined): Promise<CallToolResult>;
@@ -0,0 +1,76 @@
1
+ import { accountGasFailure, AccountGasConfirmationRefusal } from './execution-account-gas-view.js';
2
+ import { ZodError } from 'zod';
3
+ import { assertDelegationCaller, callerFromHeaders } from './execution-delegation.js';
4
+ import { ExecutionRefusal, isExecutionRefusal } from './execution-errors.js';
5
+ import { SponsoredAccountRefusal } from './execution-sponsored-runtime.js';
6
+ import { nativeYieldUserOpAvailability } from './native-yield-userop-index.js';
7
+ import { NATIVE_USEROP_ACTION_INPUT, NATIVE_USEROP_TOOL_RESULT, NATIVE_USEROP_AVAILABILITY_RESULT } from './native-yield-userop-mcp-definition.js';
8
+ export function unavailableNativeYieldUserOpBinding(reason = 'SPONSOR_ACTIVATION_UNCONFIGURED') {
9
+ const refuse = async () => { throw new SponsoredAccountRefusal(reason); };
10
+ return Object.freeze({ availability: async () => NATIVE_USEROP_AVAILABILITY_RESULT.parse({ ...nativeYieldUserOpAvailability(),
11
+ executionEnabled: false, recoveryAvailable: false, reason }),
12
+ reviewConsent: refuse, confirmConsent: refuse, reviewGas: refuse, prepare: refuse, submit: refuse, read: refuse, reconcile: refuse, revokeConsent: refuse });
13
+ }
14
+ function success(raw) {
15
+ const output = NATIVE_USEROP_TOOL_RESULT.parse(raw);
16
+ return { content: [{ type: 'text', text: JSON.stringify(output) }], structuredContent: output };
17
+ }
18
+ export async function callNativeYieldUserOp(runtime, raw, headers) {
19
+ let submitId, invoked = false;
20
+ try {
21
+ if (!runtime.delegation)
22
+ throw new ExecutionRefusal('DELEGATION_UNAUTHORIZED', 'Protected account caller is not authorized');
23
+ assertDelegationCaller(runtime.delegation, callerFromHeaders(headers));
24
+ const input = NATIVE_USEROP_ACTION_INPUT.parse(raw), binding = runtime.nativeYieldUserOp ?? unavailableNativeYieldUserOpBinding();
25
+ if (input.action === 'availability')
26
+ return success(NATIVE_USEROP_AVAILABILITY_RESULT.parse(await binding.availability()));
27
+ const { action, ...body } = input;
28
+ if (action === 'submit')
29
+ submitId = input.operationId;
30
+ invoked = true;
31
+ const result = NATIVE_USEROP_TOOL_RESULT.parse(await binding[action](body));
32
+ if (action === 'reviewConsent' || action === 'confirmConsent') {
33
+ if (!('consent' in result) || result.consent.account.toLowerCase() !== input.input.accountProfile.address.toLowerCase() ||
34
+ result.consent.chainId !== input.input.accountProfile.chainId ||
35
+ (action === 'reviewConsent' ? result.consent.state !== 'challenge' || !result.scope
36
+ : result.consent.state !== 'confirmed' || result.consent.consentId !== input.consentId ||
37
+ result.consent.consentCommitment !== input.consentCommitment))
38
+ throw new Error('mismatched consent');
39
+ }
40
+ else if (action === 'revokeConsent') {
41
+ if (!('nativeConsentRevoked' in result) || result.account.toLowerCase() !== input.account.toLowerCase())
42
+ throw new Error('mismatched revocation');
43
+ }
44
+ else {
45
+ if (!('state' in result) || !('operationId' in result))
46
+ throw new Error('mismatched operation');
47
+ if (action === 'prepare') {
48
+ if (result.state !== 'review' || result.account.toLowerCase() !== input.input.accountProfile.address.toLowerCase() ||
49
+ result.chainId !== input.input.accountProfile.chainId || result.marketId !== input.input.marketId ||
50
+ result.action !== input.input.action || result.input.amount !== input.input.amount)
51
+ throw new Error('mismatched preparation');
52
+ }
53
+ else if (result.operationId !== input.operationId)
54
+ throw new Error('mismatched operation');
55
+ if (input.action === 'reviewGas' && (result.state !== 'review' || result.reviewConsumed || result.gas.reviewRequired !== true || !result.gas.paymentReview ||
56
+ result.reviewCommitment === input.reviewCommitment || (input.preference !== 'auto' && result.gas.payer !== input.preference)))
57
+ throw new Error('mismatched gas review');
58
+ if (action === 'submit' && (!result.reviewConsumed || result.envelopeCommitment !== input.envelopeCommitment ||
59
+ result.reviewCommitment !== input.reviewCommitment))
60
+ throw new Error('mismatched consumed review');
61
+ }
62
+ return success(result);
63
+ }
64
+ catch (error) {
65
+ if (submitId && invoked && !(error instanceof AccountGasConfirmationRefusal))
66
+ return success({ schemaVersion: '1', kind: 'native-yield-userop', status: 'outcome-unknown', operationId: submitId,
67
+ requiresReconciliation: true, replacementPermitted: false,
68
+ attention: 'The outcome of the original submission is unknown. Read or reconcile this operation; do not submit a replacement.' });
69
+ const denied = isExecutionRefusal(error) && error.code === 'DELEGATION_UNAUTHORIZED' && !invoked;
70
+ const code = denied ? 'DELEGATION_UNAUTHORIZED' : error instanceof ZodError && !invoked
71
+ ? 'NATIVE_USEROP_REQUEST_INVALID' : accountGasFailure(error) ?? 'NATIVE_USEROP_REQUEST_REFUSED';
72
+ return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'refused', code,
73
+ message: denied ? 'The protected account caller is not authorized.' : 'The native UserOp action is unavailable or refused. Read current availability and the original operation before continuing.' }) }] };
74
+ }
75
+ }
76
+ //# sourceMappingURL=native-yield-userop-registration.js.map
@@ -0,0 +1,8 @@
1
+ /** Reconcile only the canonical native UserOp. Unknown evidence never releases its shared claim. */
2
+ import { type Hex, type PublicClient } from 'viem';
3
+ import { type NativeYieldUserOpEnvelope, type NativeYieldUserOpSettlement } from './native-yield-userop-definition.js';
4
+ export interface NativeYieldUserOpReceiptBinding {
5
+ readonly userOpHash: Hex;
6
+ readonly transactionHash: Hex;
7
+ }
8
+ export declare function readNativeYieldUserOpSettlement(rawEnvelope: NativeYieldUserOpEnvelope, binding: NativeYieldUserOpReceiptBinding, client: PublicClient, payer?: 'sponsor' | 'account'): Promise<NativeYieldUserOpSettlement>;
@@ -0,0 +1,79 @@
1
+ /** Reconcile only the canonical native UserOp. Unknown evidence never releases its shared claim. */
2
+ import { getAddress } from 'viem';
3
+ import { freezeHybridValue, getHybridYieldMarket } from './hybrid-yield-markets.js';
4
+ import { NATIVE_YIELD_ERC20_ABI, NATIVE_YIELD_ROUTER_ABI } from './native-yield-definition.js';
5
+ import { nativeYieldReceiptAmounts } from './native-yield-settlement.js';
6
+ import { readConfirmedSponsoredReceipt, SponsoredReceiptUnconfirmedError } from './execution-sponsored-receipt.js';
7
+ import { sponsoredOperationLogs } from './execution-sponsored-settlement.js';
8
+ import { NATIVE_YIELD_USEROP_SETTLEMENT_SCHEMA } from './native-yield-userop-definition.js';
9
+ import { assertNativeYieldUserOpAccountState, assertNativeYieldUserOpEnvelope } from './native-yield-userop.js';
10
+ export async function readNativeYieldUserOpSettlement(rawEnvelope, binding, client, payer = 'sponsor') {
11
+ const held = (reason, status = 'held') => ({ status, reason, ...binding, releaseClaim: false, retrySafe: false });
12
+ try {
13
+ const { plan, terms } = assertNativeYieldUserOpEnvelope(rawEnvelope);
14
+ const confirmed = await readConfirmedSponsoredReceipt({ ...binding, account: terms.account, chainId: terms.chainId,
15
+ payer, entryPoint: terms.entryPoint, paymaster: payer === 'account' ? '0x0000000000000000000000000000000000000000' : terms.paymaster, maxGasCostWei: BigInt(terms.maxGasCostWei) }, client);
16
+ const receipt = await client.getTransactionReceipt({ hash: binding.transactionHash });
17
+ if (receipt.transactionHash !== confirmed.transactionHash || receipt.blockHash !== confirmed.blockHash ||
18
+ receipt.blockNumber.toString() !== confirmed.blockNumber)
19
+ return held('NATIVE_USEROP_RECEIPT_CHANGED');
20
+ if (receipt.logs.some((log, index) => log.removed || log.transactionHash !== receipt.transactionHash ||
21
+ log.blockHash !== receipt.blockHash || log.blockNumber !== receipt.blockNumber ||
22
+ !Number.isSafeInteger(log.logIndex) || log.logIndex === null ||
23
+ (index > 0 && log.logIndex <= receipt.logs[index - 1].logIndex)))
24
+ return held('NATIVE_USEROP_LOG_BINDING');
25
+ const logs = sponsoredOperationLogs(receipt, terms.entryPoint, binding.userOpHash);
26
+ if (logs.some(log => log.removed || log.transactionHash !== receipt.transactionHash ||
27
+ log.blockHash !== receipt.blockHash || log.blockNumber !== receipt.blockNumber))
28
+ return held('NATIVE_USEROP_LOG_BINDING');
29
+ const market = getHybridYieldMarket(plan.marketId);
30
+ const router = getAddress(terms.deployment.address), blockNumber = receipt.blockNumber;
31
+ await assertNativeYieldUserOpAccountState(client, terms, blockNumber, confirmed.blockHash);
32
+ const [inputAllowance, protocolAllowance, positionBalance, assetBalance, nonce] = await Promise.all([
33
+ client.readContract({ address: getAddress(plan.inputToken), abi: NATIVE_YIELD_ERC20_ABI,
34
+ functionName: 'allowance', args: [terms.account, router], blockNumber }),
35
+ client.readContract({ address: market.asset.address, abi: NATIVE_YIELD_ERC20_ABI,
36
+ functionName: 'allowance', args: [router, market.protocolTarget], blockNumber }),
37
+ client.readContract({ address: market.position.tokenAddress, abi: NATIVE_YIELD_ERC20_ABI,
38
+ functionName: 'balanceOf', args: [terms.account], blockNumber }),
39
+ client.readContract({ address: market.asset.address, abi: NATIVE_YIELD_ERC20_ABI,
40
+ functionName: 'balanceOf', args: [terms.account], blockNumber }),
41
+ client.readContract({ address: router, abi: NATIVE_YIELD_ROUTER_ABI,
42
+ functionName: 'nonces', args: [terms.account], blockNumber }),
43
+ ]);
44
+ // A failed atomic batch restores pre-existing allowances. Never copy swap's unconditional failed release.
45
+ if (inputAllowance !== 0n || protocolAllowance !== 0n)
46
+ return held('NATIVE_USEROP_ALLOWANCE_UNRESOLVED');
47
+ if (confirmed.status === 'success' ? nonce < BigInt(plan.nonce) + 1n : nonce !== BigInt(plan.nonce)) {
48
+ return held('NATIVE_USEROP_NONCE_UNRESOLVED');
49
+ }
50
+ const base = { ...binding, blockHash: confirmed.blockHash, blockNumber: confirmed.blockNumber,
51
+ owner: terms.account, marketId: plan.marketId, action: plan.action,
52
+ inputAllowance: '0', protocolAllowance: '0',
53
+ positionBalanceAtBlock: positionBalance.toString(), assetBalanceAtBlock: assetBalance.toString(),
54
+ routerNonceAtBlock: nonce.toString(), actualGasCostWei: confirmed.actualGasCostWei,
55
+ actualGasUsed: confirmed.actualGasUsed, paymaster: confirmed.paymaster,
56
+ releaseClaim: true, retrySafe: false };
57
+ const amounts = confirmed.status === 'success' ? nativeYieldReceiptAmounts(plan, { ...receipt, logs }) : undefined;
58
+ // For a reverted atomic batch, none of its execution logs may survive. Validation/paymaster logs
59
+ // are outside the protocol proof and cannot manufacture a successful native execution.
60
+ if (confirmed.status === 'reverted' && logs.some(log => log.address.toLowerCase() === router.toLowerCase())) {
61
+ return held('NATIVE_USEROP_REVERTED_PROTOCOL_LOGS');
62
+ }
63
+ if (await client.getChainId() !== terms.chainId ||
64
+ (await client.getBlock({ blockNumber })).hash !== confirmed.blockHash)
65
+ return held('NATIVE_USEROP_REORG', 'unknown');
66
+ return freezeHybridValue(NATIVE_YIELD_USEROP_SETTLEMENT_SCHEMA.parse(amounts
67
+ ? { ...base, status: 'completed', actualInput: amounts.inputAmount.toString(),
68
+ actualOutput: amounts.outputAmount.toString(), actualOttoFee: amounts.feeAmount.toString(),
69
+ feeToken: market.asset.address, protocolActionVerified: true }
70
+ : { ...base, status: 'reverted', protocolActionVerified: false }));
71
+ }
72
+ catch (error) {
73
+ // Preserve the proven receipt for the SAME sponsor activation/chain's shared breach circuit.
74
+ if (error instanceof SponsoredReceiptUnconfirmedError && error.code === 'SPONSOR_GAS_CAP_EXCEEDED')
75
+ throw error;
76
+ return held('NATIVE_USEROP_EVIDENCE_UNAVAILABLE', 'unknown');
77
+ }
78
+ }
79
+ //# sourceMappingURL=native-yield-userop-settlement.js.map
@@ -0,0 +1,18 @@
1
+ import { type NativeYieldUserOpTerms } from './native-yield-userop-definition.js';
2
+ import { type NativeYieldUserOpRuntime } from './native-yield-userop.js';
3
+ export declare function simulateNativeYieldUserOp(runtime: NativeYieldUserOpRuntime, rawEnvelope: unknown, independentTerms: NativeYieldUserOpTerms): Promise<{
4
+ verified: import("./native-yield-userop-definition.js").VerifiedNativeYieldUserOp;
5
+ blockNumber: string;
6
+ blockHash: `0x${string}`;
7
+ simulatedAtMs: number;
8
+ calls: {
9
+ to: string;
10
+ data: string;
11
+ value: "0";
12
+ }[];
13
+ batchCallData: `0x${string}`;
14
+ minimumOutputEnforced: true;
15
+ simulationOnly: true;
16
+ includesApprovals: true;
17
+ provesPaymasterValidation: false;
18
+ }>;
@@ -0,0 +1,34 @@
1
+ /** One real ordered batch eth_call against the pinned deployed delegate; no overrides or mined approvals. */
2
+ import { encodeFunctionData } from 'viem';
3
+ import { freezeHybridValue } from './hybrid-yield-markets.js';
4
+ import { refuseNative } from './native-yield-definition.js';
5
+ import { NATIVE_YIELD_USEROP_BATCH_ABI } from './native-yield-userop-definition.js';
6
+ import { nativeYieldUserOpCalls, readNativeYieldUserOpPreflight, verifyNativeYieldUserOp } from './native-yield-userop.js';
7
+ export async function simulateNativeYieldUserOp(runtime, rawEnvelope, independentTerms) {
8
+ const verified = await verifyNativeYieldUserOp(runtime, rawEnvelope, independentTerms);
9
+ const { envelope } = verified, { terms } = envelope;
10
+ const calls = nativeYieldUserOpCalls(verified);
11
+ const anchor = await readNativeYieldUserOpPreflight(runtime.client, envelope);
12
+ const data = encodeFunctionData({ abi: NATIVE_YIELD_USEROP_BATCH_ABI, functionName: 'executeBatch',
13
+ args: [calls.map(call => ({ target: call.to, value: 0n, data: call.data }))] });
14
+ // The entry point calls the upgraded OWNER, so every nested protocol call has that same owner.
15
+ // The supported reviewed ABI reverts the entire batch if any call fails. No balance or allowance overrides.
16
+ try {
17
+ await runtime.client.call({ account: terms.entryPoint, to: terms.account,
18
+ data, value: 0n, blockNumber: anchor.blockNumber });
19
+ }
20
+ catch {
21
+ return refuseNative('NATIVE_USEROP_SIMULATION_FAILED', 'The complete approval and native execution batch reverted');
22
+ }
23
+ const after = (runtime.nowMs ?? Date.now)();
24
+ if (after >= envelope.validUntilMs || anchor.blockTimestampMs > after + 5000 ||
25
+ after - anchor.blockTimestampMs > 60_000 ||
26
+ (await runtime.client.getBlock({ blockNumber: anchor.blockNumber })).hash !== anchor.blockHash) {
27
+ return refuseNative('NATIVE_USEROP_SIMULATION_STALE', 'The whole-batch simulation is stale or its block changed');
28
+ }
29
+ return freezeHybridValue({ verified, blockNumber: anchor.blockNumber.toString(), blockHash: anchor.blockHash,
30
+ simulatedAtMs: after, calls, batchCallData: data,
31
+ minimumOutputEnforced: true, simulationOnly: true,
32
+ includesApprovals: true, provesPaymasterValidation: false });
33
+ }
34
+ //# sourceMappingURL=native-yield-userop-simulation.js.map
@@ -0,0 +1,35 @@
1
+ /** Native protocol recipes for an already-upgraded, separately authorized account. Never sends. */
2
+ import { type Hex, type PublicClient } from 'viem';
3
+ import { type NativeYieldRuntime } from './native-yield.js';
4
+ import { type NativeYieldUserOpEnvelope, type NativeYieldUserOpTerms, type VerifiedNativeYieldUserOp } from './native-yield-userop-definition.js';
5
+ export interface NativeYieldUserOpRuntime extends NativeYieldRuntime {
6
+ /** Server-selected client. There is no request-provided RPC or deployment override. */
7
+ readonly client: PublicClient;
8
+ }
9
+ export declare function nativeYieldUserOpConsentCommitment(terms: NativeYieldUserOpTerms): string;
10
+ /** Durable-record integrity and exact bytes. Expiry is deliberately checked only at execution boundaries. */
11
+ export declare function assertNativeYieldUserOpEnvelope(raw: unknown): NativeYieldUserOpEnvelope;
12
+ /** Read the mutable implementation and owner state at the same block as its code pins. */
13
+ export declare function assertNativeYieldUserOpAccountState(client: PublicClient, rawTerms: NativeYieldUserOpTerms, blockNumber: bigint, blockHash: Hex): Promise<void>;
14
+ /** Fixed-block authority and allowance read; the caller re-runs it before its irreversible handoff. */
15
+ export declare function readNativeYieldUserOpPreflight(client: PublicClient, envelope: NativeYieldUserOpEnvelope): Promise<{
16
+ blockNumber: bigint;
17
+ blockHash: `0x${string}`;
18
+ blockTimestampMs: number;
19
+ }>;
20
+ export declare function prepareNativeYieldUserOp(runtime: NativeYieldUserOpRuntime, rawInput: unknown, independentTerms: NativeYieldUserOpTerms): Promise<NativeYieldUserOpEnvelope>;
21
+ export declare function verifyNativeYieldUserOp(runtime: NativeYieldUserOpRuntime, rawEnvelope: unknown, independentTerms: NativeYieldUserOpTerms): Promise<VerifiedNativeYieldUserOp>;
22
+ export declare function assertVerifiedNativeYieldUserOp(value: VerifiedNativeYieldUserOp): NativeYieldUserOpEnvelope;
23
+ /** Final read-age boundary after every blocking writer lock and immediately before provider start. */
24
+ export declare function assertFreshVerifiedNativeYieldUserOp(value: VerifiedNativeYieldUserOp, nowMs: number): void;
25
+ export declare function nativeYieldUserOpCalls(value: VerifiedNativeYieldUserOp): {
26
+ to: string;
27
+ data: string;
28
+ value: "0";
29
+ }[];
30
+ /** Recovery-only exact request reconstruction, including after Stop/expiry. Does not confer sending authority. */
31
+ export declare function nativeYieldUserOpRecordedCalls(rawEnvelope: NativeYieldUserOpEnvelope): {
32
+ to: string;
33
+ data: string;
34
+ value: "0";
35
+ }[];
@@ -0,0 +1,156 @@
1
+ /** Native protocol recipes for an already-upgraded, separately authorized account. Never sends. */
2
+ import { encodeFunctionData, getAddress, keccak256, stringToHex } from 'viem';
3
+ import { freezeHybridValue, getHybridYieldMarket, hybridYieldCommitment } from './hybrid-yield-markets.js';
4
+ import { NATIVE_YIELD_ERC20_ABI, NATIVE_YIELD_ROUTER_ABI, NATIVE_YIELD_FEE_RECIPIENT, NATIVE_YIELD_STATE_MAX_AGE_MS, NATIVE_YIELD_TTL_SECONDS, PREPARE_NATIVE_YIELD_INPUT_SCHEMA, nativeYieldFee, refuseNative } from './native-yield-definition.js';
5
+ import { buildNativeYieldProtocolPlan, resolveNativeYieldMarket } from './native-yield.js';
6
+ import { assertFreshNativeYieldProtocolPlan, verifyNativeYieldProtocolPlan } from './native-yield-verify.js';
7
+ import { NATIVE_YIELD_USEROP_ENVELOPE_SCHEMA, NATIVE_YIELD_USEROP_TERMS_SCHEMA } from './native-yield-userop-definition.js';
8
+ import { assertSponsoredAccountProfile, SponsoredAccountProfileError } from './execution-sponsored-account-profile.js';
9
+ const verified = new WeakMap();
10
+ function ensure(value, code) {
11
+ if (!value)
12
+ refuseNative(code, 'The native UserOp no longer matches its separately reviewed account, protocol or sponsorship terms');
13
+ }
14
+ const same = (a, b) => a.toLowerCase() === b.toLowerCase();
15
+ export function nativeYieldUserOpConsentCommitment(terms) {
16
+ return hybridYieldCommitment({ domain: 'otto-native-yield-userop-consent-v1', terms: NATIVE_YIELD_USEROP_TERMS_SCHEMA.parse(terms) });
17
+ }
18
+ /** Durable-record integrity and exact bytes. Expiry is deliberately checked only at execution boundaries. */
19
+ export function assertNativeYieldUserOpEnvelope(raw) {
20
+ const envelope = NATIVE_YIELD_USEROP_ENVELOPE_SCHEMA.parse(raw);
21
+ const { commitment, ...core } = envelope;
22
+ const { plan, input, terms } = envelope;
23
+ const { planCommitment, ...planCore } = plan;
24
+ ensure(hybridYieldCommitment(core) === commitment && hybridYieldCommitment(planCore) === planCommitment, 'NATIVE_USEROP_TAMPERED');
25
+ const market = resolveNativeYieldMarket(input);
26
+ ensure(plan.marketId === market.id && plan.registryCommitment === hybridYieldCommitment(market) &&
27
+ plan.intentCommitment === hybridYieldCommitment(input) && terms.intentCommitment === plan.intentCommitment &&
28
+ same(input.accountProfile.address, terms.account) && same(plan.owner, terms.account) &&
29
+ plan.chainId === terms.chainId && input.accountProfile.chainId === terms.chainId &&
30
+ hybridYieldCommitment(plan.deployment) === hybridYieldCommitment(terms.deployment) &&
31
+ plan.action === input.action && plan.amount === input.amount &&
32
+ BigInt(plan.amount) <= BigInt(terms.maximumInputAtomic) &&
33
+ plan.deadline === Math.floor(plan.preparedAtMs / 1000) + NATIVE_YIELD_TTL_SECONDS &&
34
+ plan.snapshot.observedAtMs <= plan.preparedAtMs &&
35
+ plan.preparedAtMs - plan.snapshot.observedAtMs <= NATIVE_YIELD_STATE_MAX_AGE_MS &&
36
+ envelope.preparedAtMs === plan.preparedAtMs &&
37
+ envelope.validUntilMs === Math.min(plan.deadline * 1000, terms.consentExpiresAtMs) &&
38
+ envelope.preparedAtMs >= terms.consentCreatedAtMs && envelope.validUntilMs > envelope.preparedAtMs, 'NATIVE_USEROP_BINDING');
39
+ const deposit = plan.action === 'deposit';
40
+ const inputToken = deposit ? market.asset.address : market.position.tokenAddress;
41
+ const outputToken = deposit ? market.position.tokenAddress : market.asset.address;
42
+ const amount = BigInt(plan.amount), protocolOutput = BigInt(plan.protocolOutput);
43
+ const fee = nativeYieldFee(deposit ? amount : protocolOutput);
44
+ const expectedOutput = deposit ? protocolOutput : protocolOutput - fee;
45
+ const minimum = BigInt(plan.minimumOutput);
46
+ ensure(same(plan.inputToken, inputToken) && same(plan.outputToken, outputToken) &&
47
+ same(plan.fee.recipient, NATIVE_YIELD_FEE_RECIPIENT) && same(plan.fee.token, market.asset.address) &&
48
+ BigInt(plan.fee.amount) === fee && BigInt(plan.expectedOutput) === expectedOutput &&
49
+ minimum <= expectedOutput && minimum >= expectedOutput * BigInt(10_000 - input.slippage.maxBps) / 10000n &&
50
+ (input.slippage.minOutput === undefined || minimum >= BigInt(input.slippage.minOutput)), 'NATIVE_USEROP_RECIPE');
51
+ const expected = [
52
+ { kind: 'approve_reset', to: inputToken, value: '0', data: encodeFunctionData({
53
+ abi: NATIVE_YIELD_ERC20_ABI, functionName: 'approve', args: [getAddress(terms.deployment.address), 0n]
54
+ }) },
55
+ { kind: 'approve', to: inputToken, value: '0', data: encodeFunctionData({
56
+ abi: NATIVE_YIELD_ERC20_ABI, functionName: 'approve', args: [getAddress(terms.deployment.address), amount]
57
+ }) },
58
+ { kind: 'call', to: terms.deployment.address, value: '0', data: encodeFunctionData({
59
+ abi: NATIVE_YIELD_ROUTER_ABI, functionName: 'execute', args: [keccak256(stringToHex(market.id)),
60
+ deposit, amount, minimum, BigInt(plan.nonce), BigInt(plan.deadline)]
61
+ }) },
62
+ ];
63
+ ensure(plan.steps.every((step, i) => step.kind === expected[i].kind && step.value === '0' &&
64
+ same(step.to, expected[i].to) && same(step.data, expected[i].data)), 'NATIVE_USEROP_RECIPE');
65
+ return freezeHybridValue(envelope);
66
+ }
67
+ /** Read the mutable implementation and owner state at the same block as its code pins. */
68
+ export async function assertNativeYieldUserOpAccountState(client, rawTerms, blockNumber, blockHash) {
69
+ const terms = NATIVE_YIELD_USEROP_TERMS_SCHEMA.parse(rawTerms);
70
+ try {
71
+ await assertSponsoredAccountProfile(client, terms, blockNumber, blockHash, [{ address: getAddress(terms.deployment.address), codeHash: terms.deployment.runtimeCodeHash }]);
72
+ }
73
+ catch (error) {
74
+ if (error instanceof SponsoredAccountProfileError)
75
+ ensure(false, `NATIVE_USEROP_${error.reason}`);
76
+ throw error;
77
+ }
78
+ }
79
+ /** Fixed-block authority and allowance read; the caller re-runs it before its irreversible handoff. */
80
+ export async function readNativeYieldUserOpPreflight(client, envelope) {
81
+ const { plan, terms } = assertNativeYieldUserOpEnvelope(envelope);
82
+ const market = getHybridYieldMarket(plan.marketId);
83
+ const block = await client.getBlock({ blockTag: 'latest' });
84
+ ensure(block.number !== null && block.hash, 'NATIVE_USEROP_ANCHOR');
85
+ const blockNumber = block.number;
86
+ await assertNativeYieldUserOpAccountState(client, terms, blockNumber, block.hash);
87
+ const [inputAllowance, protocolAllowance, nonce] = await Promise.all([
88
+ client.readContract({ address: getAddress(plan.inputToken), abi: NATIVE_YIELD_ERC20_ABI,
89
+ functionName: 'allowance', args: [terms.account, getAddress(terms.deployment.address)], blockNumber }),
90
+ client.readContract({ address: market.asset.address, abi: NATIVE_YIELD_ERC20_ABI,
91
+ functionName: 'allowance', args: [getAddress(terms.deployment.address), market.protocolTarget], blockNumber }),
92
+ client.readContract({ address: getAddress(terms.deployment.address), abi: NATIVE_YIELD_ROUTER_ABI,
93
+ functionName: 'nonces', args: [terms.account], blockNumber }),
94
+ ]);
95
+ ensure(inputAllowance === 0n && protocolAllowance === 0n, 'NATIVE_USEROP_INITIAL_ALLOWANCE');
96
+ ensure(nonce === BigInt(plan.nonce), 'NATIVE_USEROP_NONCE');
97
+ ensure((await client.getBlock({ blockNumber })).hash === block.hash, 'NATIVE_USEROP_REORG');
98
+ return freezeHybridValue({ blockNumber, blockHash: block.hash, blockTimestampMs: Number(block.timestamp) * 1000 });
99
+ }
100
+ export async function prepareNativeYieldUserOp(runtime, rawInput, independentTerms) {
101
+ const input = PREPARE_NATIVE_YIELD_INPUT_SCHEMA.parse(rawInput);
102
+ const terms = NATIVE_YIELD_USEROP_TERMS_SCHEMA.parse(independentTerms);
103
+ const market = resolveNativeYieldMarket(input), now = (runtime.nowMs ?? Date.now)();
104
+ ensure(now >= terms.consentCreatedAtMs && now < terms.consentExpiresAtMs &&
105
+ terms.intentCommitment === hybridYieldCommitment(input), 'NATIVE_USEROP_CONSENT');
106
+ ensure(runtime.deployments?.some(deployment => hybridYieldCommitment(deployment) === hybridYieldCommitment(terms.deployment)), 'NATIVE_DEPLOYMENT_REQUIRED');
107
+ const state = await runtime.reader.read(market, getAddress(input.accountProfile.address), input.action, BigInt(input.amount), terms.deployment);
108
+ const preparedAtMs = (runtime.nowMs ?? Date.now)();
109
+ const plan = buildNativeYieldProtocolPlan(input, market, terms.deployment, state, preparedAtMs);
110
+ const core = { version: 1, kind: 'native-yield-userop', input, plan, terms, preparedAtMs,
111
+ validUntilMs: Math.min(plan.deadline * 1000, terms.consentExpiresAtMs),
112
+ allowanceRecovery: 'atomic-batch-requires-zero-initial-and-final-allowances' };
113
+ const envelope = assertNativeYieldUserOpEnvelope({ ...core, commitment: hybridYieldCommitment(core) });
114
+ await verifyNativeYieldUserOp(runtime, envelope, terms);
115
+ return envelope;
116
+ }
117
+ export async function verifyNativeYieldUserOp(runtime, rawEnvelope, independentTerms) {
118
+ const envelope = assertNativeYieldUserOpEnvelope(rawEnvelope);
119
+ const terms = NATIVE_YIELD_USEROP_TERMS_SCHEMA.parse(independentTerms);
120
+ ensure(hybridYieldCommitment(terms) === hybridYieldCommitment(envelope.terms), 'NATIVE_USEROP_CONSENT_CHANGED');
121
+ const now = (runtime.nowMs ?? Date.now)();
122
+ ensure(now >= terms.consentCreatedAtMs && now >= envelope.preparedAtMs && now < envelope.validUntilMs, 'NATIVE_USEROP_EXPIRED');
123
+ const protocolPlan = await verifyNativeYieldProtocolPlan(runtime, envelope.plan, envelope.input, {
124
+ account: { address: terms.account, chainId: terms.chainId }, maximumInputAtomic: BigInt(terms.maximumInputAtomic),
125
+ });
126
+ const anchor = await readNativeYieldUserOpPreflight(runtime.client, envelope);
127
+ const monotonicAtMs = performance.now();
128
+ const after = (runtime.nowMs ?? Date.now)();
129
+ ensure(after < envelope.validUntilMs && anchor.blockTimestampMs <= after + 5000 &&
130
+ after - anchor.blockTimestampMs <= 60_000, 'NATIVE_USEROP_EXPIRED');
131
+ const result = freezeHybridValue({ envelope, verificationOnly: true });
132
+ verified.set(result, { protocolPlan, blockTimestampMs: anchor.blockTimestampMs,
133
+ checkedAtMs: after, monotonicAtMs });
134
+ return result;
135
+ }
136
+ export function assertVerifiedNativeYieldUserOp(value) {
137
+ ensure(value && verified.has(value) && Object.isFrozen(value), 'NATIVE_USEROP_UNVERIFIED');
138
+ return value.envelope;
139
+ }
140
+ /** Final read-age boundary after every blocking writer lock and immediately before provider start. */
141
+ export function assertFreshVerifiedNativeYieldUserOp(value, nowMs) {
142
+ const envelope = assertVerifiedNativeYieldUserOp(value), facts = verified.get(value);
143
+ const monotonicNow = performance.now();
144
+ ensure(Number.isSafeInteger(nowMs) && nowMs >= facts.checkedAtMs && monotonicNow >= facts.monotonicAtMs, 'NATIVE_USEROP_EXPIRED');
145
+ const current = Math.max(nowMs, facts.checkedAtMs + monotonicNow - facts.monotonicAtMs);
146
+ ensure(current < envelope.validUntilMs && current - facts.blockTimestampMs <= NATIVE_YIELD_STATE_MAX_AGE_MS, 'NATIVE_USEROP_EXPIRED');
147
+ assertFreshNativeYieldProtocolPlan(facts.protocolPlan, nowMs);
148
+ }
149
+ export function nativeYieldUserOpCalls(value) {
150
+ return nativeYieldUserOpRecordedCalls(assertVerifiedNativeYieldUserOp(value));
151
+ }
152
+ /** Recovery-only exact request reconstruction, including after Stop/expiry. Does not confer sending authority. */
153
+ export function nativeYieldUserOpRecordedCalls(rawEnvelope) {
154
+ return freezeHybridValue(assertNativeYieldUserOpEnvelope(rawEnvelope).plan.steps.map(step => ({ to: step.to.toLowerCase(), data: step.data.toLowerCase(), value: '0' })));
155
+ }
156
+ //# sourceMappingURL=native-yield-userop.js.map