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,71 @@
1
+ /** Authenticated CDP account adapter. The sole native send surface is private to this runtime. */
2
+ import { type Address, type PublicClient } from 'viem';
3
+ import type { DelegationCapStore } from './execution-delegation-cap-store.js';
4
+ import type { DelegationPolicyRecord } from './execution-delegation-policy.js';
5
+ import { type NativeYieldAccountActivation, type NativeYieldAccountAuthority } from './native-yield-account-definition.js';
6
+ import { type NativeYieldAccountPriceObservation, type ResolvedNativeYieldAccountLimits } from './native-yield-account-policy.js';
7
+ export interface NativeYieldAccountCdp {
8
+ readonly endUser: {
9
+ validateAccessToken(input: {
10
+ accessToken: string;
11
+ }): Promise<{
12
+ userId: string;
13
+ evmAccounts?: readonly string[];
14
+ evmAccountObjects?: readonly {
15
+ address: string;
16
+ }[];
17
+ }>;
18
+ getEndUser(input: {
19
+ userId: string;
20
+ }): Promise<{
21
+ userId: string;
22
+ evmAccounts?: readonly string[];
23
+ evmAccountObjects?: readonly {
24
+ address: string;
25
+ }[];
26
+ }>;
27
+ getDelegationForEndUser(input: {
28
+ userId: string;
29
+ }): Promise<{
30
+ expiresAt: string;
31
+ }>;
32
+ sendEvmTransaction(input: {
33
+ userId: string;
34
+ address: string;
35
+ transaction: `0x${string}`;
36
+ network: 'base' | 'arbitrum';
37
+ idempotencyKey: string;
38
+ }): Promise<{
39
+ transactionHash: string;
40
+ }>;
41
+ };
42
+ readonly policies: {
43
+ listPolicies(input: {
44
+ scope: 'project';
45
+ }): Promise<{
46
+ policies?: readonly DelegationPolicyRecord[];
47
+ }>;
48
+ };
49
+ }
50
+ export interface NativeYieldAccountIdentity {
51
+ userId: string;
52
+ accounts: readonly Address[];
53
+ }
54
+ export declare class NativeYieldAccountRuntime {
55
+ private readonly cdp;
56
+ private readonly caps;
57
+ readonly clients: Readonly<Partial<Record<8453 | 42161, PublicClient>>>;
58
+ readonly now: () => number;
59
+ constructor(cdp: NativeYieldAccountCdp, caps: DelegationCapStore, clients: Readonly<Partial<Record<8453 | 42161, PublicClient>>>, now?: () => number);
60
+ client(chainId: 8453 | 42161): PublicClient;
61
+ identity(accessToken: string): Promise<NativeYieldAccountIdentity>;
62
+ authority(accessToken: string, account: string, activation: NativeYieldAccountActivation, purpose: 'consent' | 'send'): Promise<{
63
+ authority: NativeYieldAccountAuthority;
64
+ policyPhase: 'legacy-v2' | 'native-v3';
65
+ }>;
66
+ /** Last awaited application authority check before dispatch; Stop is never inferred from an older snapshot. */
67
+ assertCurrentCap(authority: NativeYieldAccountAuthority): Promise<void>;
68
+ /** Close the final RPC/simulation await with fresh token ownership, live grant and durable Stop checks. */
69
+ assertCurrentSession(accessToken: string, authority: NativeYieldAccountAuthority): Promise<void>;
70
+ price(limits: ResolvedNativeYieldAccountLimits): Promise<NativeYieldAccountPriceObservation | undefined>;
71
+ }
@@ -0,0 +1,125 @@
1
+ /** Authenticated CDP account adapter. The sole native send surface is private to this runtime. */
2
+ import { getAddress, parseAbi } from 'viem';
3
+ import { MODEL_B_CAP_RULESET_VERSION } from './execution-delegation-cap-store.js';
4
+ import { hybridYieldCommitment } from './hybrid-yield-markets.js';
5
+ import { refuseNative } from './native-yield-definition.js';
6
+ import { NATIVE_ACCOUNT_AUTHORITY_SCHEMA, NATIVE_ACCOUNT_RULESET, NATIVE_ACCOUNT_SCOPES } from './native-yield-account-definition.js';
7
+ import { assertNativeAccountSendFence, assertNativeConsentPolicyContext, nativeYieldAccountActivationCommitment } from './native-yield-account-policy.js';
8
+ function accounts(user) {
9
+ return [...new Set([...(user.evmAccounts ?? []), ...(user.evmAccountObjects ?? []).map((a) => a.address)].map((a) => getAddress(a)))];
10
+ }
11
+ export class NativeYieldAccountRuntime {
12
+ cdp;
13
+ caps;
14
+ clients;
15
+ now;
16
+ constructor(cdp, caps, clients, now = Date.now) {
17
+ this.cdp = cdp;
18
+ this.caps = caps;
19
+ this.clients = clients;
20
+ this.now = now;
21
+ }
22
+ client(chainId) {
23
+ const pub = this.clients[chainId];
24
+ if (!pub)
25
+ return refuseNative('NATIVE_CHAIN_UNAVAILABLE', 'A reviewed account reader is unavailable');
26
+ return pub;
27
+ }
28
+ async identity(accessToken) {
29
+ if (!accessToken || accessToken.length > 16384)
30
+ return refuseNative('NATIVE_TOKEN_INVALID', 'A current account session is required');
31
+ let user;
32
+ try {
33
+ user = await this.cdp.endUser.validateAccessToken({ accessToken });
34
+ }
35
+ catch {
36
+ return refuseNative('NATIVE_TOKEN_INVALID', 'The account session could not be verified');
37
+ }
38
+ if (!/^[a-zA-Z0-9-]{1,100}$/.test(user.userId))
39
+ return refuseNative('NATIVE_TOKEN_INVALID', 'Invalid account identity');
40
+ const current = await this.cdp.endUser.getEndUser({ userId: user.userId });
41
+ const currentAccounts = accounts(current);
42
+ const owned = accounts(user).filter((a) => currentAccounts.includes(a));
43
+ if (current.userId !== user.userId || owned.length === 0)
44
+ return refuseNative('NATIVE_OWNER_MISMATCH', 'The session owns no current account');
45
+ return { userId: user.userId, accounts: owned };
46
+ }
47
+ async authority(accessToken, account, activation, purpose) {
48
+ const who = await this.identity(accessToken), owner = getAddress(account);
49
+ if (!who.accounts.includes(owner) || !this.caps.available)
50
+ return refuseNative('NATIVE_AUTHORITY_UNAVAILABLE', 'Current owned account and durable cap are required');
51
+ const [cap, generation, grant, policyReply] = await Promise.all([
52
+ this.caps.readActive(who.userId, this.now()), this.caps.readRevokeGeneration(who.userId),
53
+ this.cdp.endUser.getDelegationForEndUser({ userId: who.userId }), this.cdp.policies.listPolicies({ scope: 'project' }),
54
+ ]);
55
+ if (!cap || cap.state !== 'confirmed_active' || cap.requiredVersion !== MODEL_B_CAP_RULESET_VERSION ||
56
+ cap.revokeGeneration !== generation || Date.parse(grant.expiresAt) !== Date.parse(cap.expiresAt) ||
57
+ !Number.isFinite(Date.parse(grant.expiresAt)) || Date.parse(grant.expiresAt) <= this.now())
58
+ return refuseNative('NATIVE_GRANT_UNAVAILABLE', 'The confirmed current grant and Stop generation must match');
59
+ const policies = policyReply.policies ?? [];
60
+ const fence = purpose === 'send' ? { ...assertNativeAccountSendFence(policies, activation), phase: 'native-v3' }
61
+ : assertNativeConsentPolicyContext(policies, activation);
62
+ for (const deployment of activation.deployments) {
63
+ const pub = this.client(deployment.chainId);
64
+ const [chain, code] = await Promise.all([pub.getChainId(), pub.getCode({ address: owner })]);
65
+ if (chain !== deployment.chainId || (code && code !== '0x'))
66
+ return refuseNative('NATIVE_ACCOUNT_KIND_UNSUPPORTED', 'Only the verified EOA on the exact configured chain is supported');
67
+ }
68
+ const authority = NATIVE_ACCOUNT_AUTHORITY_SCHEMA.parse({ userId: who.userId, account: owner,
69
+ mintKey: cap.mintKey, grantExpiresAt: new Date(Date.parse(grant.expiresAt)).toISOString(), revokeGeneration: generation,
70
+ capRulesetVersion: cap.requiredVersion, perSwapCapUsd: cap.perSwapCapUsd,
71
+ policyId: fence.policyId, policyName: fence.policyName, policyDigest: fence.policyDigest,
72
+ legacyRulesDigest: fence.legacyRulesDigest, nativeRulesDigest: fence.nativeRulesDigest,
73
+ activationCommitment: nativeYieldAccountActivationCommitment(activation),
74
+ scopeCommitment: hybridYieldCommitment({ domain: 'native-yield-account-scope-v1', ruleset: NATIVE_ACCOUNT_RULESET,
75
+ scopes: NATIVE_ACCOUNT_SCOPES, deployments: activation.deployments, marketRules: activation.marketRules,
76
+ gasLimits: activation.gasLimits, priceRules: activation.priceRules }),
77
+ ruleset: NATIVE_ACCOUNT_RULESET, scopes: [...NATIVE_ACCOUNT_SCOPES] });
78
+ return { authority, policyPhase: fence.phase };
79
+ }
80
+ /** Last awaited application authority check before dispatch; Stop is never inferred from an older snapshot. */
81
+ async assertCurrentCap(authority) {
82
+ const [cap, generation] = await Promise.all([
83
+ this.caps.readActive(authority.userId, this.now()), this.caps.readRevokeGeneration(authority.userId),
84
+ ]);
85
+ if (!cap || cap.state !== 'confirmed_active' || cap.mintKey !== authority.mintKey ||
86
+ cap.revokeGeneration !== generation || generation !== authority.revokeGeneration ||
87
+ cap.requiredVersion !== authority.capRulesetVersion || cap.perSwapCapUsd !== authority.perSwapCapUsd ||
88
+ Date.parse(cap.expiresAt) !== Date.parse(authority.grantExpiresAt) || Date.parse(cap.expiresAt) <= this.now())
89
+ return refuseNative('NATIVE_GRANT_CHANGED', 'The grant or Stop generation changed before sending');
90
+ }
91
+ /** Close the final RPC/simulation await with fresh token ownership, live grant and durable Stop checks. */
92
+ async assertCurrentSession(accessToken, authority) {
93
+ const [who, grant] = await Promise.all([
94
+ this.identity(accessToken), this.cdp.endUser.getDelegationForEndUser({ userId: authority.userId }),
95
+ ]);
96
+ if (who.userId !== authority.userId || !who.accounts.includes(getAddress(authority.account)) ||
97
+ Date.parse(grant.expiresAt) !== Date.parse(authority.grantExpiresAt) || Date.parse(grant.expiresAt) <= this.now())
98
+ return refuseNative('NATIVE_GRANT_CHANGED', 'The account session or live grant changed before sending');
99
+ await this.assertCurrentCap(authority);
100
+ }
101
+ async price(limits) {
102
+ if (limits.marketRule.action === 'withdraw' || limits.market.asset.symbol === 'USDC')
103
+ return undefined;
104
+ const rule = limits.activation.priceRules.find((p) => p.chainId === limits.market.chainId &&
105
+ p.asset.toLowerCase() === limits.market.asset.address.toLowerCase());
106
+ if (!rule)
107
+ return refuseNative('NATIVE_PRICE_UNAVAILABLE', 'An approved asset valuation is required');
108
+ const pub = this.client(rule.chainId), block = await pub.getBlock({ blockTag: 'latest' });
109
+ if (block.number === null || !block.hash)
110
+ return refuseNative('NATIVE_PRICE_UNAVAILABLE', 'Missing price block');
111
+ const abi = parseAbi(['function decimals() view returns (uint8)',
112
+ 'function latestRoundData() view returns (uint80 roundId,int256 answer,uint256 startedAt,uint256 updatedAt,uint80 answeredInRound)']);
113
+ const [decimals, round] = await Promise.all([
114
+ pub.readContract({ address: getAddress(rule.feed), abi, functionName: 'decimals', blockNumber: block.number }),
115
+ pub.readContract({ address: getAddress(rule.feed), abi, functionName: 'latestRoundData', blockNumber: block.number }),
116
+ ]);
117
+ const canonical = await pub.getBlock({ blockNumber: block.number });
118
+ if (canonical.hash !== block.hash || await pub.getChainId() !== rule.chainId)
119
+ return refuseNative('NATIVE_PRICE_UNAVAILABLE', 'Price block is not canonical');
120
+ return { chainId: rule.chainId, asset: getAddress(rule.asset), feed: getAddress(rule.feed), feedDecimals: decimals,
121
+ roundId: round[0], answer: round[1], startedAt: round[2], updatedAt: round[3], answeredInRound: round[4],
122
+ blockNumber: block.number, blockHash: block.hash, blockTimestampMs: Number(block.timestamp) * 1000, observedAtMs: this.now() };
123
+ }
124
+ }
125
+ //# sourceMappingURL=native-yield-account-runtime.js.map
@@ -0,0 +1,40 @@
1
+ import { type ExecutionJournalDatabase } from './execution-journal-schema.js';
2
+ import { type NativeYieldAccountOperation, type NativeYieldAccountOperationContext, type NativeYieldAccountAuthority, type NativeYieldAccountStep, type NativeYieldAccountReceipt } from './native-yield-account-definition.js';
3
+ export declare function nativeAccountDigest(value: unknown): string;
4
+ export declare function nativeAccountReviewCommitment(operationId: string, context: Omit<NativeYieldAccountOperationContext, 'reviewCommitment'>): string;
5
+ export declare function nativeAccountRevocationCommitment(operation: NativeYieldAccountOperation): string;
6
+ /** Rebuild invariants on every read. The database is evidence, never an unchecked signing request. */
7
+ export declare function validateNativeAccountOperation(raw: unknown): NativeYieldAccountOperation;
8
+ export declare class NativeYieldAccountStore {
9
+ readonly db: ExecutionJournalDatabase;
10
+ private readonly now;
11
+ constructor(db: ExecutionJournalDatabase, now?: () => number);
12
+ transaction<T>(fn: () => T): T;
13
+ private decode;
14
+ private checkClaims;
15
+ private requireClaim;
16
+ read(userId: string, operationId: string): NativeYieldAccountOperation;
17
+ list(userId: string): NativeYieldAccountOperation[];
18
+ private save;
19
+ create(context: Omit<NativeYieldAccountOperationContext, 'reviewCommitment'>): NativeYieldAccountOperation;
20
+ begin(userId: string, operationId: string, planCommitment: string, reviewCommitment: string, authority: NativeYieldAccountAuthority): NativeYieldAccountOperation;
21
+ assertConsent(op: NativeYieldAccountOperation, authority: NativeYieldAccountAuthority): void;
22
+ append(userId: string, operationId: string, rawStep: NativeYieldAccountStep): NativeYieldAccountOperation;
23
+ evidence(userId: string, operationId: string, index: number, evidence: {
24
+ state: 'submitted';
25
+ transactionHash: string;
26
+ } | {
27
+ state: 'mined' | 'confirmed' | 'reverted';
28
+ receipt: NativeYieldAccountReceipt;
29
+ finality: 'mined' | 'finalized';
30
+ } | {
31
+ state: 'unknown' | 'not-submitted';
32
+ }): NativeYieldAccountOperation;
33
+ attention(userId: string, operationId: string, code: string): NativeYieldAccountOperation;
34
+ /** Caller supplies finalized transaction/protocol/zero-allowance proofs; this commits the terminal record and release atomically. */
35
+ finish(userId: string, operationId: string, outcome: {
36
+ state: 'completed' | 'failed';
37
+ result: unknown;
38
+ }): NativeYieldAccountOperation;
39
+ }
40
+ export declare function openNativeYieldAccountStore(root: string, now?: () => number, requireExistingLegacyJournal?: boolean): Promise<NativeYieldAccountStore>;
@@ -0,0 +1,307 @@
1
+ import { NATIVE_OPERATION_SCHEMA, assertExecutionStorageSchema } from './execution-journal-tables.js';
2
+ /** Durable native journal in the SAME operations.db as legacy execution. No tokens, retries or TTL unlocks. */
3
+ import { randomUUID, createHash } from 'node:crypto';
4
+ import { access, mkdir } from 'node:fs/promises';
5
+ import { join } from 'node:path';
6
+ import { getAddress, parseTransaction } from 'viem';
7
+ import { hybridYieldCommitment } from './hybrid-yield-markets.js';
8
+ import { nativeYieldFee } from './native-yield-definition.js';
9
+ import { nativeYieldAllowanceRevocation } from './native-yield-verify.js';
10
+ import { assertExecutionJournalCompatible, claimNativeExecution, initializeExecutionJournal, readUserExecutionClaim, releaseNativeExecutionClaim } from './execution-journal-schema.js';
11
+ import { initializeNativeYieldConsents, assertCurrentNativeYieldConsent } from './native-yield-consent-store.js';
12
+ import { NATIVE_ACCOUNT_OPERATION_SCHEMA, NATIVE_ACCOUNT_OPERATION_CONTEXT_SCHEMA, NATIVE_ACCOUNT_STEP_SCHEMA, NATIVE_ACCOUNT_SETTLEMENT_SCHEMA } from './native-yield-account-definition.js';
13
+ export function nativeAccountDigest(value) {
14
+ return createHash('sha256').update(JSON.stringify(value)).digest('hex');
15
+ }
16
+ export function nativeAccountReviewCommitment(operationId, context) {
17
+ return hybridYieldCommitment({ domain: 'native-yield-account-review-v1', operationId, ...context });
18
+ }
19
+ export function nativeAccountRevocationCommitment(operation) {
20
+ return hybridYieldCommitment({ domain: 'native-yield-account-clear-v1', operationId: operation.operationId,
21
+ planCommitment: operation.context.plan.planCommitment, account: operation.account, chainId: operation.chainId });
22
+ }
23
+ const unresolved = (op) => op.reviewConsumed && !['completed', 'failed'].includes(op.state);
24
+ function invalid(detail) { throw new Error(`NATIVE_JOURNAL_INVALID: ${detail}`); }
25
+ /** Rebuild invariants on every read. The database is evidence, never an unchecked signing request. */
26
+ export function validateNativeAccountOperation(raw) {
27
+ const op = NATIVE_ACCOUNT_OPERATION_SCHEMA.parse(raw), { reviewCommitment, ...core } = op.context;
28
+ if (!op.operationId.startsWith('ny_') || op.userId !== core.consent.authority.userId ||
29
+ getAddress(op.account) !== getAddress(core.plan.owner) || getAddress(op.account) !== getAddress(core.consent.authority.account) ||
30
+ op.chainId !== core.plan.chainId || reviewCommitment !== nativeAccountReviewCommitment(op.operationId, core) ||
31
+ (op.state === 'review') !== !op.reviewConsumed || op.updatedAtMs < op.createdAtMs)
32
+ invalid('operation binding');
33
+ const { planCommitment, ...planCore } = core.plan;
34
+ if (hybridYieldCommitment(planCore) !== planCommitment || core.plan.intentCommitment !== hybridYieldCommitment(core.input))
35
+ invalid('plan seal');
36
+ if (op.state === 'review' && op.steps.length)
37
+ invalid('review contains sends');
38
+ let prior = -1;
39
+ for (const step of op.steps) {
40
+ const expected = step.index === 3 ? nativeYieldAllowanceRevocation(core.plan, { account: { address: op.account, chainId: op.chainId } }, core.activation.deployments) : core.plan.steps[step.index];
41
+ if (!expected || step.index <= prior || (step.index < 3 && step.index !== prior + 1) ||
42
+ step.kind !== ['approve_reset', 'approve', 'call', 'allowance_clear'][step.index] ||
43
+ step.requestDigest !== nativeAccountDigest(step.request) || step.request.userId !== op.userId ||
44
+ getAddress(step.request.address) !== getAddress(op.account) ||
45
+ step.request.network !== (op.chainId === 8453 ? 'base' : 'arbitrum'))
46
+ invalid('step binding');
47
+ const tx = parseTransaction(step.request.transaction);
48
+ if (tx.type !== 'eip1559' || tx.chainId !== op.chainId || !tx.to ||
49
+ getAddress(tx.to) !== getAddress(expected.to) || (tx.data ?? '0x').toLowerCase() !== expected.data.toLowerCase() ||
50
+ (tx.value ?? 0n) !== 0n || tx.nonce === undefined || tx.gas === undefined || tx.gas <= 0n ||
51
+ tx.maxFeePerGas === undefined || tx.maxPriorityFeePerGas === undefined || tx.r || tx.s || tx.yParity !== undefined ||
52
+ (tx.accessList?.length ?? 0) > 0)
53
+ invalid('unsigned request');
54
+ if (['submitted', 'mined', 'confirmed', 'reverted'].includes(step.state) && !step.transactionHash)
55
+ invalid('missing hash');
56
+ if (['mined', 'confirmed', 'reverted'].includes(step.state) && (!step.receipt || !step.receiptFinality ||
57
+ (step.state === 'confirmed' && step.receiptFinality !== 'finalized') ||
58
+ (step.state === 'mined' && step.receiptFinality !== 'mined') ||
59
+ step.receipt.transactionHash.toLowerCase() !== step.transactionHash?.toLowerCase() ||
60
+ (step.state === 'reverted' ? step.receipt.status !== 'reverted' : step.receipt.status !== 'success')))
61
+ invalid('receipt state');
62
+ if (['prepared', 'not-submitted', 'unknown'].includes(step.state) && (step.transactionHash || step.receipt || step.receiptFinality))
63
+ invalid('unexpected evidence');
64
+ if (step.state === 'submitted' && (step.receipt || step.receiptFinality))
65
+ invalid('unsealed receipt');
66
+ prior = step.index;
67
+ }
68
+ if (op.state === 'completed' && (!op.result || !op.steps.some((s) => s.index === 2 && s.state === 'confirmed') ||
69
+ op.steps.some((s) => !['confirmed', 'not-submitted'].includes(s.state))))
70
+ invalid('completion proof');
71
+ if (op.state === 'failed' && op.steps.some((s) => !['confirmed', 'reverted', 'not-submitted'].includes(s.state) ||
72
+ (s.state !== 'not-submitted' && s.receiptFinality !== 'finalized')))
73
+ invalid('failed evidence');
74
+ if (op.state === 'completed') {
75
+ const result = op.result, call = op.steps.find((step) => step.index === 2);
76
+ if (!result || result.status !== 'completed' || !call?.receipt ||
77
+ getAddress(result.owner) !== getAddress(op.account) || result.marketId !== core.plan.marketId || result.action !== core.plan.action ||
78
+ result.transactionHash.toLowerCase() !== call.transactionHash?.toLowerCase() || result.blockNumber !== call.receipt.blockNumber ||
79
+ result.actualInput !== core.plan.amount || BigInt(result.actualOutput) < BigInt(core.plan.minimumOutput) ||
80
+ getAddress(result.feeToken) !== getAddress(core.plan.fee.token) ||
81
+ BigInt(result.actualOttoFee) !== nativeYieldFee(core.plan.action === 'deposit' ? BigInt(result.actualInput) :
82
+ BigInt(result.actualOutput) + BigInt(result.actualOttoFee)) ||
83
+ result.gasUsed !== call.receipt.gasUsed || BigInt(result.receiptGasCostWei) !==
84
+ BigInt(call.receipt.gasUsed) * BigInt(call.receipt.effectiveGasPrice))
85
+ invalid('completed result binding');
86
+ }
87
+ else if (op.state === 'failed') {
88
+ if (op.result?.status !== 'closed-without-native-completion' || op.steps.some((step) => step.index === 2 && step.state === 'confirmed'))
89
+ invalid('failed result binding');
90
+ }
91
+ else if (op.result !== undefined)
92
+ invalid('nonterminal result');
93
+ return op;
94
+ }
95
+ export class NativeYieldAccountStore {
96
+ db;
97
+ now;
98
+ constructor(db, now = Date.now) {
99
+ this.db = db;
100
+ this.now = now;
101
+ assertExecutionJournalCompatible(db, 3);
102
+ initializeNativeYieldConsents(db);
103
+ assertExecutionStorageSchema(db, NATIVE_OPERATION_SCHEMA);
104
+ this.transaction(() => this.checkClaims());
105
+ }
106
+ transaction(fn) {
107
+ if (this.db.isTransaction) {
108
+ const savepoint = `native_${randomUUID().replaceAll('-', '')}`;
109
+ this.db.exec(`SAVEPOINT ${savepoint}`);
110
+ try {
111
+ assertExecutionJournalCompatible(this.db, 3);
112
+ const value = fn();
113
+ this.db.exec(`RELEASE ${savepoint}`);
114
+ return value;
115
+ }
116
+ catch (error) {
117
+ try {
118
+ this.db.exec(`ROLLBACK TO ${savepoint}`);
119
+ this.db.exec(`RELEASE ${savepoint}`);
120
+ }
121
+ catch { /* retain original failure */ }
122
+ throw error;
123
+ }
124
+ }
125
+ this.db.exec('BEGIN IMMEDIATE');
126
+ try {
127
+ assertExecutionJournalCompatible(this.db, 3);
128
+ const value = fn();
129
+ this.db.exec('COMMIT');
130
+ return value;
131
+ }
132
+ catch (error) {
133
+ try {
134
+ this.db.exec('ROLLBACK');
135
+ }
136
+ catch { /* retain original failure */ }
137
+ throw error;
138
+ }
139
+ }
140
+ decode(row) {
141
+ if (!row)
142
+ return undefined;
143
+ const value = row;
144
+ const op = validateNativeAccountOperation(JSON.parse(value.record_json));
145
+ if (op.operationId !== value.operation_id || op.userId !== value.user_id)
146
+ invalid('row identity');
147
+ return op;
148
+ }
149
+ checkClaims() {
150
+ const rows = this.db.prepare('SELECT * FROM native_yield_operations').all().map((r) => this.decode(r));
151
+ for (const op of rows.filter(unresolved))
152
+ this.requireClaim(op);
153
+ const claims = this.db.prepare("SELECT user_id,claim_id FROM user_execution_claims WHERE kind='native'").all();
154
+ for (const claim of claims)
155
+ if (!rows.some((op) => unresolved(op) && op.userId === claim.user_id && op.operationId === claim.claim_id))
156
+ invalid('orphan native claim');
157
+ }
158
+ requireClaim(op) {
159
+ const claim = readUserExecutionClaim(this.db, op.userId);
160
+ if (claim?.kind !== 'native' || claim.claimId !== op.operationId)
161
+ invalid('native claim mismatch');
162
+ }
163
+ read(userId, operationId) {
164
+ assertExecutionJournalCompatible(this.db, 3);
165
+ const op = this.decode(this.db.prepare('SELECT * FROM native_yield_operations WHERE operation_id=? AND user_id=?').get(operationId, userId));
166
+ if (!op)
167
+ throw new Error('NATIVE_OPERATION_NOT_FOUND');
168
+ if (unresolved(op))
169
+ this.requireClaim(op);
170
+ return op;
171
+ }
172
+ list(userId) {
173
+ assertExecutionJournalCompatible(this.db, 3);
174
+ return this.db.prepare('SELECT * FROM native_yield_operations WHERE user_id=? ORDER BY rowid DESC LIMIT 100').all(userId)
175
+ .map((row) => { const op = this.decode(row); if (unresolved(op))
176
+ this.requireClaim(op); return op; });
177
+ }
178
+ save(op) {
179
+ op.updatedAtMs = this.now();
180
+ if (op.state !== 'attention')
181
+ delete op.failureCode;
182
+ validateNativeAccountOperation(op);
183
+ const changed = this.db.prepare('UPDATE native_yield_operations SET record_json=? WHERE operation_id=? AND user_id=?')
184
+ .run(JSON.stringify(op), op.operationId, op.userId);
185
+ if (Number(changed.changes) !== 1)
186
+ invalid('write disappeared');
187
+ return op;
188
+ }
189
+ create(context) {
190
+ return this.transaction(() => {
191
+ const operationId = `ny_${randomUUID()}`, now = this.now();
192
+ const full = NATIVE_ACCOUNT_OPERATION_CONTEXT_SCHEMA.parse({ ...context, reviewCommitment: nativeAccountReviewCommitment(operationId, context) });
193
+ assertCurrentNativeYieldConsent(this.db, full.consent, full.consent.authority, now);
194
+ if (readUserExecutionClaim(this.db, full.consent.authority.userId))
195
+ throw new Error('NATIVE_EXECUTION_BUSY');
196
+ const op = validateNativeAccountOperation({ operationId, userId: full.consent.authority.userId, account: full.plan.owner,
197
+ chainId: full.plan.chainId, state: 'review', context: full, reviewConsumed: false, createdAtMs: now, updatedAtMs: now, steps: [] });
198
+ this.db.prepare('INSERT INTO native_yield_operations (operation_id,user_id,record_json) VALUES (?,?,?)')
199
+ .run(operationId, op.userId, JSON.stringify(op));
200
+ return op;
201
+ });
202
+ }
203
+ begin(userId, operationId, planCommitment, reviewCommitment, authority) {
204
+ return this.transaction(() => {
205
+ const op = this.read(userId, operationId);
206
+ if (op.state !== 'review' || op.reviewConsumed || op.context.plan.planCommitment !== planCommitment ||
207
+ op.context.reviewCommitment !== reviewCommitment || op.context.plan.deadline * 1000 <= this.now())
208
+ throw new Error('NATIVE_REVIEW_REQUIRED');
209
+ assertCurrentNativeYieldConsent(this.db, op.context.consent, authority, this.now());
210
+ if (claimNativeExecution(this.db, { userId, operationId }, this.now()).outcome !== 'started')
211
+ throw new Error('NATIVE_EXECUTION_BUSY');
212
+ op.reviewConsumed = true;
213
+ op.state = 'active';
214
+ return this.save(op);
215
+ });
216
+ }
217
+ assertConsent(op, authority) {
218
+ this.transaction(() => {
219
+ const current = this.read(op.userId, op.operationId);
220
+ this.requireClaim(current);
221
+ assertCurrentNativeYieldConsent(this.db, current.context.consent, authority, this.now());
222
+ });
223
+ }
224
+ append(userId, operationId, rawStep) {
225
+ return this.transaction(() => {
226
+ const op = this.read(userId, operationId), step = NATIVE_ACCOUNT_STEP_SCHEMA.parse(rawStep);
227
+ this.requireClaim(op);
228
+ if (step.state !== 'prepared' || op.steps.some((s) => s.index === step.index) ||
229
+ op.steps.some((s) => ['prepared', 'submitted', 'unknown'].includes(s.state)) ||
230
+ (step.index < 3 && op.steps.some((s) => !['mined', 'confirmed'].includes(s.state))))
231
+ invalid('unsafe new step');
232
+ op.steps.push(step);
233
+ op.state = 'active';
234
+ return this.save(op);
235
+ });
236
+ }
237
+ evidence(userId, operationId, index, evidence) {
238
+ return this.transaction(() => {
239
+ const op = this.read(userId, operationId);
240
+ this.requireClaim(op);
241
+ const step = op.steps.find((s) => s.index === index);
242
+ if (!step)
243
+ invalid('unknown step');
244
+ if (evidence.state === 'unknown' || evidence.state === 'not-submitted') {
245
+ if (step.state !== 'prepared')
246
+ invalid('request already left pre-send');
247
+ step.state = evidence.state;
248
+ }
249
+ else {
250
+ const hash = 'receipt' in evidence ? evidence.receipt.transactionHash : 'transactionHash' in evidence ? evidence.transactionHash : invalid('evidence shape');
251
+ if (step.state === 'not-submitted' || (step.transactionHash && step.transactionHash.toLowerCase() !== hash.toLowerCase()))
252
+ invalid('hash changed');
253
+ if (step.state === 'confirmed' && evidence.state !== 'confirmed')
254
+ invalid('final receipt regressed');
255
+ step.transactionHash = hash;
256
+ step.state = evidence.state;
257
+ if ('receipt' in evidence) {
258
+ if (step.receiptFinality === 'finalized' && (evidence.finality !== 'finalized' ||
259
+ nativeAccountDigest(step.receipt) !== nativeAccountDigest(evidence.receipt)))
260
+ invalid('final receipt changed');
261
+ step.receipt = evidence.receipt;
262
+ step.receiptFinality = evidence.finality;
263
+ }
264
+ }
265
+ op.state = evidence.state === 'unknown' || evidence.state === 'reverted' || evidence.state === 'not-submitted' ? 'attention' : 'confirming';
266
+ return this.save(op);
267
+ });
268
+ }
269
+ attention(userId, operationId, code) {
270
+ return this.transaction(() => {
271
+ const op = this.read(userId, operationId);
272
+ this.requireClaim(op);
273
+ op.state = 'attention';
274
+ op.failureCode = /^[A-Z0-9_]{1,100}$/.test(code) ? code : 'NATIVE_ACTION_STOPPED';
275
+ return this.save(op);
276
+ });
277
+ }
278
+ /** Caller supplies finalized transaction/protocol/zero-allowance proofs; this commits the terminal record and release atomically. */
279
+ finish(userId, operationId, outcome) {
280
+ return this.transaction(() => {
281
+ const op = this.read(userId, operationId);
282
+ this.requireClaim(op);
283
+ op.state = outcome.state;
284
+ op.result = NATIVE_ACCOUNT_SETTLEMENT_SCHEMA.parse(outcome.result);
285
+ this.save(op);
286
+ releaseNativeExecutionClaim(this.db, { userId, operationId });
287
+ return op;
288
+ });
289
+ }
290
+ }
291
+ export async function openNativeYieldAccountStore(root, now = Date.now, requireExistingLegacyJournal = false) {
292
+ if (requireExistingLegacyJournal)
293
+ await access(join(root, 'operations.db'));
294
+ else
295
+ await mkdir(root, { recursive: true, mode: 0o700 });
296
+ const specifier = 'node:sqlite';
297
+ const { DatabaseSync } = await import(specifier);
298
+ const db = new DatabaseSync(join(root, 'operations.db'));
299
+ if (requireExistingLegacyJournal && !db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='operations'").get())
300
+ invalid('existing legacy operation journal required');
301
+ db.exec('PRAGMA busy_timeout=5000');
302
+ initializeExecutionJournal(db, now());
303
+ assertExecutionJournalCompatible(db, 3);
304
+ db.exec('PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL; PRAGMA foreign_keys=ON;');
305
+ return new NativeYieldAccountStore(db, now);
306
+ }
307
+ //# sourceMappingURL=native-yield-account-store.js.map