@jinn-network/client 0.1.6-canary.fb9c8196 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/bootstrap-endpoint.js +0 -45
- package/dist/api/bootstrap-endpoint.js.map +1 -1
- package/dist/api/fleet-build.d.ts +0 -1
- package/dist/api/fleet-build.js +1 -2
- package/dist/api/fleet-build.js.map +1 -1
- package/dist/api/gather-status.js +1 -68
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/hermes-doctor-endpoint.d.ts +0 -10
- package/dist/api/hermes-doctor-endpoint.js +23 -30
- package/dist/api/hermes-doctor-endpoint.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +0 -16
- package/dist/api/setup-endpoints.js +0 -28
- package/dist/api/setup-endpoints.js.map +1 -1
- package/dist/api/status-build.d.ts +0 -14
- package/dist/api/status-build.js +18 -23
- package/dist/api/status-build.js.map +1 -1
- package/dist/build-info.json +4 -4
- package/dist/build-meta.json +1 -1
- package/dist/cli/commands/solver-nets.js +9 -24
- package/dist/cli/commands/solver-nets.js.map +1 -1
- package/dist/config.d.ts +0 -9
- package/dist/config.js +0 -7
- package/dist/config.js.map +1 -1
- package/dist/daemon/daemon.d.ts +0 -8
- package/dist/daemon/daemon.js +0 -17
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/dashboard/assets/{index-CarzUepP.css → index-DOlzFN8a.css} +1 -1
- package/dist/dashboard/assets/index-NkZ7CTAT.js +140 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/earning/bootstrap.d.ts +0 -59
- package/dist/earning/bootstrap.js +41 -139
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/contracts.d.ts +0 -12
- package/dist/earning/contracts.js +0 -7
- package/dist/earning/contracts.js.map +1 -1
- package/dist/earning/funding-plan.js.map +1 -1
- package/dist/earning/jinn-rewards.d.ts +0 -46
- package/dist/earning/jinn-rewards.js +0 -32
- package/dist/earning/jinn-rewards.js.map +1 -1
- package/dist/earning/testnet-setup-migration.d.ts +0 -12
- package/dist/earning/testnet-setup-migration.js +1 -17
- package/dist/earning/testnet-setup-migration.js.map +1 -1
- package/dist/earning/types.d.ts +0 -15
- package/dist/harnesses/impls/hermes-agent/harness.d.ts +1 -23
- package/dist/harnesses/impls/hermes-agent/harness.js +0 -49
- package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
- package/dist/harnesses/impls/index.d.ts +0 -2
- package/dist/harnesses/impls/index.js +1 -5
- package/dist/harnesses/impls/index.js.map +1 -1
- package/dist/main.js +30 -204
- package/dist/main.js.map +1 -1
- package/dist/operator-errors.d.ts +0 -7
- package/dist/operator-errors.js +1 -13
- package/dist/operator-errors.js.map +1 -1
- package/dist/solver-nets/prediction-operator-ux.js +3 -24
- package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
- package/dist/solver-nets/registry.d.ts +0 -1
- package/dist/solver-nets/registry.js +1 -1
- package/dist/solver-nets/registry.js.map +1 -1
- package/package.json +1 -1
- package/dist/api/setup-retry-endpoint.d.ts +0 -19
- package/dist/api/setup-retry-endpoint.js +0 -32
- package/dist/api/setup-retry-endpoint.js.map +0 -1
- package/dist/daemon/eviction-loop.d.ts +0 -40
- package/dist/daemon/eviction-loop.js +0 -67
- package/dist/daemon/eviction-loop.js.map +0 -1
- package/dist/dashboard/assets/index-C_QnE4YV.js +0 -140
- package/dist/harnesses/cost-estimates.d.ts +0 -145
- package/dist/harnesses/cost-estimates.js +0 -297
- package/dist/harnesses/cost-estimates.js.map +0 -1
- package/dist/restart-daemon.d.ts +0 -71
- package/dist/restart-daemon.js +0 -82
- package/dist/restart-daemon.js.map +0 -1
- package/dist/setup/halt-mode.d.ts +0 -14
- package/dist/setup/halt-mode.js +0 -17
- package/dist/setup/halt-mode.js.map +0 -1
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500;600&display=swap"
|
|
11
11
|
rel="stylesheet"
|
|
12
12
|
/>
|
|
13
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-NkZ7CTAT.js"></script>
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DOlzFN8a.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
|
@@ -6,44 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { FleetState, FleetBootstrapResult } from './types.js';
|
|
8
8
|
import { requestTestnetFunding } from './faucet.js';
|
|
9
|
-
import { type JinnOnchainNetwork } from './viem-clients.js';
|
|
10
|
-
/**
|
|
11
|
-
* 2× cold-start headroom for master ETH target on a fresh bootstrap.
|
|
12
|
-
*
|
|
13
|
-
* Gas accounting for a single standard-mode service on first run:
|
|
14
|
-
* ~1.3M gas for the Safe deploy + stake + mech (at 2 gwei ≈ 0.0026 ETH)
|
|
15
|
-
* + 0.002 ETH Safe seed (sent to the Safe so it can pay mech fees)
|
|
16
|
-
* ≈ 0.0046 ETH minimum; 2× gives ≈ 0.009–0.010 ETH — the bootstrap
|
|
17
|
-
* `minEoaGasEth` default.
|
|
18
|
-
*
|
|
19
|
-
* The multiplier only applies when no service has a persisted `service_id`
|
|
20
|
-
* on-chain (i.e. the fleet is truly cold — OR migration-wiped, where
|
|
21
|
-
* services exist in shape but lost their on-chain anchor). Once any service
|
|
22
|
-
* has committed a `service_id`, the fleet is past the cold-start cliff and
|
|
23
|
-
* 1× suffices.
|
|
24
|
-
*
|
|
25
|
-
* Single source of truth: imported by funding-plan.ts.
|
|
26
|
-
*/
|
|
27
|
-
export declare const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
|
|
28
|
-
/**
|
|
29
|
-
* Compute the required master ETH gate for the standard staking mode.
|
|
30
|
-
*
|
|
31
|
-
* @param services Persisted service states
|
|
32
|
-
* @param minEoaGasEth Configured minimum EOA gas target (wei)
|
|
33
|
-
* @param standardMultiplier Cold-start multiplier (defaults to {@link STANDARD_MASTER_BOOTSTRAP_MULTIPLIER})
|
|
34
|
-
* @param pendingSetupMigration True when deprecated testnet setup detected
|
|
35
|
-
* @param targetServices How many services the fleet is aiming for
|
|
36
|
-
*/
|
|
37
|
-
export declare function computeRequiredMasterEth({ services, minEoaGasEth, standardMultiplier, pendingSetupMigration, targetServices, }: {
|
|
38
|
-
services: Array<{
|
|
39
|
-
service_id: number | null | undefined;
|
|
40
|
-
step?: string;
|
|
41
|
-
}>;
|
|
42
|
-
minEoaGasEth: bigint;
|
|
43
|
-
standardMultiplier?: bigint;
|
|
44
|
-
pendingSetupMigration?: boolean;
|
|
45
|
-
targetServices?: number;
|
|
46
|
-
}): bigint;
|
|
47
9
|
/** Master ETH required to FINISH the whole bootstrap from a fresh start (not
|
|
48
10
|
* just to enter Stage 1). Centralized so the daemon's ensureStage1 gate,
|
|
49
11
|
* the read-side funding-plan, gather-status, and the panel faucet target
|
|
@@ -324,24 +286,3 @@ export declare class FleetBootstrapper {
|
|
|
324
286
|
}
|
|
325
287
|
/** @deprecated Use FleetBootstrapper */
|
|
326
288
|
export declare const EarningBootstrapper: typeof FleetBootstrapper;
|
|
327
|
-
export interface RecoverEvictedServiceOptions {
|
|
328
|
-
/** Display index of the service (used only for log messages). */
|
|
329
|
-
serviceDisplayIndex: number;
|
|
330
|
-
serviceId: number;
|
|
331
|
-
stakingAddress: string;
|
|
332
|
-
distributorAddress: string;
|
|
333
|
-
rpcUrl: string;
|
|
334
|
-
chain: JinnOnchainNetwork;
|
|
335
|
-
mnemonic: string;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Re-stake an evicted service by calling `distributor.reStake(stakingProxy, serviceId)`.
|
|
339
|
-
*
|
|
340
|
-
* Extracted from `FleetBootstrapper.recoverEvictedService` so it can be called
|
|
341
|
-
* from the in-process `EvictionLoop` without requiring a full bootstrapper
|
|
342
|
-
* context (jinn-mono-hjex.3).
|
|
343
|
-
*
|
|
344
|
-
* The caller is responsible for advancing the local service step back to
|
|
345
|
-
* `mech_deployed` after this returns (just like the bootstrapper resume path does).
|
|
346
|
-
*/
|
|
347
|
-
export declare function recoverEvictedService(opts: RecoverEvictedServiceOptions): Promise<void>;
|
|
@@ -20,51 +20,11 @@ import { isUnauthorizedAccountError } from '../errors/unauthorized-account.js';
|
|
|
20
20
|
import { createJinnPublicClient, createJinnWalletClient } from './viem-clients.js';
|
|
21
21
|
import { isTransientEthReadError } from '../chain-read-errors.js';
|
|
22
22
|
import { nextFleetServiceIndex } from './next-service-index.js';
|
|
23
|
-
import { displayFleetServiceIndex } from './fleet-display-index.js';
|
|
24
23
|
import { rpcHostForDisplay } from '../preflight/rpc-network.js';
|
|
25
24
|
import { detectDeprecatedTestnetSetup, migrateDeprecatedTestnetSetup, } from './testnet-setup-migration.js';
|
|
26
25
|
const addr = (value) => getAddress(value);
|
|
27
26
|
const SAFE_TOKEN_BOOTSTRAP_MULTIPLIER = 2n;
|
|
28
|
-
|
|
29
|
-
* 2× cold-start headroom for master ETH target on a fresh bootstrap.
|
|
30
|
-
*
|
|
31
|
-
* Gas accounting for a single standard-mode service on first run:
|
|
32
|
-
* ~1.3M gas for the Safe deploy + stake + mech (at 2 gwei ≈ 0.0026 ETH)
|
|
33
|
-
* + 0.002 ETH Safe seed (sent to the Safe so it can pay mech fees)
|
|
34
|
-
* ≈ 0.0046 ETH minimum; 2× gives ≈ 0.009–0.010 ETH — the bootstrap
|
|
35
|
-
* `minEoaGasEth` default.
|
|
36
|
-
*
|
|
37
|
-
* The multiplier only applies when no service has a persisted `service_id`
|
|
38
|
-
* on-chain (i.e. the fleet is truly cold — OR migration-wiped, where
|
|
39
|
-
* services exist in shape but lost their on-chain anchor). Once any service
|
|
40
|
-
* has committed a `service_id`, the fleet is past the cold-start cliff and
|
|
41
|
-
* 1× suffices.
|
|
42
|
-
*
|
|
43
|
-
* Single source of truth: imported by funding-plan.ts.
|
|
44
|
-
*/
|
|
45
|
-
export const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
|
|
46
|
-
/**
|
|
47
|
-
* Compute the required master ETH gate for the standard staking mode.
|
|
48
|
-
*
|
|
49
|
-
* @param services Persisted service states
|
|
50
|
-
* @param minEoaGasEth Configured minimum EOA gas target (wei)
|
|
51
|
-
* @param standardMultiplier Cold-start multiplier (defaults to {@link STANDARD_MASTER_BOOTSTRAP_MULTIPLIER})
|
|
52
|
-
* @param pendingSetupMigration True when deprecated testnet setup detected
|
|
53
|
-
* @param targetServices How many services the fleet is aiming for
|
|
54
|
-
*/
|
|
55
|
-
export function computeRequiredMasterEth({ services, minEoaGasEth, standardMultiplier = STANDARD_MASTER_BOOTSTRAP_MULTIPLIER, pendingSetupMigration = false, targetServices = 1, }) {
|
|
56
|
-
const completedCount = services.filter(s => s.step !== undefined && isOperationalServiceStep(s.step)).length;
|
|
57
|
-
const standardFleetAlreadyComplete = !pendingSetupMigration && completedCount >= targetServices;
|
|
58
|
-
if (standardFleetAlreadyComplete)
|
|
59
|
-
return 0n;
|
|
60
|
-
// "Cold in liability" = no service has an on-chain anchor yet.
|
|
61
|
-
// This includes:
|
|
62
|
-
// 1. Fresh fleet (services array is empty)
|
|
63
|
-
// 2. Migration-wiped fleet (services exist in shape but service_id === null)
|
|
64
|
-
// Apply the 2× headroom multiplier in both cases.
|
|
65
|
-
const hasPersistedOnChain = services.some(s => s.service_id != null);
|
|
66
|
-
return minEoaGasEth * (hasPersistedOnChain ? 1n : standardMultiplier);
|
|
67
|
-
}
|
|
27
|
+
const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
|
|
68
28
|
/** Master ETH required to FINISH the whole bootstrap from a fresh start (not
|
|
69
29
|
* just to enter Stage 1). Centralized so the daemon's ensureStage1 gate,
|
|
70
30
|
* the read-side funding-plan, gather-status, and the panel faucet target
|
|
@@ -456,10 +416,11 @@ export class FleetBootstrapper {
|
|
|
456
416
|
stakingMode: this.stakingMode,
|
|
457
417
|
currentStakingContract: this.config.stakingContract,
|
|
458
418
|
}).services.length > 0;
|
|
419
|
+
const completedCountBeforeFunding = state.services.filter(s => isOperationalServiceStep(s.step)).length;
|
|
459
420
|
const standardFleetAlreadyComplete = this.stakingMode === 'standard' &&
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
421
|
+
!pendingSetupMigration &&
|
|
422
|
+
completedCountBeforeFunding >= this.targetServices;
|
|
423
|
+
const standardFleetHasInProgressServices = this.stakingMode === 'standard' && state.services.length > 0;
|
|
463
424
|
const requiredMasterEth = this.stakingMode === 'standard'
|
|
464
425
|
? (standardFleetAlreadyComplete
|
|
465
426
|
? 0n
|
|
@@ -617,7 +578,7 @@ export class FleetBootstrapper {
|
|
|
617
578
|
};
|
|
618
579
|
}
|
|
619
580
|
catch (error) {
|
|
620
|
-
const { summary, hint, rawMessage
|
|
581
|
+
const { summary, hint, rawMessage } = formatBootstrapOperatorMessage(error);
|
|
621
582
|
const userMessage = hint !== undefined ? `${summary}\nHint: ${hint}` : summary;
|
|
622
583
|
if (this.debug) {
|
|
623
584
|
console.error(`[fleet-bootstrap] Bootstrap failed:`, error);
|
|
@@ -633,21 +594,11 @@ export class FleetBootstrapper {
|
|
|
633
594
|
console.error(`[fleet-bootstrap] raw: ${rawMessage.split('\n')[0]}`);
|
|
634
595
|
}
|
|
635
596
|
}
|
|
636
|
-
// Extract a tx hash embedded in the error message by the on-chain revert
|
|
637
|
-
// paths (format: "...tx failed for service N: 0x<hash>" or
|
|
638
|
-
// "...tx reverted: 0x<hash>"). Surfaced in the fatal envelope so the SPA
|
|
639
|
-
// can render a block-explorer link. jinn-mono-hjex reviewer fix.
|
|
640
|
-
const txHashMatch = /(0x[a-fA-F0-9]{64})/.exec(rawMessage);
|
|
641
|
-
const txHash = txHashMatch ? txHashMatch[1] : null;
|
|
642
597
|
return {
|
|
643
598
|
ok: false,
|
|
644
599
|
fleet_state: state,
|
|
645
600
|
message: userMessage,
|
|
646
601
|
rawErrorMessage: rawMessage,
|
|
647
|
-
// Preserve the structured category so the error envelope in main.ts
|
|
648
|
-
// can surface it in `details.category` for SPA consumers. jinn-mono-hjex.6
|
|
649
|
-
...(category !== undefined ? { errorCategory: category } : {}),
|
|
650
|
-
...(txHash !== null ? { txHash } : {}),
|
|
651
602
|
};
|
|
652
603
|
}
|
|
653
604
|
}
|
|
@@ -1093,32 +1044,6 @@ export class FleetBootstrapper {
|
|
|
1093
1044
|
return this.store.updateService(index, { step: 'staked' });
|
|
1094
1045
|
}
|
|
1095
1046
|
}
|
|
1096
|
-
// Pre-stake precondition: if migration cleared service_id but kept agent_address,
|
|
1097
|
-
// check the EOA is not already registered on-chain as an agent instance. If it is,
|
|
1098
|
-
// calling stake() again would revert with AgentInstanceRegistered (selector 0x631695bd)
|
|
1099
|
-
// and there is nothing useful the operator can do without rotating the agent EOA.
|
|
1100
|
-
// Fail fast with a typed error instead of letting the contract revert.
|
|
1101
|
-
if (svc.agent_address && svc.service_id === null && this.config.serviceRegistry) {
|
|
1102
|
-
let alreadyBound = false;
|
|
1103
|
-
try {
|
|
1104
|
-
const boundServiceId = (await this.publicClient.readContract({
|
|
1105
|
-
address: getAddress(this.config.serviceRegistry),
|
|
1106
|
-
abi: SERVICE_REGISTRY_L2_ABI,
|
|
1107
|
-
functionName: 'mapAgentInstances',
|
|
1108
|
-
args: [getAddress(svc.agent_address)],
|
|
1109
|
-
}));
|
|
1110
|
-
alreadyBound = boundServiceId > 0n;
|
|
1111
|
-
}
|
|
1112
|
-
catch {
|
|
1113
|
-
// Registry read failure is non-fatal — proceed and let stake() surface
|
|
1114
|
-
// the error if the agent really is bound.
|
|
1115
|
-
}
|
|
1116
|
-
if (alreadyBound) {
|
|
1117
|
-
throw new Error(`agent_already_bound: agent EOA ${svc.agent_address} is already registered as an agent instance on-chain. ` +
|
|
1118
|
-
`The previous setup retirement may have been incomplete. ` +
|
|
1119
|
-
`Contact support or rotate the agent EOA to continue.`);
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
1047
|
// Fresh distributor stake() creates a new on-chain service. If state still
|
|
1123
1048
|
// references an old Safe (e.g. hand-edited JSON), sweep it before replacing.
|
|
1124
1049
|
if (svc.service_id === null && svc.safe_address && state.master_address) {
|
|
@@ -1184,19 +1109,42 @@ export class FleetBootstrapper {
|
|
|
1184
1109
|
const svc = state.services.find(s => s.index === index);
|
|
1185
1110
|
const serviceId = svc.service_id;
|
|
1186
1111
|
const stakingAddress = this.stakingAddressForService(svc);
|
|
1187
|
-
|
|
1188
|
-
//
|
|
1189
|
-
//
|
|
1190
|
-
//
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
chain: this.chain,
|
|
1198
|
-
mnemonic,
|
|
1112
|
+
// `reStake()` is operator-scoped: the master EOA must match the
|
|
1113
|
+
// distributor's recorded `mapServiceIdCuratingAgents[serviceId]` entry.
|
|
1114
|
+
// If it doesn't, the operator is likely using the wrong earning dir or
|
|
1115
|
+
// password, or the service needs owner / managing-agent recovery.
|
|
1116
|
+
const masterAccount = deriveMasterSigner(mnemonic);
|
|
1117
|
+
const masterWallet = createJinnWalletClient(this.config.rpcUrl, this.chain, masterAccount);
|
|
1118
|
+
const reStakeData = encodeFunctionData({
|
|
1119
|
+
abi: STOLAS_DISTRIBUTOR_ABI,
|
|
1120
|
+
functionName: 'reStake',
|
|
1121
|
+
args: [stakingAddress, BigInt(serviceId)],
|
|
1199
1122
|
});
|
|
1123
|
+
console.error(`[fleet-bootstrap] Service ${index}: calling distributor.reStake() for evicted service ${serviceId}`);
|
|
1124
|
+
let reStakeHash;
|
|
1125
|
+
try {
|
|
1126
|
+
reStakeHash = await viemSendTransactionWithRetry(masterWallet, this.publicClient, {
|
|
1127
|
+
account: masterAccount,
|
|
1128
|
+
to: addr(this.config.distributorAddress),
|
|
1129
|
+
data: reStakeData,
|
|
1130
|
+
gas: 1500000n,
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
catch (err) {
|
|
1134
|
+
const message = flattenErrorMessage(err);
|
|
1135
|
+
if (isUnauthorizedAccountError(message)) {
|
|
1136
|
+
throw new Error(`Service ${index} (service_id ${serviceId}) is evicted on the staking proxy, but master EOA ${masterAccount.address} is not authorized to reStake it. ` +
|
|
1137
|
+
`The distributor only permits the recorded service operator, a managing agent, or the owner. ` +
|
|
1138
|
+
`Verify JINN_EARNING_DIR and JINN_PASSWORD derive the original master EOA for this service, then re-run jinn bootstrap; otherwise request owner / managing-agent recovery or abandon-and-rebootstrap. ` +
|
|
1139
|
+
`reStake revert: ${message}`);
|
|
1140
|
+
}
|
|
1141
|
+
throw err;
|
|
1142
|
+
}
|
|
1143
|
+
const receipt = await waitForTransactionReceiptWithRetry(this.publicClient, reStakeHash);
|
|
1144
|
+
if (receipt.status !== 'success') {
|
|
1145
|
+
throw new Error(`reStake failed for service ${index}: ${reStakeHash}`);
|
|
1146
|
+
}
|
|
1147
|
+
console.error(`[fleet-bootstrap] Service ${index}: reStake confirmed (tx: ${reStakeHash})`);
|
|
1200
1148
|
// Service is now Staked again with the same service_id, safe_address, and mech_address.
|
|
1201
1149
|
// Step back to `mech_deployed` so the resume loop advances through
|
|
1202
1150
|
// `stepRegisterAgent` (idempotent — short-circuits if `agent_id` is
|
|
@@ -1949,50 +1897,4 @@ export class FleetBootstrapper {
|
|
|
1949
1897
|
}
|
|
1950
1898
|
/** @deprecated Use FleetBootstrapper */
|
|
1951
1899
|
export const EarningBootstrapper = FleetBootstrapper;
|
|
1952
|
-
/**
|
|
1953
|
-
* Re-stake an evicted service by calling `distributor.reStake(stakingProxy, serviceId)`.
|
|
1954
|
-
*
|
|
1955
|
-
* Extracted from `FleetBootstrapper.recoverEvictedService` so it can be called
|
|
1956
|
-
* from the in-process `EvictionLoop` without requiring a full bootstrapper
|
|
1957
|
-
* context (jinn-mono-hjex.3).
|
|
1958
|
-
*
|
|
1959
|
-
* The caller is responsible for advancing the local service step back to
|
|
1960
|
-
* `mech_deployed` after this returns (just like the bootstrapper resume path does).
|
|
1961
|
-
*/
|
|
1962
|
-
export async function recoverEvictedService(opts) {
|
|
1963
|
-
const { serviceDisplayIndex, serviceId, stakingAddress, distributorAddress, rpcUrl, chain, mnemonic, } = opts;
|
|
1964
|
-
const masterAccount = deriveMasterSigner(mnemonic);
|
|
1965
|
-
const publicClient = createJinnPublicClient(rpcUrl, chain);
|
|
1966
|
-
const masterWallet = createJinnWalletClient(rpcUrl, chain, masterAccount);
|
|
1967
|
-
const reStakeData = encodeFunctionData({
|
|
1968
|
-
abi: STOLAS_DISTRIBUTOR_ABI,
|
|
1969
|
-
functionName: 'reStake',
|
|
1970
|
-
args: [addr(stakingAddress), BigInt(serviceId)],
|
|
1971
|
-
});
|
|
1972
|
-
console.error(`[eviction-recovery] Service ${serviceDisplayIndex}: calling distributor.reStake() for evicted service ${serviceId}`);
|
|
1973
|
-
let reStakeHash;
|
|
1974
|
-
try {
|
|
1975
|
-
reStakeHash = await viemSendTransactionWithRetry(masterWallet, publicClient, {
|
|
1976
|
-
account: masterAccount,
|
|
1977
|
-
to: addr(distributorAddress),
|
|
1978
|
-
data: reStakeData,
|
|
1979
|
-
gas: 1500000n,
|
|
1980
|
-
});
|
|
1981
|
-
}
|
|
1982
|
-
catch (err) {
|
|
1983
|
-
const message = flattenErrorMessage(err);
|
|
1984
|
-
if (isUnauthorizedAccountError(message)) {
|
|
1985
|
-
throw new Error(`Service ${serviceDisplayIndex} (service_id ${serviceId}) is evicted on the staking proxy, but master EOA ` +
|
|
1986
|
-
`${masterAccount.address} is not authorized to reStake it. ` +
|
|
1987
|
-
`Verify JINN_EARNING_DIR and JINN_PASSWORD derive the original master EOA for this service. ` +
|
|
1988
|
-
`reStake revert: ${message}`);
|
|
1989
|
-
}
|
|
1990
|
-
throw err;
|
|
1991
|
-
}
|
|
1992
|
-
const receipt = await waitForTransactionReceiptWithRetry(publicClient, reStakeHash);
|
|
1993
|
-
if (receipt.status !== 'success') {
|
|
1994
|
-
throw new Error(`reStake failed for service ${serviceDisplayIndex}: ${reStakeHash}`);
|
|
1995
|
-
}
|
|
1996
|
-
console.error(`[eviction-recovery] Service ${serviceDisplayIndex}: reStake confirmed (tx: ${reStakeHash})`);
|
|
1997
|
-
}
|
|
1998
1900
|
//# sourceMappingURL=bootstrap.js.map
|