@xyo-network/chain-sdk 5.0.1 → 5.0.2
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/browser/modules/ethereum/indexing/RestStakeEventsViewer.d.ts +15 -0
- package/dist/browser/modules/ethereum/indexing/RestStakeEventsViewer.d.ts.map +1 -1
- package/dist/browser/modules/ethereum/indexing/RestStakeViewer.d.ts +60 -0
- package/dist/browser/modules/ethereum/indexing/RestStakeViewer.d.ts.map +1 -0
- package/dist/browser/modules/ethereum/indexing/index.d.ts +1 -0
- package/dist/browser/modules/ethereum/indexing/index.d.ts.map +1 -1
- package/dist/neutral/ethereum.mjs +229 -9
- package/dist/neutral/ethereum.mjs.map +4 -4
- package/dist/neutral/modules/ethereum/indexing/RestStakeEventsViewer.d.ts +15 -0
- package/dist/neutral/modules/ethereum/indexing/RestStakeEventsViewer.d.ts.map +1 -1
- package/dist/neutral/modules/ethereum/indexing/RestStakeViewer.d.ts +60 -0
- package/dist/neutral/modules/ethereum/indexing/RestStakeViewer.d.ts.map +1 -0
- package/dist/neutral/modules/ethereum/indexing/index.d.ts +1 -0
- package/dist/neutral/modules/ethereum/indexing/index.d.ts.map +1 -1
- package/dist/node/modules/ethereum/indexing/RestStakeEventsViewer.d.ts +15 -0
- package/dist/node/modules/ethereum/indexing/RestStakeEventsViewer.d.ts.map +1 -1
- package/dist/node/modules/ethereum/indexing/RestStakeViewer.d.ts +60 -0
- package/dist/node/modules/ethereum/indexing/RestStakeViewer.d.ts.map +1 -0
- package/dist/node/modules/ethereum/indexing/index.d.ts +1 -0
- package/dist/node/modules/ethereum/indexing/index.d.ts.map +1 -1
- package/package.json +12 -11
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { EthAddress } from '@ariestools/sdk';
|
|
2
2
|
import type { StakeEvent, StakeEventFilter, StakeEventName, StakeEventsViewer } from '@xyo-network/xl1-sdk';
|
|
3
3
|
import { AbstractCreatableProvider } from '@xyo-network/xl1-sdk';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/** Provider-specific settings read from `providerBindings.StakeEventsViewer.options`. */
|
|
6
|
+
export declare const RestStakeEventsViewerOptionsZod: z.ZodObject<{
|
|
7
|
+
headPollIntervalMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
4
9
|
/**
|
|
5
10
|
* StakeEventsViewer backed by the finalized contract-event index rather than eth_getLogs.
|
|
6
11
|
* Raw indexed logs remain contract-generic; this viewer applies the staking ABI at the edge.
|
|
@@ -17,19 +22,29 @@ export declare class RestStakeEventsViewer extends AbstractCreatableProvider imp
|
|
|
17
22
|
private readonly completeFrames;
|
|
18
23
|
private readonly contractInterface;
|
|
19
24
|
private currentHead?;
|
|
25
|
+
private headPollIntervalMs;
|
|
26
|
+
private lastSuccessfulSyncAt?;
|
|
20
27
|
private manifestPromise?;
|
|
28
|
+
private positionCountCheckpoints;
|
|
21
29
|
private stakeEventCache;
|
|
30
|
+
private readonly stakeEventsByPosition;
|
|
22
31
|
private syncPromise?;
|
|
23
32
|
private tailFrame?;
|
|
24
33
|
get address(): EthAddress;
|
|
25
34
|
get eventIndexBaseUrl(): string;
|
|
26
35
|
protected get fetchFn(): typeof globalThis.fetch;
|
|
36
|
+
/** Creates the provider instance after its configuration has resolved. */
|
|
37
|
+
createHandler(): Promise<void>;
|
|
27
38
|
positionCount(range: [number, number | 'latest']): Promise<number>;
|
|
28
39
|
stakeEvents<TName extends StakeEventName>(range?: [number, number | 'latest'], filter?: StakeEventFilter<TName>): Promise<StakeEvent<TName>[]>;
|
|
40
|
+
private assertRangeAvailable;
|
|
29
41
|
private decodeIndexedStakeEvents;
|
|
30
42
|
private fetchJson;
|
|
31
43
|
private getManifest;
|
|
44
|
+
private indexStakeEvents;
|
|
32
45
|
private matchesFilter;
|
|
46
|
+
private matchingStakeEvents;
|
|
47
|
+
private positionCountThrough;
|
|
33
48
|
private stakeEventFromLog;
|
|
34
49
|
private sync;
|
|
35
50
|
private syncFromHead;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RestStakeEventsViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeEventsViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAKjD,OAAO,KAAK,EAEV,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAChE,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAG1B,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"RestStakeEventsViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeEventsViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAKjD,OAAO,KAAK,EAEV,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAChE,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAG1B,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,yFAAyF;AACzF,eAAO,MAAM,+BAA+B;;iBAAiE,CAAA;AAO7G;;;;;GAKG;AACH,qBACa,qBAAsB,SAAQ,yBAA0B,YAAW,iBAAiB;IAC/F,MAAM,CAAC,QAAQ,CAAC,eAAe,oBAAoB;IACnD,MAAM,CAAC,QAAQ,CAAC,cAAc,sBAA2B;IACzD,MAAM,CAAC,QAAQ,CAAC,YAAY,UAAK;IACjC,MAAM,CAAC,QAAQ,CAAC,QAAQ,wBAA6B;IACrD,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAG,MAAM,CAAS;IACzC,OAAO,sBAAuC;IAE9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoD;IACtF,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,kBAAkB,CAAgC;IAC1D,OAAO,CAAC,oBAAoB,CAAC,CAAQ;IACrC,OAAO,CAAC,eAAe,CAAC,CAAgC;IACxD,OAAO,CAAC,wBAAwB,CAAgC;IAChE,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAkC;IACxE,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,SAAS,CAAC,CAAoB;IAEtC,IAAI,OAAO,IAAI,UAAU,CAExB;IAED,IAAI,iBAAiB,IAAI,MAAM,CAO9B;IAED,SAAS,KAAK,OAAO,IAAI,OAAO,UAAU,CAAC,KAAK,CAE/C;IAED,0EAA0E;IAC3D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAUvC,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAQlE,WAAW,CAAC,KAAK,SAAS,cAAc,EAC5C,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAiB,EAClD,MAAM,CAAC,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAC/B,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;IAM/B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,wBAAwB;YAalB,SAAS;YAMT,WAAW;IASzB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,iBAAiB;YAgBX,IAAI;YAcJ,YAAY;CAmC3B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Address } from '@ariestools/sdk';
|
|
2
|
+
import type { Position, StakeEventsViewer, StakeViewer } from '@xyo-network/xl1-sdk';
|
|
3
|
+
import { AbstractCreatableProvider } from '@xyo-network/xl1-sdk';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/** Provider-specific settings read from `providerBindings.StakeViewer.options`. */
|
|
6
|
+
export declare const RestStakeViewerOptionsZod: z.ZodObject<{
|
|
7
|
+
refreshIntervalMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
/**
|
|
10
|
+
* StakeViewer materialized from the finalized REST event index.
|
|
11
|
+
*
|
|
12
|
+
* The indexer remains the only process that tails the EVM contract. Consumers
|
|
13
|
+
* rebuild their local position view from immutable indexed events after the
|
|
14
|
+
* configured refresh interval, so API replicas never attach EVM log listeners.
|
|
15
|
+
*/
|
|
16
|
+
export declare class RestStakeViewer extends AbstractCreatableProvider implements StakeViewer {
|
|
17
|
+
static readonly connectionTypes: readonly ["rest"];
|
|
18
|
+
static readonly defaultMoniker: "StakeViewer";
|
|
19
|
+
static readonly dependencies: ("StakeEventsViewer" | "ChainContractViewer")[];
|
|
20
|
+
static readonly monikers: "StakeViewer"[];
|
|
21
|
+
static readonly surface: "node";
|
|
22
|
+
readonly moniker: "StakeViewer";
|
|
23
|
+
private _chainContractViewer;
|
|
24
|
+
private _stakeEventsViewer;
|
|
25
|
+
private lastSuccessfulSyncAt?;
|
|
26
|
+
private positionIndex;
|
|
27
|
+
private positionsByStaked;
|
|
28
|
+
private positionsByStaker;
|
|
29
|
+
private refreshIntervalMs;
|
|
30
|
+
private syncPromise?;
|
|
31
|
+
/** Returns the finalized stake-event source used to materialize positions. */
|
|
32
|
+
get stakeEvents(): StakeEventsViewer;
|
|
33
|
+
/** Returns active finalized stake positions. */
|
|
34
|
+
activeStakes(): Promise<Position[]>;
|
|
35
|
+
/** Creates the provider after its REST binding and dependencies resolve. */
|
|
36
|
+
createHandler(): Promise<void>;
|
|
37
|
+
/** Returns the configured chain's withdrawal delay. */
|
|
38
|
+
minWithdrawalBlocks(): Promise<number>;
|
|
39
|
+
/** Returns finalized positions that have been removed but not withdrawn. */
|
|
40
|
+
removedStakes(): Promise<Position[]>;
|
|
41
|
+
/** Returns the configured rewards contract address. */
|
|
42
|
+
rewardsContract(): Promise<Address>;
|
|
43
|
+
/** Returns a finalized position by its contract id. */
|
|
44
|
+
stakeById(id: number): Promise<Position>;
|
|
45
|
+
/** Returns a staker's finalized position by its contract slot. */
|
|
46
|
+
stakeByStaker(staker: Address, slot: number): Promise<Position>;
|
|
47
|
+
/** Returns finalized positions added for an address in the supplied EVM block range. */
|
|
48
|
+
stakesByStaked(staked: Address, range?: [number, number | undefined]): Promise<Position[]>;
|
|
49
|
+
/** Returns finalized positions added by a staker in the supplied EVM block range. */
|
|
50
|
+
stakesByStaker(staker: Address, range?: [number, number | undefined]): Promise<Position[]>;
|
|
51
|
+
/** Returns the configured staking-token address. */
|
|
52
|
+
stakingTokenAddress(): Promise<Address>;
|
|
53
|
+
/** Returns finalized positions that have completed withdrawal. */
|
|
54
|
+
withdrawnStakes(): Promise<Position[]>;
|
|
55
|
+
private applyEvent;
|
|
56
|
+
private positionsInRange;
|
|
57
|
+
private rebuildPositionIndex;
|
|
58
|
+
private sync;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=RestStakeViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RestStakeViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,KAAK,EACW,QAAQ,EAA0B,iBAAiB,EAAE,WAAW,EACtF,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAC1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,mFAAmF;AACnF,eAAO,MAAM,yBAAyB;;iBAAgE,CAAA;AAEtG;;;;;;GAMG;AACH,qBACa,eAAgB,SAAQ,yBAA0B,YAAW,WAAW;IACnF,MAAM,CAAC,QAAQ,CAAC,eAAe,oBAAoB;IACnD,MAAM,CAAC,QAAQ,CAAC,cAAc,gBAAqB;IACnD,MAAM,CAAC,QAAQ,CAAC,YAAY,kDAAyD;IACrF,MAAM,CAAC,QAAQ,CAAC,QAAQ,kBAAuB;IAC/C,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAG,MAAM,CAAS;IACzC,QAAQ,CAAC,OAAO,gBAAiC;IAEjD,OAAO,CAAC,oBAAoB,CAAsB;IAClD,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,oBAAoB,CAAC,CAAQ;IACrC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,WAAW,CAAC,CAAe;IAEnC,8EAA8E;IAC9E,IAAI,WAAW,IAAI,iBAAiB,CAEnC;IAED,gDAAgD;IAC1C,YAAY,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKzC,4EAA4E;IAC7D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7C,uDAAuD;IACjD,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5C,4EAA4E;IACtE,aAAa,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAK1C,uDAAuD;IACjD,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzC,uDAAuD;IACjD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAK9C,kEAAkE;IAC5D,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAMrE,wFAAwF;IAClF,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAkB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKhH,qFAAqF;IAC/E,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAkB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKhH,oDAAoD;IAC9C,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7C,kEAAkE;IAC5D,eAAe,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAK5C,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,oBAAoB;YAoBd,IAAI;CAcnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,sBAAsB,CAAA"}
|
|
@@ -463,14 +463,22 @@ import {
|
|
|
463
463
|
StakeEventsViewerMoniker
|
|
464
464
|
} from "@xyo-network/xl1-sdk";
|
|
465
465
|
import { Interface } from "ethers";
|
|
466
|
+
import { z } from "zod";
|
|
466
467
|
var STAKE_EVENT_NAMES = /* @__PURE__ */ new Set(["StakeAdded", "StakeRemoved", "StakeWithdrawn"]);
|
|
468
|
+
var DEFAULT_HEAD_POLL_INTERVAL_MS = 5e3;
|
|
469
|
+
var MIN_HEAD_POLL_INTERVAL_MS = 5e3;
|
|
470
|
+
var RestStakeEventsViewerOptionsZod = z.object({ headPollIntervalMs: z.coerce.number().optional() });
|
|
467
471
|
var RestStakeEventsViewer = class extends AbstractCreatableProvider {
|
|
468
472
|
moniker = RestStakeEventsViewer.defaultMoniker;
|
|
469
473
|
completeFrames = /* @__PURE__ */ new Map();
|
|
470
474
|
contractInterface = new Interface(IAddressStakingEvents__factory.abi);
|
|
471
475
|
currentHead;
|
|
476
|
+
headPollIntervalMs = DEFAULT_HEAD_POLL_INTERVAL_MS;
|
|
477
|
+
lastSuccessfulSyncAt;
|
|
472
478
|
manifestPromise;
|
|
479
|
+
positionCountCheckpoints = [];
|
|
473
480
|
stakeEventCache = [];
|
|
481
|
+
stakeEventsByPosition = /* @__PURE__ */ new Map();
|
|
474
482
|
syncPromise;
|
|
475
483
|
tailFrame;
|
|
476
484
|
get address() {
|
|
@@ -487,13 +495,34 @@ var RestStakeEventsViewer = class extends AbstractCreatableProvider {
|
|
|
487
495
|
get fetchFn() {
|
|
488
496
|
return this.context.fetchFn ?? fetch.bind(globalThis);
|
|
489
497
|
}
|
|
498
|
+
/** Creates the provider instance after its configuration has resolved. */
|
|
499
|
+
async createHandler() {
|
|
500
|
+
await super.createHandler();
|
|
501
|
+
RestStakeEventsViewer.requireBoundConnection(this.config);
|
|
502
|
+
const { headPollIntervalMs } = RestStakeEventsViewerOptionsZod.parse(this.config.options);
|
|
503
|
+
if (headPollIntervalMs !== void 0) {
|
|
504
|
+
assertEx5(headPollIntervalMs >= MIN_HEAD_POLL_INTERVAL_MS, () => `headPollIntervalMs must be at least ${MIN_HEAD_POLL_INTERVAL_MS}ms`);
|
|
505
|
+
}
|
|
506
|
+
this.headPollIntervalMs = headPollIntervalMs ?? DEFAULT_HEAD_POLL_INTERVAL_MS;
|
|
507
|
+
}
|
|
490
508
|
async positionCount(range) {
|
|
491
|
-
|
|
492
|
-
|
|
509
|
+
await this.sync();
|
|
510
|
+
this.assertRangeAvailable(range);
|
|
511
|
+
if (range[0] === 0) return this.positionCountThrough(range[1]);
|
|
512
|
+
const events = this.matchingStakeEvents(range);
|
|
513
|
+
return events.reduce((max, event) => Math.max(max, event.args.id), -1) + 1;
|
|
493
514
|
}
|
|
494
515
|
async stakeEvents(range = [0, "latest"], filter) {
|
|
495
516
|
await this.sync();
|
|
496
|
-
|
|
517
|
+
this.assertRangeAvailable(range);
|
|
518
|
+
return this.matchingStakeEvents(range, filter);
|
|
519
|
+
}
|
|
520
|
+
assertRangeAvailable(range) {
|
|
521
|
+
const head = assertEx5(this.currentHead, () => "EVM event index head is unavailable");
|
|
522
|
+
assertEx5(
|
|
523
|
+
range[1] === "latest" || range[1] <= head.block,
|
|
524
|
+
() => `Stake-event range ends at ${range[1]}, beyond EVM event index head ${head.block}`
|
|
525
|
+
);
|
|
497
526
|
}
|
|
498
527
|
decodeIndexedStakeEvents() {
|
|
499
528
|
const frames = [...this.completeFrames.entries()].sort(([a], [b]) => a - b).map(([, frame]) => frame);
|
|
@@ -516,6 +545,21 @@ var RestStakeEventsViewer = class extends AbstractCreatableProvider {
|
|
|
516
545
|
})();
|
|
517
546
|
return await this.manifestPromise;
|
|
518
547
|
}
|
|
548
|
+
indexStakeEvents(events) {
|
|
549
|
+
this.stakeEventCache = events;
|
|
550
|
+
this.positionCountCheckpoints = [];
|
|
551
|
+
this.stakeEventsByPosition.clear();
|
|
552
|
+
let maxPositionId = -1;
|
|
553
|
+
for (const event of events) {
|
|
554
|
+
const positionEvents = this.stakeEventsByPosition.get(event.args.id) ?? [];
|
|
555
|
+
positionEvents.push(event);
|
|
556
|
+
this.stakeEventsByPosition.set(event.args.id, positionEvents);
|
|
557
|
+
if (event.args.id > maxPositionId) {
|
|
558
|
+
maxPositionId = event.args.id;
|
|
559
|
+
this.positionCountCheckpoints.push({ count: maxPositionId + 1, time: event.time });
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
519
563
|
// eslint-disable-next-line complexity
|
|
520
564
|
matchesFilter(event, range, filter) {
|
|
521
565
|
if (range[1] !== "latest" && event.time > range[1]) return false;
|
|
@@ -526,6 +570,25 @@ var RestStakeEventsViewer = class extends AbstractCreatableProvider {
|
|
|
526
570
|
if (isDefined3(filter?.args?.staker) && event.args.staker !== filter.args.staker) return false;
|
|
527
571
|
return true;
|
|
528
572
|
}
|
|
573
|
+
matchingStakeEvents(range, filter) {
|
|
574
|
+
const positionId = filter?.args?.id;
|
|
575
|
+
const candidates = isDefined3(positionId) ? this.stakeEventsByPosition.get(positionId) ?? [] : this.stakeEventCache;
|
|
576
|
+
return candidates.filter((event) => this.matchesFilter(event, range, filter));
|
|
577
|
+
}
|
|
578
|
+
positionCountThrough(end) {
|
|
579
|
+
if (end === "latest") return this.positionCountCheckpoints.at(-1)?.count ?? 0;
|
|
580
|
+
let low = 0;
|
|
581
|
+
let high = this.positionCountCheckpoints.length;
|
|
582
|
+
while (low < high) {
|
|
583
|
+
const middle = Math.floor((low + high) / 2);
|
|
584
|
+
if (this.positionCountCheckpoints[middle].time <= end) {
|
|
585
|
+
low = middle + 1;
|
|
586
|
+
} else {
|
|
587
|
+
high = middle;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return this.positionCountCheckpoints[low - 1]?.count ?? 0;
|
|
591
|
+
}
|
|
529
592
|
stakeEventFromLog(log) {
|
|
530
593
|
const parsed = this.contractInterface.parseLog({ data: log.data, topics: log.topics });
|
|
531
594
|
if (parsed === null || !STAKE_EVENT_NAMES.has(parsed.name)) return;
|
|
@@ -542,7 +605,12 @@ var RestStakeEventsViewer = class extends AbstractCreatableProvider {
|
|
|
542
605
|
};
|
|
543
606
|
}
|
|
544
607
|
async sync() {
|
|
545
|
-
|
|
608
|
+
const now = Date.now();
|
|
609
|
+
const elapsed = this.lastSuccessfulSyncAt === void 0 ? void 0 : now - this.lastSuccessfulSyncAt;
|
|
610
|
+
if (this.currentHead !== void 0 && elapsed !== void 0 && elapsed >= 0 && elapsed < this.headPollIntervalMs) return;
|
|
611
|
+
this.syncPromise ??= this.syncFromHead().then(() => {
|
|
612
|
+
this.lastSuccessfulSyncAt = Date.now();
|
|
613
|
+
}).finally(() => {
|
|
546
614
|
this.syncPromise = void 0;
|
|
547
615
|
});
|
|
548
616
|
await this.syncPromise;
|
|
@@ -573,7 +641,7 @@ var RestStakeEventsViewer = class extends AbstractCreatableProvider {
|
|
|
573
641
|
assertEx5(this.tailFrame.fromBlock === tailStart, () => "EVM event index tail starts at the wrong block");
|
|
574
642
|
assertEx5(this.tailFrame.toBlock === head.block, () => "EVM event index tail is stale relative to its head");
|
|
575
643
|
}
|
|
576
|
-
this.
|
|
644
|
+
this.indexStakeEvents(this.decodeIndexedStakeEvents());
|
|
577
645
|
this.currentHead = head;
|
|
578
646
|
}
|
|
579
647
|
};
|
|
@@ -586,8 +654,157 @@ RestStakeEventsViewer = __decorateClass([
|
|
|
586
654
|
creatableProvider()
|
|
587
655
|
], RestStakeEventsViewer);
|
|
588
656
|
|
|
657
|
+
// src/modules/ethereum/indexing/RestStakeViewer.ts
|
|
658
|
+
import { assertEx as assertEx6, toAddress as toAddress3 } from "@ariestools/sdk";
|
|
659
|
+
import {
|
|
660
|
+
AbstractCreatableProvider as AbstractCreatableProvider2,
|
|
661
|
+
ChainContractViewerMoniker,
|
|
662
|
+
creatableProvider as creatableProvider2,
|
|
663
|
+
StakeEventsViewerMoniker as StakeEventsViewerMoniker2,
|
|
664
|
+
StakeViewerMoniker
|
|
665
|
+
} from "@xyo-network/xl1-sdk";
|
|
666
|
+
import { z as z2 } from "zod";
|
|
667
|
+
var DEFAULT_REFRESH_INTERVAL_MS = 5e3;
|
|
668
|
+
var MIN_REFRESH_INTERVAL_MS = 5e3;
|
|
669
|
+
var RestStakeViewerOptionsZod = z2.object({ refreshIntervalMs: z2.coerce.number().optional() });
|
|
670
|
+
var RestStakeViewer = class extends AbstractCreatableProvider2 {
|
|
671
|
+
moniker = RestStakeViewer.defaultMoniker;
|
|
672
|
+
_chainContractViewer;
|
|
673
|
+
_stakeEventsViewer;
|
|
674
|
+
lastSuccessfulSyncAt;
|
|
675
|
+
positionIndex = /* @__PURE__ */ new Map();
|
|
676
|
+
positionsByStaked = /* @__PURE__ */ new Map();
|
|
677
|
+
positionsByStaker = /* @__PURE__ */ new Map();
|
|
678
|
+
refreshIntervalMs = DEFAULT_REFRESH_INTERVAL_MS;
|
|
679
|
+
syncPromise;
|
|
680
|
+
/** Returns the finalized stake-event source used to materialize positions. */
|
|
681
|
+
get stakeEvents() {
|
|
682
|
+
return this._stakeEventsViewer;
|
|
683
|
+
}
|
|
684
|
+
/** Returns active finalized stake positions. */
|
|
685
|
+
async activeStakes() {
|
|
686
|
+
await this.sync();
|
|
687
|
+
return this.positionIndex.values().filter((position) => position.removeBlock === 0 && position.withdrawBlock === 0).toArray();
|
|
688
|
+
}
|
|
689
|
+
/** Creates the provider after its REST binding and dependencies resolve. */
|
|
690
|
+
async createHandler() {
|
|
691
|
+
await super.createHandler();
|
|
692
|
+
RestStakeViewer.requireBoundConnection(this.config);
|
|
693
|
+
const { refreshIntervalMs } = RestStakeViewerOptionsZod.parse(this.config.options);
|
|
694
|
+
if (refreshIntervalMs !== void 0) {
|
|
695
|
+
assertEx6(refreshIntervalMs >= MIN_REFRESH_INTERVAL_MS, () => `refreshIntervalMs must be at least ${MIN_REFRESH_INTERVAL_MS}ms`);
|
|
696
|
+
}
|
|
697
|
+
this.refreshIntervalMs = refreshIntervalMs ?? DEFAULT_REFRESH_INTERVAL_MS;
|
|
698
|
+
this._chainContractViewer = await this.locator.getInstance(ChainContractViewerMoniker);
|
|
699
|
+
this._stakeEventsViewer = await this.locator.getInstance(StakeEventsViewerMoniker2);
|
|
700
|
+
}
|
|
701
|
+
/** Returns the configured chain's withdrawal delay. */
|
|
702
|
+
async minWithdrawalBlocks() {
|
|
703
|
+
return await this._chainContractViewer.minWithdrawalBlocks();
|
|
704
|
+
}
|
|
705
|
+
/** Returns finalized positions that have been removed but not withdrawn. */
|
|
706
|
+
async removedStakes() {
|
|
707
|
+
await this.sync();
|
|
708
|
+
return this.positionIndex.values().filter((position) => position.removeBlock !== 0 && position.withdrawBlock === 0).toArray();
|
|
709
|
+
}
|
|
710
|
+
/** Returns the configured rewards contract address. */
|
|
711
|
+
async rewardsContract() {
|
|
712
|
+
return toAddress3(await this._chainContractViewer.rewardsContract());
|
|
713
|
+
}
|
|
714
|
+
/** Returns a finalized position by its contract id. */
|
|
715
|
+
async stakeById(id) {
|
|
716
|
+
await this.sync();
|
|
717
|
+
return assertEx6(this.positionIndex.get(id), () => `RestStakeViewer: position ${id} not found in finalized event index`);
|
|
718
|
+
}
|
|
719
|
+
/** Returns a staker's finalized position by its contract slot. */
|
|
720
|
+
async stakeByStaker(staker, slot) {
|
|
721
|
+
await this.sync();
|
|
722
|
+
const position = this.positionsByStaker.get(toAddress3(staker))?.at(slot);
|
|
723
|
+
return assertEx6(position, () => `RestStakeViewer: staker ${staker} has no finalized position at slot ${slot}`);
|
|
724
|
+
}
|
|
725
|
+
/** Returns finalized positions added for an address in the supplied EVM block range. */
|
|
726
|
+
async stakesByStaked(staked, range = [0, void 0]) {
|
|
727
|
+
await this.sync();
|
|
728
|
+
return this.positionsInRange(this.positionsByStaked.get(toAddress3(staked)) ?? [], range);
|
|
729
|
+
}
|
|
730
|
+
/** Returns finalized positions added by a staker in the supplied EVM block range. */
|
|
731
|
+
async stakesByStaker(staker, range = [0, void 0]) {
|
|
732
|
+
await this.sync();
|
|
733
|
+
return this.positionsInRange(this.positionsByStaker.get(toAddress3(staker)) ?? [], range);
|
|
734
|
+
}
|
|
735
|
+
/** Returns the configured staking-token address. */
|
|
736
|
+
async stakingTokenAddress() {
|
|
737
|
+
return toAddress3(await this._chainContractViewer.stakingTokenAddress());
|
|
738
|
+
}
|
|
739
|
+
/** Returns finalized positions that have completed withdrawal. */
|
|
740
|
+
async withdrawnStakes() {
|
|
741
|
+
await this.sync();
|
|
742
|
+
return this.positionIndex.values().filter((position) => position.removeBlock !== 0 && position.withdrawBlock !== 0).toArray();
|
|
743
|
+
}
|
|
744
|
+
applyEvent(index, event) {
|
|
745
|
+
if (event.name === "StakeAdded") {
|
|
746
|
+
index.set(event.args.id, {
|
|
747
|
+
id: event.args.id,
|
|
748
|
+
staked: toAddress3(event.args.staked),
|
|
749
|
+
staker: toAddress3(event.args.staker),
|
|
750
|
+
amount: event.args.amount,
|
|
751
|
+
addBlock: event.time,
|
|
752
|
+
removeBlock: 0,
|
|
753
|
+
withdrawBlock: 0
|
|
754
|
+
});
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
const position = assertEx6(index.get(event.args.id), () => `RestStakeViewer: ${event.name} precedes StakeAdded for position ${event.args.id}`);
|
|
758
|
+
index.set(event.args.id, {
|
|
759
|
+
...position,
|
|
760
|
+
...event.name === "StakeRemoved" ? { removeBlock: event.time } : { withdrawBlock: event.time }
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
positionsInRange(positions, range) {
|
|
764
|
+
const [fromBlock, configuredToBlock] = range;
|
|
765
|
+
const toBlock = configuredToBlock ?? Number.MAX_SAFE_INTEGER;
|
|
766
|
+
return positions.filter((position) => position.addBlock >= fromBlock && position.addBlock <= toBlock);
|
|
767
|
+
}
|
|
768
|
+
rebuildPositionIndex(events) {
|
|
769
|
+
const positionIndex = /* @__PURE__ */ new Map();
|
|
770
|
+
for (const event of events.toSorted((left, right) => left.time - right.time)) {
|
|
771
|
+
this.applyEvent(positionIndex, event);
|
|
772
|
+
}
|
|
773
|
+
const positionsByStaked = /* @__PURE__ */ new Map();
|
|
774
|
+
const positionsByStaker = /* @__PURE__ */ new Map();
|
|
775
|
+
for (const position of positionIndex.values().toArray().toSorted((left, right) => left.id - right.id)) {
|
|
776
|
+
const staked = toAddress3(position.staked);
|
|
777
|
+
const staker = toAddress3(position.staker);
|
|
778
|
+
positionsByStaked.set(staked, [...positionsByStaked.get(staked) ?? [], position]);
|
|
779
|
+
positionsByStaker.set(staker, [...positionsByStaker.get(staker) ?? [], position]);
|
|
780
|
+
}
|
|
781
|
+
this.positionIndex = positionIndex;
|
|
782
|
+
this.positionsByStaked = positionsByStaked;
|
|
783
|
+
this.positionsByStaker = positionsByStaker;
|
|
784
|
+
}
|
|
785
|
+
async sync() {
|
|
786
|
+
const now = Date.now();
|
|
787
|
+
const elapsed = this.lastSuccessfulSyncAt === void 0 ? void 0 : now - this.lastSuccessfulSyncAt;
|
|
788
|
+
if (elapsed !== void 0 && elapsed >= 0 && elapsed < this.refreshIntervalMs) return;
|
|
789
|
+
this.syncPromise ??= Promise.resolve(this.stakeEvents.stakeEvents([0, "latest"])).then((events) => this.rebuildPositionIndex(events)).then(() => {
|
|
790
|
+
this.lastSuccessfulSyncAt = Date.now();
|
|
791
|
+
}).finally(() => {
|
|
792
|
+
this.syncPromise = void 0;
|
|
793
|
+
});
|
|
794
|
+
await this.syncPromise;
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
__publicField(RestStakeViewer, "connectionTypes", ["rest"]);
|
|
798
|
+
__publicField(RestStakeViewer, "defaultMoniker", StakeViewerMoniker);
|
|
799
|
+
__publicField(RestStakeViewer, "dependencies", [ChainContractViewerMoniker, StakeEventsViewerMoniker2]);
|
|
800
|
+
__publicField(RestStakeViewer, "monikers", [StakeViewerMoniker]);
|
|
801
|
+
__publicField(RestStakeViewer, "surface", "node");
|
|
802
|
+
RestStakeViewer = __decorateClass([
|
|
803
|
+
creatableProvider2()
|
|
804
|
+
], RestStakeViewer);
|
|
805
|
+
|
|
589
806
|
// src/modules/ethereum/providers/AbstractEvmRunner.ts
|
|
590
|
-
import { assertEx as
|
|
807
|
+
import { assertEx as assertEx7 } from "@ariestools/sdk";
|
|
591
808
|
import { AbstractEvmProvider } from "@xyo-network/xl1-sdk";
|
|
592
809
|
function evmContractRunnerHandleKey(moniker) {
|
|
593
810
|
return `evm-contract-runner:${moniker}`;
|
|
@@ -595,7 +812,7 @@ function evmContractRunnerHandleKey(moniker) {
|
|
|
595
812
|
var AbstractEvmRunner = class extends AbstractEvmProvider {
|
|
596
813
|
_runner;
|
|
597
814
|
get runner() {
|
|
598
|
-
return
|
|
815
|
+
return assertEx7(this._runner, () => "EVM contract runner not initialized");
|
|
599
816
|
}
|
|
600
817
|
/** Creates the provider instance after its dependencies and configuration have resolved. */
|
|
601
818
|
async createHandler() {
|
|
@@ -611,7 +828,7 @@ var AbstractEvmRunner = class extends AbstractEvmProvider {
|
|
|
611
828
|
import { toEthAddress as toEthAddress5 } from "@ariestools/sdk";
|
|
612
829
|
import { IStakedXyoChain__factory } from "@xyo-network/typechain";
|
|
613
830
|
import {
|
|
614
|
-
creatableProvider as
|
|
831
|
+
creatableProvider as creatableProvider3,
|
|
615
832
|
StakeRunnerMoniker
|
|
616
833
|
} from "@xyo-network/xl1-sdk";
|
|
617
834
|
import { getAddress } from "ethers/address";
|
|
@@ -642,13 +859,16 @@ __publicField(EvmStakeRunner, "dependencies", []);
|
|
|
642
859
|
__publicField(EvmStakeRunner, "monikers", [StakeRunnerMoniker]);
|
|
643
860
|
__publicField(EvmStakeRunner, "surface", "node");
|
|
644
861
|
EvmStakeRunner = __decorateClass([
|
|
645
|
-
|
|
862
|
+
creatableProvider3()
|
|
646
863
|
], EvmStakeRunner);
|
|
647
864
|
export {
|
|
648
865
|
AbstractEvmRunner,
|
|
649
866
|
BaseEthProvider,
|
|
650
867
|
EvmStakeRunner,
|
|
651
868
|
RestStakeEventsViewer,
|
|
869
|
+
RestStakeEventsViewerOptionsZod,
|
|
870
|
+
RestStakeViewer,
|
|
871
|
+
RestStakeViewerOptionsZod,
|
|
652
872
|
blockRangeChunks,
|
|
653
873
|
calculateEthBlockRate,
|
|
654
874
|
calculateEthTimeRate,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/modules/ethereum/BaseEthProvider.ts", "../../src/modules/ethereum/block/blockRangeChunks.ts", "../../src/modules/ethereum/block/rate/blockRate.ts", "../../src/modules/ethereum/block/rate/timeRate.ts", "../../src/modules/ethereum/createChain.ts", "../../src/modules/ethereum/createChainContract.ts", "../../src/modules/ethereum/createChainRewardsContract.ts", "../../src/modules/ethereum/nextContractAddress.ts", "../../src/modules/ethereum/ethereum.ts", "../../src/modules/ethereum/indexing/RestStakeEventsViewer.ts", "../../src/modules/ethereum/providers/AbstractEvmRunner.ts", "../../src/modules/ethereum/providers/EvmStakeRunner.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n Address, BlockAPI,\n BlockNumberOrTag,\n CompileResultAPI,\n EthExecutionAPI,\n FeeHistoryResultAPI,\n Filter,\n FilterResultsAPI,\n HexString, HexString8Bytes,\n HexString32Bytes,\n HexString256Bytes,\n HexStringBytes,\n SignedTransactionInfoAPI,\n SyncingStatusAPI,\n TransactionCallAPI,\n TransactionInfoAPI,\n TransactionReceiptAPI,\n TransactionWithSenderAPI,\n Uint,\n Uint256,\n} from 'web3-types'\n\nexport class BaseEthProvider implements EthExecutionAPI {\n eth_accounts(): Address[] {\n throw new Error('Method not implemented.')\n }\n\n eth_blockNumber(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_call(_transaction: TransactionCallAPI, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_clearSubscriptions(_keepSyncing?: boolean): void {\n throw new Error('Method not implemented.')\n }\n\n eth_coinbase(): Address {\n throw new Error('Method not implemented.')\n }\n\n eth_compileLLL(_code: string): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_compileSerpent(_code: string): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_compileSolidity(_code: string): CompileResultAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_estimateGas(_transaction: Partial<TransactionWithSenderAPI>, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_feeHistory(_blockCount: Uint, _newestBlock: BlockNumberOrTag, _rewardPercentiles: number[]): FeeHistoryResultAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_gasPrice(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBalance(_address: Address, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockByHash(_blockHash: HexString32Bytes, _hydrated: boolean): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockByNumber(_blockNumber: BlockNumberOrTag, _hydrated: boolean): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockTransactionCountByHash(_blockHash: HexString32Bytes): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockTransactionCountByNumber(_blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getCode(_address: Address, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_getCompilers(): string[] {\n throw new Error('Method not implemented.')\n }\n\n eth_getFilterChanges(_filterIdentifier: Uint): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getFilterLogs(_filterIdentifier: Uint): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getLogs(_filter: Filter): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getStorageAt(_address: Address, _storageSlot: Uint256, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByBlockHashAndIndex(_blockHash: HexString32Bytes, _transactionIndex: Uint): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByBlockNumberAndIndex(_blockNumber: BlockNumberOrTag, _transactionIndex: Uint): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByHash(_transactionHash: HexString32Bytes): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionCount(_address: Address, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionReceipt(_transactionHash: HexString32Bytes): TransactionReceiptAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleByBlockHashAndIndex(_blockHash: HexString32Bytes, _uncleIndex: Uint): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleByBlockNumberAndIndex(_blockNumber: BlockNumberOrTag, _uncleIndex: Uint): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleCountByBlockHash(_blockHash: HexString32Bytes): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleCountByBlockNumber(_blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getWork(): [HexString32Bytes, HexString32Bytes, HexString32Bytes] {\n throw new Error('Method not implemented.')\n }\n\n eth_hashrate(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_maxPriorityFeePerGas(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_mining(): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_newBlockFilter(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_newFilter(_filter: Filter): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_newPendingTransactionFilter(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_protocolVersion(): string {\n throw new Error('Method not implemented.')\n }\n\n eth_sendRawTransaction(_transaction: HexStringBytes): HexString32Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_sendTransaction(_transaction: TransactionWithSenderAPI | Partial<TransactionWithSenderAPI>): HexString32Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_sign(_address: Address, _message: HexStringBytes): HexString256Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_signTransaction(_transaction: TransactionWithSenderAPI | Partial<TransactionWithSenderAPI>): HexStringBytes | SignedTransactionInfoAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_submitHashrate(_hashRate: HexString32Bytes, _id: HexString32Bytes): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_submitWork(_nonce: HexString8Bytes, _hash: HexString32Bytes, _digest: HexString32Bytes): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_subscribe(..._params: ['newHeads'] | ['newPendingTransactions'] | ['syncing'] | ['logs', { address?: HexString; topics?: HexString[] }]): HexString {\n throw new Error('Method not implemented.')\n }\n\n eth_syncing(): SyncingStatusAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_uninstallFilter(_filterIdentifier: Uint): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_unsubscribe(_subscriptionId: HexString): HexString {\n throw new Error('Method not implemented.')\n }\n}\n", "/**\n * Split an inclusive block range into fixed-size inclusive chunks.\n *\n * @example\n * blockRangeChunks(0, 5000, 2000) // [[0, 1999], [2000, 3999], [4000, 5000]]\n */\nexport function blockRangeChunks(\n fromBlock: number,\n toBlock: number,\n chunkSize: number,\n): [number, number][] {\n if (!Number.isInteger(chunkSize) || chunkSize < 1) {\n throw new TypeError(`chunkSize must be an integer >= 1, got ${chunkSize}`)\n }\n if (!Number.isFinite(fromBlock) || !Number.isFinite(toBlock)) {\n throw new TypeError(`fromBlock and toBlock must be finite numbers, got [${fromBlock}, ${toBlock}]`)\n }\n if (fromBlock > toBlock) {\n return []\n }\n\n const chunks: [number, number][] = []\n for (let start = fromBlock; start <= toBlock; start += chunkSize) {\n const end = Math.min(start + chunkSize - 1, toBlock)\n chunks.push([start, end])\n }\n return chunks\n}\n", "import { isDefined, isFalsy } from '@ariestools/sdk'\nimport type {\n EthBlockNumber, EthBlockRange, EthBlockRate, TimeDurations,\n} from '@xyo-network/xl1-sdk'\nimport {\n asEthBlockRange, rateMultipliers, timeDurations,\n} from '@xyo-network/xl1-sdk'\nimport type { Block, Provider } from 'ethers/providers'\n\nexport const ethBlockRate = (\n startBlock: Block,\n endBlock: Block,\n timeUnit?: keyof TimeDurations,\n): EthBlockRate => {\n const heightDifference = endBlock.number - startBlock.number\n const timeDifference = endBlock.timestamp - startBlock.timestamp\n\n const rate = heightDifference / timeDifference\n\n const timeUnitValue = isDefined(timeUnit) ? timeUnit : 'millis'\n const returnedTimeDifference = isDefined(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference\n const timePerBlock = returnedTimeDifference / heightDifference\n\n return {\n range: asEthBlockRange([startBlock.number, endBlock.number], true),\n span: heightDifference,\n rate: isDefined(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,\n timeUnit: timeUnitValue,\n timeDifference: returnedTimeDifference,\n timePerBlock,\n }\n}\n\nexport const getEthBlockRateBlocks = async (\n provider: Provider,\n startBlockHeight: EthBlockNumber,\n endBlockHeight: EthBlockNumber,\n): Promise<{ endingBlock: Block; startingBlock: Block }> => {\n if (endBlockHeight <= startBlockHeight) {\n console.error('startBlockHeight', startBlockHeight)\n console.error('endBlockHeight', endBlockHeight)\n throw new Error('End block height must be greater than start block height')\n }\n\n const startingBlock = await provider.getBlock(startBlockHeight)\n const endingBlock = await provider.getBlock(endBlockHeight)\n\n if (isFalsy(startingBlock) || isFalsy(endingBlock)) {\n throw new Error('Could not retrieve blocks for speed calculation')\n }\n\n return { startingBlock, endingBlock }\n}\n\nexport const calculateEthBlockRate = async (\n provider: Provider,\n range: EthBlockRange,\n timeUnit?: keyof TimeDurations,\n): Promise<EthBlockRate> => {\n const [startBlockHeight, endBlockHeight] = range\n const { startingBlock, endingBlock } = await getEthBlockRateBlocks(\n provider,\n startBlockHeight,\n endBlockHeight,\n )\n return ethBlockRate(startingBlock, endingBlock, timeUnit)\n}\n", "import {\n assertEx, isDefined, isDefinedNotNull,\n} from '@ariestools/sdk'\nimport type {\n EthBlockNumber,\n EthBlockRate,\n SingleTimeConfig,\n TimeDurations,\n} from '@xyo-network/xl1-sdk'\nimport {\n asEthBlockNumber, asEthBlockRange, getTimeConfigInMilliseconds,\n} from '@xyo-network/xl1-sdk'\nimport type { Block, Provider } from 'ethers/providers'\n\nimport { calculateEthBlockRate } from './blockRate.ts'\n\nconst DEFAULT_TOLERANCE_MS = 30_000 // 30 seconds\nconst DEFAULT_MAX_ATTEMPTS = 20\n\nexport const calculateEthTimeRate = async (\n provider: Provider,\n timeConfig: SingleTimeConfig,\n startBlockNumber?: EthBlockNumber,\n timeUnit?: keyof TimeDurations,\n // default tolerance of 30 seconds to cut down on iterations\n toleranceMs = DEFAULT_TOLERANCE_MS,\n // maximum recursive attempts to prevent infinite loops\n maxAttempts = DEFAULT_MAX_ATTEMPTS,\n): Promise<EthBlockRate> => {\n // check the time config has only one key\n assertEx(Object.keys(timeConfig ?? {}).length === 1, () => 'Only one time unit should be specified in timeConfig')\n\n // resolve the starting block\n const startBlock = isDefinedNotNull(startBlockNumber) ? await provider.getBlock(BigInt(startBlockNumber)) : null\n\n // Ensure the start block could be resolved\n assertEx(isDefinedNotNull(startBlockNumber) && isDefinedNotNull(startBlock), () => 'Start block could not be resolved')\n\n const resolvedStartBlock = isDefinedNotNull(startBlock)\n ? startBlock\n : assertEx(await provider.getBlock('latest'))\n\n const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig)\n assertEx(timeInMilliseconds > 0, () => 'Time duration must be greater than zero')\n\n // Estimate blocks per milliseconds (bpm) based on average block time\n const blocksPerMillisecondRate = 1 / (12 * 1000) // Approximate average block time of 12 seconds\n\n // Calculate the number of blocks in the given time duration\n const initialBlocksInDuration = Math.floor(blocksPerMillisecondRate * timeInMilliseconds)\n\n // Recursively find the proper end block\n const endBlockNumber = await findEndBlockRecursive(\n provider,\n resolvedStartBlock,\n timeInMilliseconds,\n initialBlocksInDuration,\n toleranceMs,\n maxAttempts,\n )\n\n return await calculateEthBlockRate(\n provider,\n asEthBlockRange([endBlockNumber, resolvedStartBlock.number], true),\n timeUnit,\n )\n}\n\nconst findEndBlockRecursive = async (\n provider: Provider,\n startBlock: Block,\n targetTimeMs: number,\n estimatedBlocksBack: number,\n toleranceMs: number,\n attemptsRemaining: number,\n): Promise<EthBlockNumber> => {\n console.log(`Attempts remaining: ${attemptsRemaining}, Estimated blocks back: ${estimatedBlocksBack}`)\n assertEx(attemptsRemaining > 0, () => 'Maximum attempts reached while searching for end block')\n\n const startBlockEpoch = startBlock.timestamp\n const estimatedEndBlockNumber = startBlock.number - estimatedBlocksBack\n\n if (estimatedEndBlockNumber < 0) {\n throw new Error('Estimated end block number is less than zero')\n }\n\n // Fetch the estimated end block\n const endBlock = await provider.getBlock(estimatedEndBlockNumber)\n const resolvedEndBlock = assertEx(\n isDefined(endBlock) ? endBlock : undefined,\n () => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`,\n )\n\n const endBlockEpoch = resolvedEndBlock.timestamp\n const actualTimeDifference = startBlockEpoch - endBlockEpoch\n\n // Check if we're within tolerance\n const timeDelta = Math.abs(actualTimeDifference - targetTimeMs)\n if (timeDelta <= toleranceMs) {\n return asEthBlockNumber(resolvedEndBlock.number, true)\n }\n\n // TODO - in order to support older POW days, we might need to shift away from using adjustmentFactor but do a pure binary search\n // Calculate adjustment factor and recursively search\n let adjustedBlocksBack: number\n if (actualTimeDifference < targetTimeMs) {\n // Need to go further back\n const adjustmentFactor = targetTimeMs / actualTimeDifference\n adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor)\n if (adjustedBlocksBack > startBlock.number) {\n adjustedBlocksBack = startBlock.number / 2\n }\n } else {\n // Need to come forward\n const adjustmentFactor = actualTimeDifference / targetTimeMs\n adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor)\n }\n\n return await findEndBlockRecursive(\n provider,\n startBlock,\n targetTimeMs,\n adjustedBlocksBack,\n toleranceMs,\n attemptsRemaining - 1,\n )\n}\n", "import type {\n Address,\n EthAddress,\n} from '@ariestools/sdk'\nimport {\n toAddress,\n toEthAddress,\n} from '@ariestools/sdk'\nimport type { AccountInstance } from '@xyo-network/sdk'\nimport { PayloadBuilder } from '@xyo-network/sdk'\nimport { type HydratedBlockWithHashMeta, XYO_NETWORK_STAKING_ADDRESS } from '@xyo-network/xl1-sdk'\nimport type { Signer } from 'ethers/providers'\n\nimport { createGenesisBlock } from '#protocol'\n\nimport { createChainContract } from './createChainContract.ts'\nimport { createChainRewardsContract } from './createChainRewardsContract.ts'\nimport type { GasConfig } from './ethereum.ts'\nimport { nextContractAddress } from './nextContractAddress.ts'\n\nexport async function createChain(\n signer: Signer,\n stakingTokenAddress: EthAddress | Address,\n initialBlockProducer: AccountInstance,\n rewardsContractAddress: Address | null,\n genesisBlockRewardAmount: bigint,\n genesisBlockRewardAddress: Address,\n minWithdrawalBlocks: bigint,\n maxStakersPerAddress = 10,\n unlimitedStakingAddress = XYO_NETWORK_STAKING_ADDRESS,\n minStake = 10_000n,\n gas?: GasConfig,\n): Promise<[Address, HydratedBlockWithHashMeta, Address]> {\n const ethStakingTokenAddress = toEthAddress(stakingTokenAddress)\n const rewardContractAddressResolved = rewardsContractAddress ?? (await createChainRewardsContract(signer, genesisBlockRewardAmount, gas))\n const contractAddress = await nextContractAddress(signer)\n const genesisBlock = await createGenesisBlock(\n initialBlockProducer,\n contractAddress,\n genesisBlockRewardAmount,\n genesisBlockRewardAddress,\n )\n const chainId = toAddress(await createChainContract(\n signer,\n ethStakingTokenAddress,\n await PayloadBuilder.hash(genesisBlock[0]),\n rewardContractAddressResolved,\n minWithdrawalBlocks,\n maxStakersPerAddress,\n unlimitedStakingAddress,\n minStake,\n gas,\n ))\n return [chainId, genesisBlock, rewardContractAddressResolved]\n}\n", "import type {\n Address, EthAddress, Hash,\n} from '@ariestools/sdk'\nimport {\n asAddress, assertEx,\n ETH_ZERO_ADDRESS, hexToBigInt, toEthAddress,\n} from '@ariestools/sdk'\nimport { StakedXyoChainV2__factory } from '@xyo-network/typechain'\nimport { XYO_NETWORK_STAKING_ADDRESS } from '@xyo-network/xl1-sdk'\nimport type { Signer } from 'ethers/providers'\n\nimport type { GasConfig } from './ethereum.ts'\n\nexport const createChainContract = async (\n signer: Signer,\n stakingTokenAddress: EthAddress,\n genesisBlockHash: Hash,\n rewardsContractAddress: Address,\n minWithdrawalBlocks: bigint,\n maxStakersPerAddress = 10,\n unlimitedStakingAddress = XYO_NETWORK_STAKING_ADDRESS,\n minStake = 10_000n,\n gas: GasConfig = {},\n): Promise<Address> => {\n try {\n const xyoChainFactory = new StakedXyoChainV2__factory(signer)\n const deployResponse = await xyoChainFactory.deploy(\n ETH_ZERO_ADDRESS, // forkFromChainId\n 0n, // forkFromLastBlockNumber\n hexToBigInt(genesisBlockHash), // forkFromLastHash\n toEthAddress(rewardsContractAddress),\n minWithdrawalBlocks, // min withdraw blocks\n toEthAddress(stakingTokenAddress),\n maxStakersPerAddress,\n toEthAddress(unlimitedStakingAddress),\n minStake,\n gas,\n )\n await deployResponse.waitForDeployment()\n const xyoChainContractAddress = await deployResponse.getAddress()\n return assertEx(asAddress(xyoChainContractAddress), () => 'Invalid staking contract address')\n } catch (ex) {\n console.log(ex)\n throw ex\n }\n}\n", "import type { Address } from '@ariestools/sdk'\nimport {\n asAddress, assertEx, toFixedPoint,\n} from '@ariestools/sdk'\nimport { XyoChainRewards__factory as XyoChainRewardsFactory } from '@xyo-network/typechain'\nimport { parseUnits, type Signer } from 'ethers'\n\nimport type { GasConfig } from './ethereum.ts'\n\nconst gasConfig = () => {\n return {\n gasLimit: 2_000_000, // Set the gas limit\n gasPrice: parseUnits('100', 'gwei'),\n }\n}\n\nexport const createChainRewardsContract = async (\n signer: Signer,\n genesisReward = 0n,\n gas: GasConfig = gasConfig(),\n): Promise<Address> => {\n try {\n const xyoChainRewardsFactory = new XyoChainRewardsFactory(signer)\n const deployResponse = await xyoChainRewardsFactory.deploy(\n toFixedPoint(1000n),\n 1_000_000n,\n 95n,\n 100n,\n toFixedPoint(30n),\n genesisReward,\n 18n,\n gas,\n )\n await deployResponse.waitForDeployment()\n const xyoChainRewardsAddress = await deployResponse.getAddress()\n return assertEx(asAddress(xyoChainRewardsAddress), () => 'Invalid rewards contract address')\n } catch (ex) {\n console.log(ex)\n throw ex\n }\n}\n", "import type { Address } from '@ariestools/sdk'\nimport {\n asAddress, assertEx, toEthAddress,\n} from '@ariestools/sdk'\nimport { getCreateAddress } from 'ethers/address'\nimport type { Provider, Signer } from 'ethers/providers'\n\n/**\n * Predicts the next contract address for a contract that will be deployed\n * @param address The address of the deployer\n * @param provider The provider to use\n * @returns The predicted contract address\n */\nexport const nextContractAddressForAddress = async (address: Address, provider: Provider) => {\n // Get the deployer address\n const deployerAddress = toEthAddress(address)\n\n // Get the next nonce for the deployer account\n const nonce = await provider.getTransactionCount(deployerAddress)\n\n // Predict the next deployed contract contract address\n const contractAddress = getCreateAddress({ from: deployerAddress, nonce })\n\n // Return the predicted contract address\n return assertEx(asAddress(contractAddress), () => 'Unable to convert contract address to address')\n}\n\n/**\n * Predicts the next contract address for a contract that will be deployed\n * @param signer The signer to use when deploying the contract\n * @returns The predicted contract address\n */\nexport const nextContractAddress = async (signer: Signer) => {\n const provider = assertEx(signer.provider, () => 'Unable to obtain provider from signer')\n const address = assertEx(asAddress(await signer.getAddress()), () => 'Unable to obtain address from signer')\n return await nextContractAddressForAddress(address, provider)\n}\n", "import { parseUnits } from 'ethers/utils'\n\nexport interface GasConfig {\n gasLimit?: number\n gasPrice?: bigint\n}\n\nexport const getDefaultGasConfig = (): GasConfig => {\n return {\n gasLimit: 2_000_000, // Set the gas limit\n gasPrice: parseUnits('100', 'gwei'),\n }\n}\n", "import type { EthAddress } from '@ariestools/sdk'\nimport {\n assertEx, isDefined, toAddress, toEthAddress,\n} from '@ariestools/sdk'\nimport { IAddressStakingEvents__factory } from '@xyo-network/typechain'\nimport type {\n EvmEventIndexFrame, EvmEventIndexHead, EvmEventIndexLog, EvmEventIndexManifest,\n StakeEvent, StakeEventFilter, StakeEventName, StakeEventsViewer,\n} from '@xyo-network/xl1-sdk'\nimport {\n AbstractCreatableProvider, asAttoXL1, asEvmEventIndexFrame, asEvmEventIndexHead, asEvmEventIndexManifest,\n creatableProvider, evmEventIndexFramePath, evmEventIndexHeadPath, evmEventIndexManifestPath, evmEventIndexTailPath,\n StakeEventsViewerMoniker,\n} from '@xyo-network/xl1-sdk'\nimport { Interface } from 'ethers'\n\nconst STAKE_EVENT_NAMES = new Set<string>(['StakeAdded', 'StakeRemoved', 'StakeWithdrawn'])\n\n/**\n * StakeEventsViewer backed by the finalized contract-event index rather than eth_getLogs.\n * Raw indexed logs remain contract-generic; this viewer applies the staking ABI at the edge.\n * The staking contract address comes from `config.chain.id` and the index bucket URL from\n * the bound `rest` connection's `baseUrl`.\n */\n@creatableProvider()\nexport class RestStakeEventsViewer extends AbstractCreatableProvider implements StakeEventsViewer {\n static readonly connectionTypes = ['rest'] as const\n static readonly defaultMoniker = StakeEventsViewerMoniker\n static readonly dependencies = []\n static readonly monikers = [StakeEventsViewerMoniker]\n static readonly surface = 'node' as const\n moniker = RestStakeEventsViewer.defaultMoniker\n\n private readonly completeFrames = new Map<number, EvmEventIndexFrame>()\n private readonly contractInterface = new Interface(IAddressStakingEvents__factory.abi)\n private currentHead?: EvmEventIndexHead\n private manifestPromise?: Promise<EvmEventIndexManifest>\n private stakeEventCache: StakeEvent[] = []\n private syncPromise?: Promise<void>\n private tailFrame?: EvmEventIndexFrame\n\n get address(): EthAddress {\n return toEthAddress(assertEx(this.config.chain.id, () => 'RestStakeEventsViewer requires config.chain.id (the staking contract address)'))\n }\n\n get eventIndexBaseUrl(): string {\n const connection = RestStakeEventsViewer.requireBoundConnection(this.config)\n const baseUrl = assertEx(\n connection.config.type === 'rest' ? connection.config.baseUrl : undefined,\n () => `Connection \"${connection.name}\" bound to RestStakeEventsViewer requires a rest baseUrl`,\n )\n return baseUrl.replace(/\\/+$/, '')\n }\n\n protected get fetchFn(): typeof globalThis.fetch {\n return this.context.fetchFn ?? fetch.bind(globalThis)\n }\n\n async positionCount(range: [number, number | 'latest']): Promise<number> {\n const events = await this.stakeEvents(range)\n return Math.max(-1, ...events.map(event => event.args.id)) + 1\n }\n\n async stakeEvents<TName extends StakeEventName>(\n range: [number, number | 'latest'] = [0, 'latest'],\n filter?: StakeEventFilter<TName>,\n ): Promise<StakeEvent<TName>[]> {\n await this.sync()\n return this.stakeEventCache.filter(event => this.matchesFilter(event, range, filter)) as StakeEvent<TName>[]\n }\n\n private decodeIndexedStakeEvents(): StakeEvent[] {\n const frames = [...this.completeFrames.entries()]\n .sort(([a], [b]) => a - b)\n .map(([, frame]) => frame)\n const logs = [...frames, ...(this.tailFrame === undefined ? [] : [this.tailFrame])]\n .flatMap(frame => frame.logs)\n .sort((a, b) => a.blockNumber - b.blockNumber || a.transactionIndex - b.transactionIndex || a.index - b.index)\n return logs.flatMap((log) => {\n const event = this.stakeEventFromLog(log)\n return event === undefined ? [] : [event]\n })\n }\n\n private async fetchJson(path: string): Promise<unknown> {\n const response = await this.fetchFn(`${this.eventIndexBaseUrl}/${path}`)\n assertEx(response.ok, () => `EVM event index request failed [${response.status}] for ${path}`)\n return await response.json()\n }\n\n private async getManifest(): Promise<EvmEventIndexManifest> {\n this.manifestPromise ??= (async () => {\n const manifest = asEvmEventIndexManifest(await this.fetchJson(evmEventIndexManifestPath(this.address)), true)\n assertEx(manifest.address.toLowerCase() === this.address.toLowerCase(), () => 'EVM event index manifest address mismatch')\n return manifest\n })()\n return await this.manifestPromise\n }\n\n // eslint-disable-next-line complexity\n private matchesFilter<TName extends StakeEventName>(\n event: StakeEvent,\n range: [number, number | 'latest'],\n filter?: StakeEventFilter<TName>,\n ): boolean {\n if (range[1] !== 'latest' && event.time > range[1]) return false\n if (event.time < range[0]) return false\n if (isDefined(filter?.name) && event.name !== filter.name) return false\n if (isDefined(filter?.args?.id) && event.args.id !== filter.args.id) return false\n if (isDefined(filter?.args?.staked) && event.args.staked !== filter.args.staked) return false\n if (isDefined(filter?.args?.staker) && event.args.staker !== filter.args.staker) return false\n return true\n }\n\n private stakeEventFromLog(log: EvmEventIndexLog): StakeEvent | undefined {\n const parsed = this.contractInterface.parseLog({ data: log.data, topics: log.topics })\n if (parsed === null || !STAKE_EVENT_NAMES.has(parsed.name)) return\n const [staked, staker, id, amount] = parsed.args\n return {\n name: parsed.name as StakeEventName,\n args: {\n amount: asAttoXL1(amount as bigint),\n id: Number(id),\n staked: toAddress(staked as string),\n staker: toAddress(staker as string),\n },\n time: log.blockNumber,\n }\n }\n\n private async sync(): Promise<void> {\n this.syncPromise ??= this.syncFromHead().finally(() => {\n this.syncPromise = undefined\n })\n await this.syncPromise\n }\n\n private async syncFromHead(): Promise<void> {\n const manifest = await this.getManifest()\n const head = asEvmEventIndexHead(await this.fetchJson(evmEventIndexHeadPath(this.address)), true)\n assertEx(head.address.toLowerCase() === this.address.toLowerCase(), () => 'EVM event index head address mismatch')\n assertEx(head.chainId === manifest.chainId, () => 'EVM event index chain mismatch')\n if (this.currentHead?.block === head.block && this.currentHead.hash === head.hash) return\n\n if (this.currentHead !== undefined && (head.block < this.currentHead.block || (head.block === this.currentHead.block && head.hash !== this.currentHead.hash))) {\n this.completeFrames.clear()\n this.tailFrame = undefined\n }\n\n const indexedBlockCount = Math.max(0, head.block - manifest.deploymentBlock + 1)\n const completeFrameCount = Math.floor(indexedBlockCount / manifest.frameSize)\n const missingFrameIndexes = Array.from({ length: completeFrameCount }, (_, index) => index)\n .filter(index => !this.completeFrames.has(index))\n await Promise.all(missingFrameIndexes.map(async (index) => {\n const frame = asEvmEventIndexFrame(await this.fetchJson(evmEventIndexFramePath(this.address, index)), true)\n const expectedFrom = manifest.deploymentBlock + index * manifest.frameSize\n assertEx(frame.fromBlock === expectedFrom, () => `EVM event index frame ${index} starts at the wrong block`)\n assertEx(frame.toBlock === expectedFrom + manifest.frameSize - 1, () => `EVM event index frame ${index} is incomplete`)\n this.completeFrames.set(index, frame)\n }))\n\n const tailStart = manifest.deploymentBlock + completeFrameCount * manifest.frameSize\n this.tailFrame = tailStart <= head.block\n ? asEvmEventIndexFrame(await this.fetchJson(`${evmEventIndexTailPath(this.address)}?head=${head.hash}`), true)\n : undefined\n if (this.tailFrame !== undefined) {\n assertEx(this.tailFrame.fromBlock === tailStart, () => 'EVM event index tail starts at the wrong block')\n assertEx(this.tailFrame.toBlock === head.block, () => 'EVM event index tail is stale relative to its head')\n }\n this.stakeEventCache = this.decodeIndexedStakeEvents()\n this.currentHead = head\n }\n}\n", "import { assertEx } from '@ariestools/sdk'\nimport type { CreatableProviderParams } from '@xyo-network/xl1-sdk'\nimport { AbstractEvmProvider } from '@xyo-network/xl1-sdk'\nimport type { BaseContract, ContractRunner } from 'ethers'\n\n/** Shared-handle key for a moniker's seeded EVM contract runner (ethers signer/wallet). */\nexport function evmContractRunnerHandleKey(moniker: string): string {\n return `evm-contract-runner:${moniker}`\n}\n\n/**\n * Base for EVM mutation providers. The contract runner (an ethers signer/wallet) is a\n * thick runtime object with no config representation \u2014 hosts seed it in\n * `context.connectionHandles` under `evmContractRunnerHandleKey(moniker)` before create.\n */\nexport abstract class AbstractEvmRunner<TContract extends BaseContract = BaseContract,\n TParams extends CreatableProviderParams = CreatableProviderParams> extends\n AbstractEvmProvider<TParams, TContract> {\n private _runner?: ContractRunner\n\n protected get runner(): ContractRunner {\n return assertEx(this._runner, () => 'EVM contract runner not initialized')\n }\n\n /** Creates the provider instance after its dependencies and configuration have resolved. */\n override async createHandler() {\n const key = evmContractRunnerHandleKey(this.moniker)\n this._runner = await this.connectionHandles.getOrOpen<ContractRunner>(key, () => {\n throw new Error(`No EVM contract runner seeded for [${this.moniker}] \u2014 set context.connectionHandles[\"${key}\"] before create`)\n })\n await super.createHandler()\n }\n}\n", "import type { Address, EthAddress } from '@ariestools/sdk'\nimport { toEthAddress } from '@ariestools/sdk'\nimport type { IStakedXyoChain } from '@xyo-network/typechain'\nimport { IStakedXyoChain__factory } from '@xyo-network/typechain'\nimport type { StakeRunner } from '@xyo-network/xl1-sdk'\nimport {\n creatableProvider,\n StakeRunnerMoniker,\n} from '@xyo-network/xl1-sdk'\nimport { getAddress } from 'ethers/address'\n\nimport { AbstractEvmRunner } from './AbstractEvmRunner.ts'\n\n@creatableProvider()\nexport class EvmStakeRunner extends AbstractEvmRunner<IStakedXyoChain> implements StakeRunner {\n static readonly connectionTypes = ['evm-rpc'] as const\n static readonly defaultMoniker = StakeRunnerMoniker\n static readonly dependencies = []\n static readonly monikers = [StakeRunnerMoniker]\n static readonly surface = 'node' as const\n override moniker = EvmStakeRunner.defaultMoniker\n\n async addStake(staked: Address, amount: bigint): Promise<boolean> {\n const result = await (this.contract).addStake(getAddress(toEthAddress(staked)), amount)\n await result.wait()\n return true\n }\n\n async removeStake(slot: bigint): Promise<boolean> {\n const result = await (this.contract).removeStake(slot)\n await result.wait()\n return true\n }\n\n async withdrawStake(slot: bigint): Promise<boolean> {\n const result = await (this.contract).withdrawStake(slot)\n await result.wait()\n return true\n }\n\n protected override connectContract(address: EthAddress) {\n return IStakedXyoChain__factory.connect(address, this.runner)\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["isDefined", "asEthBlockRange", "asEthBlockRange", "isDefined", "toEthAddress", "XYO_NETWORK_STAKING_ADDRESS", "assertEx", "asAddress", "assertEx", "asAddress", "assertEx", "toEthAddress", "XYO_NETWORK_STAKING_ADDRESS", "toEthAddress", "parseUnits", "assertEx", "isDefined", "toAddress", "toEthAddress", "toEthAddress", "assertEx", "isDefined", "toAddress", "assertEx", "toEthAddress", "creatableProvider", "toEthAddress", "creatableProvider"]
|
|
3
|
+
"sources": ["../../src/modules/ethereum/BaseEthProvider.ts", "../../src/modules/ethereum/block/blockRangeChunks.ts", "../../src/modules/ethereum/block/rate/blockRate.ts", "../../src/modules/ethereum/block/rate/timeRate.ts", "../../src/modules/ethereum/createChain.ts", "../../src/modules/ethereum/createChainContract.ts", "../../src/modules/ethereum/createChainRewardsContract.ts", "../../src/modules/ethereum/nextContractAddress.ts", "../../src/modules/ethereum/ethereum.ts", "../../src/modules/ethereum/indexing/RestStakeEventsViewer.ts", "../../src/modules/ethereum/indexing/RestStakeViewer.ts", "../../src/modules/ethereum/providers/AbstractEvmRunner.ts", "../../src/modules/ethereum/providers/EvmStakeRunner.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n Address, BlockAPI,\n BlockNumberOrTag,\n CompileResultAPI,\n EthExecutionAPI,\n FeeHistoryResultAPI,\n Filter,\n FilterResultsAPI,\n HexString, HexString8Bytes,\n HexString32Bytes,\n HexString256Bytes,\n HexStringBytes,\n SignedTransactionInfoAPI,\n SyncingStatusAPI,\n TransactionCallAPI,\n TransactionInfoAPI,\n TransactionReceiptAPI,\n TransactionWithSenderAPI,\n Uint,\n Uint256,\n} from 'web3-types'\n\nexport class BaseEthProvider implements EthExecutionAPI {\n eth_accounts(): Address[] {\n throw new Error('Method not implemented.')\n }\n\n eth_blockNumber(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_call(_transaction: TransactionCallAPI, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_clearSubscriptions(_keepSyncing?: boolean): void {\n throw new Error('Method not implemented.')\n }\n\n eth_coinbase(): Address {\n throw new Error('Method not implemented.')\n }\n\n eth_compileLLL(_code: string): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_compileSerpent(_code: string): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_compileSolidity(_code: string): CompileResultAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_estimateGas(_transaction: Partial<TransactionWithSenderAPI>, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_feeHistory(_blockCount: Uint, _newestBlock: BlockNumberOrTag, _rewardPercentiles: number[]): FeeHistoryResultAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_gasPrice(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBalance(_address: Address, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockByHash(_blockHash: HexString32Bytes, _hydrated: boolean): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockByNumber(_blockNumber: BlockNumberOrTag, _hydrated: boolean): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockTransactionCountByHash(_blockHash: HexString32Bytes): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getBlockTransactionCountByNumber(_blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getCode(_address: Address, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_getCompilers(): string[] {\n throw new Error('Method not implemented.')\n }\n\n eth_getFilterChanges(_filterIdentifier: Uint): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getFilterLogs(_filterIdentifier: Uint): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getLogs(_filter: Filter): FilterResultsAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getStorageAt(_address: Address, _storageSlot: Uint256, _blockNumber: BlockNumberOrTag): HexStringBytes {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByBlockHashAndIndex(_blockHash: HexString32Bytes, _transactionIndex: Uint): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByBlockNumberAndIndex(_blockNumber: BlockNumberOrTag, _transactionIndex: Uint): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionByHash(_transactionHash: HexString32Bytes): TransactionInfoAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionCount(_address: Address, _blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getTransactionReceipt(_transactionHash: HexString32Bytes): TransactionReceiptAPI | undefined {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleByBlockHashAndIndex(_blockHash: HexString32Bytes, _uncleIndex: Uint): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleByBlockNumberAndIndex(_blockNumber: BlockNumberOrTag, _uncleIndex: Uint): BlockAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleCountByBlockHash(_blockHash: HexString32Bytes): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getUncleCountByBlockNumber(_blockNumber: BlockNumberOrTag): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_getWork(): [HexString32Bytes, HexString32Bytes, HexString32Bytes] {\n throw new Error('Method not implemented.')\n }\n\n eth_hashrate(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_maxPriorityFeePerGas(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_mining(): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_newBlockFilter(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_newFilter(_filter: Filter): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_newPendingTransactionFilter(): Uint {\n throw new Error('Method not implemented.')\n }\n\n eth_protocolVersion(): string {\n throw new Error('Method not implemented.')\n }\n\n eth_sendRawTransaction(_transaction: HexStringBytes): HexString32Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_sendTransaction(_transaction: TransactionWithSenderAPI | Partial<TransactionWithSenderAPI>): HexString32Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_sign(_address: Address, _message: HexStringBytes): HexString256Bytes {\n throw new Error('Method not implemented.')\n }\n\n eth_signTransaction(_transaction: TransactionWithSenderAPI | Partial<TransactionWithSenderAPI>): HexStringBytes | SignedTransactionInfoAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_submitHashrate(_hashRate: HexString32Bytes, _id: HexString32Bytes): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_submitWork(_nonce: HexString8Bytes, _hash: HexString32Bytes, _digest: HexString32Bytes): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_subscribe(..._params: ['newHeads'] | ['newPendingTransactions'] | ['syncing'] | ['logs', { address?: HexString; topics?: HexString[] }]): HexString {\n throw new Error('Method not implemented.')\n }\n\n eth_syncing(): SyncingStatusAPI {\n throw new Error('Method not implemented.')\n }\n\n eth_uninstallFilter(_filterIdentifier: Uint): boolean {\n throw new Error('Method not implemented.')\n }\n\n eth_unsubscribe(_subscriptionId: HexString): HexString {\n throw new Error('Method not implemented.')\n }\n}\n", "/**\n * Split an inclusive block range into fixed-size inclusive chunks.\n *\n * @example\n * blockRangeChunks(0, 5000, 2000) // [[0, 1999], [2000, 3999], [4000, 5000]]\n */\nexport function blockRangeChunks(\n fromBlock: number,\n toBlock: number,\n chunkSize: number,\n): [number, number][] {\n if (!Number.isInteger(chunkSize) || chunkSize < 1) {\n throw new TypeError(`chunkSize must be an integer >= 1, got ${chunkSize}`)\n }\n if (!Number.isFinite(fromBlock) || !Number.isFinite(toBlock)) {\n throw new TypeError(`fromBlock and toBlock must be finite numbers, got [${fromBlock}, ${toBlock}]`)\n }\n if (fromBlock > toBlock) {\n return []\n }\n\n const chunks: [number, number][] = []\n for (let start = fromBlock; start <= toBlock; start += chunkSize) {\n const end = Math.min(start + chunkSize - 1, toBlock)\n chunks.push([start, end])\n }\n return chunks\n}\n", "import { isDefined, isFalsy } from '@ariestools/sdk'\nimport type {\n EthBlockNumber, EthBlockRange, EthBlockRate, TimeDurations,\n} from '@xyo-network/xl1-sdk'\nimport {\n asEthBlockRange, rateMultipliers, timeDurations,\n} from '@xyo-network/xl1-sdk'\nimport type { Block, Provider } from 'ethers/providers'\n\nexport const ethBlockRate = (\n startBlock: Block,\n endBlock: Block,\n timeUnit?: keyof TimeDurations,\n): EthBlockRate => {\n const heightDifference = endBlock.number - startBlock.number\n const timeDifference = endBlock.timestamp - startBlock.timestamp\n\n const rate = heightDifference / timeDifference\n\n const timeUnitValue = isDefined(timeUnit) ? timeUnit : 'millis'\n const returnedTimeDifference = isDefined(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference\n const timePerBlock = returnedTimeDifference / heightDifference\n\n return {\n range: asEthBlockRange([startBlock.number, endBlock.number], true),\n span: heightDifference,\n rate: isDefined(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,\n timeUnit: timeUnitValue,\n timeDifference: returnedTimeDifference,\n timePerBlock,\n }\n}\n\nexport const getEthBlockRateBlocks = async (\n provider: Provider,\n startBlockHeight: EthBlockNumber,\n endBlockHeight: EthBlockNumber,\n): Promise<{ endingBlock: Block; startingBlock: Block }> => {\n if (endBlockHeight <= startBlockHeight) {\n console.error('startBlockHeight', startBlockHeight)\n console.error('endBlockHeight', endBlockHeight)\n throw new Error('End block height must be greater than start block height')\n }\n\n const startingBlock = await provider.getBlock(startBlockHeight)\n const endingBlock = await provider.getBlock(endBlockHeight)\n\n if (isFalsy(startingBlock) || isFalsy(endingBlock)) {\n throw new Error('Could not retrieve blocks for speed calculation')\n }\n\n return { startingBlock, endingBlock }\n}\n\nexport const calculateEthBlockRate = async (\n provider: Provider,\n range: EthBlockRange,\n timeUnit?: keyof TimeDurations,\n): Promise<EthBlockRate> => {\n const [startBlockHeight, endBlockHeight] = range\n const { startingBlock, endingBlock } = await getEthBlockRateBlocks(\n provider,\n startBlockHeight,\n endBlockHeight,\n )\n return ethBlockRate(startingBlock, endingBlock, timeUnit)\n}\n", "import {\n assertEx, isDefined, isDefinedNotNull,\n} from '@ariestools/sdk'\nimport type {\n EthBlockNumber,\n EthBlockRate,\n SingleTimeConfig,\n TimeDurations,\n} from '@xyo-network/xl1-sdk'\nimport {\n asEthBlockNumber, asEthBlockRange, getTimeConfigInMilliseconds,\n} from '@xyo-network/xl1-sdk'\nimport type { Block, Provider } from 'ethers/providers'\n\nimport { calculateEthBlockRate } from './blockRate.ts'\n\nconst DEFAULT_TOLERANCE_MS = 30_000 // 30 seconds\nconst DEFAULT_MAX_ATTEMPTS = 20\n\nexport const calculateEthTimeRate = async (\n provider: Provider,\n timeConfig: SingleTimeConfig,\n startBlockNumber?: EthBlockNumber,\n timeUnit?: keyof TimeDurations,\n // default tolerance of 30 seconds to cut down on iterations\n toleranceMs = DEFAULT_TOLERANCE_MS,\n // maximum recursive attempts to prevent infinite loops\n maxAttempts = DEFAULT_MAX_ATTEMPTS,\n): Promise<EthBlockRate> => {\n // check the time config has only one key\n assertEx(Object.keys(timeConfig ?? {}).length === 1, () => 'Only one time unit should be specified in timeConfig')\n\n // resolve the starting block\n const startBlock = isDefinedNotNull(startBlockNumber) ? await provider.getBlock(BigInt(startBlockNumber)) : null\n\n // Ensure the start block could be resolved\n assertEx(isDefinedNotNull(startBlockNumber) && isDefinedNotNull(startBlock), () => 'Start block could not be resolved')\n\n const resolvedStartBlock = isDefinedNotNull(startBlock)\n ? startBlock\n : assertEx(await provider.getBlock('latest'))\n\n const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig)\n assertEx(timeInMilliseconds > 0, () => 'Time duration must be greater than zero')\n\n // Estimate blocks per milliseconds (bpm) based on average block time\n const blocksPerMillisecondRate = 1 / (12 * 1000) // Approximate average block time of 12 seconds\n\n // Calculate the number of blocks in the given time duration\n const initialBlocksInDuration = Math.floor(blocksPerMillisecondRate * timeInMilliseconds)\n\n // Recursively find the proper end block\n const endBlockNumber = await findEndBlockRecursive(\n provider,\n resolvedStartBlock,\n timeInMilliseconds,\n initialBlocksInDuration,\n toleranceMs,\n maxAttempts,\n )\n\n return await calculateEthBlockRate(\n provider,\n asEthBlockRange([endBlockNumber, resolvedStartBlock.number], true),\n timeUnit,\n )\n}\n\nconst findEndBlockRecursive = async (\n provider: Provider,\n startBlock: Block,\n targetTimeMs: number,\n estimatedBlocksBack: number,\n toleranceMs: number,\n attemptsRemaining: number,\n): Promise<EthBlockNumber> => {\n console.log(`Attempts remaining: ${attemptsRemaining}, Estimated blocks back: ${estimatedBlocksBack}`)\n assertEx(attemptsRemaining > 0, () => 'Maximum attempts reached while searching for end block')\n\n const startBlockEpoch = startBlock.timestamp\n const estimatedEndBlockNumber = startBlock.number - estimatedBlocksBack\n\n if (estimatedEndBlockNumber < 0) {\n throw new Error('Estimated end block number is less than zero')\n }\n\n // Fetch the estimated end block\n const endBlock = await provider.getBlock(estimatedEndBlockNumber)\n const resolvedEndBlock = assertEx(\n isDefined(endBlock) ? endBlock : undefined,\n () => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`,\n )\n\n const endBlockEpoch = resolvedEndBlock.timestamp\n const actualTimeDifference = startBlockEpoch - endBlockEpoch\n\n // Check if we're within tolerance\n const timeDelta = Math.abs(actualTimeDifference - targetTimeMs)\n if (timeDelta <= toleranceMs) {\n return asEthBlockNumber(resolvedEndBlock.number, true)\n }\n\n // TODO - in order to support older POW days, we might need to shift away from using adjustmentFactor but do a pure binary search\n // Calculate adjustment factor and recursively search\n let adjustedBlocksBack: number\n if (actualTimeDifference < targetTimeMs) {\n // Need to go further back\n const adjustmentFactor = targetTimeMs / actualTimeDifference\n adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor)\n if (adjustedBlocksBack > startBlock.number) {\n adjustedBlocksBack = startBlock.number / 2\n }\n } else {\n // Need to come forward\n const adjustmentFactor = actualTimeDifference / targetTimeMs\n adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor)\n }\n\n return await findEndBlockRecursive(\n provider,\n startBlock,\n targetTimeMs,\n adjustedBlocksBack,\n toleranceMs,\n attemptsRemaining - 1,\n )\n}\n", "import type {\n Address,\n EthAddress,\n} from '@ariestools/sdk'\nimport {\n toAddress,\n toEthAddress,\n} from '@ariestools/sdk'\nimport type { AccountInstance } from '@xyo-network/sdk'\nimport { PayloadBuilder } from '@xyo-network/sdk'\nimport { type HydratedBlockWithHashMeta, XYO_NETWORK_STAKING_ADDRESS } from '@xyo-network/xl1-sdk'\nimport type { Signer } from 'ethers/providers'\n\nimport { createGenesisBlock } from '#protocol'\n\nimport { createChainContract } from './createChainContract.ts'\nimport { createChainRewardsContract } from './createChainRewardsContract.ts'\nimport type { GasConfig } from './ethereum.ts'\nimport { nextContractAddress } from './nextContractAddress.ts'\n\nexport async function createChain(\n signer: Signer,\n stakingTokenAddress: EthAddress | Address,\n initialBlockProducer: AccountInstance,\n rewardsContractAddress: Address | null,\n genesisBlockRewardAmount: bigint,\n genesisBlockRewardAddress: Address,\n minWithdrawalBlocks: bigint,\n maxStakersPerAddress = 10,\n unlimitedStakingAddress = XYO_NETWORK_STAKING_ADDRESS,\n minStake = 10_000n,\n gas?: GasConfig,\n): Promise<[Address, HydratedBlockWithHashMeta, Address]> {\n const ethStakingTokenAddress = toEthAddress(stakingTokenAddress)\n const rewardContractAddressResolved = rewardsContractAddress ?? (await createChainRewardsContract(signer, genesisBlockRewardAmount, gas))\n const contractAddress = await nextContractAddress(signer)\n const genesisBlock = await createGenesisBlock(\n initialBlockProducer,\n contractAddress,\n genesisBlockRewardAmount,\n genesisBlockRewardAddress,\n )\n const chainId = toAddress(await createChainContract(\n signer,\n ethStakingTokenAddress,\n await PayloadBuilder.hash(genesisBlock[0]),\n rewardContractAddressResolved,\n minWithdrawalBlocks,\n maxStakersPerAddress,\n unlimitedStakingAddress,\n minStake,\n gas,\n ))\n return [chainId, genesisBlock, rewardContractAddressResolved]\n}\n", "import type {\n Address, EthAddress, Hash,\n} from '@ariestools/sdk'\nimport {\n asAddress, assertEx,\n ETH_ZERO_ADDRESS, hexToBigInt, toEthAddress,\n} from '@ariestools/sdk'\nimport { StakedXyoChainV2__factory } from '@xyo-network/typechain'\nimport { XYO_NETWORK_STAKING_ADDRESS } from '@xyo-network/xl1-sdk'\nimport type { Signer } from 'ethers/providers'\n\nimport type { GasConfig } from './ethereum.ts'\n\nexport const createChainContract = async (\n signer: Signer,\n stakingTokenAddress: EthAddress,\n genesisBlockHash: Hash,\n rewardsContractAddress: Address,\n minWithdrawalBlocks: bigint,\n maxStakersPerAddress = 10,\n unlimitedStakingAddress = XYO_NETWORK_STAKING_ADDRESS,\n minStake = 10_000n,\n gas: GasConfig = {},\n): Promise<Address> => {\n try {\n const xyoChainFactory = new StakedXyoChainV2__factory(signer)\n const deployResponse = await xyoChainFactory.deploy(\n ETH_ZERO_ADDRESS, // forkFromChainId\n 0n, // forkFromLastBlockNumber\n hexToBigInt(genesisBlockHash), // forkFromLastHash\n toEthAddress(rewardsContractAddress),\n minWithdrawalBlocks, // min withdraw blocks\n toEthAddress(stakingTokenAddress),\n maxStakersPerAddress,\n toEthAddress(unlimitedStakingAddress),\n minStake,\n gas,\n )\n await deployResponse.waitForDeployment()\n const xyoChainContractAddress = await deployResponse.getAddress()\n return assertEx(asAddress(xyoChainContractAddress), () => 'Invalid staking contract address')\n } catch (ex) {\n console.log(ex)\n throw ex\n }\n}\n", "import type { Address } from '@ariestools/sdk'\nimport {\n asAddress, assertEx, toFixedPoint,\n} from '@ariestools/sdk'\nimport { XyoChainRewards__factory as XyoChainRewardsFactory } from '@xyo-network/typechain'\nimport { parseUnits, type Signer } from 'ethers'\n\nimport type { GasConfig } from './ethereum.ts'\n\nconst gasConfig = () => {\n return {\n gasLimit: 2_000_000, // Set the gas limit\n gasPrice: parseUnits('100', 'gwei'),\n }\n}\n\nexport const createChainRewardsContract = async (\n signer: Signer,\n genesisReward = 0n,\n gas: GasConfig = gasConfig(),\n): Promise<Address> => {\n try {\n const xyoChainRewardsFactory = new XyoChainRewardsFactory(signer)\n const deployResponse = await xyoChainRewardsFactory.deploy(\n toFixedPoint(1000n),\n 1_000_000n,\n 95n,\n 100n,\n toFixedPoint(30n),\n genesisReward,\n 18n,\n gas,\n )\n await deployResponse.waitForDeployment()\n const xyoChainRewardsAddress = await deployResponse.getAddress()\n return assertEx(asAddress(xyoChainRewardsAddress), () => 'Invalid rewards contract address')\n } catch (ex) {\n console.log(ex)\n throw ex\n }\n}\n", "import type { Address } from '@ariestools/sdk'\nimport {\n asAddress, assertEx, toEthAddress,\n} from '@ariestools/sdk'\nimport { getCreateAddress } from 'ethers/address'\nimport type { Provider, Signer } from 'ethers/providers'\n\n/**\n * Predicts the next contract address for a contract that will be deployed\n * @param address The address of the deployer\n * @param provider The provider to use\n * @returns The predicted contract address\n */\nexport const nextContractAddressForAddress = async (address: Address, provider: Provider) => {\n // Get the deployer address\n const deployerAddress = toEthAddress(address)\n\n // Get the next nonce for the deployer account\n const nonce = await provider.getTransactionCount(deployerAddress)\n\n // Predict the next deployed contract contract address\n const contractAddress = getCreateAddress({ from: deployerAddress, nonce })\n\n // Return the predicted contract address\n return assertEx(asAddress(contractAddress), () => 'Unable to convert contract address to address')\n}\n\n/**\n * Predicts the next contract address for a contract that will be deployed\n * @param signer The signer to use when deploying the contract\n * @returns The predicted contract address\n */\nexport const nextContractAddress = async (signer: Signer) => {\n const provider = assertEx(signer.provider, () => 'Unable to obtain provider from signer')\n const address = assertEx(asAddress(await signer.getAddress()), () => 'Unable to obtain address from signer')\n return await nextContractAddressForAddress(address, provider)\n}\n", "import { parseUnits } from 'ethers/utils'\n\nexport interface GasConfig {\n gasLimit?: number\n gasPrice?: bigint\n}\n\nexport const getDefaultGasConfig = (): GasConfig => {\n return {\n gasLimit: 2_000_000, // Set the gas limit\n gasPrice: parseUnits('100', 'gwei'),\n }\n}\n", "import type { EthAddress } from '@ariestools/sdk'\nimport {\n assertEx, isDefined, toAddress, toEthAddress,\n} from '@ariestools/sdk'\nimport { IAddressStakingEvents__factory } from '@xyo-network/typechain'\nimport type {\n EvmEventIndexFrame, EvmEventIndexHead, EvmEventIndexLog, EvmEventIndexManifest,\n StakeEvent, StakeEventFilter, StakeEventName, StakeEventsViewer,\n} from '@xyo-network/xl1-sdk'\nimport {\n AbstractCreatableProvider, asAttoXL1, asEvmEventIndexFrame, asEvmEventIndexHead, asEvmEventIndexManifest,\n creatableProvider, evmEventIndexFramePath, evmEventIndexHeadPath, evmEventIndexManifestPath, evmEventIndexTailPath,\n StakeEventsViewerMoniker,\n} from '@xyo-network/xl1-sdk'\nimport { Interface } from 'ethers'\nimport { z } from 'zod'\n\nconst STAKE_EVENT_NAMES = new Set<string>(['StakeAdded', 'StakeRemoved', 'StakeWithdrawn'])\nconst DEFAULT_HEAD_POLL_INTERVAL_MS = 5000\nconst MIN_HEAD_POLL_INTERVAL_MS = 5000\n\n/** Provider-specific settings read from `providerBindings.StakeEventsViewer.options`. */\nexport const RestStakeEventsViewerOptionsZod = z.object({ headPollIntervalMs: z.coerce.number().optional() })\n\ninterface PositionCountCheckpoint {\n count: number\n time: number\n}\n\n/**\n * StakeEventsViewer backed by the finalized contract-event index rather than eth_getLogs.\n * Raw indexed logs remain contract-generic; this viewer applies the staking ABI at the edge.\n * The staking contract address comes from `config.chain.id` and the index bucket URL from\n * the bound `rest` connection's `baseUrl`.\n */\n@creatableProvider()\nexport class RestStakeEventsViewer extends AbstractCreatableProvider implements StakeEventsViewer {\n static readonly connectionTypes = ['rest'] as const\n static readonly defaultMoniker = StakeEventsViewerMoniker\n static readonly dependencies = []\n static readonly monikers = [StakeEventsViewerMoniker]\n static readonly surface = 'node' as const\n moniker = RestStakeEventsViewer.defaultMoniker\n\n private readonly completeFrames = new Map<number, EvmEventIndexFrame>()\n private readonly contractInterface = new Interface(IAddressStakingEvents__factory.abi)\n private currentHead?: EvmEventIndexHead\n private headPollIntervalMs = DEFAULT_HEAD_POLL_INTERVAL_MS\n private lastSuccessfulSyncAt?: number\n private manifestPromise?: Promise<EvmEventIndexManifest>\n private positionCountCheckpoints: PositionCountCheckpoint[] = []\n private stakeEventCache: StakeEvent[] = []\n private readonly stakeEventsByPosition = new Map<number, StakeEvent[]>()\n private syncPromise?: Promise<void>\n private tailFrame?: EvmEventIndexFrame\n\n get address(): EthAddress {\n return toEthAddress(assertEx(this.config.chain.id, () => 'RestStakeEventsViewer requires config.chain.id (the staking contract address)'))\n }\n\n get eventIndexBaseUrl(): string {\n const connection = RestStakeEventsViewer.requireBoundConnection(this.config)\n const baseUrl = assertEx(\n connection.config.type === 'rest' ? connection.config.baseUrl : undefined,\n () => `Connection \"${connection.name}\" bound to RestStakeEventsViewer requires a rest baseUrl`,\n )\n return baseUrl.replace(/\\/+$/, '')\n }\n\n protected get fetchFn(): typeof globalThis.fetch {\n return this.context.fetchFn ?? fetch.bind(globalThis)\n }\n\n /** Creates the provider instance after its configuration has resolved. */\n override async createHandler(): Promise<void> {\n await super.createHandler()\n RestStakeEventsViewer.requireBoundConnection(this.config)\n const { headPollIntervalMs } = RestStakeEventsViewerOptionsZod.parse(this.config.options)\n if (headPollIntervalMs !== undefined) {\n assertEx(headPollIntervalMs >= MIN_HEAD_POLL_INTERVAL_MS, () => `headPollIntervalMs must be at least ${MIN_HEAD_POLL_INTERVAL_MS}ms`)\n }\n this.headPollIntervalMs = headPollIntervalMs ?? DEFAULT_HEAD_POLL_INTERVAL_MS\n }\n\n async positionCount(range: [number, number | 'latest']): Promise<number> {\n await this.sync()\n this.assertRangeAvailable(range)\n if (range[0] === 0) return this.positionCountThrough(range[1])\n const events = this.matchingStakeEvents(range)\n return events.reduce((max, event) => Math.max(max, event.args.id), -1) + 1\n }\n\n async stakeEvents<TName extends StakeEventName>(\n range: [number, number | 'latest'] = [0, 'latest'],\n filter?: StakeEventFilter<TName>,\n ): Promise<StakeEvent<TName>[]> {\n await this.sync()\n this.assertRangeAvailable(range)\n return this.matchingStakeEvents(range, filter)\n }\n\n private assertRangeAvailable(range: [number, number | 'latest']): void {\n const head = assertEx(this.currentHead, () => 'EVM event index head is unavailable')\n assertEx(\n range[1] === 'latest' || range[1] <= head.block,\n () => `Stake-event range ends at ${range[1]}, beyond EVM event index head ${head.block}`,\n )\n }\n\n private decodeIndexedStakeEvents(): StakeEvent[] {\n const frames = [...this.completeFrames.entries()]\n .sort(([a], [b]) => a - b)\n .map(([, frame]) => frame)\n const logs = [...frames, ...(this.tailFrame === undefined ? [] : [this.tailFrame])]\n .flatMap(frame => frame.logs)\n .sort((a, b) => a.blockNumber - b.blockNumber || a.transactionIndex - b.transactionIndex || a.index - b.index)\n return logs.flatMap((log) => {\n const event = this.stakeEventFromLog(log)\n return event === undefined ? [] : [event]\n })\n }\n\n private async fetchJson(path: string): Promise<unknown> {\n const response = await this.fetchFn(`${this.eventIndexBaseUrl}/${path}`)\n assertEx(response.ok, () => `EVM event index request failed [${response.status}] for ${path}`)\n return await response.json()\n }\n\n private async getManifest(): Promise<EvmEventIndexManifest> {\n this.manifestPromise ??= (async () => {\n const manifest = asEvmEventIndexManifest(await this.fetchJson(evmEventIndexManifestPath(this.address)), true)\n assertEx(manifest.address.toLowerCase() === this.address.toLowerCase(), () => 'EVM event index manifest address mismatch')\n return manifest\n })()\n return await this.manifestPromise\n }\n\n private indexStakeEvents(events: StakeEvent[]): void {\n this.stakeEventCache = events\n this.positionCountCheckpoints = []\n this.stakeEventsByPosition.clear()\n let maxPositionId = -1\n for (const event of events) {\n const positionEvents = this.stakeEventsByPosition.get(event.args.id) ?? []\n positionEvents.push(event)\n this.stakeEventsByPosition.set(event.args.id, positionEvents)\n if (event.args.id > maxPositionId) {\n maxPositionId = event.args.id\n this.positionCountCheckpoints.push({ count: maxPositionId + 1, time: event.time })\n }\n }\n }\n\n // eslint-disable-next-line complexity\n private matchesFilter<TName extends StakeEventName>(\n event: StakeEvent,\n range: [number, number | 'latest'],\n filter?: StakeEventFilter<TName>,\n ): boolean {\n if (range[1] !== 'latest' && event.time > range[1]) return false\n if (event.time < range[0]) return false\n if (isDefined(filter?.name) && event.name !== filter.name) return false\n if (isDefined(filter?.args?.id) && event.args.id !== filter.args.id) return false\n if (isDefined(filter?.args?.staked) && event.args.staked !== filter.args.staked) return false\n if (isDefined(filter?.args?.staker) && event.args.staker !== filter.args.staker) return false\n return true\n }\n\n private matchingStakeEvents<TName extends StakeEventName>(\n range: [number, number | 'latest'],\n filter?: StakeEventFilter<TName>,\n ): StakeEvent<TName>[] {\n const positionId = filter?.args?.id\n const candidates = isDefined(positionId)\n ? this.stakeEventsByPosition.get(positionId) ?? []\n : this.stakeEventCache\n return candidates.filter(event => this.matchesFilter(event, range, filter)) as StakeEvent<TName>[]\n }\n\n private positionCountThrough(end: number | 'latest'): number {\n if (end === 'latest') return this.positionCountCheckpoints.at(-1)?.count ?? 0\n let low = 0\n let high = this.positionCountCheckpoints.length\n while (low < high) {\n const middle = Math.floor((low + high) / 2)\n if (this.positionCountCheckpoints[middle].time <= end) {\n low = middle + 1\n } else {\n high = middle\n }\n }\n return this.positionCountCheckpoints[low - 1]?.count ?? 0\n }\n\n private stakeEventFromLog(log: EvmEventIndexLog): StakeEvent | undefined {\n const parsed = this.contractInterface.parseLog({ data: log.data, topics: log.topics })\n if (parsed === null || !STAKE_EVENT_NAMES.has(parsed.name)) return\n const [staked, staker, id, amount] = parsed.args\n return {\n name: parsed.name as StakeEventName,\n args: {\n amount: asAttoXL1(amount as bigint),\n id: Number(id),\n staked: toAddress(staked as string),\n staker: toAddress(staker as string),\n },\n time: log.blockNumber,\n }\n }\n\n private async sync(): Promise<void> {\n const now = Date.now()\n const elapsed = this.lastSuccessfulSyncAt === undefined ? undefined : now - this.lastSuccessfulSyncAt\n if (this.currentHead !== undefined && elapsed !== undefined && elapsed >= 0 && elapsed < this.headPollIntervalMs) return\n this.syncPromise ??= this.syncFromHead()\n .then(() => {\n this.lastSuccessfulSyncAt = Date.now()\n })\n .finally(() => {\n this.syncPromise = undefined\n })\n await this.syncPromise\n }\n\n private async syncFromHead(): Promise<void> {\n const manifest = await this.getManifest()\n const head = asEvmEventIndexHead(await this.fetchJson(evmEventIndexHeadPath(this.address)), true)\n assertEx(head.address.toLowerCase() === this.address.toLowerCase(), () => 'EVM event index head address mismatch')\n assertEx(head.chainId === manifest.chainId, () => 'EVM event index chain mismatch')\n if (this.currentHead?.block === head.block && this.currentHead.hash === head.hash) return\n\n if (this.currentHead !== undefined && (head.block < this.currentHead.block || (head.block === this.currentHead.block && head.hash !== this.currentHead.hash))) {\n this.completeFrames.clear()\n this.tailFrame = undefined\n }\n\n const indexedBlockCount = Math.max(0, head.block - manifest.deploymentBlock + 1)\n const completeFrameCount = Math.floor(indexedBlockCount / manifest.frameSize)\n const missingFrameIndexes = Array.from({ length: completeFrameCount }, (_, index) => index)\n .filter(index => !this.completeFrames.has(index))\n await Promise.all(missingFrameIndexes.map(async (index) => {\n const frame = asEvmEventIndexFrame(await this.fetchJson(evmEventIndexFramePath(this.address, index)), true)\n const expectedFrom = manifest.deploymentBlock + index * manifest.frameSize\n assertEx(frame.fromBlock === expectedFrom, () => `EVM event index frame ${index} starts at the wrong block`)\n assertEx(frame.toBlock === expectedFrom + manifest.frameSize - 1, () => `EVM event index frame ${index} is incomplete`)\n this.completeFrames.set(index, frame)\n }))\n\n const tailStart = manifest.deploymentBlock + completeFrameCount * manifest.frameSize\n this.tailFrame = tailStart <= head.block\n ? asEvmEventIndexFrame(await this.fetchJson(`${evmEventIndexTailPath(this.address)}?head=${head.hash}`), true)\n : undefined\n if (this.tailFrame !== undefined) {\n assertEx(this.tailFrame.fromBlock === tailStart, () => 'EVM event index tail starts at the wrong block')\n assertEx(this.tailFrame.toBlock === head.block, () => 'EVM event index tail is stale relative to its head')\n }\n this.indexStakeEvents(this.decodeIndexedStakeEvents())\n this.currentHead = head\n }\n}\n", "import type { Address } from '@ariestools/sdk'\nimport { assertEx, toAddress } from '@ariestools/sdk'\nimport type {\n ChainContractViewer, Position, PositionId, StakeEvent, StakeEventsViewer, StakeViewer,\n} from '@xyo-network/xl1-sdk'\nimport {\n AbstractCreatableProvider, ChainContractViewerMoniker, creatableProvider, StakeEventsViewerMoniker, StakeViewerMoniker,\n} from '@xyo-network/xl1-sdk'\nimport { z } from 'zod'\n\nconst DEFAULT_REFRESH_INTERVAL_MS = 5000\nconst MIN_REFRESH_INTERVAL_MS = 5000\n\n/** Provider-specific settings read from `providerBindings.StakeViewer.options`. */\nexport const RestStakeViewerOptionsZod = z.object({ refreshIntervalMs: z.coerce.number().optional() })\n\n/**\n * StakeViewer materialized from the finalized REST event index.\n *\n * The indexer remains the only process that tails the EVM contract. Consumers\n * rebuild their local position view from immutable indexed events after the\n * configured refresh interval, so API replicas never attach EVM log listeners.\n */\n@creatableProvider()\nexport class RestStakeViewer extends AbstractCreatableProvider implements StakeViewer {\n static readonly connectionTypes = ['rest'] as const\n static readonly defaultMoniker = StakeViewerMoniker\n static readonly dependencies = [ChainContractViewerMoniker, StakeEventsViewerMoniker]\n static readonly monikers = [StakeViewerMoniker]\n static readonly surface = 'node' as const\n readonly moniker = RestStakeViewer.defaultMoniker\n\n private _chainContractViewer!: ChainContractViewer\n private _stakeEventsViewer!: StakeEventsViewer\n private lastSuccessfulSyncAt?: number\n private positionIndex = new Map<number, Position>()\n private positionsByStaked = new Map<Address, Position[]>()\n private positionsByStaker = new Map<Address, Position[]>()\n private refreshIntervalMs = DEFAULT_REFRESH_INTERVAL_MS\n private syncPromise?: Promise<void>\n\n /** Returns the finalized stake-event source used to materialize positions. */\n get stakeEvents(): StakeEventsViewer {\n return this._stakeEventsViewer\n }\n\n /** Returns active finalized stake positions. */\n async activeStakes(): Promise<Position[]> {\n await this.sync()\n return this.positionIndex.values().filter(position => position.removeBlock === 0 && position.withdrawBlock === 0).toArray()\n }\n\n /** Creates the provider after its REST binding and dependencies resolve. */\n override async createHandler(): Promise<void> {\n await super.createHandler()\n RestStakeViewer.requireBoundConnection(this.config)\n const { refreshIntervalMs } = RestStakeViewerOptionsZod.parse(this.config.options)\n if (refreshIntervalMs !== undefined) {\n assertEx(refreshIntervalMs >= MIN_REFRESH_INTERVAL_MS, () => `refreshIntervalMs must be at least ${MIN_REFRESH_INTERVAL_MS}ms`)\n }\n this.refreshIntervalMs = refreshIntervalMs ?? DEFAULT_REFRESH_INTERVAL_MS\n this._chainContractViewer = await this.locator.getInstance<ChainContractViewer>(ChainContractViewerMoniker)\n this._stakeEventsViewer = await this.locator.getInstance<StakeEventsViewer>(StakeEventsViewerMoniker)\n }\n\n /** Returns the configured chain's withdrawal delay. */\n async minWithdrawalBlocks(): Promise<number> {\n return await this._chainContractViewer.minWithdrawalBlocks()\n }\n\n /** Returns finalized positions that have been removed but not withdrawn. */\n async removedStakes(): Promise<Position[]> {\n await this.sync()\n return this.positionIndex.values().filter(position => position.removeBlock !== 0 && position.withdrawBlock === 0).toArray()\n }\n\n /** Returns the configured rewards contract address. */\n async rewardsContract(): Promise<Address> {\n return toAddress(await this._chainContractViewer.rewardsContract())\n }\n\n /** Returns a finalized position by its contract id. */\n async stakeById(id: number): Promise<Position> {\n await this.sync()\n return assertEx(this.positionIndex.get(id), () => `RestStakeViewer: position ${id} not found in finalized event index`)\n }\n\n /** Returns a staker's finalized position by its contract slot. */\n async stakeByStaker(staker: Address, slot: number): Promise<Position> {\n await this.sync()\n const position = this.positionsByStaker.get(toAddress(staker))?.at(slot)\n return assertEx(position, () => `RestStakeViewer: staker ${staker} has no finalized position at slot ${slot}`)\n }\n\n /** Returns finalized positions added for an address in the supplied EVM block range. */\n async stakesByStaked(staked: Address, range: [number, number | undefined] = [0, undefined]): Promise<Position[]> {\n await this.sync()\n return this.positionsInRange(this.positionsByStaked.get(toAddress(staked)) ?? [], range)\n }\n\n /** Returns finalized positions added by a staker in the supplied EVM block range. */\n async stakesByStaker(staker: Address, range: [number, number | undefined] = [0, undefined]): Promise<Position[]> {\n await this.sync()\n return this.positionsInRange(this.positionsByStaker.get(toAddress(staker)) ?? [], range)\n }\n\n /** Returns the configured staking-token address. */\n async stakingTokenAddress(): Promise<Address> {\n return toAddress(await this._chainContractViewer.stakingTokenAddress())\n }\n\n /** Returns finalized positions that have completed withdrawal. */\n async withdrawnStakes(): Promise<Position[]> {\n await this.sync()\n return this.positionIndex.values().filter(position => position.removeBlock !== 0 && position.withdrawBlock !== 0).toArray()\n }\n\n private applyEvent(index: Map<number, Position>, event: StakeEvent): void {\n if (event.name === 'StakeAdded') {\n index.set(event.args.id, {\n id: event.args.id as PositionId,\n staked: toAddress(event.args.staked),\n staker: toAddress(event.args.staker),\n amount: event.args.amount,\n addBlock: event.time,\n removeBlock: 0,\n withdrawBlock: 0,\n })\n return\n }\n const position = assertEx(index.get(event.args.id), () => `RestStakeViewer: ${event.name} precedes StakeAdded for position ${event.args.id}`)\n index.set(event.args.id, {\n ...position,\n ...(event.name === 'StakeRemoved' ? { removeBlock: event.time } : { withdrawBlock: event.time }),\n })\n }\n\n private positionsInRange(positions: Position[], range: [number, number | undefined]): Position[] {\n const [fromBlock, configuredToBlock] = range\n const toBlock = configuredToBlock ?? Number.MAX_SAFE_INTEGER\n return positions.filter(position => position.addBlock >= fromBlock && position.addBlock <= toBlock)\n }\n\n private rebuildPositionIndex(events: StakeEvent[]): void {\n const positionIndex = new Map<number, Position>()\n for (const event of events.toSorted((left, right) => left.time - right.time)) {\n this.applyEvent(positionIndex, event)\n }\n\n const positionsByStaked = new Map<Address, Position[]>()\n const positionsByStaker = new Map<Address, Position[]>()\n for (const position of positionIndex.values().toArray().toSorted((left, right) => left.id - right.id)) {\n const staked = toAddress(position.staked)\n const staker = toAddress(position.staker)\n positionsByStaked.set(staked, [...positionsByStaked.get(staked) ?? [], position])\n positionsByStaker.set(staker, [...positionsByStaker.get(staker) ?? [], position])\n }\n\n this.positionIndex = positionIndex\n this.positionsByStaked = positionsByStaked\n this.positionsByStaker = positionsByStaker\n }\n\n private async sync(): Promise<void> {\n const now = Date.now()\n const elapsed = this.lastSuccessfulSyncAt === undefined ? undefined : now - this.lastSuccessfulSyncAt\n if (elapsed !== undefined && elapsed >= 0 && elapsed < this.refreshIntervalMs) return\n this.syncPromise ??= Promise.resolve(this.stakeEvents.stakeEvents([0, 'latest']))\n .then(events => this.rebuildPositionIndex(events))\n .then(() => {\n this.lastSuccessfulSyncAt = Date.now()\n })\n .finally(() => {\n this.syncPromise = undefined\n })\n await this.syncPromise\n }\n}\n", "import { assertEx } from '@ariestools/sdk'\nimport type { CreatableProviderParams } from '@xyo-network/xl1-sdk'\nimport { AbstractEvmProvider } from '@xyo-network/xl1-sdk'\nimport type { BaseContract, ContractRunner } from 'ethers'\n\n/** Shared-handle key for a moniker's seeded EVM contract runner (ethers signer/wallet). */\nexport function evmContractRunnerHandleKey(moniker: string): string {\n return `evm-contract-runner:${moniker}`\n}\n\n/**\n * Base for EVM mutation providers. The contract runner (an ethers signer/wallet) is a\n * thick runtime object with no config representation \u2014 hosts seed it in\n * `context.connectionHandles` under `evmContractRunnerHandleKey(moniker)` before create.\n */\nexport abstract class AbstractEvmRunner<TContract extends BaseContract = BaseContract,\n TParams extends CreatableProviderParams = CreatableProviderParams> extends\n AbstractEvmProvider<TParams, TContract> {\n private _runner?: ContractRunner\n\n protected get runner(): ContractRunner {\n return assertEx(this._runner, () => 'EVM contract runner not initialized')\n }\n\n /** Creates the provider instance after its dependencies and configuration have resolved. */\n override async createHandler() {\n const key = evmContractRunnerHandleKey(this.moniker)\n this._runner = await this.connectionHandles.getOrOpen<ContractRunner>(key, () => {\n throw new Error(`No EVM contract runner seeded for [${this.moniker}] \u2014 set context.connectionHandles[\"${key}\"] before create`)\n })\n await super.createHandler()\n }\n}\n", "import type { Address, EthAddress } from '@ariestools/sdk'\nimport { toEthAddress } from '@ariestools/sdk'\nimport type { IStakedXyoChain } from '@xyo-network/typechain'\nimport { IStakedXyoChain__factory } from '@xyo-network/typechain'\nimport type { StakeRunner } from '@xyo-network/xl1-sdk'\nimport {\n creatableProvider,\n StakeRunnerMoniker,\n} from '@xyo-network/xl1-sdk'\nimport { getAddress } from 'ethers/address'\n\nimport { AbstractEvmRunner } from './AbstractEvmRunner.ts'\n\n@creatableProvider()\nexport class EvmStakeRunner extends AbstractEvmRunner<IStakedXyoChain> implements StakeRunner {\n static readonly connectionTypes = ['evm-rpc'] as const\n static readonly defaultMoniker = StakeRunnerMoniker\n static readonly dependencies = []\n static readonly monikers = [StakeRunnerMoniker]\n static readonly surface = 'node' as const\n override moniker = EvmStakeRunner.defaultMoniker\n\n async addStake(staked: Address, amount: bigint): Promise<boolean> {\n const result = await (this.contract).addStake(getAddress(toEthAddress(staked)), amount)\n await result.wait()\n return true\n }\n\n async removeStake(slot: bigint): Promise<boolean> {\n const result = await (this.contract).removeStake(slot)\n await result.wait()\n return true\n }\n\n async withdrawStake(slot: bigint): Promise<boolean> {\n const result = await (this.contract).withdrawStake(slot)\n await result.wait()\n return true\n }\n\n protected override connectContract(address: EthAddress) {\n return IStakedXyoChain__factory.connect(address, this.runner)\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["isDefined", "asEthBlockRange", "asEthBlockRange", "isDefined", "toEthAddress", "XYO_NETWORK_STAKING_ADDRESS", "assertEx", "asAddress", "assertEx", "asAddress", "assertEx", "toEthAddress", "XYO_NETWORK_STAKING_ADDRESS", "toEthAddress", "parseUnits", "assertEx", "isDefined", "toAddress", "toEthAddress", "toEthAddress", "assertEx", "isDefined", "toAddress", "assertEx", "toAddress", "AbstractCreatableProvider", "creatableProvider", "StakeEventsViewerMoniker", "z", "z", "AbstractCreatableProvider", "assertEx", "StakeEventsViewerMoniker", "toAddress", "creatableProvider", "assertEx", "toEthAddress", "creatableProvider", "toEthAddress", "creatableProvider"]
|
|
7
7
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { EthAddress } from '@ariestools/sdk';
|
|
2
2
|
import type { StakeEvent, StakeEventFilter, StakeEventName, StakeEventsViewer } from '@xyo-network/xl1-sdk';
|
|
3
3
|
import { AbstractCreatableProvider } from '@xyo-network/xl1-sdk';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/** Provider-specific settings read from `providerBindings.StakeEventsViewer.options`. */
|
|
6
|
+
export declare const RestStakeEventsViewerOptionsZod: z.ZodObject<{
|
|
7
|
+
headPollIntervalMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
4
9
|
/**
|
|
5
10
|
* StakeEventsViewer backed by the finalized contract-event index rather than eth_getLogs.
|
|
6
11
|
* Raw indexed logs remain contract-generic; this viewer applies the staking ABI at the edge.
|
|
@@ -17,19 +22,29 @@ export declare class RestStakeEventsViewer extends AbstractCreatableProvider imp
|
|
|
17
22
|
private readonly completeFrames;
|
|
18
23
|
private readonly contractInterface;
|
|
19
24
|
private currentHead?;
|
|
25
|
+
private headPollIntervalMs;
|
|
26
|
+
private lastSuccessfulSyncAt?;
|
|
20
27
|
private manifestPromise?;
|
|
28
|
+
private positionCountCheckpoints;
|
|
21
29
|
private stakeEventCache;
|
|
30
|
+
private readonly stakeEventsByPosition;
|
|
22
31
|
private syncPromise?;
|
|
23
32
|
private tailFrame?;
|
|
24
33
|
get address(): EthAddress;
|
|
25
34
|
get eventIndexBaseUrl(): string;
|
|
26
35
|
protected get fetchFn(): typeof globalThis.fetch;
|
|
36
|
+
/** Creates the provider instance after its configuration has resolved. */
|
|
37
|
+
createHandler(): Promise<void>;
|
|
27
38
|
positionCount(range: [number, number | 'latest']): Promise<number>;
|
|
28
39
|
stakeEvents<TName extends StakeEventName>(range?: [number, number | 'latest'], filter?: StakeEventFilter<TName>): Promise<StakeEvent<TName>[]>;
|
|
40
|
+
private assertRangeAvailable;
|
|
29
41
|
private decodeIndexedStakeEvents;
|
|
30
42
|
private fetchJson;
|
|
31
43
|
private getManifest;
|
|
44
|
+
private indexStakeEvents;
|
|
32
45
|
private matchesFilter;
|
|
46
|
+
private matchingStakeEvents;
|
|
47
|
+
private positionCountThrough;
|
|
33
48
|
private stakeEventFromLog;
|
|
34
49
|
private sync;
|
|
35
50
|
private syncFromHead;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RestStakeEventsViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeEventsViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAKjD,OAAO,KAAK,EAEV,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAChE,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAG1B,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"RestStakeEventsViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeEventsViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAKjD,OAAO,KAAK,EAEV,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAChE,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAG1B,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,yFAAyF;AACzF,eAAO,MAAM,+BAA+B;;iBAAiE,CAAA;AAO7G;;;;;GAKG;AACH,qBACa,qBAAsB,SAAQ,yBAA0B,YAAW,iBAAiB;IAC/F,MAAM,CAAC,QAAQ,CAAC,eAAe,oBAAoB;IACnD,MAAM,CAAC,QAAQ,CAAC,cAAc,sBAA2B;IACzD,MAAM,CAAC,QAAQ,CAAC,YAAY,UAAK;IACjC,MAAM,CAAC,QAAQ,CAAC,QAAQ,wBAA6B;IACrD,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAG,MAAM,CAAS;IACzC,OAAO,sBAAuC;IAE9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoD;IACtF,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,kBAAkB,CAAgC;IAC1D,OAAO,CAAC,oBAAoB,CAAC,CAAQ;IACrC,OAAO,CAAC,eAAe,CAAC,CAAgC;IACxD,OAAO,CAAC,wBAAwB,CAAgC;IAChE,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAkC;IACxE,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,SAAS,CAAC,CAAoB;IAEtC,IAAI,OAAO,IAAI,UAAU,CAExB;IAED,IAAI,iBAAiB,IAAI,MAAM,CAO9B;IAED,SAAS,KAAK,OAAO,IAAI,OAAO,UAAU,CAAC,KAAK,CAE/C;IAED,0EAA0E;IAC3D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAUvC,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAQlE,WAAW,CAAC,KAAK,SAAS,cAAc,EAC5C,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAiB,EAClD,MAAM,CAAC,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAC/B,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;IAM/B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,wBAAwB;YAalB,SAAS;YAMT,WAAW;IASzB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,iBAAiB;YAgBX,IAAI;YAcJ,YAAY;CAmC3B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Address } from '@ariestools/sdk';
|
|
2
|
+
import type { Position, StakeEventsViewer, StakeViewer } from '@xyo-network/xl1-sdk';
|
|
3
|
+
import { AbstractCreatableProvider } from '@xyo-network/xl1-sdk';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/** Provider-specific settings read from `providerBindings.StakeViewer.options`. */
|
|
6
|
+
export declare const RestStakeViewerOptionsZod: z.ZodObject<{
|
|
7
|
+
refreshIntervalMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
/**
|
|
10
|
+
* StakeViewer materialized from the finalized REST event index.
|
|
11
|
+
*
|
|
12
|
+
* The indexer remains the only process that tails the EVM contract. Consumers
|
|
13
|
+
* rebuild their local position view from immutable indexed events after the
|
|
14
|
+
* configured refresh interval, so API replicas never attach EVM log listeners.
|
|
15
|
+
*/
|
|
16
|
+
export declare class RestStakeViewer extends AbstractCreatableProvider implements StakeViewer {
|
|
17
|
+
static readonly connectionTypes: readonly ["rest"];
|
|
18
|
+
static readonly defaultMoniker: "StakeViewer";
|
|
19
|
+
static readonly dependencies: ("StakeEventsViewer" | "ChainContractViewer")[];
|
|
20
|
+
static readonly monikers: "StakeViewer"[];
|
|
21
|
+
static readonly surface: "node";
|
|
22
|
+
readonly moniker: "StakeViewer";
|
|
23
|
+
private _chainContractViewer;
|
|
24
|
+
private _stakeEventsViewer;
|
|
25
|
+
private lastSuccessfulSyncAt?;
|
|
26
|
+
private positionIndex;
|
|
27
|
+
private positionsByStaked;
|
|
28
|
+
private positionsByStaker;
|
|
29
|
+
private refreshIntervalMs;
|
|
30
|
+
private syncPromise?;
|
|
31
|
+
/** Returns the finalized stake-event source used to materialize positions. */
|
|
32
|
+
get stakeEvents(): StakeEventsViewer;
|
|
33
|
+
/** Returns active finalized stake positions. */
|
|
34
|
+
activeStakes(): Promise<Position[]>;
|
|
35
|
+
/** Creates the provider after its REST binding and dependencies resolve. */
|
|
36
|
+
createHandler(): Promise<void>;
|
|
37
|
+
/** Returns the configured chain's withdrawal delay. */
|
|
38
|
+
minWithdrawalBlocks(): Promise<number>;
|
|
39
|
+
/** Returns finalized positions that have been removed but not withdrawn. */
|
|
40
|
+
removedStakes(): Promise<Position[]>;
|
|
41
|
+
/** Returns the configured rewards contract address. */
|
|
42
|
+
rewardsContract(): Promise<Address>;
|
|
43
|
+
/** Returns a finalized position by its contract id. */
|
|
44
|
+
stakeById(id: number): Promise<Position>;
|
|
45
|
+
/** Returns a staker's finalized position by its contract slot. */
|
|
46
|
+
stakeByStaker(staker: Address, slot: number): Promise<Position>;
|
|
47
|
+
/** Returns finalized positions added for an address in the supplied EVM block range. */
|
|
48
|
+
stakesByStaked(staked: Address, range?: [number, number | undefined]): Promise<Position[]>;
|
|
49
|
+
/** Returns finalized positions added by a staker in the supplied EVM block range. */
|
|
50
|
+
stakesByStaker(staker: Address, range?: [number, number | undefined]): Promise<Position[]>;
|
|
51
|
+
/** Returns the configured staking-token address. */
|
|
52
|
+
stakingTokenAddress(): Promise<Address>;
|
|
53
|
+
/** Returns finalized positions that have completed withdrawal. */
|
|
54
|
+
withdrawnStakes(): Promise<Position[]>;
|
|
55
|
+
private applyEvent;
|
|
56
|
+
private positionsInRange;
|
|
57
|
+
private rebuildPositionIndex;
|
|
58
|
+
private sync;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=RestStakeViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RestStakeViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,KAAK,EACW,QAAQ,EAA0B,iBAAiB,EAAE,WAAW,EACtF,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAC1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,mFAAmF;AACnF,eAAO,MAAM,yBAAyB;;iBAAgE,CAAA;AAEtG;;;;;;GAMG;AACH,qBACa,eAAgB,SAAQ,yBAA0B,YAAW,WAAW;IACnF,MAAM,CAAC,QAAQ,CAAC,eAAe,oBAAoB;IACnD,MAAM,CAAC,QAAQ,CAAC,cAAc,gBAAqB;IACnD,MAAM,CAAC,QAAQ,CAAC,YAAY,kDAAyD;IACrF,MAAM,CAAC,QAAQ,CAAC,QAAQ,kBAAuB;IAC/C,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAG,MAAM,CAAS;IACzC,QAAQ,CAAC,OAAO,gBAAiC;IAEjD,OAAO,CAAC,oBAAoB,CAAsB;IAClD,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,oBAAoB,CAAC,CAAQ;IACrC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,WAAW,CAAC,CAAe;IAEnC,8EAA8E;IAC9E,IAAI,WAAW,IAAI,iBAAiB,CAEnC;IAED,gDAAgD;IAC1C,YAAY,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKzC,4EAA4E;IAC7D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7C,uDAAuD;IACjD,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5C,4EAA4E;IACtE,aAAa,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAK1C,uDAAuD;IACjD,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzC,uDAAuD;IACjD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAK9C,kEAAkE;IAC5D,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAMrE,wFAAwF;IAClF,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAkB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKhH,qFAAqF;IAC/E,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAkB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKhH,oDAAoD;IAC9C,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7C,kEAAkE;IAC5D,eAAe,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAK5C,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,oBAAoB;YAoBd,IAAI;CAcnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,sBAAsB,CAAA"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { EthAddress } from '@ariestools/sdk';
|
|
2
2
|
import type { StakeEvent, StakeEventFilter, StakeEventName, StakeEventsViewer } from '@xyo-network/xl1-sdk';
|
|
3
3
|
import { AbstractCreatableProvider } from '@xyo-network/xl1-sdk';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/** Provider-specific settings read from `providerBindings.StakeEventsViewer.options`. */
|
|
6
|
+
export declare const RestStakeEventsViewerOptionsZod: z.ZodObject<{
|
|
7
|
+
headPollIntervalMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
4
9
|
/**
|
|
5
10
|
* StakeEventsViewer backed by the finalized contract-event index rather than eth_getLogs.
|
|
6
11
|
* Raw indexed logs remain contract-generic; this viewer applies the staking ABI at the edge.
|
|
@@ -17,19 +22,29 @@ export declare class RestStakeEventsViewer extends AbstractCreatableProvider imp
|
|
|
17
22
|
private readonly completeFrames;
|
|
18
23
|
private readonly contractInterface;
|
|
19
24
|
private currentHead?;
|
|
25
|
+
private headPollIntervalMs;
|
|
26
|
+
private lastSuccessfulSyncAt?;
|
|
20
27
|
private manifestPromise?;
|
|
28
|
+
private positionCountCheckpoints;
|
|
21
29
|
private stakeEventCache;
|
|
30
|
+
private readonly stakeEventsByPosition;
|
|
22
31
|
private syncPromise?;
|
|
23
32
|
private tailFrame?;
|
|
24
33
|
get address(): EthAddress;
|
|
25
34
|
get eventIndexBaseUrl(): string;
|
|
26
35
|
protected get fetchFn(): typeof globalThis.fetch;
|
|
36
|
+
/** Creates the provider instance after its configuration has resolved. */
|
|
37
|
+
createHandler(): Promise<void>;
|
|
27
38
|
positionCount(range: [number, number | 'latest']): Promise<number>;
|
|
28
39
|
stakeEvents<TName extends StakeEventName>(range?: [number, number | 'latest'], filter?: StakeEventFilter<TName>): Promise<StakeEvent<TName>[]>;
|
|
40
|
+
private assertRangeAvailable;
|
|
29
41
|
private decodeIndexedStakeEvents;
|
|
30
42
|
private fetchJson;
|
|
31
43
|
private getManifest;
|
|
44
|
+
private indexStakeEvents;
|
|
32
45
|
private matchesFilter;
|
|
46
|
+
private matchingStakeEvents;
|
|
47
|
+
private positionCountThrough;
|
|
33
48
|
private stakeEventFromLog;
|
|
34
49
|
private sync;
|
|
35
50
|
private syncFromHead;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RestStakeEventsViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeEventsViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAKjD,OAAO,KAAK,EAEV,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAChE,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAG1B,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"RestStakeEventsViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeEventsViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAKjD,OAAO,KAAK,EAEV,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAChE,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAG1B,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,yFAAyF;AACzF,eAAO,MAAM,+BAA+B;;iBAAiE,CAAA;AAO7G;;;;;GAKG;AACH,qBACa,qBAAsB,SAAQ,yBAA0B,YAAW,iBAAiB;IAC/F,MAAM,CAAC,QAAQ,CAAC,eAAe,oBAAoB;IACnD,MAAM,CAAC,QAAQ,CAAC,cAAc,sBAA2B;IACzD,MAAM,CAAC,QAAQ,CAAC,YAAY,UAAK;IACjC,MAAM,CAAC,QAAQ,CAAC,QAAQ,wBAA6B;IACrD,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAG,MAAM,CAAS;IACzC,OAAO,sBAAuC;IAE9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoD;IACtF,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,kBAAkB,CAAgC;IAC1D,OAAO,CAAC,oBAAoB,CAAC,CAAQ;IACrC,OAAO,CAAC,eAAe,CAAC,CAAgC;IACxD,OAAO,CAAC,wBAAwB,CAAgC;IAChE,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAkC;IACxE,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,SAAS,CAAC,CAAoB;IAEtC,IAAI,OAAO,IAAI,UAAU,CAExB;IAED,IAAI,iBAAiB,IAAI,MAAM,CAO9B;IAED,SAAS,KAAK,OAAO,IAAI,OAAO,UAAU,CAAC,KAAK,CAE/C;IAED,0EAA0E;IAC3D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAUvC,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAQlE,WAAW,CAAC,KAAK,SAAS,cAAc,EAC5C,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAiB,EAClD,MAAM,CAAC,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAC/B,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;IAM/B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,wBAAwB;YAalB,SAAS;YAMT,WAAW;IASzB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,iBAAiB;YAgBX,IAAI;YAcJ,YAAY;CAmC3B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Address } from '@ariestools/sdk';
|
|
2
|
+
import type { Position, StakeEventsViewer, StakeViewer } from '@xyo-network/xl1-sdk';
|
|
3
|
+
import { AbstractCreatableProvider } from '@xyo-network/xl1-sdk';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/** Provider-specific settings read from `providerBindings.StakeViewer.options`. */
|
|
6
|
+
export declare const RestStakeViewerOptionsZod: z.ZodObject<{
|
|
7
|
+
refreshIntervalMs: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
/**
|
|
10
|
+
* StakeViewer materialized from the finalized REST event index.
|
|
11
|
+
*
|
|
12
|
+
* The indexer remains the only process that tails the EVM contract. Consumers
|
|
13
|
+
* rebuild their local position view from immutable indexed events after the
|
|
14
|
+
* configured refresh interval, so API replicas never attach EVM log listeners.
|
|
15
|
+
*/
|
|
16
|
+
export declare class RestStakeViewer extends AbstractCreatableProvider implements StakeViewer {
|
|
17
|
+
static readonly connectionTypes: readonly ["rest"];
|
|
18
|
+
static readonly defaultMoniker: "StakeViewer";
|
|
19
|
+
static readonly dependencies: ("StakeEventsViewer" | "ChainContractViewer")[];
|
|
20
|
+
static readonly monikers: "StakeViewer"[];
|
|
21
|
+
static readonly surface: "node";
|
|
22
|
+
readonly moniker: "StakeViewer";
|
|
23
|
+
private _chainContractViewer;
|
|
24
|
+
private _stakeEventsViewer;
|
|
25
|
+
private lastSuccessfulSyncAt?;
|
|
26
|
+
private positionIndex;
|
|
27
|
+
private positionsByStaked;
|
|
28
|
+
private positionsByStaker;
|
|
29
|
+
private refreshIntervalMs;
|
|
30
|
+
private syncPromise?;
|
|
31
|
+
/** Returns the finalized stake-event source used to materialize positions. */
|
|
32
|
+
get stakeEvents(): StakeEventsViewer;
|
|
33
|
+
/** Returns active finalized stake positions. */
|
|
34
|
+
activeStakes(): Promise<Position[]>;
|
|
35
|
+
/** Creates the provider after its REST binding and dependencies resolve. */
|
|
36
|
+
createHandler(): Promise<void>;
|
|
37
|
+
/** Returns the configured chain's withdrawal delay. */
|
|
38
|
+
minWithdrawalBlocks(): Promise<number>;
|
|
39
|
+
/** Returns finalized positions that have been removed but not withdrawn. */
|
|
40
|
+
removedStakes(): Promise<Position[]>;
|
|
41
|
+
/** Returns the configured rewards contract address. */
|
|
42
|
+
rewardsContract(): Promise<Address>;
|
|
43
|
+
/** Returns a finalized position by its contract id. */
|
|
44
|
+
stakeById(id: number): Promise<Position>;
|
|
45
|
+
/** Returns a staker's finalized position by its contract slot. */
|
|
46
|
+
stakeByStaker(staker: Address, slot: number): Promise<Position>;
|
|
47
|
+
/** Returns finalized positions added for an address in the supplied EVM block range. */
|
|
48
|
+
stakesByStaked(staked: Address, range?: [number, number | undefined]): Promise<Position[]>;
|
|
49
|
+
/** Returns finalized positions added by a staker in the supplied EVM block range. */
|
|
50
|
+
stakesByStaker(staker: Address, range?: [number, number | undefined]): Promise<Position[]>;
|
|
51
|
+
/** Returns the configured staking-token address. */
|
|
52
|
+
stakingTokenAddress(): Promise<Address>;
|
|
53
|
+
/** Returns finalized positions that have completed withdrawal. */
|
|
54
|
+
withdrawnStakes(): Promise<Position[]>;
|
|
55
|
+
private applyEvent;
|
|
56
|
+
private positionsInRange;
|
|
57
|
+
private rebuildPositionIndex;
|
|
58
|
+
private sync;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=RestStakeViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RestStakeViewer.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/RestStakeViewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,KAAK,EACW,QAAQ,EAA0B,iBAAiB,EAAE,WAAW,EACtF,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EAC1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,mFAAmF;AACnF,eAAO,MAAM,yBAAyB;;iBAAgE,CAAA;AAEtG;;;;;;GAMG;AACH,qBACa,eAAgB,SAAQ,yBAA0B,YAAW,WAAW;IACnF,MAAM,CAAC,QAAQ,CAAC,eAAe,oBAAoB;IACnD,MAAM,CAAC,QAAQ,CAAC,cAAc,gBAAqB;IACnD,MAAM,CAAC,QAAQ,CAAC,YAAY,kDAAyD;IACrF,MAAM,CAAC,QAAQ,CAAC,QAAQ,kBAAuB;IAC/C,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAG,MAAM,CAAS;IACzC,QAAQ,CAAC,OAAO,gBAAiC;IAEjD,OAAO,CAAC,oBAAoB,CAAsB;IAClD,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,oBAAoB,CAAC,CAAQ;IACrC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,WAAW,CAAC,CAAe;IAEnC,8EAA8E;IAC9E,IAAI,WAAW,IAAI,iBAAiB,CAEnC;IAED,gDAAgD;IAC1C,YAAY,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKzC,4EAA4E;IAC7D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7C,uDAAuD;IACjD,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5C,4EAA4E;IACtE,aAAa,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAK1C,uDAAuD;IACjD,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzC,uDAAuD;IACjD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAK9C,kEAAkE;IAC5D,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAMrE,wFAAwF;IAClF,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAkB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKhH,qFAAqF;IAC/E,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,GAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAkB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKhH,oDAAoD;IAC9C,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7C,kEAAkE;IAC5D,eAAe,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAK5C,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,oBAAoB;YAoBd,IAAI;CAcnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/modules/ethereum/indexing/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,sBAAsB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@xyo-network/chain-sdk",
|
|
4
|
-
"version": "5.0.
|
|
4
|
+
"version": "5.0.2",
|
|
5
5
|
"description": "XYO Layer One SDK",
|
|
6
6
|
"homepage": "https://xylabs.com",
|
|
7
7
|
"bugs": {
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"README.md"
|
|
122
122
|
],
|
|
123
123
|
"dependencies": {
|
|
124
|
-
"@ariestools/sdk": "~8.1.
|
|
124
|
+
"@ariestools/sdk": "~8.1.8",
|
|
125
125
|
"@opentelemetry/context-async-hooks": "~2.10.0",
|
|
126
126
|
"@opentelemetry/context-zone": "~2.10.0",
|
|
127
127
|
"@opentelemetry/core": "~2.10.0",
|
|
@@ -137,26 +137,27 @@
|
|
|
137
137
|
"@xyo-network/sdk": "~7.2.3",
|
|
138
138
|
"@xyo-network/typechain": "~4.1.3",
|
|
139
139
|
"ajv": "~8.20.0",
|
|
140
|
-
"chalk": "~
|
|
140
|
+
"chalk": "~6.0.0",
|
|
141
141
|
"shallowequal": "~1.1.0"
|
|
142
142
|
},
|
|
143
143
|
"devDependencies": {
|
|
144
|
-
"@ariestools/toolchain": "~
|
|
145
|
-
"@ariestools/tsconfig": "~
|
|
144
|
+
"@ariestools/toolchain": "~9.0.0",
|
|
145
|
+
"@ariestools/tsconfig": "~9.0.0",
|
|
146
146
|
"@ariestools/vitest-extended": "~8.0.3",
|
|
147
147
|
"@opentelemetry/api": "~1.9.1",
|
|
148
148
|
"@types/shallowequal": "~1.1.5",
|
|
149
149
|
"@xyo-network/archivist-mongodb": "~7.2.3",
|
|
150
150
|
"@xyo-network/sdk-protocol": "~7.2.3",
|
|
151
|
-
"@xyo-network/xl1-driver-lmdb": "~5.
|
|
152
|
-
"@xyo-network/xl1-driver-mongodb": "~5.
|
|
153
|
-
"@xyo-network/xl1-sdk": "~5.
|
|
151
|
+
"@xyo-network/xl1-driver-lmdb": "~5.1.2",
|
|
152
|
+
"@xyo-network/xl1-driver-mongodb": "~5.1.2",
|
|
153
|
+
"@xyo-network/xl1-sdk": "~5.1.2",
|
|
154
154
|
"async-mutex": "~0.5.0",
|
|
155
|
-
"eslint": "~10.8.
|
|
155
|
+
"eslint": "~10.8.1",
|
|
156
|
+
"eslint-import-resolver-typescript": "~4.4.5",
|
|
156
157
|
"ethers": "~6.17.0",
|
|
157
158
|
"tslib": "~2.8.1",
|
|
158
159
|
"typescript": "~6.0.3",
|
|
159
|
-
"vite": "~8.1
|
|
160
|
+
"vite": "~8.2.1",
|
|
160
161
|
"vitest": "~4.1.10",
|
|
161
162
|
"web3-types": "~1.10.0",
|
|
162
163
|
"zod": "~4.4.3"
|
|
@@ -166,7 +167,7 @@
|
|
|
166
167
|
"@opentelemetry/api": "^1.9",
|
|
167
168
|
"@opentelemetry/sdk-trace-base": "^2.9",
|
|
168
169
|
"@xyo-network/sdk": "^7.2",
|
|
169
|
-
"@xyo-network/xl1-sdk": "^5.
|
|
170
|
+
"@xyo-network/xl1-sdk": "^5.1",
|
|
170
171
|
"async-mutex": "^0.5",
|
|
171
172
|
"ethers": "^6.17",
|
|
172
173
|
"web3-types": "^1.10",
|