@jinn-network/client 0.1.0-canary.adfd078d

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 (278) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/deployments/deployment-phase1a-l2-baseSepolia-fast.json +32 -0
  4. package/deployments/deployment-phase1a-token-baseSepolia-fast.json +27 -0
  5. package/deployments/deployment-phase1b-mech-baseSepolia-fast.json +26 -0
  6. package/deployments/deployment-stolas-l2-baseSepolia-fast.json +35 -0
  7. package/dist/adapters/adapter.d.ts +11 -0
  8. package/dist/adapters/adapter.js +2 -0
  9. package/dist/adapters/adapter.js.map +1 -0
  10. package/dist/adapters/local/adapter.d.ts +20 -0
  11. package/dist/adapters/local/adapter.js +146 -0
  12. package/dist/adapters/local/adapter.js.map +1 -0
  13. package/dist/adapters/mech/adapter.d.ts +29 -0
  14. package/dist/adapters/mech/adapter.js +332 -0
  15. package/dist/adapters/mech/adapter.js.map +1 -0
  16. package/dist/adapters/mech/claim-policy.d.ts +40 -0
  17. package/dist/adapters/mech/claim-policy.js +104 -0
  18. package/dist/adapters/mech/claim-policy.js.map +1 -0
  19. package/dist/adapters/mech/contracts.d.ts +44 -0
  20. package/dist/adapters/mech/contracts.js +323 -0
  21. package/dist/adapters/mech/contracts.js.map +1 -0
  22. package/dist/adapters/mech/ipfs.d.ts +43 -0
  23. package/dist/adapters/mech/ipfs.js +142 -0
  24. package/dist/adapters/mech/ipfs.js.map +1 -0
  25. package/dist/adapters/mech/safe.d.ts +15 -0
  26. package/dist/adapters/mech/safe.js +113 -0
  27. package/dist/adapters/mech/safe.js.map +1 -0
  28. package/dist/adapters/mech/types.d.ts +561 -0
  29. package/dist/adapters/mech/types.js +340 -0
  30. package/dist/adapters/mech/types.js.map +1 -0
  31. package/dist/api/balance-build.d.ts +22 -0
  32. package/dist/api/balance-build.js +37 -0
  33. package/dist/api/balance-build.js.map +1 -0
  34. package/dist/api/fleet-build.d.ts +62 -0
  35. package/dist/api/fleet-build.js +91 -0
  36. package/dist/api/fleet-build.js.map +1 -0
  37. package/dist/api/gather-status.d.ts +20 -0
  38. package/dist/api/gather-status.js +137 -0
  39. package/dist/api/gather-status.js.map +1 -0
  40. package/dist/api/history-build.d.ts +32 -0
  41. package/dist/api/history-build.js +48 -0
  42. package/dist/api/history-build.js.map +1 -0
  43. package/dist/api/peers.d.ts +27 -0
  44. package/dist/api/peers.js +94 -0
  45. package/dist/api/peers.js.map +1 -0
  46. package/dist/api/rewards-build.d.ts +20 -0
  47. package/dist/api/rewards-build.js +42 -0
  48. package/dist/api/rewards-build.js.map +1 -0
  49. package/dist/api/server.d.ts +34 -0
  50. package/dist/api/server.js +130 -0
  51. package/dist/api/server.js.map +1 -0
  52. package/dist/api/status-build.d.ts +92 -0
  53. package/dist/api/status-build.js +175 -0
  54. package/dist/api/status-build.js.map +1 -0
  55. package/dist/api/status-rollup-build.d.ts +36 -0
  56. package/dist/api/status-rollup-build.js +69 -0
  57. package/dist/api/status-rollup-build.js.map +1 -0
  58. package/dist/auth/erc8128.d.ts +43 -0
  59. package/dist/auth/erc8128.js +88 -0
  60. package/dist/auth/erc8128.js.map +1 -0
  61. package/dist/bin/jinn.d.ts +11 -0
  62. package/dist/bin/jinn.js +20 -0
  63. package/dist/bin/jinn.js.map +1 -0
  64. package/dist/build-meta.json +3 -0
  65. package/dist/chain-read-errors.d.ts +9 -0
  66. package/dist/chain-read-errors.js +43 -0
  67. package/dist/chain-read-errors.js.map +1 -0
  68. package/dist/cli/action.d.ts +26 -0
  69. package/dist/cli/action.js +56 -0
  70. package/dist/cli/action.js.map +1 -0
  71. package/dist/cli/command.d.ts +62 -0
  72. package/dist/cli/command.js +29 -0
  73. package/dist/cli/command.js.map +1 -0
  74. package/dist/cli/commands/balance.d.ts +3 -0
  75. package/dist/cli/commands/balance.js +46 -0
  76. package/dist/cli/commands/balance.js.map +1 -0
  77. package/dist/cli/commands/bootstrap.d.ts +3 -0
  78. package/dist/cli/commands/bootstrap.js +165 -0
  79. package/dist/cli/commands/bootstrap.js.map +1 -0
  80. package/dist/cli/commands/claim-rewards.d.ts +3 -0
  81. package/dist/cli/commands/claim-rewards.js +121 -0
  82. package/dist/cli/commands/claim-rewards.js.map +1 -0
  83. package/dist/cli/commands/doctor.d.ts +3 -0
  84. package/dist/cli/commands/doctor.js +151 -0
  85. package/dist/cli/commands/doctor.js.map +1 -0
  86. package/dist/cli/commands/fleet-scale.d.ts +3 -0
  87. package/dist/cli/commands/fleet-scale.js +449 -0
  88. package/dist/cli/commands/fleet-scale.js.map +1 -0
  89. package/dist/cli/commands/fleet.d.ts +3 -0
  90. package/dist/cli/commands/fleet.js +45 -0
  91. package/dist/cli/commands/fleet.js.map +1 -0
  92. package/dist/cli/commands/fund-requirements.d.ts +3 -0
  93. package/dist/cli/commands/fund-requirements.js +139 -0
  94. package/dist/cli/commands/fund-requirements.js.map +1 -0
  95. package/dist/cli/commands/history.d.ts +3 -0
  96. package/dist/cli/commands/history.js +61 -0
  97. package/dist/cli/commands/history.js.map +1 -0
  98. package/dist/cli/commands/init.d.ts +3 -0
  99. package/dist/cli/commands/init.js +91 -0
  100. package/dist/cli/commands/init.js.map +1 -0
  101. package/dist/cli/commands/keys-backup.d.ts +3 -0
  102. package/dist/cli/commands/keys-backup.js +107 -0
  103. package/dist/cli/commands/keys-backup.js.map +1 -0
  104. package/dist/cli/commands/logs.d.ts +3 -0
  105. package/dist/cli/commands/logs.js +69 -0
  106. package/dist/cli/commands/logs.js.map +1 -0
  107. package/dist/cli/commands/rewards.d.ts +3 -0
  108. package/dist/cli/commands/rewards.js +54 -0
  109. package/dist/cli/commands/rewards.js.map +1 -0
  110. package/dist/cli/commands/run.d.ts +3 -0
  111. package/dist/cli/commands/run.js +96 -0
  112. package/dist/cli/commands/run.js.map +1 -0
  113. package/dist/cli/commands/status.d.ts +3 -0
  114. package/dist/cli/commands/status.js +54 -0
  115. package/dist/cli/commands/status.js.map +1 -0
  116. package/dist/cli/commands/stop.d.ts +3 -0
  117. package/dist/cli/commands/stop.js +82 -0
  118. package/dist/cli/commands/stop.js.map +1 -0
  119. package/dist/cli/commands/submit-intent.d.ts +3 -0
  120. package/dist/cli/commands/submit-intent.js +169 -0
  121. package/dist/cli/commands/submit-intent.js.map +1 -0
  122. package/dist/cli/commands/version.d.ts +3 -0
  123. package/dist/cli/commands/version.js +114 -0
  124. package/dist/cli/commands/version.js.map +1 -0
  125. package/dist/cli/commands/withdraw.d.ts +3 -0
  126. package/dist/cli/commands/withdraw.js +181 -0
  127. package/dist/cli/commands/withdraw.js.map +1 -0
  128. package/dist/cli/deployment-digest.d.ts +10 -0
  129. package/dist/cli/deployment-digest.js +25 -0
  130. package/dist/cli/deployment-digest.js.map +1 -0
  131. package/dist/cli/execution-context.d.ts +50 -0
  132. package/dist/cli/execution-context.js +154 -0
  133. package/dist/cli/execution-context.js.map +1 -0
  134. package/dist/cli/help.d.ts +3 -0
  135. package/dist/cli/help.js +37 -0
  136. package/dist/cli/help.js.map +1 -0
  137. package/dist/cli/index.d.ts +17 -0
  138. package/dist/cli/index.js +132 -0
  139. package/dist/cli/index.js.map +1 -0
  140. package/dist/cli/introspection-context.d.ts +10 -0
  141. package/dist/cli/introspection-context.js +60 -0
  142. package/dist/cli/introspection-context.js.map +1 -0
  143. package/dist/cli/output.d.ts +36 -0
  144. package/dist/cli/output.js +35 -0
  145. package/dist/cli/output.js.map +1 -0
  146. package/dist/cli/password.d.ts +12 -0
  147. package/dist/cli/password.js +51 -0
  148. package/dist/cli/password.js.map +1 -0
  149. package/dist/config.d.ts +174 -0
  150. package/dist/config.js +252 -0
  151. package/dist/config.js.map +1 -0
  152. package/dist/daemon/creator.d.ts +24 -0
  153. package/dist/daemon/creator.js +80 -0
  154. package/dist/daemon/creator.js.map +1 -0
  155. package/dist/daemon/daemon.d.ts +60 -0
  156. package/dist/daemon/daemon.js +158 -0
  157. package/dist/daemon/daemon.js.map +1 -0
  158. package/dist/daemon/delivery-watcher.d.ts +10 -0
  159. package/dist/daemon/delivery-watcher.js +37 -0
  160. package/dist/daemon/delivery-watcher.js.map +1 -0
  161. package/dist/daemon/restorer.d.ts +19 -0
  162. package/dist/daemon/restorer.js +82 -0
  163. package/dist/daemon/restorer.js.map +1 -0
  164. package/dist/daemon/reward-claim-loop.d.ts +38 -0
  165. package/dist/daemon/reward-claim-loop.js +48 -0
  166. package/dist/daemon/reward-claim-loop.js.map +1 -0
  167. package/dist/discovery/registry.d.ts +43 -0
  168. package/dist/discovery/registry.js +104 -0
  169. package/dist/discovery/registry.js.map +1 -0
  170. package/dist/discovery/subgraph.d.ts +37 -0
  171. package/dist/discovery/subgraph.js +87 -0
  172. package/dist/discovery/subgraph.js.map +1 -0
  173. package/dist/earning/bootstrap.d.ts +79 -0
  174. package/dist/earning/bootstrap.js +989 -0
  175. package/dist/earning/bootstrap.js.map +1 -0
  176. package/dist/earning/contracts.d.ts +431 -0
  177. package/dist/earning/contracts.js +518 -0
  178. package/dist/earning/contracts.js.map +1 -0
  179. package/dist/earning/evidence-simhash.d.ts +59 -0
  180. package/dist/earning/evidence-simhash.js +87 -0
  181. package/dist/earning/evidence-simhash.js.map +1 -0
  182. package/dist/earning/fleet-display-index.d.ts +8 -0
  183. package/dist/earning/fleet-display-index.js +12 -0
  184. package/dist/earning/fleet-display-index.js.map +1 -0
  185. package/dist/earning/fleet-retire.d.ts +28 -0
  186. package/dist/earning/fleet-retire.js +75 -0
  187. package/dist/earning/fleet-retire.js.map +1 -0
  188. package/dist/earning/jinn-rewards.d.ts +62 -0
  189. package/dist/earning/jinn-rewards.js +81 -0
  190. package/dist/earning/jinn-rewards.js.map +1 -0
  191. package/dist/earning/next-service-index.d.ts +4 -0
  192. package/dist/earning/next-service-index.js +7 -0
  193. package/dist/earning/next-service-index.js.map +1 -0
  194. package/dist/earning/orphan-sweep.d.ts +33 -0
  195. package/dist/earning/orphan-sweep.js +157 -0
  196. package/dist/earning/orphan-sweep.js.map +1 -0
  197. package/dist/earning/reconcile.d.ts +37 -0
  198. package/dist/earning/reconcile.js +216 -0
  199. package/dist/earning/reconcile.js.map +1 -0
  200. package/dist/earning/safe-adapter.d.ts +70 -0
  201. package/dist/earning/safe-adapter.js +228 -0
  202. package/dist/earning/safe-adapter.js.map +1 -0
  203. package/dist/earning/stolas-claim.d.ts +47 -0
  204. package/dist/earning/stolas-claim.js +115 -0
  205. package/dist/earning/stolas-claim.js.map +1 -0
  206. package/dist/earning/store.d.ts +36 -0
  207. package/dist/earning/store.js +156 -0
  208. package/dist/earning/store.js.map +1 -0
  209. package/dist/earning/types.d.ts +123 -0
  210. package/dist/earning/types.js +64 -0
  211. package/dist/earning/types.js.map +1 -0
  212. package/dist/earning/viem-clients.d.ts +9 -0
  213. package/dist/earning/viem-clients.js +22 -0
  214. package/dist/earning/viem-clients.js.map +1 -0
  215. package/dist/earning/wallet.d.ts +20 -0
  216. package/dist/earning/wallet.js +103 -0
  217. package/dist/earning/wallet.js.map +1 -0
  218. package/dist/errors/envelope.d.ts +41 -0
  219. package/dist/errors/envelope.js +48 -0
  220. package/dist/errors/envelope.js.map +1 -0
  221. package/dist/index.d.ts +14 -0
  222. package/dist/index.js +17 -0
  223. package/dist/index.js.map +1 -0
  224. package/dist/main.d.ts +32 -0
  225. package/dist/main.js +281 -0
  226. package/dist/main.js.map +1 -0
  227. package/dist/mcp/server.d.ts +14 -0
  228. package/dist/mcp/server.js +205 -0
  229. package/dist/mcp/server.js.map +1 -0
  230. package/dist/operator-errors.d.ts +16 -0
  231. package/dist/operator-errors.js +88 -0
  232. package/dist/operator-errors.js.map +1 -0
  233. package/dist/preflight/claude-binary.d.ts +19 -0
  234. package/dist/preflight/claude-binary.js +44 -0
  235. package/dist/preflight/claude-binary.js.map +1 -0
  236. package/dist/preflight/claude-invocation-envelope.d.ts +11 -0
  237. package/dist/preflight/claude-invocation-envelope.js +67 -0
  238. package/dist/preflight/claude-invocation-envelope.js.map +1 -0
  239. package/dist/runner/claude.d.ts +15 -0
  240. package/dist/runner/claude.js +193 -0
  241. package/dist/runner/claude.js.map +1 -0
  242. package/dist/runner/runner.d.ts +11 -0
  243. package/dist/runner/runner.js +2 -0
  244. package/dist/runner/runner.js.map +1 -0
  245. package/dist/runner/simple.d.ts +8 -0
  246. package/dist/runner/simple.js +11 -0
  247. package/dist/runner/simple.js.map +1 -0
  248. package/dist/store/store.d.ts +74 -0
  249. package/dist/store/store.js +173 -0
  250. package/dist/store/store.js.map +1 -0
  251. package/dist/tx-retry.d.ts +55 -0
  252. package/dist/tx-retry.js +214 -0
  253. package/dist/tx-retry.js.map +1 -0
  254. package/dist/types/desired-state.d.ts +41 -0
  255. package/dist/types/desired-state.js +16 -0
  256. package/dist/types/desired-state.js.map +1 -0
  257. package/dist/types/errors.d.ts +8 -0
  258. package/dist/types/errors.js +17 -0
  259. package/dist/types/errors.js.map +1 -0
  260. package/dist/types/index.d.ts +2 -0
  261. package/dist/types/index.js +3 -0
  262. package/dist/types/index.js.map +1 -0
  263. package/dist/withdraw/args.d.ts +29 -0
  264. package/dist/withdraw/args.js +198 -0
  265. package/dist/withdraw/args.js.map +1 -0
  266. package/dist/withdraw/run-withdraw-plan.d.ts +21 -0
  267. package/dist/withdraw/run-withdraw-plan.js +257 -0
  268. package/dist/withdraw/run-withdraw-plan.js.map +1 -0
  269. package/dist/x402/acquire.d.ts +6 -0
  270. package/dist/x402/acquire.js +32 -0
  271. package/dist/x402/acquire.js.map +1 -0
  272. package/dist/x402/facilitator.d.ts +11 -0
  273. package/dist/x402/facilitator.js +52 -0
  274. package/dist/x402/facilitator.js.map +1 -0
  275. package/dist/x402/handler.d.ts +15 -0
  276. package/dist/x402/handler.js +40 -0
  277. package/dist/x402/handler.js.map +1 -0
  278. package/package.json +72 -0
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Pure reconciliation rules: persisted fleet service state vs on-chain signals.
3
+ * Used by FleetBootstrapper so operators need not hand-edit earning_state.json.
4
+ */
5
+ import { getAddress } from 'viem';
6
+ const ZERO = '0x0000000000000000000000000000000000000000';
7
+ const STANDARD_POST_STAKE = new Set([
8
+ 'staked',
9
+ 'mech_deployed',
10
+ 'complete',
11
+ ]);
12
+ const SELF_BOND_STAKE_STEPS = new Set([
13
+ 'service_staked',
14
+ 'staked',
15
+ 'mech_deployed',
16
+ 'complete',
17
+ ]);
18
+ /** Self-bond registry state → latest local step that must not be ahead of chain (bootstrap idempotency). */
19
+ const REGISTRY_MAX_STEP = {
20
+ 0: 'service_created',
21
+ 1: 'service_activated',
22
+ 2: 'agents_registered',
23
+ 3: 'service_deployed',
24
+ 4: 'service_staked',
25
+ };
26
+ const STEP_ORDER = [
27
+ 'awaiting_stake',
28
+ 'service_created',
29
+ 'service_activated',
30
+ 'agents_registered',
31
+ 'service_deployed',
32
+ 'service_staked',
33
+ 'staked',
34
+ 'mech_deployed',
35
+ 'complete',
36
+ ];
37
+ function stepIndex(step) {
38
+ const i = STEP_ORDER.indexOf(step);
39
+ return i === -1 ? 0 : i;
40
+ }
41
+ function isZeroishAddress(addr) {
42
+ if (!addr)
43
+ return true;
44
+ try {
45
+ return getAddress(addr) === getAddress(ZERO);
46
+ }
47
+ catch {
48
+ return true;
49
+ }
50
+ }
51
+ function clearServiceIdentity() {
52
+ return {
53
+ service_id: null,
54
+ safe_address: null,
55
+ mech_address: null,
56
+ staking_address: null,
57
+ step: 'awaiting_stake',
58
+ error: null,
59
+ };
60
+ }
61
+ /**
62
+ * Standard (distributor) mode: staking proxy is source of truth for stake/eviction.
63
+ */
64
+ export function reconcileStandardService(index, svc, chain, ctx) {
65
+ if (svc.service_id === null)
66
+ return null;
67
+ const id = svc.service_id;
68
+ if (chain.stakingState === 'inconclusive' || chain.registryState === 'inconclusive') {
69
+ return null;
70
+ }
71
+ if (chain.stakingState === 'revert') {
72
+ return {
73
+ message: `[jinn-earning] Service ${index}: persisted id=${id} is unknown to the staking contract (RPC reverted). Clearing local service id and Safe/mech fields; next bootstrap will run a fresh distributor stake().`,
74
+ patch: clearServiceIdentity(),
75
+ };
76
+ }
77
+ if (chain.stakingState === 2) {
78
+ // Eviction: resumeService runs reStake; no state patch here.
79
+ return null;
80
+ }
81
+ // Crashed after assigning service_id but before stake confirmed — or stale id
82
+ if (svc.step === 'awaiting_stake' && chain.stakingState === 0) {
83
+ return {
84
+ message: `[jinn-earning] Service ${index}: local step was awaiting_stake but service_id=${id} is not staked on-chain. Clearing stale id/Safe/mech; next bootstrap will call distributor stake() cleanly.`,
85
+ patch: clearServiceIdentity(),
86
+ };
87
+ }
88
+ // State file behind chain (e.g. crash after stake mined before step save)
89
+ if (svc.step === 'awaiting_stake' && chain.stakingState === 1) {
90
+ const safe = chain.stakingMultisig && !isZeroishAddress(chain.stakingMultisig)
91
+ ? getAddress(chain.stakingMultisig)
92
+ : svc.safe_address;
93
+ if (!safe || isZeroishAddress(safe)) {
94
+ return null;
95
+ }
96
+ return {
97
+ message: `[jinn-earning] Service ${index}: on-chain shows id=${id} already staked; advancing local step from awaiting_stake to staked (Safe ${safe}).`,
98
+ patch: {
99
+ step: 'staked',
100
+ safe_address: safe,
101
+ staking_address: getAddress(ctx.stakingContract),
102
+ error: null,
103
+ },
104
+ };
105
+ }
106
+ if (STANDARD_POST_STAKE.has(svc.step) && chain.stakingState === 0) {
107
+ return {
108
+ message: `[jinn-earning] Service ${index}: on-chain staking is unstaked for id=${id} while local step was '${svc.step}' (e.g. unstakeAndWithdraw or a crashed tx). Resetting to awaiting_stake; next bootstrap will provision a new service via the distributor.`,
109
+ patch: clearServiceIdentity(),
110
+ };
111
+ }
112
+ return null;
113
+ }
114
+ function maxStepForRegistryState(registryState) {
115
+ if (registryState >= 4)
116
+ return 'service_staked';
117
+ return REGISTRY_MAX_STEP[registryState] ?? 'service_created';
118
+ }
119
+ /**
120
+ * Self-bond mode: registry + Safe bytecode + staking.
121
+ */
122
+ export function reconcileSelfBondService(index, svc, chain) {
123
+ const step = svc.step;
124
+ if (chain.stakingState === 'inconclusive' || chain.registryState === 'inconclusive') {
125
+ return null;
126
+ }
127
+ // Safe predicted or required but not deployed while we think we passed setup
128
+ if (step !== 'awaiting_stake' &&
129
+ svc.safe_address &&
130
+ chain.safeDeployed === false) {
131
+ return {
132
+ message: `[jinn-earning] Service ${index}: Safe ${svc.safe_address} has no bytecode on-chain but local step was '${step}'. Rewinding to awaiting_stake to re-run Safe prediction and deployment.`,
133
+ patch: clearServiceIdentity(),
134
+ };
135
+ }
136
+ if (svc.service_id !== null) {
137
+ const id = svc.service_id;
138
+ if (chain.registryState === 'revert') {
139
+ return {
140
+ message: `[jinn-earning] Service ${index}: could not read service ${id} from the registry (RPC reverted). Clearing service id; bootstrap will recreate the service when you re-run.`,
141
+ patch: {
142
+ service_id: null,
143
+ mech_address: null,
144
+ staking_address: null,
145
+ step: chain.safeDeployed === true ? 'service_created' : 'awaiting_stake',
146
+ error: null,
147
+ },
148
+ };
149
+ }
150
+ const reg = chain.registryState;
151
+ const multisigMissing = chain.registryMultisig === null || isZeroishAddress(chain.registryMultisig);
152
+ if (typeof reg === 'number' && reg === 0 && multisigMissing) {
153
+ return {
154
+ message: `[jinn-earning] Service ${index}: registry shows no service at id=${id} (evicted / terminated / wrong id). Clearing local service id; next bootstrap will create a new service from step '${chain.safeDeployed === true ? 'service_created' : 'awaiting_stake'}'.`,
155
+ patch: {
156
+ service_id: null,
157
+ mech_address: null,
158
+ staking_address: null,
159
+ step: chain.safeDeployed === true ? 'service_created' : 'awaiting_stake',
160
+ error: null,
161
+ },
162
+ };
163
+ }
164
+ // Staking beats registry-order heuristics (eviction / unstaked while registry still "deployed")
165
+ if (chain.stakingState !== 'revert' && SELF_BOND_STAKE_STEPS.has(step)) {
166
+ if (chain.stakingState === 2) {
167
+ return {
168
+ message: `[jinn-earning] Service ${index}: service ${id} is evicted on-chain (staking state 2). Rewinding to service_staked to re-stake when you re-run.`,
169
+ patch: {
170
+ step: 'service_staked',
171
+ mech_address: null,
172
+ error: null,
173
+ },
174
+ };
175
+ }
176
+ if (chain.stakingState === 0) {
177
+ return {
178
+ message: `[jinn-earning] Service ${index}: service ${id} is not staked on-chain while local step was '${step}' (e.g. partial stake or unstake). Rewinding to service_staked to retry staking.`,
179
+ patch: {
180
+ step: 'service_staked',
181
+ mech_address: null,
182
+ error: null,
183
+ },
184
+ };
185
+ }
186
+ }
187
+ // Local step ahead of chain (e.g. tx never mined after state save)
188
+ if (typeof reg === 'number' && reg > 0) {
189
+ const maxStep = maxStepForRegistryState(reg);
190
+ if (stepIndex(step) > stepIndex(maxStep)) {
191
+ const patch = {
192
+ step: maxStep,
193
+ error: null,
194
+ };
195
+ if (stepIndex(maxStep) < stepIndex('staked')) {
196
+ patch.mech_address = null;
197
+ }
198
+ if (stepIndex(maxStep) < stepIndex('service_staked')) {
199
+ patch.staking_address = null;
200
+ }
201
+ return {
202
+ message: `[jinn-earning] Service ${index}: local step '${step}' was ahead of registry state (${reg}) for id=${id}. Rewinding to '${maxStep}' so bootstrap can resubmit the correct on-chain steps.`,
203
+ patch,
204
+ };
205
+ }
206
+ }
207
+ }
208
+ return null;
209
+ }
210
+ export function reconcileServiceAgainstChain(stakingMode, svc, chain, ctx) {
211
+ if (stakingMode === 'standard') {
212
+ return reconcileStandardService(svc.index, svc, chain, ctx);
213
+ }
214
+ return reconcileSelfBondService(svc.index, svc, chain);
215
+ }
216
+ //# sourceMappingURL=reconcile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/earning/reconcile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Thin wrapper around @safe-global/protocol-kit isolating import/init quirks.
3
+ *
4
+ * NodeNext treats protocol-kit's .d.ts as CJS (the package lacks "type":"module"),
5
+ * so `import Safe from '...'` resolves to the module namespace rather than the class.
6
+ * This adapter defines a minimal SafeInstance interface for what we actually use,
7
+ * decoupling the earning bootstrap from SDK type-level instability.
8
+ */
9
+ import type { MetaTransactionData, TransactionResult } from '@safe-global/types-kit';
10
+ import { type Hex } from 'viem';
11
+ export type { MetaTransactionData, TransactionResult };
12
+ /** Minimal interface covering the Safe SDK methods we actually call. */
13
+ export interface SafeInstance {
14
+ getAddress(): Promise<string>;
15
+ isSafeDeployed(): Promise<boolean>;
16
+ createSafeDeploymentTransaction(): Promise<{
17
+ to: string;
18
+ value: string;
19
+ data: string;
20
+ }>;
21
+ createTransaction(props: {
22
+ transactions: MetaTransactionData[];
23
+ }): Promise<SafeTransaction>;
24
+ signTransaction(tx: SafeTransaction): Promise<SafeTransaction>;
25
+ executeTransaction(tx: SafeTransaction, options?: Record<string, unknown>): Promise<TransactionResult>;
26
+ }
27
+ /** Opaque handle -- we never inspect SafeTransaction internals. */
28
+ export interface SafeTransaction {
29
+ }
30
+ export interface PredictedSafeResult {
31
+ safe: SafeInstance;
32
+ address: string;
33
+ }
34
+ /**
35
+ * Initialise a Safe SDK instance for a not-yet-deployed Safe (CREATE2 prediction).
36
+ */
37
+ export declare function initPredictedSafe(opts: {
38
+ rpcUrl: string;
39
+ signerKey: string;
40
+ owners: string[];
41
+ threshold: number;
42
+ }): Promise<PredictedSafeResult>;
43
+ /**
44
+ * Initialise a Safe SDK instance for an already-deployed Safe.
45
+ */
46
+ export declare function initDeployedSafe(opts: {
47
+ rpcUrl: string;
48
+ signerKey: string;
49
+ safeAddress: string;
50
+ }): Promise<SafeInstance>;
51
+ /**
52
+ * Build + sign + execute a batch of calls through a deployed Safe.
53
+ * For 1-of-1 Safes the signer is the sole owner, so sign + execute in one shot.
54
+ */
55
+ export declare function executeSafeTxBatch(safe: SafeInstance, transactions: MetaTransactionData[]): Promise<TransactionResult>;
56
+ /**
57
+ * Execute a single Safe transaction directly via the Safe contract, bypassing
58
+ * Safe SDK gas estimation for calls that are known to misbehave under viem.
59
+ */
60
+ export declare function executeSafeTxDirect(opts: {
61
+ rpcUrl: string;
62
+ signerKey: Hex;
63
+ safeAddress: string;
64
+ to: string;
65
+ value?: bigint;
66
+ data: Hex;
67
+ gasLimit?: bigint;
68
+ }): Promise<{
69
+ hash: string;
70
+ }>;
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Thin wrapper around @safe-global/protocol-kit isolating import/init quirks.
3
+ *
4
+ * NodeNext treats protocol-kit's .d.ts as CJS (the package lacks "type":"module"),
5
+ * so `import Safe from '...'` resolves to the module namespace rather than the class.
6
+ * This adapter defines a minimal SafeInstance interface for what we actually use,
7
+ * decoupling the earning bootstrap from SDK type-level instability.
8
+ */
9
+ import { bytesToHex, concat, createPublicClient, createWalletClient, encodeFunctionData, hexToBytes, http, toHex, zeroAddress, } from 'viem';
10
+ import { base, baseSepolia } from 'viem/chains';
11
+ import { privateKeyToAccount } from 'viem/accounts';
12
+ import { viemFeeOverridesForAttempt, withRecoverableRetry } from '../tx-retry.js';
13
+ const SAFE_EXECUTION_FALLBACK_GAS_LIMIT = 2_000_000;
14
+ const SAFE_ABI = [
15
+ {
16
+ type: 'function',
17
+ name: 'execTransaction',
18
+ stateMutability: 'nonpayable',
19
+ inputs: [
20
+ { name: 'to', type: 'address' },
21
+ { name: 'value', type: 'uint256' },
22
+ { name: 'data', type: 'bytes' },
23
+ { name: 'operation', type: 'uint8' },
24
+ { name: 'safeTxGas', type: 'uint256' },
25
+ { name: 'baseGas', type: 'uint256' },
26
+ { name: 'gasPrice', type: 'uint256' },
27
+ { name: 'gasToken', type: 'address' },
28
+ { name: 'refundReceiver', type: 'address' },
29
+ { name: 'signatures', type: 'bytes' },
30
+ ],
31
+ outputs: [{ name: '', type: 'bool' }],
32
+ },
33
+ {
34
+ type: 'function',
35
+ name: 'nonce',
36
+ stateMutability: 'view',
37
+ inputs: [],
38
+ outputs: [{ name: '', type: 'uint256' }],
39
+ },
40
+ {
41
+ type: 'function',
42
+ name: 'getTransactionHash',
43
+ stateMutability: 'view',
44
+ inputs: [
45
+ { name: 'to', type: 'address' },
46
+ { name: 'value', type: 'uint256' },
47
+ { name: 'data', type: 'bytes' },
48
+ { name: 'operation', type: 'uint8' },
49
+ { name: 'safeTxGas', type: 'uint256' },
50
+ { name: 'baseGas', type: 'uint256' },
51
+ { name: 'gasPrice', type: 'uint256' },
52
+ { name: 'gasToken', type: 'address' },
53
+ { name: 'refundReceiver', type: 'address' },
54
+ { name: '_nonce', type: 'uint256' },
55
+ ],
56
+ outputs: [{ name: '', type: 'bytes32' }],
57
+ },
58
+ ];
59
+ /**
60
+ * Resolve the `Safe.init` function regardless of CJS/ESM interop shape.
61
+ */
62
+ async function resolveSafeInit() {
63
+ // Dynamic import avoids NodeNext static-analysis issues.
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ const mod = await import('@safe-global/protocol-kit');
66
+ const SafeClass = mod.default?.default ?? mod.default ?? mod;
67
+ if (typeof SafeClass?.init !== 'function') {
68
+ throw new Error('Failed to resolve Safe.init from @safe-global/protocol-kit. ' +
69
+ `Got: ${typeof SafeClass} (keys: ${Object.keys(SafeClass ?? {}).join(', ')})`);
70
+ }
71
+ return SafeClass.init.bind(SafeClass);
72
+ }
73
+ async function resolveExecutionRpcUrl(rpcUrl) {
74
+ if (!rpcUrl.includes('tenderly.co')) {
75
+ return rpcUrl;
76
+ }
77
+ try {
78
+ const id = await createPublicClient({ transport: http(rpcUrl) }).getChainId();
79
+ if (id === 8453)
80
+ return 'https://base.publicnode.com';
81
+ if (id === 84532)
82
+ return 'https://sepolia.base.org';
83
+ }
84
+ catch {
85
+ /* fall through */
86
+ }
87
+ return rpcUrl;
88
+ }
89
+ function chainForId(chainId, rpcUrl) {
90
+ if (chainId === 8453)
91
+ return base;
92
+ if (chainId === 84532)
93
+ return baseSepolia;
94
+ return {
95
+ id: chainId,
96
+ name: 'Custom',
97
+ nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
98
+ rpcUrls: { default: { http: [rpcUrl] } },
99
+ };
100
+ }
101
+ /**
102
+ * Initialise a Safe SDK instance for a not-yet-deployed Safe (CREATE2 prediction).
103
+ */
104
+ export async function initPredictedSafe(opts) {
105
+ const init = await resolveSafeInit();
106
+ const safe = await init({
107
+ provider: opts.rpcUrl,
108
+ signer: opts.signerKey,
109
+ predictedSafe: {
110
+ safeAccountConfig: {
111
+ owners: opts.owners,
112
+ threshold: opts.threshold,
113
+ },
114
+ },
115
+ });
116
+ const address = await safe.getAddress();
117
+ return { safe, address };
118
+ }
119
+ /**
120
+ * Initialise a Safe SDK instance for an already-deployed Safe.
121
+ */
122
+ export async function initDeployedSafe(opts) {
123
+ const init = await resolveSafeInit();
124
+ return init({
125
+ provider: opts.rpcUrl,
126
+ signer: opts.signerKey,
127
+ safeAddress: opts.safeAddress,
128
+ });
129
+ }
130
+ /**
131
+ * Build + sign + execute a batch of calls through a deployed Safe.
132
+ * For 1-of-1 Safes the signer is the sole owner, so sign + execute in one shot.
133
+ */
134
+ export async function executeSafeTxBatch(safe, transactions) {
135
+ return withRecoverableRetry(async () => {
136
+ const safeTx = await safe.createTransaction({ transactions });
137
+ const signedTx = await safe.signTransaction(safeTx);
138
+ try {
139
+ return await safe.executeTransaction(signedTx);
140
+ }
141
+ catch (err) {
142
+ const message = err instanceof Error ? err.message : String(err);
143
+ if (!message.includes('GS013')) {
144
+ throw err;
145
+ }
146
+ // Safe SDK gas estimation intermittently fails on certain inner calls
147
+ // (notably staking approve+stake batches) even when the transaction itself succeeds.
148
+ return safe.executeTransaction(signedTx, {
149
+ gasLimit: SAFE_EXECUTION_FALLBACK_GAS_LIMIT,
150
+ });
151
+ }
152
+ }, {
153
+ onRetry: ({ attempt, message }) => {
154
+ console.error(`[safe-adapter] executeSafeTxBatch retry ${attempt}: ${message}`);
155
+ },
156
+ });
157
+ }
158
+ /**
159
+ * Execute a single Safe transaction directly via the Safe contract, bypassing
160
+ * Safe SDK gas estimation for calls that are known to misbehave under viem.
161
+ */
162
+ export async function executeSafeTxDirect(opts) {
163
+ const executionRpcUrl = await resolveExecutionRpcUrl(opts.rpcUrl);
164
+ const chainId = await createPublicClient({ transport: http(executionRpcUrl) }).getChainId();
165
+ const chain = chainForId(chainId, executionRpcUrl);
166
+ const publicClient = createPublicClient({
167
+ chain,
168
+ transport: http(executionRpcUrl),
169
+ });
170
+ const account = privateKeyToAccount(opts.signerKey);
171
+ const walletClient = createWalletClient({
172
+ account,
173
+ chain,
174
+ transport: http(executionRpcUrl),
175
+ });
176
+ const safeAddress = opts.safeAddress;
177
+ const to = opts.to;
178
+ const value = opts.value ?? 0n;
179
+ const baseGas = opts.gasLimit ?? BigInt(SAFE_EXECUTION_FALLBACK_GAS_LIMIT);
180
+ const hash = await withRecoverableRetry(async (attemptIndex) => {
181
+ const nonce = await publicClient.readContract({
182
+ address: safeAddress,
183
+ abi: SAFE_ABI,
184
+ functionName: 'nonce',
185
+ });
186
+ const safeTxHash = await publicClient.readContract({
187
+ address: safeAddress,
188
+ abi: SAFE_ABI,
189
+ functionName: 'getTransactionHash',
190
+ args: [to, value, opts.data, 0, 0n, 0n, 0n, zeroAddress, zeroAddress, nonce],
191
+ });
192
+ const sigHex = await walletClient.signMessage({
193
+ account,
194
+ message: { raw: hexToBytes(safeTxHash) },
195
+ });
196
+ const sigBytes = hexToBytes(sigHex);
197
+ const r = bytesToHex(sigBytes.slice(0, 32));
198
+ const s = bytesToHex(sigBytes.slice(32, 64));
199
+ const v = sigBytes[64] + 4;
200
+ const adjustedSig = concat([r, s, toHex(v, { size: 1 })]);
201
+ const data = encodeFunctionData({
202
+ abi: SAFE_ABI,
203
+ functionName: 'execTransaction',
204
+ args: [to, value, opts.data, 0, 0n, 0n, 0n, zeroAddress, zeroAddress, adjustedSig],
205
+ });
206
+ const feeOverrides = await viemFeeOverridesForAttempt(publicClient, attemptIndex);
207
+ const txParams = {
208
+ account,
209
+ to: safeAddress,
210
+ data,
211
+ gas: baseGas + BigInt(attemptIndex) * 50000n,
212
+ ...feeOverrides,
213
+ };
214
+ if ('maxFeePerGas' in txParams &&
215
+ txParams.maxFeePerGas !== undefined &&
216
+ 'maxPriorityFeePerGas' in txParams &&
217
+ txParams.maxPriorityFeePerGas !== undefined) {
218
+ delete txParams.gasPrice;
219
+ }
220
+ return walletClient.sendTransaction(txParams);
221
+ }, {
222
+ onRetry: ({ attempt, message }) => {
223
+ console.error(`[safe-adapter] executeSafeTxDirect retry ${attempt}: ${message}`);
224
+ },
225
+ });
226
+ return { hash };
227
+ }
228
+ //# sourceMappingURL=safe-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-adapter.js","sourceRoot":"","sources":["../../src/earning/safe-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * stOLAS ExternalStakingDistributor reward claims for fleet services.
3
+ *
4
+ * The distributor's claim() calls checkpointAndClaim on each staking proxy; the OLAS-style
5
+ * staking implementation reverts on zero reward, so we read calculateStakingReward first and
6
+ * skip sends when pending is zero (no revert loop).
7
+ *
8
+ * TODO(self-bond): rewards are owned by the service Safe; wire Safe-batched staking.claim /
9
+ * checkpointAndClaim when staking_mode is self-bond (not distributor-mediated).
10
+ */
11
+ import type { PublicClient } from 'viem';
12
+ import type { WalletClient } from 'viem';
13
+ import type { ServiceState, StakingMode } from './types.js';
14
+ export interface StolasClaimTarget {
15
+ stakingProxy: string;
16
+ serviceId: number;
17
+ }
18
+ /**
19
+ * Services that may need distributor.claim (pure filter for tests and tick).
20
+ */
21
+ export declare function listStolasClaimTargets(services: ServiceState[]): StolasClaimTarget[];
22
+ export interface StolasClaimTickResult {
23
+ attempted: number;
24
+ submitted: number;
25
+ skippedNoPending: number;
26
+ skippedNoDistributor: boolean;
27
+ skippedWrongMode: boolean;
28
+ /** Services where pending reward was non-zero and a claim tx was attempted (send path). */
29
+ claimAttempted: number;
30
+ failedRecoverable: number;
31
+ /** Non-recoverable send errors, bad/missing receipts, etc. */
32
+ failedPermanent: number;
33
+ }
34
+ /**
35
+ * For each fleet service with pending staking rewards, submit distributor.claim([proxy],[id]).
36
+ * Errors on individual services are logged and swallowed so the daemon loop stays healthy.
37
+ */
38
+ export declare function tickStolasDistributorClaims(publicClient: PublicClient, masterWallet: WalletClient, options: {
39
+ distributorAddress: string | undefined;
40
+ stakingMode: StakingMode;
41
+ targets: StolasClaimTarget[];
42
+ /**
43
+ * When true (CLI), all claim sends failing recoverably surfaces {@link TransientError};
44
+ * any permanent/receipt failure surfaces a normal Error. Daemon callers omit this.
45
+ */
46
+ strict?: boolean;
47
+ }): Promise<StolasClaimTickResult>;