@xyo-network/xl1-protocol-sdk 1.26.24 → 1.26.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts +2 -0
  2. package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts.map +1 -1
  3. package/dist/neutral/config/Actor.d.ts +12 -0
  4. package/dist/neutral/config/Actor.d.ts.map +1 -1
  5. package/dist/neutral/config/Actors.d.ts +2 -0
  6. package/dist/neutral/config/Actors.d.ts.map +1 -1
  7. package/dist/neutral/config/Base.d.ts +2 -0
  8. package/dist/neutral/config/Base.d.ts.map +1 -1
  9. package/dist/neutral/config/Config.d.ts +8 -0
  10. package/dist/neutral/config/Config.d.ts.map +1 -1
  11. package/dist/neutral/config/HostActor.d.ts +12 -0
  12. package/dist/neutral/config/HostActor.d.ts.map +1 -1
  13. package/dist/neutral/config/Validation.d.ts +2 -0
  14. package/dist/neutral/config/Validation.d.ts.map +1 -1
  15. package/dist/neutral/context/Actor.d.ts +12 -0
  16. package/dist/neutral/context/Actor.d.ts.map +1 -1
  17. package/dist/neutral/context/HostActor.d.ts +12 -0
  18. package/dist/neutral/context/HostActor.d.ts.map +1 -1
  19. package/dist/neutral/getFileConfig.d.ts +4 -0
  20. package/dist/neutral/getFileConfig.d.ts.map +1 -1
  21. package/dist/neutral/getFileConfig.mjs +19 -1
  22. package/dist/neutral/getFileConfig.mjs.map +1 -1
  23. package/dist/neutral/index.mjs +1978 -1960
  24. package/dist/neutral/index.mjs.map +1 -1
  25. package/dist/neutral/isInternetAvailable.d.ts.map +1 -1
  26. package/dist/neutral/model/CreatableProviderContext.zod.d.ts +12 -0
  27. package/dist/neutral/model/CreatableProviderContext.zod.d.ts.map +1 -1
  28. package/dist/neutral/test/index.mjs +427 -411
  29. package/dist/neutral/test/index.mjs.map +1 -1
  30. package/package.json +8 -10
@@ -979,2137 +979,2155 @@ var TelemetryConfigZod = z15.object({
979
979
  // src/config/Validation.ts
980
980
  import { AddressZod as AddressZod2, asAddress } from "@xylabs/sdk-js";
981
981
  import { globalRegistry as globalRegistry11, z as z16 } from "zod";
982
- var ValidationConfigZod = z16.object({
983
- allowedRewardRedeemers: z16.preprocess((val) => {
984
- if (typeof val === "string") {
985
- return val.split(",").map((s) => asAddress(s.trim()));
986
- }
987
- return val;
988
- }, z16.array(AddressZod2).optional().register(globalRegistry11, {
989
- description: "List of allowed reward redeemer addresses, if undefined anyone can participate",
990
- title: "allowedRewardRedeemers",
991
- type: "array"
992
- })),
993
- allowedRewardEscrowAccountSigners: z16.preprocess((val) => {
994
- if (typeof val === "string") {
995
- return val.split(",").map((s) => asAddress(s.trim()));
996
- }
997
- return val;
998
- }, z16.array(AddressZod2).optional().register(globalRegistry11, {
999
- description: "List of allowed reward escrow account signer addresses, if undefined anyone can participate",
1000
- title: "allowedRewardEscrowAccountSigners",
1001
- type: "array"
1002
- }))
1003
- });
1004
-
1005
- // src/config/Base.ts
1006
- var BaseConfigZod = z17.object({
1007
- chain: ChainConfigZod.default(ChainConfigZod.parse({})).describe("Configuration for the chain"),
1008
- dataLake: DataLakeConfigZod.optional().describe("Configuration for data lakes"),
1009
- evm: EvmConfigZod.default(EvmConfigZod.parse({})).describe("Configuration for EVM-backed services"),
1010
- log: LogConfigZod.default(LogConfigZod.parse({})).describe("Configuration for logging"),
1011
- providers: ProvidersConfigZod.default(ProvidersConfigZod.parse([])).describe("Configuration for providers"),
1012
- remote: RemoteConfigZod.default(RemoteConfigZod.parse({})).describe("Configuration for remote services"),
1013
- storage: StorageConfigZod.default(StorageConfigZod.parse({})).describe("Configuration for the storage"),
1014
- telemetry: TelemetryConfigZod.default(TelemetryConfigZod.parse({})).describe("Configuration for telemetry"),
1015
- validation: ValidationConfigZod.default(ValidationConfigZod.parse({})).describe("Configuration for validation")
1016
- });
1017
-
1018
- // src/config/Actor.ts
1019
- var ActorConfigZod = BaseConfigZod.extend({
1020
- name: z18.string(),
1021
- mnemonic: MnemonicStringZod.optional().register(globalRegistry12, {
1022
- description: "Mnemonic for the Actor wallet",
1023
- title: "mnemonic",
1024
- type: "string"
1025
- }),
1026
- healthCheckPort: z18.coerce.number().optional().register(globalRegistry12, {
1027
- description: "Port for the Producer health checks",
1028
- title: "producer.healthCheckPort",
1029
- type: "number"
1030
- })
1031
- });
1032
- var isActorConfig = zodIsFactory2(ActorConfigZod);
1033
- var asActorConfig = zodAsFactory2(ActorConfigZod, "asActorConfig");
1034
- var toActorConfig = zodToFactory2(ActorConfigZod, "toActorConfig");
1035
-
1036
- // src/config/Actors.ts
1037
- import z19 from "zod";
1038
- var ActorsConfigZod = z19.array(ActorConfigZod.loose()).describe("Actor-specific configurations that override the base configuration when the actor is running").default([]);
1039
-
1040
- // src/config/Config.ts
1041
- var ConfigZod = BaseConfigZod.extend({ actors: ActorsConfigZod }).describe("The complete configuration for the protocol, including global settings and actor-specific overrides");
1042
- function resolveConfig(config) {
1043
- const parsedConfig = ConfigZod.parse(config);
1044
- const { actors, ...rootConfig } = parsedConfig;
1045
- parsedConfig.actors = actors.map((actorConfig) => {
1046
- return ActorConfigZod.loose().parse({ ...rootConfig, ...actorConfig });
1047
- });
1048
- return parsedConfig;
1049
- }
1050
-
1051
- // src/config/HostActor.ts
1052
- import {
1053
- zodAsFactory as zodAsFactory3,
1054
- zodIsFactory as zodIsFactory3,
1055
- zodToFactory as zodToFactory3
1056
- } from "@xylabs/sdk-js";
1057
- import { globalRegistry as globalRegistry13, z as z20 } from "zod";
1058
- var HostActorConfigZod = ActorConfigZod.extend({
1059
- host: z20.string().default("localhost").register(globalRegistry13, {
1060
- default: "localhost",
1061
- description: "Host for the Actor",
1062
- title: "host",
1063
- type: "string"
1064
- }),
1065
- port: z20.coerce.number().default(8080).register(globalRegistry13, {
1066
- default: 8080,
1067
- description: "Port for the Actor",
1068
- title: "port",
1069
- type: "number"
1070
- })
1071
- });
1072
- var isHostActorConfig = zodIsFactory3(HostActorConfigZod);
1073
- var asHostActorConfig = zodAsFactory3(HostActorConfigZod, "asHostActorConfig");
1074
- var toHostActorConfig = zodToFactory3(HostActorConfigZod, "toHostActorConfig");
1075
-
1076
- // src/config/UsageMeta.ts
1077
- import { z as z21 } from "zod";
1078
- var DescriptionSchema = z21.string();
1079
- var TitleSchema = z21.string();
1080
- var JSONSchemaMetaSchema = z21.object({
1081
- id: z21.string().optional(),
1082
- title: TitleSchema.optional(),
1083
- description: DescriptionSchema.optional(),
1084
- deprecated: z21.boolean().optional()
1085
- }).catchall(z21.unknown());
1086
- var GlobalMetaSchema = JSONSchemaMetaSchema.extend({});
1087
- var ChoicesSchema = z21.array(z21.union([z21.string(), z21.number(), z21.literal(true), z21.undefined()])).readonly();
1088
- var UsageMetaSchema = GlobalMetaSchema.extend({
1089
- choices: ChoicesSchema.optional(),
1090
- default: z21.unknown().optional(),
1091
- description: DescriptionSchema,
1092
- group: z21.string().optional(),
1093
- hidden: z21.boolean().optional(),
1094
- title: TitleSchema,
1095
- type: z21.union([
1096
- z21.literal("array"),
1097
- z21.literal("count"),
1098
- z21.literal("boolean"),
1099
- z21.literal("number"),
1100
- z21.literal("string")
1101
- ])
1102
- });
1103
- function isUsageMeta(v) {
1104
- return UsageMetaSchema.safeParse(v).success;
1105
- }
1106
-
1107
- // src/constants.ts
1108
- var XL1_NETWORK_STAKING_GENESIS_PERIOD_END_EPOCH = 1760572800;
1109
- var XL1_NETWORK_STAKING_GENESIS_PERIOD_END_XL1_BLOCK = 107496;
1110
-
1111
- // src/context/Actor.ts
1112
- import {
1113
- zodAsFactory as zodAsFactory5,
1114
- zodIsFactory as zodIsFactory5,
1115
- zodToFactory as zodToFactory5
1116
- } from "@xylabs/sdk-js";
1117
-
1118
- // src/model/CreatableProviderContext.zod.ts
1119
- import {
1120
- zodAsFactory as zodAsFactory4,
1121
- zodIsFactory as zodIsFactory4,
1122
- zodToFactory as zodToFactory4
1123
- } from "@xylabs/sdk-js";
1124
- import { CachingContextZod } from "@xyo-network/xl1-protocol-lib";
1125
- import { z as z22 } from "zod";
1126
- var RuntimeStatusMonitorZod = z22.custom((val) => val && typeof val === "object");
1127
- var ProviderFactoryLocatorZod = z22.lazy(() => z22.custom((val) => val && typeof val === "object" && "context" in val && "registry" in val));
1128
- var BaseConfigContextZod = CachingContextZod.extend({
1129
- config: BaseConfigZod.loose(),
1130
- locator: ProviderFactoryLocatorZod.optional()
1131
- });
1132
- var CreatableProviderContextZod = z22.lazy(() => BaseConfigContextZod.extend({
1133
- _id: z22.string().optional(),
1134
- locator: ProviderFactoryLocatorZod,
1135
- statusReporter: RuntimeStatusMonitorZod.optional()
1136
- }));
1137
- var isBaseConfigContext = zodIsFactory4(BaseConfigContextZod);
1138
- var asBaseConfigContext = zodAsFactory4(BaseConfigContextZod, "asBaseConfigContext");
1139
- var toBaseConfigContext = zodToFactory4(BaseConfigContextZod, "toBaseConfigContext");
1140
- var isCreatableProviderContext = zodIsFactory4(CreatableProviderContextZod);
1141
- var asCreatableProviderContext = zodAsFactory4(CreatableProviderContextZod, "asCreatableProviderContext");
1142
- var toCreatableProviderContext = zodToFactory4(CreatableProviderContextZod, "toCreatableProviderContext");
1143
-
1144
- // src/model/PayloadBundle/bundledPayloadToHydratedBlock.ts
1145
- import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/sdk-js";
1146
- import { asSignedBlockBoundWitnessWithHashMeta } from "@xyo-network/xl1-protocol-lib";
1147
- var bundledPayloadToHydratedBlock = async (payload) => {
1148
- const withHashMeta = await PayloadBuilder2.addHashMeta(payload.payloads);
1149
- const tx = asSignedBlockBoundWitnessWithHashMeta(withHashMeta.find((p) => p._hash === payload.root));
1150
- if (tx) {
1151
- return [tx, withHashMeta.filter((p) => p._hash !== payload.root)];
1152
- }
1153
- };
1154
-
1155
- // src/model/PayloadBundle/bundledPayloadToHydratedTransaction.ts
1156
- import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/sdk-js";
1157
- import { asSignedTransactionBoundWitnessWithHashMeta } from "@xyo-network/xl1-protocol-lib";
1158
- var bundledPayloadToHydratedTransaction = async (payload) => {
1159
- const withHashMeta = await PayloadBuilder3.addHashMeta(payload.payloads);
1160
- const tx = asSignedTransactionBoundWitnessWithHashMeta(withHashMeta.find((p) => p._hash === payload.root));
1161
- if (tx) {
1162
- return [tx, withHashMeta.filter((p) => p._hash !== payload.root)];
1163
- }
1164
- };
1165
-
1166
- // src/model/PayloadBundle/hydratedBlockToPayloadBundle.ts
1167
- import { PayloadBundleSchema } from "@xyo-network/sdk-js";
1168
- import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/sdk-js";
1169
- var hydratedBlockToPayloadBundle = (transaction) => {
1170
- const root = transaction[0]._hash;
1171
- return bundle(root, transaction);
1172
- };
1173
- var bundle = (root, transaction) => {
1174
- const payloads = flattenHydratedBlock(transaction).flatMap((p) => PayloadBuilder4.omitStorageMeta(p));
1175
- return new PayloadBuilder4({ schema: PayloadBundleSchema }).fields({ payloads, root }).build();
1176
- };
1177
-
1178
- // src/model/PayloadBundle/hydratedTransactionToPayloadBundle.ts
1179
- import { PayloadBundleSchema as PayloadBundleSchema2 } from "@xyo-network/sdk-js";
1180
- import { PayloadBuilder as PayloadBuilder11 } from "@xyo-network/sdk-js";
1181
-
1182
- // src/transaction/buildRandomTransaction.ts
1183
- import { Account } from "@xyo-network/sdk-js";
1184
- import { asXL1BlockNumber as asXL1BlockNumber2, isAllowedBlockPayload } from "@xyo-network/xl1-protocol-lib";
1185
-
1186
- // src/createTransferPayload.ts
1187
- import { toHex } from "@xylabs/sdk-js";
1188
- import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/sdk-js";
1189
- import { TransferSchema } from "@xyo-network/xl1-protocol-lib";
1190
- function createTransferPayload(from, transfers, context) {
1191
- return new PayloadBuilder5({ schema: TransferSchema }).fields({
1192
- epoch: Date.now(),
1193
- from,
1194
- transfers: Object.fromEntries(Object.entries(transfers).map(([k, v]) => [k, toHex(v)])),
1195
- context
1196
- }).build();
1197
- }
1198
-
1199
- // src/transaction/buildTransaction.ts
1200
- import { assertEx as assertEx7, toHex as toHex2 } from "@xylabs/sdk-js";
1201
- import {
1202
- asAnyPayload as asAnyPayload2,
1203
- BoundWitnessBuilder,
1204
- PayloadBuilder as PayloadBuilder6
1205
- } from "@xyo-network/sdk-js";
1206
- import { defaultTransactionFees } from "@xyo-network/xl1-protocol-lib";
1207
- async function buildTransaction(chain, onChainPayloads, offChainPayloads, signer, nbf, exp, from, fees = defaultTransactionFees) {
1208
- if (from === void 0 && Array.isArray(signer)) {
1209
- throw new Error("from is required when signer is an array");
1210
- }
1211
- const txBoundWitnessFields = {
1212
- chain,
1213
- fees: {
1214
- base: toHex2(fees.base),
1215
- gasLimit: toHex2(fees.gasLimit),
1216
- gasPrice: toHex2(fees.gasPrice),
1217
- priority: toHex2(fees.priority)
1218
- },
1219
- nbf,
1220
- exp
1221
- };
1222
- const elevatedHashes = await PayloadBuilder6.hashes(onChainPayloads);
1223
- const script = [];
1224
- for (const elevatedHash of elevatedHashes) {
1225
- script.push(`elevate|${elevatedHash}`);
1226
- }
1227
- const fields = {
1228
- ...txBoundWitnessFields,
1229
- from: from ?? (Array.isArray(signer) ? assertEx7(signer.at(0)?.address) : signer.address)
1230
- };
1231
- if (script.length > 0) {
1232
- fields.script = script;
1233
- }
1234
- const [tx, txPayloads] = await new BoundWitnessBuilder().fields(fields).meta({ $signatures: [] }).payloads([...onChainPayloads, ...offChainPayloads]).signers(Array.isArray(signer) ? signer : [signer]).build();
1235
- return [await PayloadBuilder6.addHashMeta(tx), await PayloadBuilder6.addHashMeta(txPayloads.map((p) => asAnyPayload2(p, true)))];
1236
- }
1237
-
1238
- // src/transaction/buildRandomTransaction.ts
1239
- var buildRandomTransaction = async (chain, payloads, account, nbf = asXL1BlockNumber2(0, true), exp = asXL1BlockNumber2(nbf + 1e3, true), privatePayloadSchemas = [], receiverAddress) => {
1240
- const elevatedPayloads2 = (payloads ?? []).filter(isAllowedBlockPayload);
1241
- const additionalPayloads = (payloads ?? []).filter((payload) => !isAllowedBlockPayload(payload));
1242
- const sender = account ?? await Account.random();
1243
- if (elevatedPayloads2?.length === 0) {
1244
- const receiver = receiverAddress ?? (await Account.random()).address;
1245
- const transferPayload = createTransferPayload(sender.address, { [receiver]: 1n });
1246
- elevatedPayloads2.push(transferPayload);
1247
- }
1248
- const hydratedTransaction = await buildTransaction(chain, elevatedPayloads2, additionalPayloads, sender, nbf, exp);
1249
- return [hydratedTransaction[0], hydratedTransaction[1].filter((p) => !privatePayloadSchemas.includes(p.schema))];
1250
- };
1251
-
1252
- // src/transaction/buildUnsignedTransaction.ts
1253
- import { toHex as toHex3 } from "@xylabs/sdk-js";
1254
- import { BoundWitnessBuilder as BoundWitnessBuilder2, PayloadBuilder as PayloadBuilder7 } from "@xyo-network/sdk-js";
1255
- import { defaultTransactionFees as defaultTransactionFees2 } from "@xyo-network/xl1-protocol-lib";
1256
- async function buildUnsignedTransaction(chain, onChainPayloads, offChainPayloads, nbf, exp, from, fees = defaultTransactionFees2) {
1257
- const txBoundWitnessFields = {
1258
- chain,
1259
- fees: {
1260
- base: toHex3(fees.base),
1261
- gasLimit: toHex3(fees.gasLimit),
1262
- gasPrice: toHex3(fees.gasPrice),
1263
- priority: toHex3(fees.priority)
1264
- },
1265
- nbf,
1266
- exp
1267
- };
1268
- const elevatedHashes = await PayloadBuilder7.hashes(onChainPayloads);
1269
- const script = [];
1270
- for (const elevatedHash of elevatedHashes) {
1271
- script.push(`elevate|${elevatedHash}`);
1272
- }
1273
- const fields = {
1274
- ...txBoundWitnessFields,
1275
- from
1276
- };
1277
- if (script.length > 0) {
1278
- fields.script = script;
1279
- }
1280
- const [tx, txPayloads] = await new BoundWitnessBuilder2().fields(fields).meta({ $signatures: [] }).payloads([...onChainPayloads, ...offChainPayloads]).build(false);
1281
- return [tx, txPayloads];
1282
- }
1283
-
1284
- // src/transaction/confirmSubmittedTransaction.ts
1285
- import { delay as delay2, isDefined as isDefined5 } from "@xylabs/sdk-js";
1286
- var DEFAULT_CONFIRMATION_ATTEMPTS = 20;
1287
- var DEFAULT_DELAY_BETWEEN_ATTEMPTS = 1e3;
1288
- var confirmSubmittedTransaction = async (viewer, txHash, options) => {
1289
- const { attempts: maxAttempts = DEFAULT_CONFIRMATION_ATTEMPTS, delay: attemptDelay = DEFAULT_DELAY_BETWEEN_ATTEMPTS } = options ?? {};
1290
- options?.logger?.log("\u{1F680} confirming transaction:", txHash, "\n");
1291
- let attempts = 0;
1292
- while (true) {
1293
- const tx = await viewer.transaction.byHash(txHash) ?? void 0;
1294
- if (isDefined5(tx)) {
1295
- options?.logger?.log("\u2705 Transaction confirmed:", txHash, "\n");
1296
- return tx;
1297
- } else {
1298
- attempts++;
1299
- if (attempts > maxAttempts) {
1300
- options?.logger?.error(`\u26A0\uFE0F Transaction not confirmed after ${maxAttempts} attempts`);
1301
- throw new Error(`Transaction ${txHash} not confirmed after ${maxAttempts} attempts`);
1302
- } else {
1303
- options?.logger?.log(`\u{1F504} Transaction not confirmed yet, attempt ${attempts}. Retrying...`, "\n");
1304
- await delay2(attemptDelay);
1305
- }
1306
- }
1307
- }
1308
- };
1309
-
1310
- // src/transaction/hydrateTransaction.ts
1311
- import { assertEx as assertEx8 } from "@xylabs/sdk-js";
1312
- import {
1313
- asAnyPayload as asAnyPayload3,
1314
- hydrateTypedBoundWitness,
1315
- tryHydrateTypedBoundWitness
1316
- } from "@xyo-network/sdk-js";
1317
- import {
1318
- asSignedHydratedTransaction,
1319
- isAllowedBlockPayload as isAllowedBlockPayload2,
1320
- isSignedTransactionBoundWitnessWithStorageMeta
1321
- } from "@xyo-network/xl1-protocol-lib";
1322
- var tryHydrateTransaction = async ({ chainMap }, hash) => {
1323
- return await tryHydrateTypedBoundWitness(
1324
- {
1325
- get(hashes) {
1326
- return chainMap.get(hashes);
1327
- },
1328
- next() {
1329
- throw new Error("Not implemented");
1330
- }
1331
- },
1332
- hash,
1333
- isSignedTransactionBoundWitnessWithStorageMeta
1334
- );
1335
- };
1336
- var hydrateTransaction = async ({ chainMap }, hash) => {
1337
- return await hydrateTypedBoundWitness(
1338
- {
1339
- get(hashes) {
1340
- return chainMap.get(hashes);
1341
- },
1342
- next() {
1343
- throw new Error("Not implemented");
1344
- }
1345
- },
1346
- hash,
1347
- isSignedTransactionBoundWitnessWithStorageMeta
1348
- );
1349
- };
1350
- function flattenHydratedTransaction(hydratedTransaction) {
1351
- const [tx, txPayloads] = hydratedTransaction;
1352
- return [...txPayloads, tx];
1353
- }
1354
- var tryUnflattenHydratedTransaction = (flattened) => {
1355
- const tx = flattened.at(-1);
1356
- const txPayloads = flattened.slice(0, -1);
1357
- return asSignedHydratedTransaction([tx, txPayloads]);
1358
- };
1359
- var unflattenHydratedTransaction = (flattened) => asSignedHydratedTransaction(tryUnflattenHydratedTransaction(flattened), true);
1360
- function flattenHydratedTransactions(hydratedTransactions) {
1361
- return hydratedTransactions.flatMap((tx) => flattenHydratedTransaction(tx));
1362
- }
1363
- var tryHydrateElevatedTransaction = async ({ chainMap }, hash) => {
1364
- const hydratedTransaction = await tryHydrateTransaction({ chainMap }, hash);
1365
- if (!hydratedTransaction) {
1366
- return void 0;
1367
- }
1368
- const [transaction, payloads] = hydratedTransaction;
1369
- const opCodes = (transaction.script ?? []).filter((operation) => operation.startsWith("elevate|"));
1370
- const elevatedPayloads2 = [];
1371
- for (const opCode of opCodes) {
1372
- const [code, hash2] = opCode.split("|");
1373
- if (code === "elevated") {
1374
- const elevatedPayload = payloads.find((payload) => payload._hash === hash2);
1375
- if (isAllowedBlockPayload2(elevatedPayload)) {
1376
- elevatedPayloads2.push(elevatedPayload);
1377
- }
1378
- }
1379
- }
1380
- if (opCodes.length === elevatedPayloads2.length) {
1381
- return [transaction, elevatedPayloads2.map((p) => asAnyPayload3(p, true))];
1382
- }
1383
- return void 0;
1384
- };
1385
- var hydrateElevatedTransaction = async (context, hash) => {
1386
- return assertEx8(await tryHydrateElevatedTransaction(context, hash), () => "Hydration failed");
1387
- };
1388
-
1389
- // src/transaction/primitives/transactionBlockByteCount.ts
1390
- import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/sdk-js";
1391
- function transactionBlockByteCount([transaction, payloads]) {
1392
- const cleanTransaction = PayloadBuilder8.omitStorageMeta(transaction);
1393
- const transactionBytes = JSON.stringify(cleanTransaction).length;
1394
- const cleanPayloads = PayloadBuilder8.omitStorageMeta(payloads);
1395
- return cleanPayloads.reduce((acc, payload) => acc + JSON.stringify(payload).length, 0) + transactionBytes;
1396
- }
1397
-
1398
- // src/transaction/primitives/transactionElevatedPayloads.ts
1399
- import { asHash as asHash2 } from "@xylabs/sdk-js";
1400
-
1401
- // src/transaction/primitives/transactionOperations.ts
1402
- function crackOperation(operation) {
1403
- const parts = operation.split("|");
1404
- if (parts.length < 2) {
1405
- throw new Error(`Invalid operation format: ${operation}`);
1406
- }
1407
- return [parts[0], parts.slice(1)];
1408
- }
1409
- function crackOperations(operations) {
1410
- return operations.map((op) => crackOperation(op));
1411
- }
1412
-
1413
- // src/transaction/primitives/transactionElevatedPayloads.ts
1414
- function transactionElevatedPayloadHashes(transaction) {
1415
- const elevateOperations = crackOperations(transaction.script ?? []).filter((op) => op[0] === "elevate");
1416
- return elevateOperations.map((op) => asHash2(op[1][0], true));
1417
- }
1418
- function transactionElevatedPayloads([transaction, payloads]) {
1419
- const hashes = transactionElevatedPayloadHashes(transaction);
1420
- const elevatedPayloads2 = payloads.filter((payload) => hashes.includes(payload._hash));
1421
- return elevatedPayloads2;
1422
- }
1423
-
1424
- // src/transaction/primitives/transactionRequiredGas.ts
1425
- import { AttoXL1 as AttoXL12, TransactionGasCosts } from "@xyo-network/xl1-protocol-lib";
1426
- function transactionBytesRequiredGas([transaction, payloads]) {
1427
- const transactionBlockBytes = transactionBlockByteCount([transaction, payloads]);
1428
- return AttoXL12(TransactionGasCosts.characterStorage * BigInt(transactionBlockBytes));
1429
- }
1430
- function transactionRequiredGas(hydratedTransaction) {
1431
- const elevatedPayloads2 = transactionElevatedPayloads(hydratedTransaction);
1432
- const hashes = elevatedPayloads2.length + 1;
1433
- const signatures = hydratedTransaction[0].addresses.length;
1434
- return AttoXL12(transactionBytesRequiredGas(hydratedTransaction) + TransactionGasCosts.hashValidation * BigInt(hashes) + TransactionGasCosts.signatureValidation * BigInt(signatures) + TransactionGasCosts.payloadValidation * BigInt(elevatedPayloads2.length));
1435
- }
1436
-
1437
- // src/transaction/script.ts
1438
- import { asHash as asHash3 } from "@xylabs/sdk-js";
1439
- import { assertEx as assertEx9, filterAs } from "@xylabs/sdk-js";
1440
- import { isHashMeta } from "@xyo-network/sdk-js";
1441
- import { isAllowedBlockPayload as isAllowedBlockPayload3 } from "@xyo-network/xl1-protocol-lib";
1442
- var tryExtractElevatedHashesFromScript = (strings) => {
1443
- const hashes = strings.filter((str) => str.startsWith("elevate|")).map((str) => str.split("|")[1]);
1444
- return filterAs(hashes, (h) => asHash3(h));
1445
- };
1446
- var extractElevatedHashesFromScript = (strings) => {
1447
- const hashes = strings.filter((str) => str.startsWith("elevate|")).map((str) => str.split("|")[1]);
1448
- const filtered = filterAs(hashes, (h) => asHash3(h));
1449
- assertEx9(filtered.length === hashes.length, () => "Invalid elevated hashes");
1450
- return filtered;
1451
- };
1452
- var tryExtractElevatedHashes = (tx) => {
1453
- const [bw, payloads] = tx;
1454
- const { script } = bw;
1455
- const hashes = script ? tryExtractElevatedHashesFromScript(script) : [];
1456
- return payloads.filter((p) => hashes.includes(p._hash)).filter(isAllowedBlockPayload3).filter(isHashMeta);
1457
- };
1458
- var extractElevatedHashes = (tx) => {
1459
- const [bw, payloads] = tx;
1460
- const { script } = bw;
1461
- const hashes = script ? tryExtractElevatedHashesFromScript(script) : [];
1462
- const filtered = payloads.filter((p) => hashes.includes(p._hash)).filter(isAllowedBlockPayload3).filter(isHashMeta);
1463
- assertEx9(filtered.length === hashes.length, () => "Invalid elevated hashes");
1464
- return filtered;
1465
- };
1466
-
1467
- // src/transaction/signTransaction.ts
1468
- import {
1469
- assertEx as assertEx10,
1470
- hexFromArrayBuffer,
1471
- toArrayBuffer
1472
- } from "@xylabs/sdk-js";
1473
- import { PayloadBuilder as PayloadBuilder9 } from "@xyo-network/sdk-js";
1474
- async function signTransaction(tx, account) {
1475
- assertEx10(tx.from === account.address, () => "Signer address does not match transaction from address");
1476
- const unsignedTx = structuredClone(tx);
1477
- unsignedTx.addresses = [account.address];
1478
- unsignedTx.previous_hashes = [account.previousHash ?? null];
1479
- const hash = await PayloadBuilder9.dataHash(unsignedTx);
1480
- const hashBytes = toArrayBuffer(hash);
1481
- const [signature] = await account.sign(hashBytes);
1482
- const result = {
1483
- ...unsignedTx,
1484
- $signatures: [hexFromArrayBuffer(signature)]
1485
- };
1486
- return result;
1487
- }
1488
982
 
1489
- // src/transaction/TransactionBuilder.ts
1490
- import { assertEx as assertEx11, Base } from "@xylabs/sdk-js";
1491
- import { PayloadBuilder as PayloadBuilder10 } from "@xyo-network/sdk-js";
1492
- import {
1493
- asXL1BlockNumber as asXL1BlockNumber3,
1494
- defaultTransactionFees as defaultTransactionFees3,
1495
- isAllowedBlockPayload as isAllowedBlockPayload4,
1496
- minTransactionFees,
1497
- XYO_ZERO_ADDRESS
1498
- } from "@xyo-network/xl1-protocol-lib";
1499
- var TransactionBuilder = class extends Base {
1500
- _blockRange;
1501
- _chain;
1502
- _elevatedPayloads = [];
1503
- _fees;
1504
- _payloads = [];
1505
- _signers = [];
1506
- constructor(options = {}) {
1507
- super(options);
1508
- }
1509
- async build() {
1510
- const chain = assertEx11(this._chain, () => "Chain must be set before building the transaction");
1511
- const fees = assertEx11(this._fees, () => "Fees must be set before building the transaction");
1512
- const blockRange = assertEx11(this._blockRange, () => "Block range must be set before building the transaction");
1513
- return await buildTransaction(
1514
- chain,
1515
- this._elevatedPayloads,
1516
- this._payloads,
1517
- this._signers,
1518
- asXL1BlockNumber3(blockRange[0], true),
1519
- asXL1BlockNumber3(blockRange[1], true),
1520
- this._signers[0]?.address,
1521
- fees
1522
- );
1523
- }
1524
- chain(chain) {
1525
- this._chain = chain;
1526
- return this;
1527
- }
1528
- async dryRun() {
1529
- return await buildTransaction(
1530
- XYO_ZERO_ADDRESS,
1531
- this._elevatedPayloads,
1532
- this._payloads,
1533
- this._signers,
1534
- asXL1BlockNumber3(0, true),
1535
- asXL1BlockNumber3(1e3, true),
1536
- this._signers[0]?.address,
1537
- defaultTransactionFees3
1538
- );
1539
- }
1540
- elevatedPayload(payload) {
1541
- const allowedPayload = isAllowedBlockPayload4(payload) ? payload : void 0;
1542
- const allowPayloadExists = assertEx11(allowedPayload, () => "Payload must be an AllowedBlockPayload");
1543
- this._elevatedPayloads.push(allowPayloadExists);
1544
- return this;
1545
- }
1546
- elevatedPayloads(payloads) {
1547
- if (payloads)
1548
- for (const payload of payloads) {
1549
- this.elevatedPayload(payload);
1550
- }
1551
- return this;
983
+ // src/primitives/block/range/blockRangeSteps.ts
984
+ import { asXL1BlockNumber as asXL1BlockNumber2, StepSizes as StepSizes3 } from "@xyo-network/xl1-protocol-lib";
985
+ function blockRangeSteps(range, steps) {
986
+ const result = [];
987
+ for (const step of steps) {
988
+ const stepSize2 = StepSizes3[step];
989
+ const startOfFirstStepCandidate = range[0] - range[0] % stepSize2 + stepSize2;
990
+ const startOfFirstStep = asXL1BlockNumber2(
991
+ startOfFirstStepCandidate,
992
+ { name: "blockRangeSteps" }
993
+ );
994
+ for (let block = startOfFirstStep; block <= range[1]; block = asXL1BlockNumber2(block + stepSize2, { name: "blockRangeSteps" })) {
995
+ result.push({ step, block });
996
+ }
1552
997
  }
1553
- async estimatedMinimumFees() {
1554
- const tx = await this.dryRun();
1555
- const requiredGas = transactionRequiredGas(tx);
1556
- return {
1557
- base: minTransactionFees.base,
1558
- // eslint-disable-next-line unicorn/prefer-math-min-max
1559
- gasLimit: requiredGas > minTransactionFees.gasLimit ? requiredGas : minTransactionFees.gasLimit,
1560
- gasPrice: minTransactionFees.gasPrice,
1561
- priority: minTransactionFees.priority
1562
- };
998
+ return result;
999
+ }
1000
+
1001
+ // src/primitives/block/rate/blockRate.ts
1002
+ import { isDefined as isDefined6, isFalsy } from "@xylabs/sdk-js";
1003
+ import { asXL1BlockRange } from "@xyo-network/xl1-protocol-lib";
1004
+
1005
+ // src/primitives/block/rate/timeHelpers.ts
1006
+ import { assertEx as assertEx7, isDefined as isDefined5 } from "@xylabs/sdk-js";
1007
+ var rateMultipliers = {
1008
+ millis: 1,
1009
+ seconds: 1e3,
1010
+ minutes: 1e3 * 60,
1011
+ hours: 1e3 * 60 * 60,
1012
+ days: 1e3 * 60 * 60 * 24,
1013
+ weeks: 1e3 * 60 * 60 * 24 * 7
1014
+ };
1015
+ var timeDurations = (timeInMs) => ({
1016
+ millis: timeInMs,
1017
+ seconds: timeInMs / 1e3,
1018
+ minutes: timeInMs / (1e3 * 60),
1019
+ hours: timeInMs / (1e3 * 60 * 60),
1020
+ days: timeInMs / (1e3 * 60 * 60 * 24),
1021
+ weeks: timeInMs / (1e3 * 60 * 60 * 24 * 7)
1022
+ });
1023
+ var getTimeConfigInMilliseconds = (timeConfig) => {
1024
+ const assertedTimeConfig = assertEx7(isDefined5(timeConfig) ? timeConfig : void 0, () => "Time configuration must be provided");
1025
+ let totalMilliseconds = 0;
1026
+ if ("years" in assertedTimeConfig) {
1027
+ totalMilliseconds += assertedTimeConfig.years * 31536e6;
1028
+ return totalMilliseconds;
1563
1029
  }
1564
- fees(fees) {
1565
- this._fees = fees;
1566
- return this;
1030
+ if ("months" in assertedTimeConfig) {
1031
+ totalMilliseconds += assertedTimeConfig.months * 2592e6;
1032
+ return totalMilliseconds;
1567
1033
  }
1568
- payload(payload) {
1569
- this._payloads.push(payload);
1570
- return this;
1034
+ if ("weeks" in assertedTimeConfig) {
1035
+ totalMilliseconds += assertedTimeConfig.weeks * 6048e5;
1036
+ return totalMilliseconds;
1571
1037
  }
1572
- payloads(payloads) {
1573
- if (payloads)
1574
- for (const payload of payloads) {
1575
- if (payload !== null) {
1576
- this.payload(payload);
1577
- }
1578
- }
1579
- return this;
1038
+ if ("days" in assertedTimeConfig) {
1039
+ totalMilliseconds += assertedTimeConfig.days * 864e5;
1040
+ return totalMilliseconds;
1580
1041
  }
1581
- range(blockRange) {
1582
- if (blockRange.length !== 2) {
1583
- throw new Error("Block range must be an array of two numbers");
1584
- }
1585
- this._blockRange = blockRange;
1586
- return this;
1042
+ if ("hours" in assertedTimeConfig) {
1043
+ totalMilliseconds += assertedTimeConfig.hours * 36e5;
1044
+ return totalMilliseconds;
1587
1045
  }
1588
- async removeElevatedPayload(payload) {
1589
- const hash = await PayloadBuilder10.hash(payload);
1590
- const existingHashes = await PayloadBuilder10.hashes(this._elevatedPayloads);
1591
- const existingPayloadIndex = existingHashes.indexOf(hash);
1592
- if (existingPayloadIndex === -1) {
1593
- throw new Error("Payload not found in the transaction");
1594
- }
1595
- this._elevatedPayloads = this._elevatedPayloads.filter((_, index) => index !== existingPayloadIndex);
1596
- return this;
1046
+ if ("minutes" in assertedTimeConfig) {
1047
+ totalMilliseconds += assertedTimeConfig.minutes * 6e4;
1048
+ return totalMilliseconds;
1597
1049
  }
1598
- async removePayload(payload) {
1599
- const hash = await PayloadBuilder10.hash(payload);
1600
- const existingHashes = await PayloadBuilder10.hashes(this._payloads);
1601
- const existingPayloadIndex = existingHashes.indexOf(hash);
1602
- if (existingPayloadIndex === -1) {
1603
- throw new Error("Payload not found in the transaction");
1604
- }
1605
- this._payloads = this._payloads.filter((_, index) => index !== existingPayloadIndex);
1606
- return this;
1050
+ return totalMilliseconds;
1051
+ };
1052
+
1053
+ // src/primitives/block/rate/blockRate.ts
1054
+ var blockRate = (startBlock, endBlock, timeUnit) => {
1055
+ const startingBlock = startBlock[0];
1056
+ const endingBlock = endBlock[0];
1057
+ const heightDifference = endingBlock.block - startingBlock.block;
1058
+ const timeDifference = endingBlock.$epoch - startingBlock.$epoch;
1059
+ if (timeDifference === 0) {
1060
+ throw new Error("Time difference must be greater than 0");
1607
1061
  }
1608
- signer(signer) {
1609
- if (signer) {
1610
- this._signers.push(signer);
1611
- }
1612
- return this;
1062
+ const rate = heightDifference / timeDifference;
1063
+ const timeUnitValue = isDefined6(timeUnit) ? timeUnit : "millis";
1064
+ const returnedTimeDifference = isDefined6(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference;
1065
+ const timePerBlock = returnedTimeDifference / heightDifference;
1066
+ return {
1067
+ range: asXL1BlockRange([startingBlock.block, endingBlock.block], true),
1068
+ span: heightDifference,
1069
+ rate: isDefined6(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,
1070
+ timeUnit: timeUnitValue,
1071
+ timeDifference: returnedTimeDifference,
1072
+ timePerBlock
1073
+ };
1074
+ };
1075
+ var getBlockRateBlocks = async (viewer, startBlockHeight, endBlockHeight) => {
1076
+ if (endBlockHeight <= startBlockHeight) {
1077
+ console.error("startBlockHeight", startBlockHeight);
1078
+ console.error("endBlockHeight", endBlockHeight);
1079
+ throw new Error("End block height must be greater than start block height");
1613
1080
  }
1614
- signers(signers) {
1615
- if (signers)
1616
- for (const signer of signers) {
1617
- if (signer !== null) {
1618
- this.signer(signer);
1619
- }
1620
- }
1621
- return this;
1081
+ const startingBlock = await viewer.blockByNumber(startBlockHeight);
1082
+ const endingBlock = await viewer.blockByNumber(endBlockHeight);
1083
+ if (isFalsy(startingBlock) || isFalsy(endingBlock)) {
1084
+ throw new Error("Could not retrieve blocks for speed calculation");
1622
1085
  }
1086
+ return { startingBlock, endingBlock };
1623
1087
  };
1624
-
1625
- // src/model/PayloadBundle/hydratedTransactionToPayloadBundle.ts
1626
- var hydratedTransactionToPayloadBundle = (transaction) => {
1627
- const root = transaction[0]._hash;
1628
- return bundle2(root, transaction);
1629
- };
1630
- var bundle2 = (root, transaction) => {
1631
- const payloads = flattenHydratedTransaction(transaction);
1632
- return new PayloadBuilder11({ schema: PayloadBundleSchema2 }).fields({ payloads, root }).build();
1088
+ var calculateBlockRate = async (viewer, range, timeUnit) => {
1089
+ const [startBlockHeight, endBlockHeight] = range;
1090
+ const { startingBlock, endingBlock } = await getBlockRateBlocks(
1091
+ viewer,
1092
+ startBlockHeight,
1093
+ endBlockHeight
1094
+ );
1095
+ return blockRate(startingBlock, endingBlock, timeUnit);
1633
1096
  };
1634
1097
 
1635
- // src/context/Actor.ts
1636
- var ActorConfigContext = BaseConfigContextZod.extend({ config: ActorConfigZod });
1637
- var isActorConfigContext = zodIsFactory5(ActorConfigContext);
1638
- var asActorConfigContext = zodAsFactory5(ActorConfigContext, "asActorConfigContext");
1639
- var toActorConfigContext = zodToFactory5(ActorConfigContext, "toActorConfigContext");
1640
-
1641
- // src/CreatableProvider/AbstractCreatableProvider.ts
1098
+ // src/primitives/block/rate/stepRate.ts
1099
+ import { assertEx as assertEx8 } from "@xylabs/sdk-js";
1642
1100
  import {
1643
- AbstractCreatable as AbstractCreatable2,
1644
- assertEx as assertEx13,
1645
- IdLogger as IdLogger2
1646
- } from "@xylabs/sdk-js";
1647
-
1648
- // src/CreatableProvider/ProviderFactory.ts
1649
- import { assertEx as assertEx12 } from "@xylabs/sdk-js";
1650
- function providerFactoryDescription(factory, labels) {
1651
- return `${factory.providerName}:${factory.defaultMoniker}:${JSON.stringify(labels ?? factory.labels ?? {})}`;
1652
- }
1653
- var ProviderFactory = class _ProviderFactory {
1654
- creatableProvider;
1655
- defaultMoniker;
1656
- defaultParams;
1657
- dependencies;
1658
- labels;
1659
- monikers;
1660
- providerName;
1661
- scope;
1662
- _uniqueId;
1663
- constructor(creatableProvider2, dependencies, params, labels = {}, scope = "context") {
1664
- this.creatableProvider = creatableProvider2;
1665
- this.defaultParams = params;
1666
- this.defaultMoniker = creatableProvider2.defaultMoniker;
1667
- this.dependencies = dependencies;
1668
- this.monikers = creatableProvider2.monikers;
1669
- this.scope = scope;
1670
- assertEx12(this.monikers.includes(this.defaultMoniker), () => "defaultMoniker must be in monikers");
1671
- this.labels = Object.assign({}, creatableProvider2.labels ?? {}, labels ?? {});
1672
- this.providerName = creatableProvider2.name;
1673
- this._uniqueId = Symbol(providerFactoryDescription(this));
1674
- }
1675
- get resolvedMoniker() {
1676
- const labels = this.labels ?? {};
1677
- const labelString = Object.entries(labels).map(([key, value]) => `${key}=${value}`).join(",");
1678
- return labelString.length === 0 ? `${this.defaultMoniker}` : `${this.defaultMoniker}|${labelString}`;
1679
- }
1680
- get uniqueId() {
1681
- return this._uniqueId;
1682
- }
1683
- static withParams(creatableProvider2, dependencies, params, labels = {}) {
1684
- return new _ProviderFactory(creatableProvider2, dependencies, params, labels);
1685
- }
1686
- factory(dependencies, params, labels = {}) {
1687
- return new _ProviderFactory(this.creatableProvider, dependencies, params, labels);
1688
- }
1689
- async getInstance(params, { start = true }) {
1690
- let scopeObject;
1691
- switch (this.scope) {
1692
- case "global": {
1693
- globalThis.xyoServiceSingletons ??= {};
1694
- scopeObject = globalThis.xyoServiceSingletons;
1695
- break;
1696
- }
1697
- case "context": {
1698
- const context = assertEx12(
1699
- params?.context,
1700
- () => "Context is required for context-scoped providers"
1701
- );
1702
- context.singletons ??= {};
1703
- scopeObject = context.singletons;
1704
- break;
1705
- }
1706
- default: {
1707
- scopeObject = {};
1708
- break;
1709
- }
1710
- }
1711
- const mergedParams = {
1712
- ...this.defaultParams,
1713
- ...params
1714
- };
1715
- const resultPromise = scopeObject[this.resolvedMoniker] ?? this.creatableProvider.create(mergedParams);
1716
- scopeObject[this.resolvedMoniker] = resultPromise;
1717
- const result = await resultPromise;
1718
- if (start) {
1719
- assertEx12(await result.start(), () => `Failed to start provider instance [${this.resolvedMoniker}]`);
1720
- }
1721
- return result;
1722
- }
1723
- async tryGetInstance(params, options) {
1724
- try {
1725
- return await this.getInstance(params, options);
1726
- } catch {
1727
- return;
1728
- }
1729
- }
1101
+ asXL1BlockRange as asXL1BlockRange2,
1102
+ isValidStep,
1103
+ StepSizes as StepSizes4
1104
+ } from "@xyo-network/xl1-protocol-lib";
1105
+ var stepRate = async (viewer, start, step, count = 1, timeUnit) => {
1106
+ const end = start + step * count;
1107
+ const range = asXL1BlockRange2([start, end], true);
1108
+ return await calculateBlockRate(viewer, range, timeUnit);
1109
+ };
1110
+ var calculateStepSizeRate = async (viewer, start, stepIndex, count = 1, timeUnit) => {
1111
+ assertEx8(isValidStep(stepIndex), () => `Invalid step index: ${stepIndex}`);
1112
+ const step = StepSizes4[stepIndex];
1113
+ return await stepRate(viewer, start, step, count, timeUnit);
1730
1114
  };
1731
1115
 
1732
- // src/CreatableProvider/AbstractCreatableProvider.ts
1733
- var AbstractCreatableProvider = class extends AbstractCreatable2 {
1734
- dependencies = {};
1735
- _contextCache;
1736
- _logger;
1737
- get logger() {
1738
- if (this._logger === void 0) {
1739
- const providedLogger = this.params.logger ?? this.context.logger;
1740
- this._logger = providedLogger ? new IdLogger2(providedLogger, () => `${this.moniker} [${this.constructor.name}]`) : null;
1741
- }
1742
- return this._logger ?? void 0;
1743
- }
1744
- get meter() {
1745
- return this.context.meterProvider?.getMeter(this.name) ?? super.meter;
1746
- }
1747
- get tracer() {
1748
- return this.context.traceProvider?.getTracer(this.name) ?? super.tracer;
1749
- }
1750
- get config() {
1751
- return this.context.config;
1116
+ // src/primitives/block/rate/timeRate.ts
1117
+ import {
1118
+ assertEx as assertEx9,
1119
+ isDefined as isDefined7,
1120
+ isDefinedNotNull
1121
+ } from "@xylabs/sdk-js";
1122
+ import { asXL1BlockNumber as asXL1BlockNumber3, asXL1BlockRange as asXL1BlockRange3 } from "@xyo-network/xl1-protocol-lib";
1123
+ var DEFAULT_TOLERANCE_MS = 3e4;
1124
+ var DEFAULT_MAX_ATTEMPTS = 10;
1125
+ var calculateTimeRate = async (viewer, timeConfig, startBlockNumber, timeUnit, toleranceMs = DEFAULT_TOLERANCE_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS) => {
1126
+ assertEx9(Object.keys(timeConfig ?? {}).length === 1, () => "Only one time unit should be specified in timeConfig");
1127
+ const startBlock = isDefinedNotNull(startBlockNumber) ? await viewer.blockByNumber(startBlockNumber) : null;
1128
+ const resolvedStartBlock = isDefinedNotNull(startBlock) ? startBlock[0] : (await viewer.currentBlock())[0];
1129
+ const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig);
1130
+ assertEx9(timeInMilliseconds > 0, () => "Time duration must be greater than zero");
1131
+ const blocksPerMillisecondRate = 1 / (12 * 1e3);
1132
+ const initialBlocksInDuration = Math.floor(blocksPerMillisecondRate * timeInMilliseconds);
1133
+ const endBlockNumber = await findEndBlockRecursive(
1134
+ viewer,
1135
+ resolvedStartBlock,
1136
+ timeInMilliseconds,
1137
+ initialBlocksInDuration,
1138
+ toleranceMs,
1139
+ maxAttempts
1140
+ );
1141
+ return await calculateBlockRate(
1142
+ viewer,
1143
+ asXL1BlockRange3([endBlockNumber, resolvedStartBlock.block], true),
1144
+ timeUnit
1145
+ );
1146
+ };
1147
+ var findEndBlockRecursive = async (viewer, startBlock, targetTimeMs, estimatedBlocksBack, toleranceMs, attemptsRemaining) => {
1148
+ console.log(`Attempts remaining: ${attemptsRemaining}, Estimated blocks back: ${estimatedBlocksBack}`);
1149
+ assertEx9(attemptsRemaining >= 0, () => "Maximum attempts reached while searching for end block");
1150
+ const startBlockEpoch = startBlock.$epoch;
1151
+ const estimatedEndBlockNumber = asXL1BlockNumber3(startBlock.block - estimatedBlocksBack, true);
1152
+ if (estimatedEndBlockNumber < 0) {
1153
+ throw new Error("Estimated end block number is less than zero");
1752
1154
  }
1753
- get context() {
1754
- return this.params.context;
1155
+ const endBlock = await viewer.blockByNumber(estimatedEndBlockNumber);
1156
+ const resolvedEndBlock = assertEx9(
1157
+ isDefined7(endBlock?.[0]) ? endBlock[0] : void 0,
1158
+ () => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`
1159
+ );
1160
+ const endBlockEpoch = resolvedEndBlock.$epoch;
1161
+ if (!Number.isFinite(startBlockEpoch) || !Number.isFinite(endBlockEpoch)) {
1162
+ throw new TypeError("Block has missing or invalid $epoch");
1755
1163
  }
1756
- get locator() {
1757
- return this.context.locator;
1164
+ const actualTimeDifference = startBlockEpoch - endBlockEpoch;
1165
+ if (actualTimeDifference === 0) {
1166
+ throw new Error("Start and end blocks have identical timestamps");
1758
1167
  }
1759
- static factory(dependencies, params) {
1760
- const factory = ProviderFactory.withParams(this, dependencies, params);
1761
- return factory;
1168
+ const timeDelta = Math.abs(actualTimeDifference - targetTimeMs);
1169
+ if (timeDelta <= toleranceMs) {
1170
+ return resolvedEndBlock.block;
1762
1171
  }
1763
- static async paramsHandler(params = {}) {
1764
- const context = assertEx13(params.context, () => new Error("Context is required"));
1765
- const config = assertEx13(context.config, () => new Error("Context config is required"));
1766
- const locator = assertEx13(context.locator, () => new Error("Context locator is required"));
1767
- return await super.paramsHandler({
1768
- ...params,
1769
- statusReporter: params.statusReporter ?? context.statusReporter,
1770
- context: {
1771
- ...context,
1772
- config,
1773
- locator
1774
- },
1775
- name: params.name ?? this.defaultMoniker,
1776
- logger: params.logger ?? context.logger
1777
- });
1172
+ let adjustedBlocksBack;
1173
+ if (actualTimeDifference < targetTimeMs) {
1174
+ const adjustmentFactor = targetTimeMs / actualTimeDifference;
1175
+ adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor);
1176
+ } else {
1177
+ const adjustmentFactor = actualTimeDifference / targetTimeMs;
1178
+ adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor);
1778
1179
  }
1779
- async createHandler() {
1780
- await super.createHandler();
1781
- if (this.tracer === void 0) {
1782
- this.logger?.warn("No tracer available in context");
1180
+ adjustedBlocksBack = Number.isFinite(adjustedBlocksBack) && adjustedBlocksBack >= 1 ? adjustedBlocksBack : 1;
1181
+ return await findEndBlockRecursive(
1182
+ viewer,
1183
+ startBlock,
1184
+ targetTimeMs,
1185
+ adjustedBlocksBack,
1186
+ toleranceMs,
1187
+ attemptsRemaining - 1
1188
+ );
1189
+ };
1190
+
1191
+ // src/primitives/chain/getWindowedChain.ts
1192
+ import {
1193
+ assertEx as assertEx10,
1194
+ isDefined as isDefined8,
1195
+ isNull,
1196
+ spanRootAsync
1197
+ } from "@xylabs/sdk-js";
1198
+ async function getWindowedChain(context, blockViewer, maxWindowSize, previousChain = []) {
1199
+ return await spanRootAsync("getWindowedChain", async () => {
1200
+ const newChain = [];
1201
+ const previousChainByHash = new Map(previousChain.map((block) => [block[0]._hash, block]));
1202
+ const head = await blockViewer.currentBlock();
1203
+ let currentBlock = head;
1204
+ console.log("[getWindowedChain] Current Block:", currentBlock?.[0]._hash);
1205
+ while (currentBlock !== null && newChain.length < maxWindowSize) {
1206
+ const currentBlockNumber = currentBlock[0].block;
1207
+ const nextBlock = newChain[0];
1208
+ if (isDefined8(nextBlock)) {
1209
+ const nextBlockNumber = nextBlock[0].block;
1210
+ assertEx10(
1211
+ currentBlockNumber === nextBlockNumber - 1,
1212
+ () => `[getWindowedChain] Non-monotonic block sequence detected: current=${currentBlockNumber}, next=${nextBlockNumber}`
1213
+ );
1214
+ }
1215
+ assertEx10(
1216
+ currentBlockNumber <= head[0].block,
1217
+ () => `[getWindowedChain] Current block number (${currentBlockNumber}) exceeds head block number (${head[0].block})`
1218
+ );
1219
+ newChain.unshift(currentBlock);
1220
+ const previousBlockHash = currentBlock[0].previous;
1221
+ if (isNull(previousBlockHash)) break;
1222
+ currentBlock = previousChainByHash.get(previousBlockHash) ?? await blockViewer.blockByHash(previousBlockHash);
1783
1223
  }
1784
- if (this.meter === void 0) {
1785
- this.logger?.warn("No meter available in context");
1224
+ return newChain;
1225
+ }, context);
1226
+ }
1227
+
1228
+ // src/primitives/chain/step/chainStepRewardAddress.ts
1229
+ import {
1230
+ assertEx as assertEx13,
1231
+ exists,
1232
+ toAddress as toAddress4
1233
+ } from "@xylabs/sdk-js";
1234
+ import {
1235
+ asTransfer,
1236
+ isTransfer,
1237
+ XYO_STEP_REWARD_ADDRESS
1238
+ } from "@xyo-network/xl1-protocol-lib";
1239
+
1240
+ // src/primitives/payload/mergeTransfers.ts
1241
+ import { hexToBigInt, toAddress } from "@xylabs/sdk-js";
1242
+ function mergeTransfers(transfers) {
1243
+ const result = {};
1244
+ for (const transfer of transfers) {
1245
+ result[transfer.from] = result[transfer.from] ?? {};
1246
+ for (const [to, value] of Object.entries(transfer.transfers)) {
1247
+ const typedTo = toAddress(to);
1248
+ result[transfer.from][typedTo] = (result[transfer.from][typedTo] ?? 0n) + hexToBigInt(value);
1786
1249
  }
1787
1250
  }
1788
- async locateAndCreate(moniker) {
1789
- return await this.locator.getInstance(moniker);
1790
- }
1791
- async tryLocateAndCreate(moniker) {
1792
- return await this.locator.tryGetInstance(moniker);
1793
- }
1794
- };
1251
+ return result;
1252
+ }
1795
1253
 
1796
- // src/CreatableProvider/CreatableProvider.ts
1797
- function creatableProvider() {
1798
- return (constructor) => {
1799
- constructor;
1800
- };
1254
+ // src/primitives/step/completedStepRewardAddress.ts
1255
+ import { toAddress as toAddress2 } from "@xylabs/sdk-js";
1256
+ import { StepSizes as StepSizes5 } from "@xyo-network/xl1-protocol-lib";
1257
+ import { keccak256 } from "ethers";
1258
+ function completedStepRewardAddress({ block, step }) {
1259
+ const resolvedStepSize = step < StepSizes5.length ? StepSizes5[step] : step;
1260
+ const addressKey = new TextEncoder().encode(`${block}|${resolvedStepSize}`);
1261
+ return toAddress2(keccak256(addressKey).slice(-40), { prefix: false });
1801
1262
  }
1802
- function labeledCreatableProvider() {
1803
- return (constructor) => {
1804
- constructor;
1805
- };
1263
+
1264
+ // src/primitives/step/derivedReceiveAddress.ts
1265
+ import { toAddress as toAddress3 } from "@xylabs/sdk-js";
1266
+ import { isDefined as isDefined9 } from "@xylabs/sdk-js";
1267
+ import { keccak256 as keccak2562 } from "ethers";
1268
+ function derivedReceiveAddress(address, scope) {
1269
+ const addressKey = new TextEncoder().encode(isDefined9(scope) ? `${scope}|${address}` : address);
1270
+ return toAddress3(keccak2562(addressKey).slice(-40), { prefix: false });
1806
1271
  }
1807
1272
 
1808
- // src/CreatableProvider/CreatableProviderRegistry.ts
1809
- import { isTruthy } from "@xylabs/sdk-js";
1810
- var buildProviderFactory = (provider, defaultParams, labels) => {
1811
- const factory = {
1812
- monikers: provider.monikers,
1813
- uniqueId: Symbol(providerFactoryDescription(provider, labels)),
1814
- // Merge module & supplied labels
1815
- labels: { ...provider.labels, ...labels },
1816
- creatableProvider: provider.creatableProvider,
1817
- dependencies: provider.dependencies,
1818
- resolvedMoniker: provider.resolvedMoniker,
1819
- providerName: provider.providerName,
1820
- scope: provider.scope,
1821
- defaultParams,
1822
- getInstance: provider.getInstance.bind(provider),
1823
- tryGetInstance: provider.tryGetInstance?.bind(provider),
1824
- defaultMoniker: provider.defaultMoniker,
1825
- factory: provider.factory.bind(provider)
1826
- };
1827
- return factory;
1828
- };
1829
- var registerCreatableProviderFactory = (registry, factory, labels, primary = false) => {
1830
- const primaryMonikers = primary !== true && isTruthy(primary) ? Array.isArray(primary) ? primary : [primary] : [];
1831
- for (const primaryMoniker of primaryMonikers) {
1832
- if (!factory.monikers.includes(primaryMoniker)) {
1833
- console.warn(`Primary moniker ${String(primary)} not found in factory monikers`);
1273
+ // src/primitives/step/stepBlockRange.ts
1274
+ import { asXL1BlockRange as asXL1BlockRange4, StepSizes as StepSizes6 } from "@xyo-network/xl1-protocol-lib";
1275
+ function stepBlockRange({ block, step }) {
1276
+ const stepSize2 = StepSizes6[step];
1277
+ const start = block - stepSize2;
1278
+ return asXL1BlockRange4([start, start + stepSize2 - 1], { name: "stepBlockRange" });
1279
+ }
1280
+
1281
+ // src/primitives/step/stepTransferIndex.ts
1282
+ import { assertEx as assertEx11 } from "@xylabs/sdk-js";
1283
+ import { StepSizes as StepSizes7 } from "@xyo-network/xl1-protocol-lib";
1284
+ function stepTransferIndex(block, step) {
1285
+ let rewardTransferCount = 0;
1286
+ let rewardTransferIndex = -1;
1287
+ for (let i = 3; i < StepSizes7.length; i++) {
1288
+ const stepSize2 = StepSizes7[i];
1289
+ if (block % stepSize2 === 0) {
1290
+ if (stepSize2 === StepSizes7[step]) {
1291
+ rewardTransferIndex = rewardTransferCount;
1292
+ }
1293
+ rewardTransferCount++;
1834
1294
  }
1835
1295
  }
1836
- const isPrimaryForMoniker = (moniker) => {
1837
- switch (typeof primary) {
1838
- case "boolean": {
1839
- return primary;
1840
- }
1841
- case "string": {
1842
- return moniker === primary;
1843
- }
1844
- case "object": {
1845
- if (Array.isArray(primary)) {
1846
- return primary.includes(moniker);
1296
+ assertEx11(rewardTransferIndex >= 0, () => `Could not find step size for step ${step} at block ${block}`);
1297
+ return [rewardTransferIndex, rewardTransferCount];
1298
+ }
1299
+
1300
+ // src/primitives/chain/step/stepRewardBlock.ts
1301
+ import { assertEx as assertEx12 } from "@xylabs/sdk-js";
1302
+ import { StepSizes as StepSizes8 } from "@xyo-network/xl1-protocol-lib";
1303
+ async function stepRewardBlock(context, blockViewer, { block, step }) {
1304
+ assertEx12(block % StepSizes8[step] === 0, () => `Block must be the first block of the step [${StepSizes8[step]}], got ${block}`);
1305
+ return assertEx12(await blockViewer.blockByNumber(block), () => `Could not find block for block number ${block}`);
1306
+ }
1307
+
1308
+ // src/primitives/chain/step/chainStepRewardAddress.ts
1309
+ async function chainStepRewardAddress(context, blockViewer, { block, step }) {
1310
+ const hydratedBlock = await stepRewardBlock(context, blockViewer, { block, step });
1311
+ const [transferIndex, transferCount] = stepTransferIndex(block, step);
1312
+ const [blockBw, payloads] = hydratedBlock;
1313
+ const transfersFromPool = payloads.filter(isTransfer).map((p) => asTransfer(p)).filter(exists).filter((t) => t.from === XYO_STEP_REWARD_ADDRESS);
1314
+ const fromEntries = Object.entries(mergeTransfers(transfersFromPool)[XYO_STEP_REWARD_ADDRESS]);
1315
+ const sortedTransferAmounts = fromEntries.toSorted(([, a], [, b]) => a > b ? -1 : a < b ? 1 : 0);
1316
+ assertEx13(
1317
+ sortedTransferAmounts.length === transferCount,
1318
+ () => `Step Transfers mismatch ${block} (${blockBw._hash}) [${sortedTransferAmounts.length} - ${transferCount}]`
1319
+ );
1320
+ return toAddress4(sortedTransferAmounts[transferIndex][0]);
1321
+ }
1322
+
1323
+ // src/primitives/chain/step/stepRewardTotal.ts
1324
+ import { assertEx as assertEx14, isDefined as isDefined10 } from "@xylabs/sdk-js";
1325
+ import {
1326
+ asAttoXL1,
1327
+ asXL1BlockRange as asXL1BlockRange5,
1328
+ isTransfer as isTransfer5,
1329
+ XYO_STEP_REWARD_ADDRESS as XYO_STEP_REWARD_ADDRESS2
1330
+ } from "@xyo-network/xl1-protocol-lib";
1331
+
1332
+ // src/payloads/AddressPairPayload.ts
1333
+ import { AsObjectFactory } from "@xylabs/sdk-js";
1334
+ import {
1335
+ asSchema,
1336
+ isPayloadOfSchemaType
1337
+ } from "@xyo-network/sdk-js";
1338
+ var AddressPairSchema = asSchema("network.xyo.address.pair", true);
1339
+ var isAddressPairPayload = isPayloadOfSchemaType(AddressPairSchema);
1340
+ var asAddressPairPayload = AsObjectFactory.create(isAddressPairPayload);
1341
+ var asOptionalAddressPairPayload = AsObjectFactory.createOptional(isAddressPairPayload);
1342
+
1343
+ // src/payloads/netBalancesForPayloads.ts
1344
+ import {
1345
+ hexToBigInt as hexToBigInt2,
1346
+ toAddress as toAddress5
1347
+ } from "@xylabs/sdk-js";
1348
+ import { span } from "@xylabs/sdk-js";
1349
+ import { isTransfer as isTransfer2 } from "@xyo-network/xl1-protocol-lib";
1350
+ var netBalancesForPayloads = (context, payloads) => {
1351
+ return span("netBalancesForPayloads", () => {
1352
+ const balances = {};
1353
+ for (const payload of payloads) {
1354
+ if (isTransfer2(payload)) {
1355
+ const { from } = payload;
1356
+ for (const [address, amount] of Object.entries(payload.transfers)) {
1357
+ balances[toAddress5(address)] = (balances[toAddress5(address)] ?? 0n) + hexToBigInt2(amount);
1358
+ balances[toAddress5(from)] = (balances[toAddress5(from)] ?? 0n) - hexToBigInt2(amount);
1847
1359
  }
1848
1360
  }
1849
1361
  }
1850
- throw new Error(`Invalid primary value: ${String(primary)}`);
1851
- };
1852
- const factoryClone = buildProviderFactory(factory, factory.defaultParams, labels);
1853
- registry[factoryClone.defaultMoniker] = [factoryClone, ...registry[factoryClone.defaultMoniker] ?? []];
1854
- for (const moniker of factoryClone.monikers) {
1855
- registry[moniker] = isPrimaryForMoniker(moniker) ? [factoryClone, ...registry[moniker] ?? []] : [...registry[moniker] ?? [], factoryClone];
1856
- }
1857
- };
1858
- var registerCreatableProviderFactories = (factories, registry = {}, primary = false) => {
1859
- for (const factory of factories) {
1860
- registerCreatableProviderFactory(registry, factory, void 0, primary);
1861
- }
1862
- return registry;
1362
+ return balances;
1363
+ }, context.traceProvider);
1863
1364
  };
1864
1365
 
1865
- // src/CreatableProvider/LabeledCreatableProviderFactory.ts
1866
- var hasLabels = (factory) => {
1867
- return factory.labels !== void 0;
1366
+ // src/payloads/netSchemasForPayloads.ts
1367
+ import {
1368
+ hexToBigInt as hexToBigInt3,
1369
+ toAddress as toAddress6
1370
+ } from "@xylabs/sdk-js";
1371
+ import { span as span2 } from "@xylabs/sdk-js";
1372
+ import { isTransfer as isTransfer3 } from "@xyo-network/xl1-protocol-lib";
1373
+ var netSchemasForPayloads = (context, payloads) => {
1374
+ return span2("netSchemasForPayloads", () => {
1375
+ const balances = {};
1376
+ for (const payload of payloads) {
1377
+ if (isTransfer3(payload)) {
1378
+ const { from } = payload;
1379
+ for (const [address, amount] of Object.entries(payload.transfers)) {
1380
+ balances[toAddress6(address)] = (balances[toAddress6(address)] ?? 0n) + hexToBigInt3(amount);
1381
+ balances[toAddress6(from)] = (balances[toAddress6(from)] ?? 0n) - hexToBigInt3(amount);
1382
+ }
1383
+ }
1384
+ }
1385
+ return balances;
1386
+ }, context.traceProvider);
1868
1387
  };
1869
- function labeledCreatableProviderFactory() {
1870
- return (constructor) => {
1871
- constructor;
1872
- };
1388
+
1389
+ // src/payloads/netTransfersForPayloads.ts
1390
+ import {
1391
+ hexToBigInt as hexToBigInt4
1392
+ } from "@xylabs/sdk-js";
1393
+ import { span as span3 } from "@xylabs/sdk-js";
1394
+ import { isTransfer as isTransfer4 } from "@xyo-network/xl1-protocol-lib";
1395
+ function netTransfersForPayloads(context, payloads) {
1396
+ return span3("netTransfersForPayloads", () => {
1397
+ const transfers = {};
1398
+ for (const payload of payloads) {
1399
+ if (isTransfer4(payload)) {
1400
+ const { from } = payload;
1401
+ transfers[from] = transfers[from] ?? {};
1402
+ for (const [to, amount] of Object.entries(payload.transfers)) {
1403
+ transfers[to] = transfers[to] ?? {};
1404
+ transfers[to][from] = (transfers[to][from] ?? 0n) + hexToBigInt4(amount);
1405
+ transfers[from][to] = (transfers[from][to] ?? 0n) - hexToBigInt4(amount);
1406
+ }
1407
+ }
1408
+ }
1409
+ return transfers;
1410
+ }, context.traceProvider);
1873
1411
  }
1874
1412
 
1875
- // src/CreatableProvider/ProviderFactoryLocator.ts
1876
- import { hasAllLabels } from "@xylabs/sdk-js";
1877
- import { assertEx as assertEx14 } from "@xylabs/sdk-js";
1878
- var ProviderFactoryLocator = class _ProviderFactoryLocator {
1879
- _context;
1880
- _registry;
1881
- _frozen = false;
1882
- _parent;
1883
- _validateDepsOnRegister;
1884
- constructor(context, registry = {}, validateDepsOnRegister = false) {
1885
- this._registry = registry;
1886
- this._context = { ...context, locator: this };
1887
- this._parent = context.locator;
1888
- this._validateDepsOnRegister = validateDepsOnRegister;
1889
- }
1890
- get context() {
1891
- return this._context;
1892
- }
1893
- get logger() {
1894
- return this.context.logger;
1895
- }
1896
- /**
1897
- * The current registry for the module factory
1898
- */
1899
- get registry() {
1900
- return this._registry;
1901
- }
1902
- get validateDepsOnRegister() {
1903
- return this._validateDepsOnRegister;
1904
- }
1905
- freeze() {
1906
- this._frozen = true;
1907
- }
1908
- async getInstance(moniker, { start = true, labels } = {}) {
1909
- return assertEx14(
1910
- await this.tryGetInstance(moniker, { start, labels }),
1911
- () => `No provider instance for the supplied config moniker [${moniker}]${labels ? ` & labels [${JSON.stringify(labels)}]` : ""} could be created`
1413
+ // src/primitives/chain/step/stepRewardTotal.ts
1414
+ function stepInRange(step, range) {
1415
+ const stepRange = stepBlockRange(step);
1416
+ return stepRange[0] >= range[0] && stepRange[1] <= range[1];
1417
+ }
1418
+ async function stepRewardTotal(context, blockViewer, { block, step }, multipliers) {
1419
+ const cacheKey = `${block}|${step}|${isDefined10(multipliers)}`;
1420
+ return await withContextCacheResponse(context, "stepRewardTotal", cacheKey, async () => {
1421
+ const [blockBw, payloads] = await stepRewardBlock(context, blockViewer, { block, step });
1422
+ assertEx14(blockBw.block === block, () => `Block Mismatch: expected ${block}, got ${blockBw.block}`);
1423
+ const [transferIndex] = stepTransferIndex(block, step);
1424
+ const stepTransfer = assertEx14(
1425
+ payloads.find((p) => isTransfer5(p) && p.from === XYO_STEP_REWARD_ADDRESS2),
1426
+ () => `No step transfer found for step ${step} at block ${block} (${blockBw._hash})`
1912
1427
  );
1913
- }
1914
- has(moniker) {
1915
- return !!this._registry[moniker];
1916
- }
1917
- /**
1918
- * Locates a provider factory that matches the supplied moniker and labels
1919
- * @param moniker The config moniker for the provider
1920
- * @param labels The labels for the provider factory
1921
- * @returns A provider factory that matches the supplied moniker and labels or throws if one is not found
1922
- */
1923
- locate(moniker, labels) {
1924
- return assertEx14(
1925
- this.tryLocate(moniker, labels),
1926
- () => `No module factory for the supplied config moniker [${moniker}]${labels ? ` & labels [${JSON.stringify(labels)}]` : ""} registered`
1428
+ const rewards = assertEx14(
1429
+ netTransfersForPayloads(context, [stepTransfer])[XYO_STEP_REWARD_ADDRESS2],
1430
+ () => `No rewards found for step reward address ${XYO_STEP_REWARD_ADDRESS2} at block ${block} (${blockBw._hash})`
1927
1431
  );
1432
+ const sortedTransfers = Object.entries(rewards).toSorted(([, a], [, b]) => a > b ? -1 : a < b ? 1 : 0);
1433
+ let result = asAttoXL1(sortedTransfers[transferIndex][1] * -1n);
1434
+ for (const [rangeKey, [numerator, denominator]] of Object.entries(multipliers)) {
1435
+ const rangeParts = rangeKey.split("|").map(Number);
1436
+ const range = asXL1BlockRange5([rangeParts[0], rangeParts[1]], { name: "stepRewardTotal" });
1437
+ if (stepInRange({ block, step }, range)) {
1438
+ result = asAttoXL1(result + result * numerator / denominator);
1439
+ }
1440
+ }
1441
+ return result;
1442
+ });
1443
+ }
1444
+
1445
+ // src/primitives/chain/step/stepsRewardTotal.ts
1446
+ import { asAttoXL1 as asAttoXL12, asXL1BlockRange as asXL1BlockRange6 } from "@xyo-network/xl1-protocol-lib";
1447
+
1448
+ // src/constants.ts
1449
+ var XL1_NETWORK_STAKING_GENESIS_PERIOD_END_EPOCH = 1760572800;
1450
+ var XL1_NETWORK_STAKING_GENESIS_PERIOD_END_XL1_BLOCK = 107496;
1451
+
1452
+ // src/primitives/chain/step/stepsRewardTotal.ts
1453
+ async function stepsRewardTotalGenesisPeriod(context, blockViewer, multipliers, stepSizes) {
1454
+ const range = asXL1BlockRange6([0, XL1_NETWORK_STAKING_GENESIS_PERIOD_END_XL1_BLOCK], { name: "stepsRewardTotalGenesisPeriod" });
1455
+ return await stepsRewardTotalRange(context, blockViewer, range, stepSizes, multipliers);
1456
+ }
1457
+ async function stepsRewardTotalRange(context, blockViewer, range, stepSizes = [3, 4, 5, 6], multipliers) {
1458
+ const steps = blockRangeSteps(range, stepSizes);
1459
+ return await stepsRewardTotal(context, blockViewer, steps, multipliers);
1460
+ }
1461
+ async function stepsRewardTotal(context, blockViewer, steps, multipliers) {
1462
+ let totalRewards = 0n;
1463
+ for (const step of steps) {
1464
+ const stepTotal = await stepRewardTotal(context, blockViewer, step, multipliers);
1465
+ totalRewards += stepTotal;
1928
1466
  }
1929
- merge(locator) {
1930
- const registry = { ...this.registry };
1931
- for (const moniker in locator.registry) {
1932
- if (registry[moniker]) {
1933
- registry[moniker].push(...locator.registry[moniker] ?? []);
1934
- } else {
1935
- registry[moniker] = locator.registry[moniker];
1467
+ return asAttoXL12(totalRewards);
1468
+ }
1469
+
1470
+ // src/primitives/chain/time/externalBlockNumberFromXL1BlockNumber.ts
1471
+ import { assertEx as assertEx15, isArray } from "@xylabs/sdk-js";
1472
+ import {
1473
+ asBlockNumber,
1474
+ asTimePayload,
1475
+ isTimePayload
1476
+ } from "@xyo-network/xl1-protocol-lib";
1477
+ var functionName = "externalBlockNumberFromXL1BlockNumber";
1478
+ async function externalBlockNumberFromXL1BlockNumber(context, blockViewer, xl1BlockNumber, externalTimeName, externalGenesisTime) {
1479
+ const cacheKey = `${xl1BlockNumber}-${externalTimeName}-${externalGenesisTime ?? "default"}`;
1480
+ return await withContextCacheResponse(context, functionName, cacheKey, async () => {
1481
+ const [, payloads = []] = await blockViewer.blockByNumber(xl1BlockNumber) ?? [];
1482
+ assertEx15(isArray(payloads));
1483
+ const timePayload = asTimePayload(payloads.find(isTimePayload));
1484
+ return asBlockNumber(
1485
+ timePayload?.[externalTimeName] ?? externalGenesisTime ?? 23372716,
1486
+ { name: functionName }
1487
+ );
1488
+ });
1489
+ }
1490
+
1491
+ // src/primitives/chain/time/externalBlockRangeFromXL1BlockRange.ts
1492
+ async function externalBlockRangeFromXL1BlockRange(context, blockViewer, xl1BlockRange, externalTimeName = "ethereum") {
1493
+ const start = await externalBlockNumberFromXL1BlockNumber(context, blockViewer, xl1BlockRange[0], externalTimeName);
1494
+ const end = await externalBlockNumberFromXL1BlockNumber(context, blockViewer, xl1BlockRange[1], externalTimeName);
1495
+ return [start, end];
1496
+ }
1497
+
1498
+ // src/primitives/chain/time/externalBlockRangeFromStep.ts
1499
+ async function externalBlockRangeFromStep(context, blockViewer, stepIdentity) {
1500
+ const cacheKey = toStepIdentityString(stepIdentity);
1501
+ return await withContextCacheResponse(context, "externalBlockRangeFromStep", cacheKey, async () => {
1502
+ const xl1BlockRange = stepBlockRange(stepIdentity);
1503
+ return await externalBlockRangeFromXL1BlockRange(context, blockViewer, xl1BlockRange);
1504
+ });
1505
+ }
1506
+
1507
+ // src/primitives/datalake/addDataLakePayloadsToPayloads.ts
1508
+ import { isUndefined as isUndefined3 } from "@xylabs/sdk-js";
1509
+ import { isAnyPayload, PayloadBuilder as PayloadBuilder2 } from "@xyo-network/sdk-js";
1510
+ async function addDataLakePayloadsToPayloads(hashes, payloads, dataLakeViewer) {
1511
+ if (isUndefined3(dataLakeViewer)) return [payloads, []];
1512
+ const missingPayloadHashes = hashes.filter((hash) => !payloads.some((p) => p._hash === hash));
1513
+ const payloadsFromDataLake = await PayloadBuilder2.addHashMeta(
1514
+ await PayloadBuilder2.addHashMeta((await dataLakeViewer.get(missingPayloadHashes)).filter(isAnyPayload))
1515
+ );
1516
+ return [[...payloads, ...payloadsFromDataLake], payloadsFromDataLake.map((p) => p._hash)];
1517
+ }
1518
+
1519
+ // src/primitives/datalake/addDataLakePayloads.ts
1520
+ async function addDataLakePayloads([boundWitness, payloads], dataLakeViewer) {
1521
+ const [updatedPayloads, foundHashes] = await addDataLakePayloadsToPayloads(boundWitness.payload_hashes, payloads, dataLakeViewer);
1522
+ return [
1523
+ [
1524
+ boundWitness,
1525
+ updatedPayloads
1526
+ ],
1527
+ foundHashes
1528
+ ];
1529
+ }
1530
+
1531
+ // src/primitives/mapToMapType.ts
1532
+ import { isDefined as isDefined11 } from "@xylabs/sdk-js";
1533
+ function mapToMapType(map) {
1534
+ return {
1535
+ get: (key) => map.get(key),
1536
+ has: (key) => map.has(key),
1537
+ set: (key, value) => {
1538
+ map.set(key, value);
1539
+ },
1540
+ setMany: (entries) => {
1541
+ for (const [key, value] of entries) {
1542
+ map.set(key, value);
1936
1543
  }
1937
- }
1938
- return new _ProviderFactoryLocator(this.context, registry);
1939
- }
1940
- /**
1941
- * Registers a single module factory (with optional tags) with the locator
1942
- * @param factory The factory to register
1943
- * @param labels The labels for the module factory
1944
- */
1945
- register(factory, labels, primary = false) {
1946
- assertEx14(!this._frozen, () => "Cannot register a module factory after the locator has been frozen");
1947
- if (this.validateDepsOnRegister) {
1948
- const missingDeps = factory.dependencies.filter((dep) => !this.registered(dep));
1949
- assertEx14(missingDeps.length === 0, () => `Cannot register module factory [${factory.uniqueId.description}] due to missing dependencies: ${missingDeps.join(", ")}`);
1950
- }
1951
- registerCreatableProviderFactory(this._registry, factory, labels, primary);
1952
- return this;
1953
- }
1954
- /**
1955
- * Registers multiple module factories with the locator
1956
- * @param factories The factories to register
1957
- */
1958
- registerMany(factories) {
1959
- for (const factory of factories) {
1960
- this.register(factory);
1961
- }
1962
- return this;
1963
- }
1964
- registered(moniker) {
1965
- return !!this.registry[moniker] || (this._parent?.registered(moniker) ?? false);
1966
- }
1967
- async tryGetInstance(moniker, { start = true, labels } = {}) {
1968
- const resolvedParams = { context: this.context };
1969
- const factory = this.tryLocate(moniker, labels);
1970
- if (factory) {
1971
- if (this.context.singletons[factory.uniqueId]) {
1972
- return this.context.singletons[factory.uniqueId];
1544
+ },
1545
+ delete: (key) => map.delete(key),
1546
+ clear: () => map.clear(),
1547
+ getMany: (keys) => {
1548
+ const result = [];
1549
+ for (const key of keys) {
1550
+ const value = map.get(key);
1551
+ if (isDefined11(value)) {
1552
+ result.push(value);
1553
+ }
1973
1554
  }
1974
- this.logger?.info(`Creating provider instance for moniker [${moniker}]${labels ? ` with labels [${JSON.stringify(labels)}]` : ""} using factory [${factory.uniqueId.description}]`);
1975
- const result = await factory.getInstance(resolvedParams, { start });
1976
- this.context.singletons[factory.uniqueId] = result;
1977
1555
  return result;
1978
- }
1979
- }
1980
- /**
1981
- * Tries to locate a module factory that matches the supplied moniker and labels
1982
- * @param moniker The config moniker for the module
1983
- * @param labels The labels for the module factory
1984
- * @returns A module factory that matches the supplied moniker and labels or undefined
1985
- */
1986
- tryLocate(moniker, labels) {
1987
- const result = (labels ? this._registry[moniker]?.filter(hasLabels).find((factory) => hasAllLabels(factory?.labels, labels)) ?? this._registry[moniker]?.[0] : this._registry[moniker]?.[0]) ?? this._parent?.tryLocate(moniker, labels);
1988
- return result;
1989
- }
1990
- validateDependencies(recursive = false) {
1991
- if (recursive) {
1992
- this._parent?.validateDependencies();
1993
- }
1994
- for (const moniker in this.registry) {
1995
- for (const factory of this.registry[moniker] ?? []) {
1996
- const missingDeps = factory.dependencies.filter((dep) => !this.registered(dep));
1997
- assertEx14(missingDeps.length === 0, () => `Module factory [${factory.uniqueId.description}] is missing dependencies: ${missingDeps.join(", ")}`);
1556
+ },
1557
+ [Symbol.iterator]: function* () {
1558
+ for (const entry of map) {
1559
+ yield entry;
1998
1560
  }
1999
1561
  }
2000
- }
2001
- };
1562
+ };
1563
+ }
2002
1564
 
2003
- // src/context/getEmptyProviderContext.ts
2004
- function getEmptyProviderContext(config) {
2005
- const singletons = {};
2006
- const caches = {};
2007
- const locator = new ProviderFactoryLocator({
2008
- config,
2009
- singletons,
2010
- caches,
2011
- logger: console
2012
- });
2013
- return locator.context;
1565
+ // src/primitives/readPayloadMapFromStore.ts
1566
+ import { isDefined as isDefined12 } from "@xylabs/sdk-js";
1567
+ function readPayloadMapFromStore(store) {
1568
+ if (isReadArchivist(store)) {
1569
+ return {
1570
+ get: async (hash) => {
1571
+ return (await store.get([hash]))[0];
1572
+ },
1573
+ getMany: async (hashes) => {
1574
+ return await store.get(hashes);
1575
+ },
1576
+ has: async (hash) => {
1577
+ return isDefined12((await store.get([hash]))[0]);
1578
+ }
1579
+ };
1580
+ }
1581
+ return store;
2014
1582
  }
2015
- function getEmptyContext(config) {
2016
- return getEmptyProviderContext(config);
1583
+ function payloadMapFromStore(store) {
1584
+ if (isReadWriteArchivist(store)) {
1585
+ return {
1586
+ get: async (hash) => {
1587
+ return (await store.get([hash]))[0];
1588
+ },
1589
+ getMany: async (hashes) => {
1590
+ return await store.get(hashes);
1591
+ },
1592
+ has: async (hash) => {
1593
+ return isDefined12((await store.get([hash]))[0]);
1594
+ },
1595
+ clear: async () => {
1596
+ return await store.clear();
1597
+ },
1598
+ delete: async (id) => {
1599
+ await store.delete([id]);
1600
+ return true;
1601
+ },
1602
+ set: async (_id, data) => {
1603
+ await store.insert([data]);
1604
+ },
1605
+ setMany: async (entries) => {
1606
+ await store.insert(entries.map((e) => e[1]));
1607
+ }
1608
+ };
1609
+ }
1610
+ return store;
2017
1611
  }
2018
1612
 
2019
- // src/context/HostActor.ts
2020
- import {
2021
- zodAsFactory as zodAsFactory6,
2022
- zodIsFactory as zodIsFactory6,
2023
- zodToFactory as zodToFactory6
2024
- } from "@xylabs/sdk-js";
2025
- var HostActorConfigContext = BaseConfigContextZod.extend({ config: HostActorConfigZod });
2026
- var isHostActorConfigContext = zodIsFactory6(HostActorConfigContext);
2027
- var asHostActorConfigContext = zodAsFactory6(HostActorConfigContext, "asHostActorConfigContext");
2028
- var toHostActorConfigContext = zodToFactory6(HostActorConfigContext, "toHostActorConfigContext");
2029
-
2030
- // src/createDeclarationPayload.ts
2031
- import { isDefined as isDefined6 } from "@xylabs/sdk-js";
2032
- import { PayloadBuilder as PayloadBuilder12 } from "@xyo-network/sdk-js";
1613
+ // src/primitives/rewardFromBlockNumber.ts
2033
1614
  import {
2034
- ChainStakeIntentSchema
1615
+ asAttoXL1 as asAttoXL13,
1616
+ XL1_REWARDS_BLOCKS_PER_STEP,
1617
+ XL1_REWARDS_CREATOR_REWARD,
1618
+ XL1_REWARDS_MIN_BLOCK_REWARD,
1619
+ XL1_REWARDS_STARTING_REWARD,
1620
+ XL1_REWARDS_STEP_FACTOR_DENOMINATOR,
1621
+ XL1_REWARDS_STEP_FACTOR_NUMERATOR
2035
1622
  } from "@xyo-network/xl1-protocol-lib";
2036
- var createDeclarationIntent = (address, intent, nbf, exp) => {
2037
- const expiration = isDefined6(exp) ? exp : nbf + 1e4;
2038
- const redeclarationIntent = new PayloadBuilder12({ schema: ChainStakeIntentSchema }).fields({
2039
- from: address,
2040
- intent,
2041
- nbf,
2042
- exp: expiration
2043
- }).build();
2044
- return redeclarationIntent;
2045
- };
2046
-
2047
- // src/eip-712/Payloads/EIP712Data.ts
2048
- import { AsObjectFactory } from "@xylabs/sdk-js";
2049
- import {
2050
- asSchema,
2051
- isPayloadOfZodType
2052
- } from "@xyo-network/sdk-js";
2053
- import { z as z24 } from "zod";
1623
+ function rewardFromBlockNumber(blockNumber) {
1624
+ if (blockNumber === 0) {
1625
+ return XL1_REWARDS_CREATOR_REWARD;
1626
+ }
1627
+ const step = Math.floor((blockNumber + XL1_REWARDS_BLOCKS_PER_STEP) / XL1_REWARDS_BLOCKS_PER_STEP);
1628
+ const stepExp = BigInt(step - 1);
1629
+ const poweredNumerator = stepExp > 0 ? XL1_REWARDS_STEP_FACTOR_NUMERATOR ** stepExp : 1n;
1630
+ const poweredDenominator = stepExp > 0 ? XL1_REWARDS_STEP_FACTOR_DENOMINATOR ** stepExp : 1n;
1631
+ const reward = XL1_REWARDS_STARTING_REWARD * poweredNumerator / poweredDenominator;
1632
+ return asAttoXL13(reward < XL1_REWARDS_MIN_BLOCK_REWARD ? XL1_REWARDS_MIN_BLOCK_REWARD : reward);
1633
+ }
2054
1634
 
2055
- // src/eip-712/Types.ts
2056
- import { z as z23 } from "zod";
2057
- var TypedDataDomainZod = z23.object({
2058
- name: z23.string().nullable().optional(),
2059
- version: z23.string().nullable().optional(),
2060
- chainId: z23.union([z23.string(), z23.number(), z23.bigint()]).nullable().optional(),
2061
- verifyingContract: z23.string().nullable().optional(),
2062
- salt: z23.union([z23.string(), z23.instanceof(Uint8Array)]).nullable().optional()
2063
- });
2064
- var TypedDataFieldZod = z23.object({
2065
- name: z23.string(),
2066
- type: z23.string()
2067
- });
2068
- var TypedDataTypesZod = z23.record(z23.string(), z23.array(TypedDataFieldZod));
2069
- var TypedDataValueZod = z23.record(z23.string(), z23.any());
1635
+ // src/primitives/rewards/networkStakeStepRewardPositionWeight.ts
1636
+ import { XYO_NETWORK_STAKING_ADDRESS } from "@xyo-network/xl1-protocol-lib";
2070
1637
 
2071
- // src/eip-712/Payloads/EIP712Data.ts
2072
- var EIP712DataPayloadFieldsZod = z24.object({
2073
- domain: TypedDataDomainZod,
2074
- types: TypedDataTypesZod,
2075
- values: TypedDataValueZod
2076
- });
2077
- var EIP712DataPayloadSchema = asSchema("network.xyo.chains.ethereum.eip712.data", true);
2078
- var isEIP712DataPayload = isPayloadOfZodType(
2079
- EIP712DataPayloadFieldsZod,
2080
- EIP712DataPayloadSchema
2081
- );
2082
- var asEIP712DataPayload = AsObjectFactory.create(isEIP712DataPayload);
1638
+ // src/primitives/stake/activeStakeAtTimeByAddress.ts
1639
+ import { isDefined as isDefined13 } from "@xylabs/sdk-js";
2083
1640
 
2084
- // src/eip-712/Payloads/EIP712Signature.ts
2085
- import { AsObjectFactory as AsObjectFactory2, HashZod } from "@xylabs/sdk-js";
2086
- import {
2087
- asSchema as asSchema2,
2088
- isPayloadOfZodType as isPayloadOfZodType2
2089
- } from "@xyo-network/sdk-js";
2090
- import { z as z25 } from "zod";
2091
- var EIP712SignaturePayloadFieldsZod = z25.object({
2092
- address: z25.string(),
2093
- hash: HashZod,
2094
- signature: z25.string()
2095
- });
2096
- var EIP712SignaturePayloadSchema = asSchema2("network.xyo.chains.ethereum.eip712.signature", true);
2097
- var isEIP712SignaturePayload = isPayloadOfZodType2(
2098
- EIP712SignaturePayloadFieldsZod,
2099
- EIP712SignaturePayloadSchema
2100
- );
2101
- var asEIP712SignaturePayload = AsObjectFactory2.create(isEIP712SignaturePayload);
1641
+ // src/primitives/stake/mergedAddRemoveStakeEventsByStaker.ts
1642
+ async function mergedAddRemoveStakeEventsByStaker(chainEvents, range, staked, staker) {
1643
+ const [addedEvents, removedEvents] = await Promise.all([
1644
+ chainEvents.stakeEvents(range, { name: "StakeAdded", args: { staked, staker } }),
1645
+ chainEvents.stakeEvents(range, { name: "StakeRemoved", args: { staked, staker } })
1646
+ ]);
1647
+ const result = [...addedEvents, ...removedEvents].toSorted((a, b) => a.time - b.time);
1648
+ return result;
1649
+ }
2102
1650
 
2103
- // src/eip-712/sign.ts
2104
- import { PayloadBuilder as PayloadBuilder13 } from "@xyo-network/sdk-js";
2105
- var signEIP712Message = async (signer, data) => {
2106
- const {
2107
- domain,
2108
- types,
2109
- values
2110
- } = data;
2111
- const signature = await signer.signTypedData(domain, types, values);
2112
- const hash = await PayloadBuilder13.hash(data);
2113
- const address = await signer.getAddress();
2114
- return {
2115
- address,
2116
- hash,
2117
- schema: EIP712SignaturePayloadSchema,
2118
- signature
2119
- };
2120
- };
1651
+ // src/primitives/stake/activeStakeAtTimeByAddress.ts
1652
+ async function activeStakeAtTimeByAddress(chain, staked, time, staker) {
1653
+ const stakeEvents = (await mergedAddRemoveStakeEventsByStaker(chain, [0, time], staked, staker)).toSorted((a, b) => a.time - b.time);
1654
+ let result = 0n;
1655
+ for (const event of stakeEvents) {
1656
+ if (event.time > time) break;
1657
+ if (event.args.staked !== staked) continue;
1658
+ if (isDefined13(staker) && event.args.staker !== staker) continue;
1659
+ if (event.name === "StakeAdded") {
1660
+ result += event.args.amount;
1661
+ } else if (event.name === "StakeRemoved") {
1662
+ result -= event.args.amount;
1663
+ }
1664
+ }
1665
+ return result;
1666
+ }
2121
1667
 
2122
- // src/eip-712/verify.ts
2123
- import { asHash as asHash4, isUndefined as isUndefined3 } from "@xylabs/sdk-js";
2124
- import { PayloadBuilder as PayloadBuilder14 } from "@xyo-network/sdk-js";
2125
- import { verifyTypedData } from "ethers";
2126
- var verifyEIP712Message = async (data, sig) => {
2127
- const {
2128
- address,
2129
- signature,
2130
- hash
2131
- } = sig;
2132
- const { schema, ...fields } = data;
2133
- const signedHash = asHash4(hash);
2134
- if (isUndefined3(signedHash) || signedHash !== await PayloadBuilder14.hash(data)) return false;
2135
- const recoveredAddress = verifyTypedData(fields.domain, fields.types, fields.values, signature);
2136
- return recoveredAddress.toLowerCase() === address.toLowerCase();
2137
- };
1668
+ // src/primitives/stake/activeStakeAtTimeByPosition.ts
1669
+ import { isUndefined as isUndefined4 } from "@xylabs/sdk-js";
2138
1670
 
2139
- // src/multipliers.ts
2140
- import { asAttoXL1 } from "@xyo-network/xl1-protocol-lib";
2141
- var XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_EARNED_REWARDS = asAttoXL1(1343884111859145740576652n);
2142
- var XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_BONUS_REWARDS = asAttoXL1(100000000000000000000000000n);
2143
- var XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_REWARDS = XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_EARNED_REWARDS + XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_BONUS_REWARDS;
2144
- var RewardMultipliers = {
2145
- [`0|${XL1_NETWORK_STAKING_GENESIS_PERIOD_END_XL1_BLOCK}`]: [XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_BONUS_REWARDS, XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_EARNED_REWARDS]
2146
- };
1671
+ // src/primitives/stake/mergedAddRemoveStakeEventsByPosition.ts
1672
+ async function mergedAddRemoveStakeEventsByPosition(chainEvents, range, position) {
1673
+ const [addedEvents, removedEvents] = await Promise.all([
1674
+ chainEvents.stakeEvents(range, { name: "StakeAdded", args: { id: position } }),
1675
+ chainEvents.stakeEvents(range, { name: "StakeRemoved", args: { id: position } })
1676
+ ]);
1677
+ const result = [...addedEvents, ...removedEvents].toSorted((a, b) => a.time - b.time);
1678
+ return result;
1679
+ }
2147
1680
 
2148
- // src/payloads/AddressPairPayload.ts
2149
- import { AsObjectFactory as AsObjectFactory3 } from "@xylabs/sdk-js";
2150
- import {
2151
- asSchema as asSchema3,
2152
- isPayloadOfSchemaType
2153
- } from "@xyo-network/sdk-js";
2154
- var AddressPairSchema = asSchema3("network.xyo.address.pair", true);
2155
- var isAddressPairPayload = isPayloadOfSchemaType(AddressPairSchema);
2156
- var asAddressPairPayload = AsObjectFactory3.create(isAddressPairPayload);
2157
- var asOptionalAddressPairPayload = AsObjectFactory3.createOptional(isAddressPairPayload);
1681
+ // src/primitives/stake/activeStakeAtTimeByPosition.ts
1682
+ async function activeStakeAtTimeByPosition(chainStakeEvents, externalTime, position) {
1683
+ const stakeEvents = (await mergedAddRemoveStakeEventsByPosition(chainStakeEvents, [0, externalTime], position)).toSorted((a, b) => a.time - b.time);
1684
+ let result = 0n;
1685
+ for (const event of stakeEvents) {
1686
+ if (event.time > externalTime) break;
1687
+ if (isUndefined4(position) || position === Number(event.args.id)) {
1688
+ if (event.name === "StakeAdded") {
1689
+ result += event.args.amount;
1690
+ } else if (event.name === "StakeRemoved") {
1691
+ result -= event.args.amount;
1692
+ }
1693
+ }
1694
+ }
1695
+ return result;
1696
+ }
2158
1697
 
2159
- // src/payloads/netBalancesForPayloads.ts
1698
+ // src/primitives/stake/allStakersForRange.ts
2160
1699
  import {
2161
- hexToBigInt,
2162
- toAddress
1700
+ toAddress as toAddress7
2163
1701
  } from "@xylabs/sdk-js";
2164
- import { span } from "@xylabs/sdk-js";
2165
- import { isTransfer } from "@xyo-network/xl1-protocol-lib";
2166
- var netBalancesForPayloads = (context, payloads) => {
2167
- return span("netBalancesForPayloads", () => {
2168
- const balances = {};
2169
- for (const payload of payloads) {
2170
- if (isTransfer(payload)) {
2171
- const { from } = payload;
2172
- for (const [address, amount] of Object.entries(payload.transfers)) {
2173
- balances[toAddress(address)] = (balances[toAddress(address)] ?? 0n) + hexToBigInt(amount);
2174
- balances[toAddress(from)] = (balances[toAddress(from)] ?? 0n) - hexToBigInt(amount);
1702
+ async function allStakersForRange(chain, externalRange, staked) {
1703
+ const mergedEvents = await mergedAddRemoveStakeEventsByStaker(chain, [0, externalRange[1]], staked);
1704
+ const resultWithZeros = {};
1705
+ for (const event of mergedEvents) {
1706
+ const staker = toAddress7(event.args.staker);
1707
+ resultWithZeros[staker] = resultWithZeros[staker] ?? 0n;
1708
+ if (event.name === "StakeAdded") {
1709
+ resultWithZeros[staker] += event.args.amount;
1710
+ } else if (event.name === "StakeRemoved") {
1711
+ resultWithZeros[staker] -= event.args.amount;
1712
+ }
1713
+ }
1714
+ const nonZero = Object.entries(resultWithZeros).filter(([, amount]) => amount > 0n).map(([address]) => address);
1715
+ const result = {};
1716
+ for (const address of nonZero) {
1717
+ result[toAddress7(address)] = resultWithZeros[toAddress7(address)];
1718
+ }
1719
+ return result;
1720
+ }
1721
+
1722
+ // src/primitives/stake/allStakersForStep.ts
1723
+ async function allStakersForStep(context, blockViewer, stakeEventsViewer, stepContext, staked) {
1724
+ const xl1BlockRange = stepBlockRange(stepContext);
1725
+ return await allStakersForRange(
1726
+ stakeEventsViewer,
1727
+ await externalBlockRangeFromXL1BlockRange(context, blockViewer, xl1BlockRange),
1728
+ staked
1729
+ );
1730
+ }
1731
+
1732
+ // src/primitives/stake/weightedStakeForRangeByPosition.ts
1733
+ import { isDefined as isDefined14 } from "@xylabs/sdk-js";
1734
+ import { asBlockNumber as asBlockNumber2 } from "@xyo-network/xl1-protocol-lib";
1735
+ async function weightedStakeForRangeByPosition(context, blockViewer, stakeEventsViewer, externalRange, staked, positionId) {
1736
+ const cacheKey = isDefined14(positionId) ? `${externalRange[0]}-${externalRange[1]}-${positionId}` : `${externalRange[0]}-${externalRange[1]}-all`;
1737
+ return await withContextCacheResponse(context, "weightedStakeForRangeByPosition", cacheKey, async () => {
1738
+ let weightedStakeSum = 0n;
1739
+ if (isDefined14(positionId)) {
1740
+ const mergedEvents = (await mergedAddRemoveStakeEventsByPosition(
1741
+ stakeEventsViewer,
1742
+ [0, externalRange[1]],
1743
+ positionId
1744
+ )).toSorted((a, b) => a.time - b.time);
1745
+ let currentTime = externalRange[0];
1746
+ let currentStake = 0n;
1747
+ if (isDefined14(staked) && mergedEvents.at(0)?.args.staked !== staked) {
1748
+ return 0n;
1749
+ }
1750
+ for (const event of mergedEvents) {
1751
+ if (event.time > currentTime) {
1752
+ weightedStakeSum += currentStake * BigInt(event.time - currentTime);
1753
+ }
1754
+ if (event.name === "StakeAdded") {
1755
+ currentStake += event.args.amount;
1756
+ } else if (event.name === "StakeRemoved") {
1757
+ currentStake -= event.args.amount;
1758
+ }
1759
+ currentStake = currentStake < 0n ? 0n : currentStake;
1760
+ currentTime = asBlockNumber2(event.time, { name: "weightedStakeForRangeByPosition" });
1761
+ if (currentTime > externalRange[1]) {
1762
+ break;
2175
1763
  }
2176
1764
  }
1765
+ if (externalRange[1] > currentTime) {
1766
+ weightedStakeSum += currentStake * BigInt(externalRange[1] - currentTime);
1767
+ }
1768
+ } else {
1769
+ const positionCount = await stakeEventsViewer.positionCount([0, externalRange[1]]);
1770
+ for (let pos = 0; pos < positionCount; pos++) {
1771
+ weightedStakeSum += await weightedStakeForRangeByPosition(context, blockViewer, stakeEventsViewer, externalRange, staked, pos);
1772
+ }
2177
1773
  }
2178
- return balances;
2179
- }, context.traceProvider);
1774
+ return weightedStakeSum;
1775
+ });
1776
+ }
1777
+
1778
+ // src/primitives/rewards/networkStakeStepRewardPositionWeight.ts
1779
+ async function networkStakeStepRewardPositionWeight(context, blockViewer, stakeEventsViewer, stepContext, position) {
1780
+ const result = await weightedStakeForRangeByPosition(
1781
+ context,
1782
+ blockViewer,
1783
+ stakeEventsViewer,
1784
+ await externalBlockRangeFromStep(context, blockViewer, stepContext),
1785
+ XYO_NETWORK_STAKING_ADDRESS,
1786
+ position
1787
+ );
1788
+ return result;
1789
+ }
1790
+
1791
+ // src/primitives/state/findMostRecentBlock.ts
1792
+ import { isSignedBlockBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol-lib";
1793
+ var DEFAULT_NEXT_OPTIONS = { limit: 50 };
1794
+ var findMostRecentBlock = async (chainArchivist, nextOptions = DEFAULT_NEXT_OPTIONS, maxIterations = Number.POSITIVE_INFINITY) => {
1795
+ let mostRecentBlock;
1796
+ let cursor;
1797
+ let batch;
1798
+ let iterations = 0;
1799
+ do {
1800
+ batch = await chainArchivist.next({
1801
+ ...nextOptions,
1802
+ order: "desc",
1803
+ cursor
1804
+ });
1805
+ const blocks = batch.filter(isSignedBlockBoundWitnessWithStorageMeta);
1806
+ const last = blocks?.at(0);
1807
+ if (last) {
1808
+ mostRecentBlock = last;
1809
+ break;
1810
+ } else {
1811
+ cursor = batch.at(-1)?._sequence;
1812
+ }
1813
+ iterations = iterations + 1;
1814
+ } while (batch.length > 0 && iterations < maxIterations);
1815
+ return mostRecentBlock;
2180
1816
  };
2181
1817
 
2182
- // src/payloads/netSchemasForPayloads.ts
2183
- import {
2184
- hexToBigInt as hexToBigInt2,
2185
- toAddress as toAddress2
2186
- } from "@xylabs/sdk-js";
2187
- import { span as span2 } from "@xylabs/sdk-js";
2188
- import { isTransfer as isTransfer2 } from "@xyo-network/xl1-protocol-lib";
2189
- var netSchemasForPayloads = (context, payloads) => {
2190
- return span2("netSchemasForPayloads", () => {
2191
- const balances = {};
2192
- for (const payload of payloads) {
2193
- if (isTransfer2(payload)) {
2194
- const { from } = payload;
2195
- for (const [address, amount] of Object.entries(payload.transfers)) {
2196
- balances[toAddress2(address)] = (balances[toAddress2(address)] ?? 0n) + hexToBigInt2(amount);
2197
- balances[toAddress2(from)] = (balances[toAddress2(from)] ?? 0n) - hexToBigInt2(amount);
2198
- }
1818
+ // src/primitives/state/hydratedBlockByNumber.ts
1819
+ import { assertEx as assertEx16, spanAsync as spanAsync2 } from "@xylabs/sdk-js";
1820
+ async function hydratedBlockByNumber(context, blockNumber) {
1821
+ return await spanAsync2("hydratedBlockByNumber", async () => {
1822
+ if (blockNumber < 0) throw new Error(`Block number ${blockNumber} is less than 0`);
1823
+ if (blockNumber > Number.MAX_SAFE_INTEGER) throw new Error(`Block number ${blockNumber} is greater than the maximum safe integer`);
1824
+ if (blockNumber % 1 !== 0) throw new Error(`Block number ${blockNumber} is not an integer`);
1825
+ const cacheKey = `${blockNumber}`;
1826
+ return await withContextCacheResponse(context, "hydratedBlockByNumber", cacheKey, async () => {
1827
+ const block = assertEx16(
1828
+ await blockFromBlockNumber(context, blockNumber),
1829
+ () => `Could not find block for block number ${blockNumber}`
1830
+ );
1831
+ return await hydrateBlock(context, block._hash);
1832
+ }, { max: 2e4 });
1833
+ }, { ...context, timeBudgetLimit: 500 });
1834
+ }
1835
+
1836
+ // src/primitives/transaction/elevatedPayloads.ts
1837
+ import { isAllowedBlockPayload } from "@xyo-network/xl1-protocol-lib";
1838
+ var ELEVATE_OPCODE = "elevate";
1839
+ function elevatedPayloads([tx, payloads]) {
1840
+ const opCodes = (tx.script ?? []).filter((operation) => operation.startsWith(`${ELEVATE_OPCODE}|`));
1841
+ const elevatedPayloads2 = [];
1842
+ for (const opCode of opCodes) {
1843
+ const [code, hash] = opCode.split("|");
1844
+ if (code === ELEVATE_OPCODE) {
1845
+ const elevatedPayload = payloads.find((payload) => payload._hash === hash);
1846
+ if (isAllowedBlockPayload(elevatedPayload)) {
1847
+ elevatedPayloads2.push(elevatedPayload);
2199
1848
  }
2200
1849
  }
2201
- return balances;
2202
- }, context.traceProvider);
2203
- };
1850
+ }
1851
+ if (opCodes.length === elevatedPayloads2.length) {
1852
+ return elevatedPayloads2;
1853
+ }
1854
+ throw new Error("Not all elevated payloads could be found in the transaction payloads");
1855
+ }
1856
+
1857
+ // src/primitives/uncle/getProducerKey.ts
1858
+ function getProducerKey(block) {
1859
+ return block[0].addresses.toSorted().join(",");
1860
+ }
1861
+
1862
+ // src/primitives/uncle/scoreUncle.ts
1863
+ var PRODUCER_DIVERSITY_BONUS = 1e3;
1864
+ function scoreUncle(finalizedWindowedChain, blocks) {
1865
+ if (blocks.length === 0) return 0;
1866
+ let score = blocks.length;
1867
+ const head = finalizedWindowedChain.at(-1);
1868
+ if (head && blocks[0]) {
1869
+ const headProducer = getProducerKey(head);
1870
+ const candidateProducer = getProducerKey(blocks[0]);
1871
+ if (headProducer !== candidateProducer) {
1872
+ score += PRODUCER_DIVERSITY_BONUS;
1873
+ }
1874
+ }
1875
+ return score;
1876
+ }
1877
+
1878
+ // src/primitives/uncle/findBestUncle.ts
1879
+ var DEFAULT_MIN_CANDIDATES = 2;
1880
+ var DEFAULT_BACKOFF_MS = 12e4;
1881
+ function findBestUncle(finalizedWindowedChain, uncles, options) {
1882
+ if (uncles.length === 0) return void 0;
1883
+ const minCandidates = options?.minCandidates ?? DEFAULT_MIN_CANDIDATES;
1884
+ const backoffMs = options?.backoffMs ?? DEFAULT_BACKOFF_MS;
1885
+ const now = options?.now ?? Date.now();
1886
+ if (uncles.length < minCandidates) {
1887
+ const headEpoch = finalizedWindowedChain.at(-1)?.[0].$epoch ?? 0;
1888
+ const headAge = now - headEpoch;
1889
+ if (headAge < backoffMs) {
1890
+ return void 0;
1891
+ }
1892
+ }
1893
+ const scores = uncles.map((uncle) => [scoreUncle(finalizedWindowedChain, uncle), uncle]).toSorted((a, b) => b[0] - a[0]);
1894
+ return scores[0]?.[1];
1895
+ }
2204
1896
 
2205
- // src/payloads/netTransfersForPayloads.ts
1897
+ // src/primitives/uncle/findUncles.ts
2206
1898
  import {
2207
- hexToBigInt as hexToBigInt3
1899
+ assertEx as assertEx17,
1900
+ exists as exists2
2208
1901
  } from "@xylabs/sdk-js";
2209
- import { span as span3 } from "@xylabs/sdk-js";
2210
- import { isTransfer as isTransfer3 } from "@xyo-network/xl1-protocol-lib";
2211
- function netTransfersForPayloads(context, payloads) {
2212
- return span3("netTransfersForPayloads", () => {
2213
- const transfers = {};
2214
- for (const payload of payloads) {
2215
- if (isTransfer3(payload)) {
2216
- const { from } = payload;
2217
- transfers[from] = transfers[from] ?? {};
2218
- for (const [to, amount] of Object.entries(payload.transfers)) {
2219
- transfers[to] = transfers[to] ?? {};
2220
- transfers[to][from] = (transfers[to][from] ?? 0n) + hexToBigInt3(amount);
2221
- transfers[from][to] = (transfers[from][to] ?? 0n) - hexToBigInt3(amount);
2222
- }
1902
+ import { isTransactionBoundWitness as isTransactionBoundWitness2 } from "@xyo-network/xl1-protocol-lib";
1903
+ function blocksToChains(blocks) {
1904
+ const chains = [];
1905
+ const map = /* @__PURE__ */ new Map();
1906
+ for (const block of blocks) {
1907
+ map.set(block[0]._hash, block);
1908
+ }
1909
+ for (const block of blocks) {
1910
+ let uncle = [block];
1911
+ let previous = block[0].previous ? map.get(block[0].previous) : void 0;
1912
+ while (previous) {
1913
+ if (previous[0].block === uncle[0][0].block - 1) {
1914
+ uncle.unshift(previous);
1915
+ previous = previous[0].previous ? map.get(previous[0].previous) : void 0;
1916
+ } else {
1917
+ uncle = [];
1918
+ break;
2223
1919
  }
2224
1920
  }
2225
- return transfers;
2226
- }, context.traceProvider);
2227
- }
2228
-
2229
- // src/primitives/block/range/blockRangeSteps.ts
2230
- import { asXL1BlockNumber as asXL1BlockNumber4, StepSizes as StepSizes3 } from "@xyo-network/xl1-protocol-lib";
2231
- function blockRangeSteps(range, steps) {
2232
- const result = [];
2233
- for (const step of steps) {
2234
- const stepSize2 = StepSizes3[step];
2235
- const startOfFirstStepCandidate = range[0] - range[0] % stepSize2 + stepSize2;
2236
- const startOfFirstStep = asXL1BlockNumber4(
2237
- startOfFirstStepCandidate,
2238
- { name: "blockRangeSteps" }
2239
- );
2240
- for (let block = startOfFirstStep; block <= range[1]; block = asXL1BlockNumber4(block + stepSize2, { name: "blockRangeSteps" })) {
2241
- result.push({ step, block });
1921
+ if (uncle.length > 0) {
1922
+ chains.push(uncle);
2242
1923
  }
2243
1924
  }
2244
- return result;
1925
+ return chains;
2245
1926
  }
2246
-
2247
- // src/primitives/block/rate/blockRate.ts
2248
- import { isDefined as isDefined8, isFalsy } from "@xylabs/sdk-js";
2249
- import { asXL1BlockRange } from "@xyo-network/xl1-protocol-lib";
2250
-
2251
- // src/primitives/block/rate/timeHelpers.ts
2252
- import { assertEx as assertEx15, isDefined as isDefined7 } from "@xylabs/sdk-js";
2253
- var rateMultipliers = {
2254
- millis: 1,
2255
- seconds: 1e3,
2256
- minutes: 1e3 * 60,
2257
- hours: 1e3 * 60 * 60,
2258
- days: 1e3 * 60 * 60 * 24,
2259
- weeks: 1e3 * 60 * 60 * 24 * 7
2260
- };
2261
- var timeDurations = (timeInMs) => ({
2262
- millis: timeInMs,
2263
- seconds: timeInMs / 1e3,
2264
- minutes: timeInMs / (1e3 * 60),
2265
- hours: timeInMs / (1e3 * 60 * 60),
2266
- days: timeInMs / (1e3 * 60 * 60 * 24),
2267
- weeks: timeInMs / (1e3 * 60 * 60 * 24 * 7)
2268
- });
2269
- var getTimeConfigInMilliseconds = (timeConfig) => {
2270
- const assertedTimeConfig = assertEx15(isDefined7(timeConfig) ? timeConfig : void 0, () => "Time configuration must be provided");
2271
- let totalMilliseconds = 0;
2272
- if ("years" in assertedTimeConfig) {
2273
- totalMilliseconds += assertedTimeConfig.years * 31536e6;
2274
- return totalMilliseconds;
2275
- }
2276
- if ("months" in assertedTimeConfig) {
2277
- totalMilliseconds += assertedTimeConfig.months * 2592e6;
2278
- return totalMilliseconds;
1927
+ function toValidUncle(_context, finalizedWindowedChain, possibleUncle) {
1928
+ const finalizedWindowStartBlockNumber = finalizedWindowedChain.at(0)?.[0].block ?? -1;
1929
+ const finalizedHead = assertEx17(finalizedWindowedChain.at(-1), () => "finalizedWindowedChain is empty");
1930
+ const prunedPossibleUncle = possibleUncle.filter((b) => b[0].block > finalizedHead[0].block);
1931
+ if (prunedPossibleUncle.length === 0) {
1932
+ return;
2279
1933
  }
2280
- if ("weeks" in assertedTimeConfig) {
2281
- totalMilliseconds += assertedTimeConfig.weeks * 6048e5;
2282
- return totalMilliseconds;
1934
+ if (prunedPossibleUncle[0][0].block !== finalizedHead[0].block + 1) {
1935
+ return;
2283
1936
  }
2284
- if ("days" in assertedTimeConfig) {
2285
- totalMilliseconds += assertedTimeConfig.days * 864e5;
2286
- return totalMilliseconds;
1937
+ if (prunedPossibleUncle[0][0].previous !== finalizedHead[0]._hash) {
1938
+ return;
2287
1939
  }
2288
- if ("hours" in assertedTimeConfig) {
2289
- totalMilliseconds += assertedTimeConfig.hours * 36e5;
2290
- return totalMilliseconds;
1940
+ const allUncleTransactions = prunedPossibleUncle.flatMap((b) => b[1]).filter(isTransactionBoundWitness2);
1941
+ const allFinalizedTransactions = finalizedWindowedChain.flatMap((b) => b[1]).filter(isTransactionBoundWitness2);
1942
+ const txPossiblyBeforeWindow = allUncleTransactions.find((tx) => tx.nbf < finalizedWindowStartBlockNumber);
1943
+ if (txPossiblyBeforeWindow) {
1944
+ return;
2291
1945
  }
2292
- if ("minutes" in assertedTimeConfig) {
2293
- totalMilliseconds += assertedTimeConfig.minutes * 6e4;
2294
- return totalMilliseconds;
1946
+ const txExistsInWindow = allUncleTransactions.find((tx) => allFinalizedTransactions.find((finalTx) => finalTx._hash === tx._hash));
1947
+ if (txExistsInWindow) {
1948
+ return;
2295
1949
  }
2296
- return totalMilliseconds;
2297
- };
1950
+ return prunedPossibleUncle;
1951
+ }
1952
+ function findUncles(context, finalizedWindowedChain, blocks) {
1953
+ return blocksToChains(blocks).map((chain) => toValidUncle(context, finalizedWindowedChain, chain)).filter(exists2);
1954
+ }
1955
+
1956
+ // src/config/Validation.ts
1957
+ var ValidationConfigZod = z16.object({
1958
+ allowedRewardRedeemers: z16.preprocess((val) => {
1959
+ if (typeof val === "string") {
1960
+ return val.split(",").map((s) => asAddress(s.trim()));
1961
+ }
1962
+ return val;
1963
+ }, z16.array(AddressZod2).optional().register(globalRegistry11, {
1964
+ description: "List of allowed reward redeemer addresses, if undefined anyone can participate",
1965
+ title: "allowedRewardRedeemers",
1966
+ type: "array"
1967
+ })),
1968
+ allowedRewardEscrowAccountSigners: z16.preprocess((val) => {
1969
+ if (typeof val === "string") {
1970
+ return val.split(",").map((s) => asAddress(s.trim()));
1971
+ }
1972
+ return val;
1973
+ }, z16.array(AddressZod2).optional().register(globalRegistry11, {
1974
+ description: "List of allowed reward escrow account signer addresses, if undefined anyone can participate",
1975
+ title: "allowedRewardEscrowAccountSigners",
1976
+ type: "array"
1977
+ })),
1978
+ minCandidates: z16.coerce.number().default(DEFAULT_MIN_CANDIDATES).register(globalRegistry11, {
1979
+ default: DEFAULT_MIN_CANDIDATES,
1980
+ description: "Minimum number of uncle candidates before selecting the best uncle",
1981
+ title: "validation.minCandidates",
1982
+ type: "number"
1983
+ }),
1984
+ backoffMs: z16.coerce.number().default(DEFAULT_BACKOFF_MS).register(globalRegistry11, {
1985
+ default: DEFAULT_BACKOFF_MS,
1986
+ description: "Back-off timeout in ms. If head age exceeds this, minCandidates is ignored",
1987
+ title: "validation.backoffMs",
1988
+ type: "number"
1989
+ })
1990
+ });
1991
+
1992
+ // src/config/Base.ts
1993
+ var BaseConfigZod = z17.object({
1994
+ chain: ChainConfigZod.default(ChainConfigZod.parse({})).describe("Configuration for the chain"),
1995
+ dataLake: DataLakeConfigZod.optional().describe("Configuration for data lakes"),
1996
+ evm: EvmConfigZod.default(EvmConfigZod.parse({})).describe("Configuration for EVM-backed services"),
1997
+ log: LogConfigZod.default(LogConfigZod.parse({})).describe("Configuration for logging"),
1998
+ providers: ProvidersConfigZod.default(ProvidersConfigZod.parse([])).describe("Configuration for providers"),
1999
+ remote: RemoteConfigZod.default(RemoteConfigZod.parse({})).describe("Configuration for remote services"),
2000
+ storage: StorageConfigZod.default(StorageConfigZod.parse({})).describe("Configuration for the storage"),
2001
+ telemetry: TelemetryConfigZod.default(TelemetryConfigZod.parse({})).describe("Configuration for telemetry"),
2002
+ validation: ValidationConfigZod.default(ValidationConfigZod.parse({})).describe("Configuration for validation")
2003
+ });
2004
+
2005
+ // src/config/Actor.ts
2006
+ var ActorConfigZod = BaseConfigZod.extend({
2007
+ name: z18.string(),
2008
+ mnemonic: MnemonicStringZod.optional().register(globalRegistry12, {
2009
+ description: "Mnemonic for the Actor wallet",
2010
+ title: "mnemonic",
2011
+ type: "string"
2012
+ }),
2013
+ healthCheckPort: z18.coerce.number().optional().register(globalRegistry12, {
2014
+ description: "Port for the Producer health checks",
2015
+ title: "producer.healthCheckPort",
2016
+ type: "number"
2017
+ })
2018
+ });
2019
+ var isActorConfig = zodIsFactory2(ActorConfigZod);
2020
+ var asActorConfig = zodAsFactory2(ActorConfigZod, "asActorConfig");
2021
+ var toActorConfig = zodToFactory2(ActorConfigZod, "toActorConfig");
2022
+
2023
+ // src/config/Actors.ts
2024
+ import z19 from "zod";
2025
+ var ActorsConfigZod = z19.array(ActorConfigZod.loose()).describe("Actor-specific configurations that override the base configuration when the actor is running").default([]);
2026
+
2027
+ // src/config/Config.ts
2028
+ var ConfigZod = BaseConfigZod.extend({ actors: ActorsConfigZod }).describe("The complete configuration for the protocol, including global settings and actor-specific overrides");
2029
+ function resolveConfig(config) {
2030
+ const parsedConfig = ConfigZod.parse(config);
2031
+ const { actors, ...rootConfig } = parsedConfig;
2032
+ parsedConfig.actors = actors.map((actorConfig) => {
2033
+ return ActorConfigZod.loose().parse({ ...rootConfig, ...actorConfig });
2034
+ });
2035
+ return parsedConfig;
2036
+ }
2037
+
2038
+ // src/config/HostActor.ts
2039
+ import {
2040
+ zodAsFactory as zodAsFactory3,
2041
+ zodIsFactory as zodIsFactory3,
2042
+ zodToFactory as zodToFactory3
2043
+ } from "@xylabs/sdk-js";
2044
+ import { globalRegistry as globalRegistry13, z as z20 } from "zod";
2045
+ var HostActorConfigZod = ActorConfigZod.extend({
2046
+ host: z20.string().default("localhost").register(globalRegistry13, {
2047
+ default: "localhost",
2048
+ description: "Host for the Actor",
2049
+ title: "host",
2050
+ type: "string"
2051
+ }),
2052
+ port: z20.coerce.number().default(8080).register(globalRegistry13, {
2053
+ default: 8080,
2054
+ description: "Port for the Actor",
2055
+ title: "port",
2056
+ type: "number"
2057
+ })
2058
+ });
2059
+ var isHostActorConfig = zodIsFactory3(HostActorConfigZod);
2060
+ var asHostActorConfig = zodAsFactory3(HostActorConfigZod, "asHostActorConfig");
2061
+ var toHostActorConfig = zodToFactory3(HostActorConfigZod, "toHostActorConfig");
2062
+
2063
+ // src/config/UsageMeta.ts
2064
+ import { z as z21 } from "zod";
2065
+ var DescriptionSchema = z21.string();
2066
+ var TitleSchema = z21.string();
2067
+ var JSONSchemaMetaSchema = z21.object({
2068
+ id: z21.string().optional(),
2069
+ title: TitleSchema.optional(),
2070
+ description: DescriptionSchema.optional(),
2071
+ deprecated: z21.boolean().optional()
2072
+ }).catchall(z21.unknown());
2073
+ var GlobalMetaSchema = JSONSchemaMetaSchema.extend({});
2074
+ var ChoicesSchema = z21.array(z21.union([z21.string(), z21.number(), z21.literal(true), z21.undefined()])).readonly();
2075
+ var UsageMetaSchema = GlobalMetaSchema.extend({
2076
+ choices: ChoicesSchema.optional(),
2077
+ default: z21.unknown().optional(),
2078
+ description: DescriptionSchema,
2079
+ group: z21.string().optional(),
2080
+ hidden: z21.boolean().optional(),
2081
+ title: TitleSchema,
2082
+ type: z21.union([
2083
+ z21.literal("array"),
2084
+ z21.literal("count"),
2085
+ z21.literal("boolean"),
2086
+ z21.literal("number"),
2087
+ z21.literal("string")
2088
+ ])
2089
+ });
2090
+ function isUsageMeta(v) {
2091
+ return UsageMetaSchema.safeParse(v).success;
2092
+ }
2298
2093
 
2299
- // src/primitives/block/rate/blockRate.ts
2300
- var blockRate = (startBlock, endBlock, timeUnit) => {
2301
- const startingBlock = startBlock[0];
2302
- const endingBlock = endBlock[0];
2303
- const heightDifference = endingBlock.block - startingBlock.block;
2304
- const timeDifference = endingBlock.$epoch - startingBlock.$epoch;
2305
- if (timeDifference === 0) {
2306
- throw new Error("Time difference must be greater than 0");
2094
+ // src/context/Actor.ts
2095
+ import {
2096
+ zodAsFactory as zodAsFactory5,
2097
+ zodIsFactory as zodIsFactory5,
2098
+ zodToFactory as zodToFactory5
2099
+ } from "@xylabs/sdk-js";
2100
+
2101
+ // src/model/CreatableProviderContext.zod.ts
2102
+ import {
2103
+ zodAsFactory as zodAsFactory4,
2104
+ zodIsFactory as zodIsFactory4,
2105
+ zodToFactory as zodToFactory4
2106
+ } from "@xylabs/sdk-js";
2107
+ import { CachingContextZod } from "@xyo-network/xl1-protocol-lib";
2108
+ import { z as z22 } from "zod";
2109
+ var RuntimeStatusMonitorZod = z22.custom((val) => val && typeof val === "object");
2110
+ var ProviderFactoryLocatorZod = z22.lazy(() => z22.custom((val) => val && typeof val === "object" && "context" in val && "registry" in val));
2111
+ var BaseConfigContextZod = CachingContextZod.extend({
2112
+ config: BaseConfigZod.loose(),
2113
+ locator: ProviderFactoryLocatorZod.optional()
2114
+ });
2115
+ var CreatableProviderContextZod = z22.lazy(() => BaseConfigContextZod.extend({
2116
+ _id: z22.string().optional(),
2117
+ locator: ProviderFactoryLocatorZod,
2118
+ statusReporter: RuntimeStatusMonitorZod.optional()
2119
+ }));
2120
+ var isBaseConfigContext = zodIsFactory4(BaseConfigContextZod);
2121
+ var asBaseConfigContext = zodAsFactory4(BaseConfigContextZod, "asBaseConfigContext");
2122
+ var toBaseConfigContext = zodToFactory4(BaseConfigContextZod, "toBaseConfigContext");
2123
+ var isCreatableProviderContext = zodIsFactory4(CreatableProviderContextZod);
2124
+ var asCreatableProviderContext = zodAsFactory4(CreatableProviderContextZod, "asCreatableProviderContext");
2125
+ var toCreatableProviderContext = zodToFactory4(CreatableProviderContextZod, "toCreatableProviderContext");
2126
+
2127
+ // src/model/PayloadBundle/bundledPayloadToHydratedBlock.ts
2128
+ import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/sdk-js";
2129
+ import { asSignedBlockBoundWitnessWithHashMeta } from "@xyo-network/xl1-protocol-lib";
2130
+ var bundledPayloadToHydratedBlock = async (payload) => {
2131
+ const withHashMeta = await PayloadBuilder3.addHashMeta(payload.payloads);
2132
+ const tx = asSignedBlockBoundWitnessWithHashMeta(withHashMeta.find((p) => p._hash === payload.root));
2133
+ if (tx) {
2134
+ return [tx, withHashMeta.filter((p) => p._hash !== payload.root)];
2307
2135
  }
2308
- const rate = heightDifference / timeDifference;
2309
- const timeUnitValue = isDefined8(timeUnit) ? timeUnit : "millis";
2310
- const returnedTimeDifference = isDefined8(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference;
2311
- const timePerBlock = returnedTimeDifference / heightDifference;
2312
- return {
2313
- range: asXL1BlockRange([startingBlock.block, endingBlock.block], true),
2314
- span: heightDifference,
2315
- rate: isDefined8(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,
2316
- timeUnit: timeUnitValue,
2317
- timeDifference: returnedTimeDifference,
2318
- timePerBlock
2319
- };
2320
2136
  };
2321
- var getBlockRateBlocks = async (viewer, startBlockHeight, endBlockHeight) => {
2322
- if (endBlockHeight <= startBlockHeight) {
2323
- console.error("startBlockHeight", startBlockHeight);
2324
- console.error("endBlockHeight", endBlockHeight);
2325
- throw new Error("End block height must be greater than start block height");
2326
- }
2327
- const startingBlock = await viewer.blockByNumber(startBlockHeight);
2328
- const endingBlock = await viewer.blockByNumber(endBlockHeight);
2329
- if (isFalsy(startingBlock) || isFalsy(endingBlock)) {
2330
- throw new Error("Could not retrieve blocks for speed calculation");
2137
+
2138
+ // src/model/PayloadBundle/bundledPayloadToHydratedTransaction.ts
2139
+ import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/sdk-js";
2140
+ import { asSignedTransactionBoundWitnessWithHashMeta } from "@xyo-network/xl1-protocol-lib";
2141
+ var bundledPayloadToHydratedTransaction = async (payload) => {
2142
+ const withHashMeta = await PayloadBuilder4.addHashMeta(payload.payloads);
2143
+ const tx = asSignedTransactionBoundWitnessWithHashMeta(withHashMeta.find((p) => p._hash === payload.root));
2144
+ if (tx) {
2145
+ return [tx, withHashMeta.filter((p) => p._hash !== payload.root)];
2331
2146
  }
2332
- return { startingBlock, endingBlock };
2333
- };
2334
- var calculateBlockRate = async (viewer, range, timeUnit) => {
2335
- const [startBlockHeight, endBlockHeight] = range;
2336
- const { startingBlock, endingBlock } = await getBlockRateBlocks(
2337
- viewer,
2338
- startBlockHeight,
2339
- endBlockHeight
2340
- );
2341
- return blockRate(startingBlock, endingBlock, timeUnit);
2342
2147
  };
2343
2148
 
2344
- // src/primitives/block/rate/stepRate.ts
2345
- import { assertEx as assertEx16 } from "@xylabs/sdk-js";
2346
- import {
2347
- asXL1BlockRange as asXL1BlockRange2,
2348
- isValidStep,
2349
- StepSizes as StepSizes4
2350
- } from "@xyo-network/xl1-protocol-lib";
2351
- var stepRate = async (viewer, start, step, count = 1, timeUnit) => {
2352
- const end = start + step * count;
2353
- const range = asXL1BlockRange2([start, end], true);
2354
- return await calculateBlockRate(viewer, range, timeUnit);
2149
+ // src/model/PayloadBundle/hydratedBlockToPayloadBundle.ts
2150
+ import { PayloadBundleSchema } from "@xyo-network/sdk-js";
2151
+ import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/sdk-js";
2152
+ var hydratedBlockToPayloadBundle = (transaction) => {
2153
+ const root = transaction[0]._hash;
2154
+ return bundle(root, transaction);
2355
2155
  };
2356
- var calculateStepSizeRate = async (viewer, start, stepIndex, count = 1, timeUnit) => {
2357
- assertEx16(isValidStep(stepIndex), () => `Invalid step index: ${stepIndex}`);
2358
- const step = StepSizes4[stepIndex];
2359
- return await stepRate(viewer, start, step, count, timeUnit);
2156
+ var bundle = (root, transaction) => {
2157
+ const payloads = flattenHydratedBlock(transaction).flatMap((p) => PayloadBuilder5.omitStorageMeta(p));
2158
+ return new PayloadBuilder5({ schema: PayloadBundleSchema }).fields({ payloads, root }).build();
2360
2159
  };
2361
2160
 
2362
- // src/primitives/block/rate/timeRate.ts
2363
- import {
2364
- assertEx as assertEx17,
2365
- isDefined as isDefined9,
2366
- isDefinedNotNull
2367
- } from "@xylabs/sdk-js";
2368
- import { asXL1BlockNumber as asXL1BlockNumber5, asXL1BlockRange as asXL1BlockRange3 } from "@xyo-network/xl1-protocol-lib";
2369
- var DEFAULT_TOLERANCE_MS = 3e4;
2370
- var DEFAULT_MAX_ATTEMPTS = 10;
2371
- var calculateTimeRate = async (viewer, timeConfig, startBlockNumber, timeUnit, toleranceMs = DEFAULT_TOLERANCE_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS) => {
2372
- assertEx17(Object.keys(timeConfig ?? {}).length === 1, () => "Only one time unit should be specified in timeConfig");
2373
- const startBlock = isDefinedNotNull(startBlockNumber) ? await viewer.blockByNumber(startBlockNumber) : null;
2374
- const resolvedStartBlock = isDefinedNotNull(startBlock) ? startBlock[0] : (await viewer.currentBlock())[0];
2375
- const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig);
2376
- assertEx17(timeInMilliseconds > 0, () => "Time duration must be greater than zero");
2377
- const blocksPerMillisecondRate = 1 / (12 * 1e3);
2378
- const initialBlocksInDuration = Math.floor(blocksPerMillisecondRate * timeInMilliseconds);
2379
- const endBlockNumber = await findEndBlockRecursive(
2380
- viewer,
2381
- resolvedStartBlock,
2382
- timeInMilliseconds,
2383
- initialBlocksInDuration,
2384
- toleranceMs,
2385
- maxAttempts
2386
- );
2387
- return await calculateBlockRate(
2388
- viewer,
2389
- asXL1BlockRange3([endBlockNumber, resolvedStartBlock.block], true),
2390
- timeUnit
2391
- );
2392
- };
2393
- var findEndBlockRecursive = async (viewer, startBlock, targetTimeMs, estimatedBlocksBack, toleranceMs, attemptsRemaining) => {
2394
- console.log(`Attempts remaining: ${attemptsRemaining}, Estimated blocks back: ${estimatedBlocksBack}`);
2395
- assertEx17(attemptsRemaining >= 0, () => "Maximum attempts reached while searching for end block");
2396
- const startBlockEpoch = startBlock.$epoch;
2397
- const estimatedEndBlockNumber = asXL1BlockNumber5(startBlock.block - estimatedBlocksBack, true);
2398
- if (estimatedEndBlockNumber < 0) {
2399
- throw new Error("Estimated end block number is less than zero");
2400
- }
2401
- const endBlock = await viewer.blockByNumber(estimatedEndBlockNumber);
2402
- const resolvedEndBlock = assertEx17(
2403
- isDefined9(endBlock?.[0]) ? endBlock[0] : void 0,
2404
- () => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`
2405
- );
2406
- const endBlockEpoch = resolvedEndBlock.$epoch;
2407
- if (!Number.isFinite(startBlockEpoch) || !Number.isFinite(endBlockEpoch)) {
2408
- throw new TypeError("Block has missing or invalid $epoch");
2409
- }
2410
- const actualTimeDifference = startBlockEpoch - endBlockEpoch;
2411
- if (actualTimeDifference === 0) {
2412
- throw new Error("Start and end blocks have identical timestamps");
2413
- }
2414
- const timeDelta = Math.abs(actualTimeDifference - targetTimeMs);
2415
- if (timeDelta <= toleranceMs) {
2416
- return resolvedEndBlock.block;
2417
- }
2418
- let adjustedBlocksBack;
2419
- if (actualTimeDifference < targetTimeMs) {
2420
- const adjustmentFactor = targetTimeMs / actualTimeDifference;
2421
- adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor);
2422
- } else {
2423
- const adjustmentFactor = actualTimeDifference / targetTimeMs;
2424
- adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor);
2425
- }
2426
- adjustedBlocksBack = Number.isFinite(adjustedBlocksBack) && adjustedBlocksBack >= 1 ? adjustedBlocksBack : 1;
2427
- return await findEndBlockRecursive(
2428
- viewer,
2429
- startBlock,
2430
- targetTimeMs,
2431
- adjustedBlocksBack,
2432
- toleranceMs,
2433
- attemptsRemaining - 1
2434
- );
2435
- };
2161
+ // src/model/PayloadBundle/hydratedTransactionToPayloadBundle.ts
2162
+ import { PayloadBundleSchema as PayloadBundleSchema2 } from "@xyo-network/sdk-js";
2163
+ import { PayloadBuilder as PayloadBuilder12 } from "@xyo-network/sdk-js";
2436
2164
 
2437
- // src/primitives/chain/getWindowedChain.ts
2438
- import {
2439
- assertEx as assertEx18,
2440
- isDefined as isDefined10,
2441
- isNull,
2442
- spanRootAsync
2443
- } from "@xylabs/sdk-js";
2444
- async function getWindowedChain(context, blockViewer, maxWindowSize, previousChain = []) {
2445
- return await spanRootAsync("getWindowedChain", async () => {
2446
- const newChain = [];
2447
- const previousChainByHash = new Map(previousChain.map((block) => [block[0]._hash, block]));
2448
- const head = await blockViewer.currentBlock();
2449
- let currentBlock = head;
2450
- console.log("[getWindowedChain] Current Block:", currentBlock?.[0]._hash);
2451
- while (currentBlock !== null && newChain.length < maxWindowSize) {
2452
- const currentBlockNumber = currentBlock[0].block;
2453
- const nextBlock = newChain[0];
2454
- if (isDefined10(nextBlock)) {
2455
- const nextBlockNumber = nextBlock[0].block;
2456
- assertEx18(
2457
- currentBlockNumber === nextBlockNumber - 1,
2458
- () => `[getWindowedChain] Non-monotonic block sequence detected: current=${currentBlockNumber}, next=${nextBlockNumber}`
2459
- );
2460
- }
2461
- assertEx18(
2462
- currentBlockNumber <= head[0].block,
2463
- () => `[getWindowedChain] Current block number (${currentBlockNumber}) exceeds head block number (${head[0].block})`
2464
- );
2465
- newChain.unshift(currentBlock);
2466
- const previousBlockHash = currentBlock[0].previous;
2467
- if (isNull(previousBlockHash)) break;
2468
- currentBlock = previousChainByHash.get(previousBlockHash) ?? await blockViewer.blockByHash(previousBlockHash);
2469
- }
2470
- return newChain;
2471
- }, context);
2165
+ // src/transaction/buildRandomTransaction.ts
2166
+ import { Account } from "@xyo-network/sdk-js";
2167
+ import { asXL1BlockNumber as asXL1BlockNumber4, isAllowedBlockPayload as isAllowedBlockPayload2 } from "@xyo-network/xl1-protocol-lib";
2168
+
2169
+ // src/createTransferPayload.ts
2170
+ import { toHex } from "@xylabs/sdk-js";
2171
+ import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/sdk-js";
2172
+ import { TransferSchema } from "@xyo-network/xl1-protocol-lib";
2173
+ function createTransferPayload(from, transfers, context) {
2174
+ return new PayloadBuilder6({ schema: TransferSchema }).fields({
2175
+ epoch: Date.now(),
2176
+ from,
2177
+ transfers: Object.fromEntries(Object.entries(transfers).map(([k, v]) => [k, toHex(v)])),
2178
+ context
2179
+ }).build();
2472
2180
  }
2473
2181
 
2474
- // src/primitives/chain/step/chainStepRewardAddress.ts
2475
- import {
2476
- assertEx as assertEx21,
2477
- exists,
2478
- toAddress as toAddress6
2479
- } from "@xylabs/sdk-js";
2182
+ // src/transaction/buildTransaction.ts
2183
+ import { assertEx as assertEx18, toHex as toHex2 } from "@xylabs/sdk-js";
2480
2184
  import {
2481
- asTransfer,
2482
- isTransfer as isTransfer4,
2483
- XYO_STEP_REWARD_ADDRESS
2484
- } from "@xyo-network/xl1-protocol-lib";
2485
-
2486
- // src/primitives/payload/mergeTransfers.ts
2487
- import { hexToBigInt as hexToBigInt4, toAddress as toAddress3 } from "@xylabs/sdk-js";
2488
- function mergeTransfers(transfers) {
2489
- const result = {};
2490
- for (const transfer of transfers) {
2491
- result[transfer.from] = result[transfer.from] ?? {};
2492
- for (const [to, value] of Object.entries(transfer.transfers)) {
2493
- const typedTo = toAddress3(to);
2494
- result[transfer.from][typedTo] = (result[transfer.from][typedTo] ?? 0n) + hexToBigInt4(value);
2495
- }
2185
+ asAnyPayload as asAnyPayload2,
2186
+ BoundWitnessBuilder,
2187
+ PayloadBuilder as PayloadBuilder7
2188
+ } from "@xyo-network/sdk-js";
2189
+ import { defaultTransactionFees } from "@xyo-network/xl1-protocol-lib";
2190
+ async function buildTransaction(chain, onChainPayloads, offChainPayloads, signer, nbf, exp, from, fees = defaultTransactionFees) {
2191
+ if (from === void 0 && Array.isArray(signer)) {
2192
+ throw new Error("from is required when signer is an array");
2193
+ }
2194
+ const txBoundWitnessFields = {
2195
+ chain,
2196
+ fees: {
2197
+ base: toHex2(fees.base),
2198
+ gasLimit: toHex2(fees.gasLimit),
2199
+ gasPrice: toHex2(fees.gasPrice),
2200
+ priority: toHex2(fees.priority)
2201
+ },
2202
+ nbf,
2203
+ exp
2204
+ };
2205
+ const elevatedHashes = await PayloadBuilder7.hashes(onChainPayloads);
2206
+ const script = [];
2207
+ for (const elevatedHash of elevatedHashes) {
2208
+ script.push(`elevate|${elevatedHash}`);
2496
2209
  }
2497
- return result;
2498
- }
2499
-
2500
- // src/primitives/step/completedStepRewardAddress.ts
2501
- import { toAddress as toAddress4 } from "@xylabs/sdk-js";
2502
- import { StepSizes as StepSizes5 } from "@xyo-network/xl1-protocol-lib";
2503
- import { keccak256 } from "ethers";
2504
- function completedStepRewardAddress({ block, step }) {
2505
- const resolvedStepSize = step < StepSizes5.length ? StepSizes5[step] : step;
2506
- const addressKey = new TextEncoder().encode(`${block}|${resolvedStepSize}`);
2507
- return toAddress4(keccak256(addressKey).slice(-40), { prefix: false });
2210
+ const fields = {
2211
+ ...txBoundWitnessFields,
2212
+ from: from ?? (Array.isArray(signer) ? assertEx18(signer.at(0)?.address) : signer.address)
2213
+ };
2214
+ if (script.length > 0) {
2215
+ fields.script = script;
2216
+ }
2217
+ const [tx, txPayloads] = await new BoundWitnessBuilder().fields(fields).meta({ $signatures: [] }).payloads([...onChainPayloads, ...offChainPayloads]).signers(Array.isArray(signer) ? signer : [signer]).build();
2218
+ return [await PayloadBuilder7.addHashMeta(tx), await PayloadBuilder7.addHashMeta(txPayloads.map((p) => asAnyPayload2(p, true)))];
2508
2219
  }
2509
2220
 
2510
- // src/primitives/step/derivedReceiveAddress.ts
2511
- import { toAddress as toAddress5 } from "@xylabs/sdk-js";
2512
- import { isDefined as isDefined11 } from "@xylabs/sdk-js";
2513
- import { keccak256 as keccak2562 } from "ethers";
2514
- function derivedReceiveAddress(address, scope) {
2515
- const addressKey = new TextEncoder().encode(isDefined11(scope) ? `${scope}|${address}` : address);
2516
- return toAddress5(keccak2562(addressKey).slice(-40), { prefix: false });
2517
- }
2221
+ // src/transaction/buildRandomTransaction.ts
2222
+ var buildRandomTransaction = async (chain, payloads, account, nbf = asXL1BlockNumber4(0, true), exp = asXL1BlockNumber4(nbf + 1e3, true), privatePayloadSchemas = [], receiverAddress) => {
2223
+ const elevatedPayloads2 = (payloads ?? []).filter(isAllowedBlockPayload2);
2224
+ const additionalPayloads = (payloads ?? []).filter((payload) => !isAllowedBlockPayload2(payload));
2225
+ const sender = account ?? await Account.random();
2226
+ if (elevatedPayloads2?.length === 0) {
2227
+ const receiver = receiverAddress ?? (await Account.random()).address;
2228
+ const transferPayload = createTransferPayload(sender.address, { [receiver]: 1n });
2229
+ elevatedPayloads2.push(transferPayload);
2230
+ }
2231
+ const hydratedTransaction = await buildTransaction(chain, elevatedPayloads2, additionalPayloads, sender, nbf, exp);
2232
+ return [hydratedTransaction[0], hydratedTransaction[1].filter((p) => !privatePayloadSchemas.includes(p.schema))];
2233
+ };
2518
2234
 
2519
- // src/primitives/step/stepBlockRange.ts
2520
- import { asXL1BlockRange as asXL1BlockRange4, StepSizes as StepSizes6 } from "@xyo-network/xl1-protocol-lib";
2521
- function stepBlockRange({ block, step }) {
2522
- const stepSize2 = StepSizes6[step];
2523
- const start = block - stepSize2;
2524
- return asXL1BlockRange4([start, start + stepSize2 - 1], { name: "stepBlockRange" });
2235
+ // src/transaction/buildUnsignedTransaction.ts
2236
+ import { toHex as toHex3 } from "@xylabs/sdk-js";
2237
+ import { BoundWitnessBuilder as BoundWitnessBuilder2, PayloadBuilder as PayloadBuilder8 } from "@xyo-network/sdk-js";
2238
+ import { defaultTransactionFees as defaultTransactionFees2 } from "@xyo-network/xl1-protocol-lib";
2239
+ async function buildUnsignedTransaction(chain, onChainPayloads, offChainPayloads, nbf, exp, from, fees = defaultTransactionFees2) {
2240
+ const txBoundWitnessFields = {
2241
+ chain,
2242
+ fees: {
2243
+ base: toHex3(fees.base),
2244
+ gasLimit: toHex3(fees.gasLimit),
2245
+ gasPrice: toHex3(fees.gasPrice),
2246
+ priority: toHex3(fees.priority)
2247
+ },
2248
+ nbf,
2249
+ exp
2250
+ };
2251
+ const elevatedHashes = await PayloadBuilder8.hashes(onChainPayloads);
2252
+ const script = [];
2253
+ for (const elevatedHash of elevatedHashes) {
2254
+ script.push(`elevate|${elevatedHash}`);
2255
+ }
2256
+ const fields = {
2257
+ ...txBoundWitnessFields,
2258
+ from
2259
+ };
2260
+ if (script.length > 0) {
2261
+ fields.script = script;
2262
+ }
2263
+ const [tx, txPayloads] = await new BoundWitnessBuilder2().fields(fields).meta({ $signatures: [] }).payloads([...onChainPayloads, ...offChainPayloads]).build(false);
2264
+ return [tx, txPayloads];
2525
2265
  }
2526
2266
 
2527
- // src/primitives/step/stepTransferIndex.ts
2528
- import { assertEx as assertEx19 } from "@xylabs/sdk-js";
2529
- import { StepSizes as StepSizes7 } from "@xyo-network/xl1-protocol-lib";
2530
- function stepTransferIndex(block, step) {
2531
- let rewardTransferCount = 0;
2532
- let rewardTransferIndex = -1;
2533
- for (let i = 3; i < StepSizes7.length; i++) {
2534
- const stepSize2 = StepSizes7[i];
2535
- if (block % stepSize2 === 0) {
2536
- if (stepSize2 === StepSizes7[step]) {
2537
- rewardTransferIndex = rewardTransferCount;
2267
+ // src/transaction/confirmSubmittedTransaction.ts
2268
+ import { delay as delay2, isDefined as isDefined15 } from "@xylabs/sdk-js";
2269
+ var DEFAULT_CONFIRMATION_ATTEMPTS = 20;
2270
+ var DEFAULT_DELAY_BETWEEN_ATTEMPTS = 1e3;
2271
+ var confirmSubmittedTransaction = async (viewer, txHash, options) => {
2272
+ const { attempts: maxAttempts = DEFAULT_CONFIRMATION_ATTEMPTS, delay: attemptDelay = DEFAULT_DELAY_BETWEEN_ATTEMPTS } = options ?? {};
2273
+ options?.logger?.log("\u{1F680} confirming transaction:", txHash, "\n");
2274
+ let attempts = 0;
2275
+ while (true) {
2276
+ const tx = await viewer.transaction.byHash(txHash) ?? void 0;
2277
+ if (isDefined15(tx)) {
2278
+ options?.logger?.log("\u2705 Transaction confirmed:", txHash, "\n");
2279
+ return tx;
2280
+ } else {
2281
+ attempts++;
2282
+ if (attempts > maxAttempts) {
2283
+ options?.logger?.error(`\u26A0\uFE0F Transaction not confirmed after ${maxAttempts} attempts`);
2284
+ throw new Error(`Transaction ${txHash} not confirmed after ${maxAttempts} attempts`);
2285
+ } else {
2286
+ options?.logger?.log(`\u{1F504} Transaction not confirmed yet, attempt ${attempts}. Retrying...`, "\n");
2287
+ await delay2(attemptDelay);
2538
2288
  }
2539
- rewardTransferCount++;
2540
2289
  }
2541
2290
  }
2542
- assertEx19(rewardTransferIndex >= 0, () => `Could not find step size for step ${step} at block ${block}`);
2543
- return [rewardTransferIndex, rewardTransferCount];
2544
- }
2545
-
2546
- // src/primitives/chain/step/stepRewardBlock.ts
2547
- import { assertEx as assertEx20 } from "@xylabs/sdk-js";
2548
- import { StepSizes as StepSizes8 } from "@xyo-network/xl1-protocol-lib";
2549
- async function stepRewardBlock(context, blockViewer, { block, step }) {
2550
- assertEx20(block % StepSizes8[step] === 0, () => `Block must be the first block of the step [${StepSizes8[step]}], got ${block}`);
2551
- return assertEx20(await blockViewer.blockByNumber(block), () => `Could not find block for block number ${block}`);
2552
- }
2553
-
2554
- // src/primitives/chain/step/chainStepRewardAddress.ts
2555
- async function chainStepRewardAddress(context, blockViewer, { block, step }) {
2556
- const hydratedBlock = await stepRewardBlock(context, blockViewer, { block, step });
2557
- const [transferIndex, transferCount] = stepTransferIndex(block, step);
2558
- const [blockBw, payloads] = hydratedBlock;
2559
- const transfersFromPool = payloads.filter(isTransfer4).map((p) => asTransfer(p)).filter(exists).filter((t) => t.from === XYO_STEP_REWARD_ADDRESS);
2560
- const fromEntries = Object.entries(mergeTransfers(transfersFromPool)[XYO_STEP_REWARD_ADDRESS]);
2561
- const sortedTransferAmounts = fromEntries.toSorted(([, a], [, b]) => a > b ? -1 : a < b ? 1 : 0);
2562
- assertEx21(
2563
- sortedTransferAmounts.length === transferCount,
2564
- () => `Step Transfers mismatch ${block} (${blockBw._hash}) [${sortedTransferAmounts.length} - ${transferCount}]`
2565
- );
2566
- return toAddress6(sortedTransferAmounts[transferIndex][0]);
2567
- }
2291
+ };
2568
2292
 
2569
- // src/primitives/chain/step/stepRewardTotal.ts
2570
- import { assertEx as assertEx22, isDefined as isDefined12 } from "@xylabs/sdk-js";
2293
+ // src/transaction/hydrateTransaction.ts
2294
+ import { assertEx as assertEx19 } from "@xylabs/sdk-js";
2571
2295
  import {
2572
- asAttoXL1 as asAttoXL12,
2573
- asXL1BlockRange as asXL1BlockRange5,
2574
- isTransfer as isTransfer5,
2575
- XYO_STEP_REWARD_ADDRESS as XYO_STEP_REWARD_ADDRESS2
2296
+ asAnyPayload as asAnyPayload3,
2297
+ hydrateTypedBoundWitness,
2298
+ tryHydrateTypedBoundWitness
2299
+ } from "@xyo-network/sdk-js";
2300
+ import {
2301
+ asSignedHydratedTransaction,
2302
+ isAllowedBlockPayload as isAllowedBlockPayload3,
2303
+ isSignedTransactionBoundWitnessWithStorageMeta
2576
2304
  } from "@xyo-network/xl1-protocol-lib";
2577
- function stepInRange(step, range) {
2578
- const stepRange = stepBlockRange(step);
2579
- return stepRange[0] >= range[0] && stepRange[1] <= range[1];
2580
- }
2581
- async function stepRewardTotal(context, blockViewer, { block, step }, multipliers) {
2582
- const cacheKey = `${block}|${step}|${isDefined12(multipliers)}`;
2583
- return await withContextCacheResponse(context, "stepRewardTotal", cacheKey, async () => {
2584
- const [blockBw, payloads] = await stepRewardBlock(context, blockViewer, { block, step });
2585
- assertEx22(blockBw.block === block, () => `Block Mismatch: expected ${block}, got ${blockBw.block}`);
2586
- const [transferIndex] = stepTransferIndex(block, step);
2587
- const stepTransfer = assertEx22(
2588
- payloads.find((p) => isTransfer5(p) && p.from === XYO_STEP_REWARD_ADDRESS2),
2589
- () => `No step transfer found for step ${step} at block ${block} (${blockBw._hash})`
2590
- );
2591
- const rewards = assertEx22(
2592
- netTransfersForPayloads(context, [stepTransfer])[XYO_STEP_REWARD_ADDRESS2],
2593
- () => `No rewards found for step reward address ${XYO_STEP_REWARD_ADDRESS2} at block ${block} (${blockBw._hash})`
2594
- );
2595
- const sortedTransfers = Object.entries(rewards).toSorted(([, a], [, b]) => a > b ? -1 : a < b ? 1 : 0);
2596
- let result = asAttoXL12(sortedTransfers[transferIndex][1] * -1n);
2597
- for (const [rangeKey, [numerator, denominator]] of Object.entries(multipliers)) {
2598
- const rangeParts = rangeKey.split("|").map(Number);
2599
- const range = asXL1BlockRange5([rangeParts[0], rangeParts[1]], { name: "stepRewardTotal" });
2600
- if (stepInRange({ block, step }, range)) {
2601
- result = asAttoXL12(result + result * numerator / denominator);
2305
+ var tryHydrateTransaction = async ({ chainMap }, hash) => {
2306
+ return await tryHydrateTypedBoundWitness(
2307
+ {
2308
+ get(hashes) {
2309
+ return chainMap.get(hashes);
2310
+ },
2311
+ next() {
2312
+ throw new Error("Not implemented");
2602
2313
  }
2603
- }
2604
- return result;
2605
- });
2606
- }
2607
-
2608
- // src/primitives/chain/step/stepsRewardTotal.ts
2609
- import { asAttoXL1 as asAttoXL13, asXL1BlockRange as asXL1BlockRange6 } from "@xyo-network/xl1-protocol-lib";
2610
- async function stepsRewardTotalGenesisPeriod(context, blockViewer, multipliers, stepSizes) {
2611
- const range = asXL1BlockRange6([0, XL1_NETWORK_STAKING_GENESIS_PERIOD_END_XL1_BLOCK], { name: "stepsRewardTotalGenesisPeriod" });
2612
- return await stepsRewardTotalRange(context, blockViewer, range, stepSizes, multipliers);
2314
+ },
2315
+ hash,
2316
+ isSignedTransactionBoundWitnessWithStorageMeta
2317
+ );
2318
+ };
2319
+ var hydrateTransaction = async ({ chainMap }, hash) => {
2320
+ return await hydrateTypedBoundWitness(
2321
+ {
2322
+ get(hashes) {
2323
+ return chainMap.get(hashes);
2324
+ },
2325
+ next() {
2326
+ throw new Error("Not implemented");
2327
+ }
2328
+ },
2329
+ hash,
2330
+ isSignedTransactionBoundWitnessWithStorageMeta
2331
+ );
2332
+ };
2333
+ function flattenHydratedTransaction(hydratedTransaction) {
2334
+ const [tx, txPayloads] = hydratedTransaction;
2335
+ return [...txPayloads, tx];
2613
2336
  }
2614
- async function stepsRewardTotalRange(context, blockViewer, range, stepSizes = [3, 4, 5, 6], multipliers) {
2615
- const steps = blockRangeSteps(range, stepSizes);
2616
- return await stepsRewardTotal(context, blockViewer, steps, multipliers);
2337
+ var tryUnflattenHydratedTransaction = (flattened) => {
2338
+ const tx = flattened.at(-1);
2339
+ const txPayloads = flattened.slice(0, -1);
2340
+ return asSignedHydratedTransaction([tx, txPayloads]);
2341
+ };
2342
+ var unflattenHydratedTransaction = (flattened) => asSignedHydratedTransaction(tryUnflattenHydratedTransaction(flattened), true);
2343
+ function flattenHydratedTransactions(hydratedTransactions) {
2344
+ return hydratedTransactions.flatMap((tx) => flattenHydratedTransaction(tx));
2617
2345
  }
2618
- async function stepsRewardTotal(context, blockViewer, steps, multipliers) {
2619
- let totalRewards = 0n;
2620
- for (const step of steps) {
2621
- const stepTotal = await stepRewardTotal(context, blockViewer, step, multipliers);
2622
- totalRewards += stepTotal;
2346
+ var tryHydrateElevatedTransaction = async ({ chainMap }, hash) => {
2347
+ const hydratedTransaction = await tryHydrateTransaction({ chainMap }, hash);
2348
+ if (!hydratedTransaction) {
2349
+ return void 0;
2623
2350
  }
2624
- return asAttoXL13(totalRewards);
2625
- }
2626
-
2627
- // src/primitives/chain/time/externalBlockNumberFromXL1BlockNumber.ts
2628
- import { assertEx as assertEx23, isArray } from "@xylabs/sdk-js";
2629
- import {
2630
- asBlockNumber,
2631
- asTimePayload,
2632
- isTimePayload
2633
- } from "@xyo-network/xl1-protocol-lib";
2634
- var functionName = "externalBlockNumberFromXL1BlockNumber";
2635
- async function externalBlockNumberFromXL1BlockNumber(context, blockViewer, xl1BlockNumber, externalTimeName, externalGenesisTime) {
2636
- const cacheKey = `${xl1BlockNumber}-${externalTimeName}-${externalGenesisTime ?? "default"}`;
2637
- return await withContextCacheResponse(context, functionName, cacheKey, async () => {
2638
- const [, payloads = []] = await blockViewer.blockByNumber(xl1BlockNumber) ?? [];
2639
- assertEx23(isArray(payloads));
2640
- const timePayload = asTimePayload(payloads.find(isTimePayload));
2641
- return asBlockNumber(
2642
- timePayload?.[externalTimeName] ?? externalGenesisTime ?? 23372716,
2643
- { name: functionName }
2644
- );
2645
- });
2646
- }
2351
+ const [transaction, payloads] = hydratedTransaction;
2352
+ const opCodes = (transaction.script ?? []).filter((operation) => operation.startsWith("elevate|"));
2353
+ const elevatedPayloads2 = [];
2354
+ for (const opCode of opCodes) {
2355
+ const [code, hash2] = opCode.split("|");
2356
+ if (code === "elevated") {
2357
+ const elevatedPayload = payloads.find((payload) => payload._hash === hash2);
2358
+ if (isAllowedBlockPayload3(elevatedPayload)) {
2359
+ elevatedPayloads2.push(elevatedPayload);
2360
+ }
2361
+ }
2362
+ }
2363
+ if (opCodes.length === elevatedPayloads2.length) {
2364
+ return [transaction, elevatedPayloads2.map((p) => asAnyPayload3(p, true))];
2365
+ }
2366
+ return void 0;
2367
+ };
2368
+ var hydrateElevatedTransaction = async (context, hash) => {
2369
+ return assertEx19(await tryHydrateElevatedTransaction(context, hash), () => "Hydration failed");
2370
+ };
2647
2371
 
2648
- // src/primitives/chain/time/externalBlockRangeFromXL1BlockRange.ts
2649
- async function externalBlockRangeFromXL1BlockRange(context, blockViewer, xl1BlockRange, externalTimeName = "ethereum") {
2650
- const start = await externalBlockNumberFromXL1BlockNumber(context, blockViewer, xl1BlockRange[0], externalTimeName);
2651
- const end = await externalBlockNumberFromXL1BlockNumber(context, blockViewer, xl1BlockRange[1], externalTimeName);
2652
- return [start, end];
2372
+ // src/transaction/primitives/transactionBlockByteCount.ts
2373
+ import { PayloadBuilder as PayloadBuilder9 } from "@xyo-network/sdk-js";
2374
+ function transactionBlockByteCount([transaction, payloads]) {
2375
+ const cleanTransaction = PayloadBuilder9.omitStorageMeta(transaction);
2376
+ const transactionBytes = JSON.stringify(cleanTransaction).length;
2377
+ const cleanPayloads = PayloadBuilder9.omitStorageMeta(payloads);
2378
+ return cleanPayloads.reduce((acc, payload) => acc + JSON.stringify(payload).length, 0) + transactionBytes;
2653
2379
  }
2654
2380
 
2655
- // src/primitives/chain/time/externalBlockRangeFromStep.ts
2656
- async function externalBlockRangeFromStep(context, blockViewer, stepIdentity) {
2657
- const cacheKey = toStepIdentityString(stepIdentity);
2658
- return await withContextCacheResponse(context, "externalBlockRangeFromStep", cacheKey, async () => {
2659
- const xl1BlockRange = stepBlockRange(stepIdentity);
2660
- return await externalBlockRangeFromXL1BlockRange(context, blockViewer, xl1BlockRange);
2661
- });
2381
+ // src/transaction/primitives/transactionElevatedPayloads.ts
2382
+ import { asHash as asHash2 } from "@xylabs/sdk-js";
2383
+
2384
+ // src/transaction/primitives/transactionOperations.ts
2385
+ function crackOperation(operation) {
2386
+ const parts = operation.split("|");
2387
+ if (parts.length < 2) {
2388
+ throw new Error(`Invalid operation format: ${operation}`);
2389
+ }
2390
+ return [parts[0], parts.slice(1)];
2391
+ }
2392
+ function crackOperations(operations) {
2393
+ return operations.map((op) => crackOperation(op));
2662
2394
  }
2663
2395
 
2664
- // src/primitives/datalake/addDataLakePayloadsToPayloads.ts
2665
- import { isUndefined as isUndefined4 } from "@xylabs/sdk-js";
2666
- import { isAnyPayload, PayloadBuilder as PayloadBuilder15 } from "@xyo-network/sdk-js";
2667
- async function addDataLakePayloadsToPayloads(hashes, payloads, dataLakeViewer) {
2668
- if (isUndefined4(dataLakeViewer)) return [payloads, []];
2669
- const missingPayloadHashes = hashes.filter((hash) => !payloads.some((p) => p._hash === hash));
2670
- const payloadsFromDataLake = await PayloadBuilder15.addHashMeta(
2671
- await PayloadBuilder15.addHashMeta((await dataLakeViewer.get(missingPayloadHashes)).filter(isAnyPayload))
2672
- );
2673
- return [[...payloads, ...payloadsFromDataLake], payloadsFromDataLake.map((p) => p._hash)];
2396
+ // src/transaction/primitives/transactionElevatedPayloads.ts
2397
+ function transactionElevatedPayloadHashes(transaction) {
2398
+ const elevateOperations = crackOperations(transaction.script ?? []).filter((op) => op[0] === "elevate");
2399
+ return elevateOperations.map((op) => asHash2(op[1][0], true));
2400
+ }
2401
+ function transactionElevatedPayloads([transaction, payloads]) {
2402
+ const hashes = transactionElevatedPayloadHashes(transaction);
2403
+ const elevatedPayloads2 = payloads.filter((payload) => hashes.includes(payload._hash));
2404
+ return elevatedPayloads2;
2674
2405
  }
2675
2406
 
2676
- // src/primitives/datalake/addDataLakePayloads.ts
2677
- async function addDataLakePayloads([boundWitness, payloads], dataLakeViewer) {
2678
- const [updatedPayloads, foundHashes] = await addDataLakePayloadsToPayloads(boundWitness.payload_hashes, payloads, dataLakeViewer);
2679
- return [
2680
- [
2681
- boundWitness,
2682
- updatedPayloads
2683
- ],
2684
- foundHashes
2685
- ];
2407
+ // src/transaction/primitives/transactionRequiredGas.ts
2408
+ import { AttoXL1 as AttoXL12, TransactionGasCosts } from "@xyo-network/xl1-protocol-lib";
2409
+ function transactionBytesRequiredGas([transaction, payloads]) {
2410
+ const transactionBlockBytes = transactionBlockByteCount([transaction, payloads]);
2411
+ return AttoXL12(TransactionGasCosts.characterStorage * BigInt(transactionBlockBytes));
2412
+ }
2413
+ function transactionRequiredGas(hydratedTransaction) {
2414
+ const elevatedPayloads2 = transactionElevatedPayloads(hydratedTransaction);
2415
+ const hashes = elevatedPayloads2.length + 1;
2416
+ const signatures = hydratedTransaction[0].addresses.length;
2417
+ return AttoXL12(transactionBytesRequiredGas(hydratedTransaction) + TransactionGasCosts.hashValidation * BigInt(hashes) + TransactionGasCosts.signatureValidation * BigInt(signatures) + TransactionGasCosts.payloadValidation * BigInt(elevatedPayloads2.length));
2686
2418
  }
2687
2419
 
2688
- // src/primitives/mapToMapType.ts
2689
- import { isDefined as isDefined13 } from "@xylabs/sdk-js";
2690
- function mapToMapType(map) {
2691
- return {
2692
- get: (key) => map.get(key),
2693
- has: (key) => map.has(key),
2694
- set: (key, value) => {
2695
- map.set(key, value);
2696
- },
2697
- setMany: (entries) => {
2698
- for (const [key, value] of entries) {
2699
- map.set(key, value);
2700
- }
2701
- },
2702
- delete: (key) => map.delete(key),
2703
- clear: () => map.clear(),
2704
- getMany: (keys) => {
2705
- const result = [];
2706
- for (const key of keys) {
2707
- const value = map.get(key);
2708
- if (isDefined13(value)) {
2709
- result.push(value);
2710
- }
2711
- }
2712
- return result;
2713
- },
2714
- [Symbol.iterator]: function* () {
2715
- for (const entry of map) {
2716
- yield entry;
2717
- }
2718
- }
2420
+ // src/transaction/script.ts
2421
+ import { asHash as asHash3 } from "@xylabs/sdk-js";
2422
+ import { assertEx as assertEx20, filterAs } from "@xylabs/sdk-js";
2423
+ import { isHashMeta } from "@xyo-network/sdk-js";
2424
+ import { isAllowedBlockPayload as isAllowedBlockPayload4 } from "@xyo-network/xl1-protocol-lib";
2425
+ var tryExtractElevatedHashesFromScript = (strings) => {
2426
+ const hashes = strings.filter((str) => str.startsWith("elevate|")).map((str) => str.split("|")[1]);
2427
+ return filterAs(hashes, (h) => asHash3(h));
2428
+ };
2429
+ var extractElevatedHashesFromScript = (strings) => {
2430
+ const hashes = strings.filter((str) => str.startsWith("elevate|")).map((str) => str.split("|")[1]);
2431
+ const filtered = filterAs(hashes, (h) => asHash3(h));
2432
+ assertEx20(filtered.length === hashes.length, () => "Invalid elevated hashes");
2433
+ return filtered;
2434
+ };
2435
+ var tryExtractElevatedHashes = (tx) => {
2436
+ const [bw, payloads] = tx;
2437
+ const { script } = bw;
2438
+ const hashes = script ? tryExtractElevatedHashesFromScript(script) : [];
2439
+ return payloads.filter((p) => hashes.includes(p._hash)).filter(isAllowedBlockPayload4).filter(isHashMeta);
2440
+ };
2441
+ var extractElevatedHashes = (tx) => {
2442
+ const [bw, payloads] = tx;
2443
+ const { script } = bw;
2444
+ const hashes = script ? tryExtractElevatedHashesFromScript(script) : [];
2445
+ const filtered = payloads.filter((p) => hashes.includes(p._hash)).filter(isAllowedBlockPayload4).filter(isHashMeta);
2446
+ assertEx20(filtered.length === hashes.length, () => "Invalid elevated hashes");
2447
+ return filtered;
2448
+ };
2449
+
2450
+ // src/transaction/signTransaction.ts
2451
+ import {
2452
+ assertEx as assertEx21,
2453
+ hexFromArrayBuffer,
2454
+ toArrayBuffer
2455
+ } from "@xylabs/sdk-js";
2456
+ import { PayloadBuilder as PayloadBuilder10 } from "@xyo-network/sdk-js";
2457
+ async function signTransaction(tx, account) {
2458
+ assertEx21(tx.from === account.address, () => "Signer address does not match transaction from address");
2459
+ const unsignedTx = structuredClone(tx);
2460
+ unsignedTx.addresses = [account.address];
2461
+ unsignedTx.previous_hashes = [account.previousHash ?? null];
2462
+ const hash = await PayloadBuilder10.dataHash(unsignedTx);
2463
+ const hashBytes = toArrayBuffer(hash);
2464
+ const [signature] = await account.sign(hashBytes);
2465
+ const result = {
2466
+ ...unsignedTx,
2467
+ $signatures: [hexFromArrayBuffer(signature)]
2719
2468
  };
2469
+ return result;
2720
2470
  }
2721
2471
 
2722
- // src/primitives/readPayloadMapFromStore.ts
2723
- import { isDefined as isDefined14 } from "@xylabs/sdk-js";
2724
- function readPayloadMapFromStore(store) {
2725
- if (isReadArchivist(store)) {
2726
- return {
2727
- get: async (hash) => {
2728
- return (await store.get([hash]))[0];
2729
- },
2730
- getMany: async (hashes) => {
2731
- return await store.get(hashes);
2732
- },
2733
- has: async (hash) => {
2734
- return isDefined14((await store.get([hash]))[0]);
2472
+ // src/transaction/TransactionBuilder.ts
2473
+ import { assertEx as assertEx22, Base } from "@xylabs/sdk-js";
2474
+ import { PayloadBuilder as PayloadBuilder11 } from "@xyo-network/sdk-js";
2475
+ import {
2476
+ asXL1BlockNumber as asXL1BlockNumber5,
2477
+ defaultTransactionFees as defaultTransactionFees3,
2478
+ isAllowedBlockPayload as isAllowedBlockPayload5,
2479
+ minTransactionFees,
2480
+ XYO_ZERO_ADDRESS
2481
+ } from "@xyo-network/xl1-protocol-lib";
2482
+ var TransactionBuilder = class extends Base {
2483
+ _blockRange;
2484
+ _chain;
2485
+ _elevatedPayloads = [];
2486
+ _fees;
2487
+ _payloads = [];
2488
+ _signers = [];
2489
+ constructor(options = {}) {
2490
+ super(options);
2491
+ }
2492
+ async build() {
2493
+ const chain = assertEx22(this._chain, () => "Chain must be set before building the transaction");
2494
+ const fees = assertEx22(this._fees, () => "Fees must be set before building the transaction");
2495
+ const blockRange = assertEx22(this._blockRange, () => "Block range must be set before building the transaction");
2496
+ return await buildTransaction(
2497
+ chain,
2498
+ this._elevatedPayloads,
2499
+ this._payloads,
2500
+ this._signers,
2501
+ asXL1BlockNumber5(blockRange[0], true),
2502
+ asXL1BlockNumber5(blockRange[1], true),
2503
+ this._signers[0]?.address,
2504
+ fees
2505
+ );
2506
+ }
2507
+ chain(chain) {
2508
+ this._chain = chain;
2509
+ return this;
2510
+ }
2511
+ async dryRun() {
2512
+ return await buildTransaction(
2513
+ XYO_ZERO_ADDRESS,
2514
+ this._elevatedPayloads,
2515
+ this._payloads,
2516
+ this._signers,
2517
+ asXL1BlockNumber5(0, true),
2518
+ asXL1BlockNumber5(1e3, true),
2519
+ this._signers[0]?.address,
2520
+ defaultTransactionFees3
2521
+ );
2522
+ }
2523
+ elevatedPayload(payload) {
2524
+ const allowedPayload = isAllowedBlockPayload5(payload) ? payload : void 0;
2525
+ const allowPayloadExists = assertEx22(allowedPayload, () => "Payload must be an AllowedBlockPayload");
2526
+ this._elevatedPayloads.push(allowPayloadExists);
2527
+ return this;
2528
+ }
2529
+ elevatedPayloads(payloads) {
2530
+ if (payloads)
2531
+ for (const payload of payloads) {
2532
+ this.elevatedPayload(payload);
2735
2533
  }
2736
- };
2534
+ return this;
2737
2535
  }
2738
- return store;
2739
- }
2740
- function payloadMapFromStore(store) {
2741
- if (isReadWriteArchivist(store)) {
2536
+ async estimatedMinimumFees() {
2537
+ const tx = await this.dryRun();
2538
+ const requiredGas = transactionRequiredGas(tx);
2742
2539
  return {
2743
- get: async (hash) => {
2744
- return (await store.get([hash]))[0];
2745
- },
2746
- getMany: async (hashes) => {
2747
- return await store.get(hashes);
2748
- },
2749
- has: async (hash) => {
2750
- return isDefined14((await store.get([hash]))[0]);
2751
- },
2752
- clear: async () => {
2753
- return await store.clear();
2754
- },
2755
- delete: async (id) => {
2756
- await store.delete([id]);
2757
- return true;
2758
- },
2759
- set: async (_id, data) => {
2760
- await store.insert([data]);
2761
- },
2762
- setMany: async (entries) => {
2763
- await store.insert(entries.map((e) => e[1]));
2540
+ base: minTransactionFees.base,
2541
+ // eslint-disable-next-line unicorn/prefer-math-min-max
2542
+ gasLimit: requiredGas > minTransactionFees.gasLimit ? requiredGas : minTransactionFees.gasLimit,
2543
+ gasPrice: minTransactionFees.gasPrice,
2544
+ priority: minTransactionFees.priority
2545
+ };
2546
+ }
2547
+ fees(fees) {
2548
+ this._fees = fees;
2549
+ return this;
2550
+ }
2551
+ payload(payload) {
2552
+ this._payloads.push(payload);
2553
+ return this;
2554
+ }
2555
+ payloads(payloads) {
2556
+ if (payloads)
2557
+ for (const payload of payloads) {
2558
+ if (payload !== null) {
2559
+ this.payload(payload);
2560
+ }
2561
+ }
2562
+ return this;
2563
+ }
2564
+ range(blockRange) {
2565
+ if (blockRange.length !== 2) {
2566
+ throw new Error("Block range must be an array of two numbers");
2567
+ }
2568
+ this._blockRange = blockRange;
2569
+ return this;
2570
+ }
2571
+ async removeElevatedPayload(payload) {
2572
+ const hash = await PayloadBuilder11.hash(payload);
2573
+ const existingHashes = await PayloadBuilder11.hashes(this._elevatedPayloads);
2574
+ const existingPayloadIndex = existingHashes.indexOf(hash);
2575
+ if (existingPayloadIndex === -1) {
2576
+ throw new Error("Payload not found in the transaction");
2577
+ }
2578
+ this._elevatedPayloads = this._elevatedPayloads.filter((_, index) => index !== existingPayloadIndex);
2579
+ return this;
2580
+ }
2581
+ async removePayload(payload) {
2582
+ const hash = await PayloadBuilder11.hash(payload);
2583
+ const existingHashes = await PayloadBuilder11.hashes(this._payloads);
2584
+ const existingPayloadIndex = existingHashes.indexOf(hash);
2585
+ if (existingPayloadIndex === -1) {
2586
+ throw new Error("Payload not found in the transaction");
2587
+ }
2588
+ this._payloads = this._payloads.filter((_, index) => index !== existingPayloadIndex);
2589
+ return this;
2590
+ }
2591
+ signer(signer) {
2592
+ if (signer) {
2593
+ this._signers.push(signer);
2594
+ }
2595
+ return this;
2596
+ }
2597
+ signers(signers) {
2598
+ if (signers)
2599
+ for (const signer of signers) {
2600
+ if (signer !== null) {
2601
+ this.signer(signer);
2602
+ }
2764
2603
  }
2765
- };
2604
+ return this;
2766
2605
  }
2767
- return store;
2768
- }
2606
+ };
2769
2607
 
2770
- // src/primitives/rewardFromBlockNumber.ts
2771
- import {
2772
- asAttoXL1 as asAttoXL14,
2773
- XL1_REWARDS_BLOCKS_PER_STEP,
2774
- XL1_REWARDS_CREATOR_REWARD,
2775
- XL1_REWARDS_MIN_BLOCK_REWARD,
2776
- XL1_REWARDS_STARTING_REWARD,
2777
- XL1_REWARDS_STEP_FACTOR_DENOMINATOR,
2778
- XL1_REWARDS_STEP_FACTOR_NUMERATOR
2779
- } from "@xyo-network/xl1-protocol-lib";
2780
- function rewardFromBlockNumber(blockNumber) {
2781
- if (blockNumber === 0) {
2782
- return XL1_REWARDS_CREATOR_REWARD;
2783
- }
2784
- const step = Math.floor((blockNumber + XL1_REWARDS_BLOCKS_PER_STEP) / XL1_REWARDS_BLOCKS_PER_STEP);
2785
- const stepExp = BigInt(step - 1);
2786
- const poweredNumerator = stepExp > 0 ? XL1_REWARDS_STEP_FACTOR_NUMERATOR ** stepExp : 1n;
2787
- const poweredDenominator = stepExp > 0 ? XL1_REWARDS_STEP_FACTOR_DENOMINATOR ** stepExp : 1n;
2788
- const reward = XL1_REWARDS_STARTING_REWARD * poweredNumerator / poweredDenominator;
2789
- return asAttoXL14(reward < XL1_REWARDS_MIN_BLOCK_REWARD ? XL1_REWARDS_MIN_BLOCK_REWARD : reward);
2790
- }
2608
+ // src/model/PayloadBundle/hydratedTransactionToPayloadBundle.ts
2609
+ var hydratedTransactionToPayloadBundle = (transaction) => {
2610
+ const root = transaction[0]._hash;
2611
+ return bundle2(root, transaction);
2612
+ };
2613
+ var bundle2 = (root, transaction) => {
2614
+ const payloads = flattenHydratedTransaction(transaction);
2615
+ return new PayloadBuilder12({ schema: PayloadBundleSchema2 }).fields({ payloads, root }).build();
2616
+ };
2791
2617
 
2792
- // src/primitives/rewards/networkStakeStepRewardPositionWeight.ts
2793
- import { XYO_NETWORK_STAKING_ADDRESS } from "@xyo-network/xl1-protocol-lib";
2618
+ // src/context/Actor.ts
2619
+ var ActorConfigContext = BaseConfigContextZod.extend({ config: ActorConfigZod });
2620
+ var isActorConfigContext = zodIsFactory5(ActorConfigContext);
2621
+ var asActorConfigContext = zodAsFactory5(ActorConfigContext, "asActorConfigContext");
2622
+ var toActorConfigContext = zodToFactory5(ActorConfigContext, "toActorConfigContext");
2794
2623
 
2795
- // src/primitives/stake/activeStakeAtTimeByAddress.ts
2796
- import { isDefined as isDefined15 } from "@xylabs/sdk-js";
2624
+ // src/CreatableProvider/AbstractCreatableProvider.ts
2625
+ import {
2626
+ AbstractCreatable as AbstractCreatable2,
2627
+ assertEx as assertEx24,
2628
+ IdLogger as IdLogger2
2629
+ } from "@xylabs/sdk-js";
2797
2630
 
2798
- // src/primitives/stake/mergedAddRemoveStakeEventsByStaker.ts
2799
- async function mergedAddRemoveStakeEventsByStaker(chainEvents, range, staked, staker) {
2800
- const [addedEvents, removedEvents] = await Promise.all([
2801
- chainEvents.stakeEvents(range, { name: "StakeAdded", args: { staked, staker } }),
2802
- chainEvents.stakeEvents(range, { name: "StakeRemoved", args: { staked, staker } })
2803
- ]);
2804
- const result = [...addedEvents, ...removedEvents].toSorted((a, b) => a.time - b.time);
2805
- return result;
2631
+ // src/CreatableProvider/ProviderFactory.ts
2632
+ import { assertEx as assertEx23 } from "@xylabs/sdk-js";
2633
+ function providerFactoryDescription(factory, labels) {
2634
+ return `${factory.providerName}:${factory.defaultMoniker}:${JSON.stringify(labels ?? factory.labels ?? {})}`;
2806
2635
  }
2807
-
2808
- // src/primitives/stake/activeStakeAtTimeByAddress.ts
2809
- async function activeStakeAtTimeByAddress(chain, staked, time, staker) {
2810
- const stakeEvents = (await mergedAddRemoveStakeEventsByStaker(chain, [0, time], staked, staker)).toSorted((a, b) => a.time - b.time);
2811
- let result = 0n;
2812
- for (const event of stakeEvents) {
2813
- if (event.time > time) break;
2814
- if (event.args.staked !== staked) continue;
2815
- if (isDefined15(staker) && event.args.staker !== staker) continue;
2816
- if (event.name === "StakeAdded") {
2817
- result += event.args.amount;
2818
- } else if (event.name === "StakeRemoved") {
2819
- result -= event.args.amount;
2820
- }
2636
+ var ProviderFactory = class _ProviderFactory {
2637
+ creatableProvider;
2638
+ defaultMoniker;
2639
+ defaultParams;
2640
+ dependencies;
2641
+ labels;
2642
+ monikers;
2643
+ providerName;
2644
+ scope;
2645
+ _uniqueId;
2646
+ constructor(creatableProvider2, dependencies, params, labels = {}, scope = "context") {
2647
+ this.creatableProvider = creatableProvider2;
2648
+ this.defaultParams = params;
2649
+ this.defaultMoniker = creatableProvider2.defaultMoniker;
2650
+ this.dependencies = dependencies;
2651
+ this.monikers = creatableProvider2.monikers;
2652
+ this.scope = scope;
2653
+ assertEx23(this.monikers.includes(this.defaultMoniker), () => "defaultMoniker must be in monikers");
2654
+ this.labels = Object.assign({}, creatableProvider2.labels ?? {}, labels ?? {});
2655
+ this.providerName = creatableProvider2.name;
2656
+ this._uniqueId = Symbol(providerFactoryDescription(this));
2821
2657
  }
2822
- return result;
2823
- }
2824
-
2825
- // src/primitives/stake/activeStakeAtTimeByPosition.ts
2826
- import { isUndefined as isUndefined5 } from "@xylabs/sdk-js";
2827
-
2828
- // src/primitives/stake/mergedAddRemoveStakeEventsByPosition.ts
2829
- async function mergedAddRemoveStakeEventsByPosition(chainEvents, range, position) {
2830
- const [addedEvents, removedEvents] = await Promise.all([
2831
- chainEvents.stakeEvents(range, { name: "StakeAdded", args: { id: position } }),
2832
- chainEvents.stakeEvents(range, { name: "StakeRemoved", args: { id: position } })
2833
- ]);
2834
- const result = [...addedEvents, ...removedEvents].toSorted((a, b) => a.time - b.time);
2835
- return result;
2836
- }
2837
-
2838
- // src/primitives/stake/activeStakeAtTimeByPosition.ts
2839
- async function activeStakeAtTimeByPosition(chainStakeEvents, externalTime, position) {
2840
- const stakeEvents = (await mergedAddRemoveStakeEventsByPosition(chainStakeEvents, [0, externalTime], position)).toSorted((a, b) => a.time - b.time);
2841
- let result = 0n;
2842
- for (const event of stakeEvents) {
2843
- if (event.time > externalTime) break;
2844
- if (isUndefined5(position) || position === Number(event.args.id)) {
2845
- if (event.name === "StakeAdded") {
2846
- result += event.args.amount;
2847
- } else if (event.name === "StakeRemoved") {
2848
- result -= event.args.amount;
2658
+ get resolvedMoniker() {
2659
+ const labels = this.labels ?? {};
2660
+ const labelString = Object.entries(labels).map(([key, value]) => `${key}=${value}`).join(",");
2661
+ return labelString.length === 0 ? `${this.defaultMoniker}` : `${this.defaultMoniker}|${labelString}`;
2662
+ }
2663
+ get uniqueId() {
2664
+ return this._uniqueId;
2665
+ }
2666
+ static withParams(creatableProvider2, dependencies, params, labels = {}) {
2667
+ return new _ProviderFactory(creatableProvider2, dependencies, params, labels);
2668
+ }
2669
+ factory(dependencies, params, labels = {}) {
2670
+ return new _ProviderFactory(this.creatableProvider, dependencies, params, labels);
2671
+ }
2672
+ async getInstance(params, { start = true }) {
2673
+ let scopeObject;
2674
+ switch (this.scope) {
2675
+ case "global": {
2676
+ globalThis.xyoServiceSingletons ??= {};
2677
+ scopeObject = globalThis.xyoServiceSingletons;
2678
+ break;
2679
+ }
2680
+ case "context": {
2681
+ const context = assertEx23(
2682
+ params?.context,
2683
+ () => "Context is required for context-scoped providers"
2684
+ );
2685
+ context.singletons ??= {};
2686
+ scopeObject = context.singletons;
2687
+ break;
2688
+ }
2689
+ default: {
2690
+ scopeObject = {};
2691
+ break;
2849
2692
  }
2850
2693
  }
2694
+ const mergedParams = {
2695
+ ...this.defaultParams,
2696
+ ...params
2697
+ };
2698
+ const resultPromise = scopeObject[this.resolvedMoniker] ?? this.creatableProvider.create(mergedParams);
2699
+ scopeObject[this.resolvedMoniker] = resultPromise;
2700
+ const result = await resultPromise;
2701
+ if (start) {
2702
+ assertEx23(await result.start(), () => `Failed to start provider instance [${this.resolvedMoniker}]`);
2703
+ }
2704
+ return result;
2851
2705
  }
2852
- return result;
2853
- }
2706
+ async tryGetInstance(params, options) {
2707
+ try {
2708
+ return await this.getInstance(params, options);
2709
+ } catch {
2710
+ return;
2711
+ }
2712
+ }
2713
+ };
2854
2714
 
2855
- // src/primitives/stake/allStakersForRange.ts
2856
- import {
2857
- toAddress as toAddress7
2858
- } from "@xylabs/sdk-js";
2859
- async function allStakersForRange(chain, externalRange, staked) {
2860
- const mergedEvents = await mergedAddRemoveStakeEventsByStaker(chain, [0, externalRange[1]], staked);
2861
- const resultWithZeros = {};
2862
- for (const event of mergedEvents) {
2863
- const staker = toAddress7(event.args.staker);
2864
- resultWithZeros[staker] = resultWithZeros[staker] ?? 0n;
2865
- if (event.name === "StakeAdded") {
2866
- resultWithZeros[staker] += event.args.amount;
2867
- } else if (event.name === "StakeRemoved") {
2868
- resultWithZeros[staker] -= event.args.amount;
2715
+ // src/CreatableProvider/AbstractCreatableProvider.ts
2716
+ var AbstractCreatableProvider = class extends AbstractCreatable2 {
2717
+ dependencies = {};
2718
+ _contextCache;
2719
+ _logger;
2720
+ get logger() {
2721
+ if (this._logger === void 0) {
2722
+ const providedLogger = this.params.logger ?? this.context.logger;
2723
+ this._logger = providedLogger ? new IdLogger2(providedLogger, () => `${this.moniker} [${this.constructor.name}]`) : null;
2724
+ }
2725
+ return this._logger ?? void 0;
2726
+ }
2727
+ get meter() {
2728
+ return this.context.meterProvider?.getMeter(this.name) ?? super.meter;
2729
+ }
2730
+ get tracer() {
2731
+ return this.context.traceProvider?.getTracer(this.name) ?? super.tracer;
2732
+ }
2733
+ get config() {
2734
+ return this.context.config;
2735
+ }
2736
+ get context() {
2737
+ return this.params.context;
2738
+ }
2739
+ get locator() {
2740
+ return this.context.locator;
2741
+ }
2742
+ static factory(dependencies, params) {
2743
+ const factory = ProviderFactory.withParams(this, dependencies, params);
2744
+ return factory;
2745
+ }
2746
+ static async paramsHandler(params = {}) {
2747
+ const context = assertEx24(params.context, () => new Error("Context is required"));
2748
+ const config = assertEx24(context.config, () => new Error("Context config is required"));
2749
+ const locator = assertEx24(context.locator, () => new Error("Context locator is required"));
2750
+ return await super.paramsHandler({
2751
+ ...params,
2752
+ statusReporter: params.statusReporter ?? context.statusReporter,
2753
+ context: {
2754
+ ...context,
2755
+ config,
2756
+ locator
2757
+ },
2758
+ name: params.name ?? this.defaultMoniker,
2759
+ logger: params.logger ?? context.logger
2760
+ });
2761
+ }
2762
+ async createHandler() {
2763
+ await super.createHandler();
2764
+ if (this.tracer === void 0) {
2765
+ this.logger?.warn("No tracer available in context");
2766
+ }
2767
+ if (this.meter === void 0) {
2768
+ this.logger?.warn("No meter available in context");
2869
2769
  }
2870
2770
  }
2871
- const nonZero = Object.entries(resultWithZeros).filter(([, amount]) => amount > 0n).map(([address]) => address);
2872
- const result = {};
2873
- for (const address of nonZero) {
2874
- result[toAddress7(address)] = resultWithZeros[toAddress7(address)];
2771
+ async locateAndCreate(moniker) {
2772
+ return await this.locator.getInstance(moniker);
2875
2773
  }
2876
- return result;
2877
- }
2774
+ async tryLocateAndCreate(moniker) {
2775
+ return await this.locator.tryGetInstance(moniker);
2776
+ }
2777
+ };
2878
2778
 
2879
- // src/primitives/stake/allStakersForStep.ts
2880
- async function allStakersForStep(context, blockViewer, stakeEventsViewer, stepContext, staked) {
2881
- const xl1BlockRange = stepBlockRange(stepContext);
2882
- return await allStakersForRange(
2883
- stakeEventsViewer,
2884
- await externalBlockRangeFromXL1BlockRange(context, blockViewer, xl1BlockRange),
2885
- staked
2886
- );
2779
+ // src/CreatableProvider/CreatableProvider.ts
2780
+ function creatableProvider() {
2781
+ return (constructor) => {
2782
+ constructor;
2783
+ };
2784
+ }
2785
+ function labeledCreatableProvider() {
2786
+ return (constructor) => {
2787
+ constructor;
2788
+ };
2887
2789
  }
2888
2790
 
2889
- // src/primitives/stake/weightedStakeForRangeByPosition.ts
2890
- import { isDefined as isDefined16 } from "@xylabs/sdk-js";
2891
- import { asBlockNumber as asBlockNumber2 } from "@xyo-network/xl1-protocol-lib";
2892
- async function weightedStakeForRangeByPosition(context, blockViewer, stakeEventsViewer, externalRange, staked, positionId) {
2893
- const cacheKey = isDefined16(positionId) ? `${externalRange[0]}-${externalRange[1]}-${positionId}` : `${externalRange[0]}-${externalRange[1]}-all`;
2894
- return await withContextCacheResponse(context, "weightedStakeForRangeByPosition", cacheKey, async () => {
2895
- let weightedStakeSum = 0n;
2896
- if (isDefined16(positionId)) {
2897
- const mergedEvents = (await mergedAddRemoveStakeEventsByPosition(
2898
- stakeEventsViewer,
2899
- [0, externalRange[1]],
2900
- positionId
2901
- )).toSorted((a, b) => a.time - b.time);
2902
- let currentTime = externalRange[0];
2903
- let currentStake = 0n;
2904
- if (isDefined16(staked) && mergedEvents.at(0)?.args.staked !== staked) {
2905
- return 0n;
2906
- }
2907
- for (const event of mergedEvents) {
2908
- if (event.time > currentTime) {
2909
- weightedStakeSum += currentStake * BigInt(event.time - currentTime);
2910
- }
2911
- if (event.name === "StakeAdded") {
2912
- currentStake += event.args.amount;
2913
- } else if (event.name === "StakeRemoved") {
2914
- currentStake -= event.args.amount;
2915
- }
2916
- currentStake = currentStake < 0n ? 0n : currentStake;
2917
- currentTime = asBlockNumber2(event.time, { name: "weightedStakeForRangeByPosition" });
2918
- if (currentTime > externalRange[1]) {
2919
- break;
2920
- }
2791
+ // src/CreatableProvider/CreatableProviderRegistry.ts
2792
+ import { isTruthy } from "@xylabs/sdk-js";
2793
+ var buildProviderFactory = (provider, defaultParams, labels) => {
2794
+ const factory = {
2795
+ monikers: provider.monikers,
2796
+ uniqueId: Symbol(providerFactoryDescription(provider, labels)),
2797
+ // Merge module & supplied labels
2798
+ labels: { ...provider.labels, ...labels },
2799
+ creatableProvider: provider.creatableProvider,
2800
+ dependencies: provider.dependencies,
2801
+ resolvedMoniker: provider.resolvedMoniker,
2802
+ providerName: provider.providerName,
2803
+ scope: provider.scope,
2804
+ defaultParams,
2805
+ getInstance: provider.getInstance.bind(provider),
2806
+ tryGetInstance: provider.tryGetInstance?.bind(provider),
2807
+ defaultMoniker: provider.defaultMoniker,
2808
+ factory: provider.factory.bind(provider)
2809
+ };
2810
+ return factory;
2811
+ };
2812
+ var registerCreatableProviderFactory = (registry, factory, labels, primary = false) => {
2813
+ const primaryMonikers = primary !== true && isTruthy(primary) ? Array.isArray(primary) ? primary : [primary] : [];
2814
+ for (const primaryMoniker of primaryMonikers) {
2815
+ if (!factory.monikers.includes(primaryMoniker)) {
2816
+ console.warn(`Primary moniker ${String(primary)} not found in factory monikers`);
2817
+ }
2818
+ }
2819
+ const isPrimaryForMoniker = (moniker) => {
2820
+ switch (typeof primary) {
2821
+ case "boolean": {
2822
+ return primary;
2921
2823
  }
2922
- if (externalRange[1] > currentTime) {
2923
- weightedStakeSum += currentStake * BigInt(externalRange[1] - currentTime);
2824
+ case "string": {
2825
+ return moniker === primary;
2924
2826
  }
2925
- } else {
2926
- const positionCount = await stakeEventsViewer.positionCount([0, externalRange[1]]);
2927
- for (let pos = 0; pos < positionCount; pos++) {
2928
- weightedStakeSum += await weightedStakeForRangeByPosition(context, blockViewer, stakeEventsViewer, externalRange, staked, pos);
2827
+ case "object": {
2828
+ if (Array.isArray(primary)) {
2829
+ return primary.includes(moniker);
2830
+ }
2929
2831
  }
2930
2832
  }
2931
- return weightedStakeSum;
2932
- });
2933
- }
2934
-
2935
- // src/primitives/rewards/networkStakeStepRewardPositionWeight.ts
2936
- async function networkStakeStepRewardPositionWeight(context, blockViewer, stakeEventsViewer, stepContext, position) {
2937
- const result = await weightedStakeForRangeByPosition(
2938
- context,
2939
- blockViewer,
2940
- stakeEventsViewer,
2941
- await externalBlockRangeFromStep(context, blockViewer, stepContext),
2942
- XYO_NETWORK_STAKING_ADDRESS,
2943
- position
2944
- );
2945
- return result;
2946
- }
2947
-
2948
- // src/primitives/state/findMostRecentBlock.ts
2949
- import { isSignedBlockBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol-lib";
2950
- var DEFAULT_NEXT_OPTIONS = { limit: 50 };
2951
- var findMostRecentBlock = async (chainArchivist, nextOptions = DEFAULT_NEXT_OPTIONS, maxIterations = Number.POSITIVE_INFINITY) => {
2952
- let mostRecentBlock;
2953
- let cursor;
2954
- let batch;
2955
- let iterations = 0;
2956
- do {
2957
- batch = await chainArchivist.next({
2958
- ...nextOptions,
2959
- order: "desc",
2960
- cursor
2961
- });
2962
- const blocks = batch.filter(isSignedBlockBoundWitnessWithStorageMeta);
2963
- const last = blocks?.at(0);
2964
- if (last) {
2965
- mostRecentBlock = last;
2966
- break;
2967
- } else {
2968
- cursor = batch.at(-1)?._sequence;
2969
- }
2970
- iterations = iterations + 1;
2971
- } while (batch.length > 0 && iterations < maxIterations);
2972
- return mostRecentBlock;
2833
+ throw new Error(`Invalid primary value: ${String(primary)}`);
2834
+ };
2835
+ const factoryClone = buildProviderFactory(factory, factory.defaultParams, labels);
2836
+ registry[factoryClone.defaultMoniker] = [factoryClone, ...registry[factoryClone.defaultMoniker] ?? []];
2837
+ for (const moniker of factoryClone.monikers) {
2838
+ registry[moniker] = isPrimaryForMoniker(moniker) ? [factoryClone, ...registry[moniker] ?? []] : [...registry[moniker] ?? [], factoryClone];
2839
+ }
2840
+ };
2841
+ var registerCreatableProviderFactories = (factories, registry = {}, primary = false) => {
2842
+ for (const factory of factories) {
2843
+ registerCreatableProviderFactory(registry, factory, void 0, primary);
2844
+ }
2845
+ return registry;
2973
2846
  };
2974
2847
 
2975
- // src/primitives/state/hydratedBlockByNumber.ts
2976
- import { assertEx as assertEx24, spanAsync as spanAsync2 } from "@xylabs/sdk-js";
2977
- async function hydratedBlockByNumber(context, blockNumber) {
2978
- return await spanAsync2("hydratedBlockByNumber", async () => {
2979
- if (blockNumber < 0) throw new Error(`Block number ${blockNumber} is less than 0`);
2980
- if (blockNumber > Number.MAX_SAFE_INTEGER) throw new Error(`Block number ${blockNumber} is greater than the maximum safe integer`);
2981
- if (blockNumber % 1 !== 0) throw new Error(`Block number ${blockNumber} is not an integer`);
2982
- const cacheKey = `${blockNumber}`;
2983
- return await withContextCacheResponse(context, "hydratedBlockByNumber", cacheKey, async () => {
2984
- const block = assertEx24(
2985
- await blockFromBlockNumber(context, blockNumber),
2986
- () => `Could not find block for block number ${blockNumber}`
2987
- );
2988
- return await hydrateBlock(context, block._hash);
2989
- }, { max: 2e4 });
2990
- }, { ...context, timeBudgetLimit: 500 });
2848
+ // src/CreatableProvider/LabeledCreatableProviderFactory.ts
2849
+ var hasLabels = (factory) => {
2850
+ return factory.labels !== void 0;
2851
+ };
2852
+ function labeledCreatableProviderFactory() {
2853
+ return (constructor) => {
2854
+ constructor;
2855
+ };
2991
2856
  }
2992
2857
 
2993
- // src/primitives/transaction/elevatedPayloads.ts
2994
- import { isAllowedBlockPayload as isAllowedBlockPayload5 } from "@xyo-network/xl1-protocol-lib";
2995
- var ELEVATE_OPCODE = "elevate";
2996
- function elevatedPayloads([tx, payloads]) {
2997
- const opCodes = (tx.script ?? []).filter((operation) => operation.startsWith(`${ELEVATE_OPCODE}|`));
2998
- const elevatedPayloads2 = [];
2999
- for (const opCode of opCodes) {
3000
- const [code, hash] = opCode.split("|");
3001
- if (code === ELEVATE_OPCODE) {
3002
- const elevatedPayload = payloads.find((payload) => payload._hash === hash);
3003
- if (isAllowedBlockPayload5(elevatedPayload)) {
3004
- elevatedPayloads2.push(elevatedPayload);
3005
- }
3006
- }
2858
+ // src/CreatableProvider/ProviderFactoryLocator.ts
2859
+ import { hasAllLabels } from "@xylabs/sdk-js";
2860
+ import { assertEx as assertEx25 } from "@xylabs/sdk-js";
2861
+ var ProviderFactoryLocator = class _ProviderFactoryLocator {
2862
+ _context;
2863
+ _registry;
2864
+ _frozen = false;
2865
+ _parent;
2866
+ _validateDepsOnRegister;
2867
+ constructor(context, registry = {}, validateDepsOnRegister = false) {
2868
+ this._registry = registry;
2869
+ this._context = { ...context, locator: this };
2870
+ this._parent = context.locator;
2871
+ this._validateDepsOnRegister = validateDepsOnRegister;
3007
2872
  }
3008
- if (opCodes.length === elevatedPayloads2.length) {
3009
- return elevatedPayloads2;
2873
+ get context() {
2874
+ return this._context;
3010
2875
  }
3011
- throw new Error("Not all elevated payloads could be found in the transaction payloads");
3012
- }
3013
-
3014
- // src/primitives/uncle/getProducerKey.ts
3015
- function getProducerKey(block) {
3016
- return block[0].addresses.toSorted().join(",");
3017
- }
3018
-
3019
- // src/primitives/uncle/scoreUncle.ts
3020
- var PRODUCER_DIVERSITY_BONUS = 1e3;
3021
- function scoreUncle(finalizedWindowedChain, blocks) {
3022
- if (blocks.length === 0) return 0;
3023
- let score = blocks.length;
3024
- const head = finalizedWindowedChain.at(-1);
3025
- if (head && blocks[0]) {
3026
- const headProducer = getProducerKey(head);
3027
- const candidateProducer = getProducerKey(blocks[0]);
3028
- if (headProducer !== candidateProducer) {
3029
- score += PRODUCER_DIVERSITY_BONUS;
3030
- }
2876
+ get logger() {
2877
+ return this.context.logger;
3031
2878
  }
3032
- return score;
3033
- }
3034
-
3035
- // src/primitives/uncle/findBestUncle.ts
3036
- var DEFAULT_MIN_CANDIDATES = 2;
3037
- var DEFAULT_BACKOFF_MS = 12e4;
3038
- function findBestUncle(finalizedWindowedChain, uncles, options) {
3039
- if (uncles.length === 0) return void 0;
3040
- const minCandidates = options?.minCandidates ?? DEFAULT_MIN_CANDIDATES;
3041
- const backoffMs = options?.backoffMs ?? DEFAULT_BACKOFF_MS;
3042
- const now = options?.now ?? Date.now();
3043
- if (uncles.length < minCandidates) {
3044
- const headEpoch = finalizedWindowedChain.at(-1)?.[0].$epoch ?? 0;
3045
- const headAge = now - headEpoch;
3046
- if (headAge < backoffMs) {
3047
- return void 0;
3048
- }
2879
+ /**
2880
+ * The current registry for the module factory
2881
+ */
2882
+ get registry() {
2883
+ return this._registry;
2884
+ }
2885
+ get validateDepsOnRegister() {
2886
+ return this._validateDepsOnRegister;
3049
2887
  }
3050
- const scores = uncles.map((uncle) => [scoreUncle(finalizedWindowedChain, uncle), uncle]).toSorted((a, b) => b[0] - a[0]);
3051
- return scores[0]?.[1];
3052
- }
3053
-
3054
- // src/primitives/uncle/findUncles.ts
3055
- import {
3056
- assertEx as assertEx25,
3057
- exists as exists2
3058
- } from "@xylabs/sdk-js";
3059
- import { isTransactionBoundWitness as isTransactionBoundWitness2 } from "@xyo-network/xl1-protocol-lib";
3060
- function blocksToChains(blocks) {
3061
- const chains = [];
3062
- const map = /* @__PURE__ */ new Map();
3063
- for (const block of blocks) {
3064
- map.set(block[0]._hash, block);
2888
+ freeze() {
2889
+ this._frozen = true;
3065
2890
  }
3066
- for (const block of blocks) {
3067
- let uncle = [block];
3068
- let previous = block[0].previous ? map.get(block[0].previous) : void 0;
3069
- while (previous) {
3070
- if (previous[0].block === uncle[0][0].block - 1) {
3071
- uncle.unshift(previous);
3072
- previous = previous[0].previous ? map.get(previous[0].previous) : void 0;
2891
+ async getInstance(moniker, { start = true, labels } = {}) {
2892
+ return assertEx25(
2893
+ await this.tryGetInstance(moniker, { start, labels }),
2894
+ () => `No provider instance for the supplied config moniker [${moniker}]${labels ? ` & labels [${JSON.stringify(labels)}]` : ""} could be created`
2895
+ );
2896
+ }
2897
+ has(moniker) {
2898
+ return !!this._registry[moniker];
2899
+ }
2900
+ /**
2901
+ * Locates a provider factory that matches the supplied moniker and labels
2902
+ * @param moniker The config moniker for the provider
2903
+ * @param labels The labels for the provider factory
2904
+ * @returns A provider factory that matches the supplied moniker and labels or throws if one is not found
2905
+ */
2906
+ locate(moniker, labels) {
2907
+ return assertEx25(
2908
+ this.tryLocate(moniker, labels),
2909
+ () => `No module factory for the supplied config moniker [${moniker}]${labels ? ` & labels [${JSON.stringify(labels)}]` : ""} registered`
2910
+ );
2911
+ }
2912
+ merge(locator) {
2913
+ const registry = { ...this.registry };
2914
+ for (const moniker in locator.registry) {
2915
+ if (registry[moniker]) {
2916
+ registry[moniker].push(...locator.registry[moniker] ?? []);
3073
2917
  } else {
3074
- uncle = [];
3075
- break;
2918
+ registry[moniker] = locator.registry[moniker];
3076
2919
  }
3077
2920
  }
3078
- if (uncle.length > 0) {
3079
- chains.push(uncle);
2921
+ return new _ProviderFactoryLocator(this.context, registry);
2922
+ }
2923
+ /**
2924
+ * Registers a single module factory (with optional tags) with the locator
2925
+ * @param factory The factory to register
2926
+ * @param labels The labels for the module factory
2927
+ */
2928
+ register(factory, labels, primary = false) {
2929
+ assertEx25(!this._frozen, () => "Cannot register a module factory after the locator has been frozen");
2930
+ if (this.validateDepsOnRegister) {
2931
+ const missingDeps = factory.dependencies.filter((dep) => !this.registered(dep));
2932
+ assertEx25(missingDeps.length === 0, () => `Cannot register module factory [${factory.uniqueId.description}] due to missing dependencies: ${missingDeps.join(", ")}`);
3080
2933
  }
2934
+ registerCreatableProviderFactory(this._registry, factory, labels, primary);
2935
+ return this;
3081
2936
  }
3082
- return chains;
3083
- }
3084
- function toValidUncle(_context, finalizedWindowedChain, possibleUncle) {
3085
- const finalizedWindowStartBlockNumber = finalizedWindowedChain.at(0)?.[0].block ?? -1;
3086
- const finalizedHead = assertEx25(finalizedWindowedChain.at(-1), () => "finalizedWindowedChain is empty");
3087
- const prunedPossibleUncle = possibleUncle.filter((b) => b[0].block > finalizedHead[0].block);
3088
- if (prunedPossibleUncle.length === 0) {
3089
- return;
2937
+ /**
2938
+ * Registers multiple module factories with the locator
2939
+ * @param factories The factories to register
2940
+ */
2941
+ registerMany(factories) {
2942
+ for (const factory of factories) {
2943
+ this.register(factory);
2944
+ }
2945
+ return this;
3090
2946
  }
3091
- if (prunedPossibleUncle[0][0].block !== finalizedHead[0].block + 1) {
3092
- return;
2947
+ registered(moniker) {
2948
+ return !!this.registry[moniker] || (this._parent?.registered(moniker) ?? false);
3093
2949
  }
3094
- if (prunedPossibleUncle[0][0].previous !== finalizedHead[0]._hash) {
3095
- return;
2950
+ async tryGetInstance(moniker, { start = true, labels } = {}) {
2951
+ const resolvedParams = { context: this.context };
2952
+ const factory = this.tryLocate(moniker, labels);
2953
+ if (factory) {
2954
+ if (this.context.singletons[factory.uniqueId]) {
2955
+ return this.context.singletons[factory.uniqueId];
2956
+ }
2957
+ this.logger?.info(`Creating provider instance for moniker [${moniker}]${labels ? ` with labels [${JSON.stringify(labels)}]` : ""} using factory [${factory.uniqueId.description}]`);
2958
+ const result = await factory.getInstance(resolvedParams, { start });
2959
+ this.context.singletons[factory.uniqueId] = result;
2960
+ return result;
2961
+ }
3096
2962
  }
3097
- const allUncleTransactions = prunedPossibleUncle.flatMap((b) => b[1]).filter(isTransactionBoundWitness2);
3098
- const allFinalizedTransactions = finalizedWindowedChain.flatMap((b) => b[1]).filter(isTransactionBoundWitness2);
3099
- const txPossiblyBeforeWindow = allUncleTransactions.find((tx) => tx.nbf < finalizedWindowStartBlockNumber);
3100
- if (txPossiblyBeforeWindow) {
3101
- return;
2963
+ /**
2964
+ * Tries to locate a module factory that matches the supplied moniker and labels
2965
+ * @param moniker The config moniker for the module
2966
+ * @param labels The labels for the module factory
2967
+ * @returns A module factory that matches the supplied moniker and labels or undefined
2968
+ */
2969
+ tryLocate(moniker, labels) {
2970
+ const result = (labels ? this._registry[moniker]?.filter(hasLabels).find((factory) => hasAllLabels(factory?.labels, labels)) ?? this._registry[moniker]?.[0] : this._registry[moniker]?.[0]) ?? this._parent?.tryLocate(moniker, labels);
2971
+ return result;
3102
2972
  }
3103
- const txExistsInWindow = allUncleTransactions.find((tx) => allFinalizedTransactions.find((finalTx) => finalTx._hash === tx._hash));
3104
- if (txExistsInWindow) {
3105
- return;
2973
+ validateDependencies(recursive = false) {
2974
+ if (recursive) {
2975
+ this._parent?.validateDependencies();
2976
+ }
2977
+ for (const moniker in this.registry) {
2978
+ for (const factory of this.registry[moniker] ?? []) {
2979
+ const missingDeps = factory.dependencies.filter((dep) => !this.registered(dep));
2980
+ assertEx25(missingDeps.length === 0, () => `Module factory [${factory.uniqueId.description}] is missing dependencies: ${missingDeps.join(", ")}`);
2981
+ }
2982
+ }
3106
2983
  }
3107
- return prunedPossibleUncle;
2984
+ };
2985
+
2986
+ // src/context/getEmptyProviderContext.ts
2987
+ function getEmptyProviderContext(config) {
2988
+ const singletons = {};
2989
+ const caches = {};
2990
+ const locator = new ProviderFactoryLocator({
2991
+ config,
2992
+ singletons,
2993
+ caches,
2994
+ logger: console
2995
+ });
2996
+ return locator.context;
3108
2997
  }
3109
- function findUncles(context, finalizedWindowedChain, blocks) {
3110
- return blocksToChains(blocks).map((chain) => toValidUncle(context, finalizedWindowedChain, chain)).filter(exists2);
2998
+ function getEmptyContext(config) {
2999
+ return getEmptyProviderContext(config);
3111
3000
  }
3112
3001
 
3002
+ // src/context/HostActor.ts
3003
+ import {
3004
+ zodAsFactory as zodAsFactory6,
3005
+ zodIsFactory as zodIsFactory6,
3006
+ zodToFactory as zodToFactory6
3007
+ } from "@xylabs/sdk-js";
3008
+ var HostActorConfigContext = BaseConfigContextZod.extend({ config: HostActorConfigZod });
3009
+ var isHostActorConfigContext = zodIsFactory6(HostActorConfigContext);
3010
+ var asHostActorConfigContext = zodAsFactory6(HostActorConfigContext, "asHostActorConfigContext");
3011
+ var toHostActorConfigContext = zodToFactory6(HostActorConfigContext, "toHostActorConfigContext");
3012
+
3013
+ // src/createDeclarationPayload.ts
3014
+ import { isDefined as isDefined16 } from "@xylabs/sdk-js";
3015
+ import { PayloadBuilder as PayloadBuilder13 } from "@xyo-network/sdk-js";
3016
+ import {
3017
+ ChainStakeIntentSchema
3018
+ } from "@xyo-network/xl1-protocol-lib";
3019
+ var createDeclarationIntent = (address, intent, nbf, exp) => {
3020
+ const expiration = isDefined16(exp) ? exp : nbf + 1e4;
3021
+ const redeclarationIntent = new PayloadBuilder13({ schema: ChainStakeIntentSchema }).fields({
3022
+ from: address,
3023
+ intent,
3024
+ nbf,
3025
+ exp: expiration
3026
+ }).build();
3027
+ return redeclarationIntent;
3028
+ };
3029
+
3030
+ // src/eip-712/Payloads/EIP712Data.ts
3031
+ import { AsObjectFactory as AsObjectFactory2 } from "@xylabs/sdk-js";
3032
+ import {
3033
+ asSchema as asSchema2,
3034
+ isPayloadOfZodType
3035
+ } from "@xyo-network/sdk-js";
3036
+ import { z as z24 } from "zod";
3037
+
3038
+ // src/eip-712/Types.ts
3039
+ import { z as z23 } from "zod";
3040
+ var TypedDataDomainZod = z23.object({
3041
+ name: z23.string().nullable().optional(),
3042
+ version: z23.string().nullable().optional(),
3043
+ chainId: z23.union([z23.string(), z23.number(), z23.bigint()]).nullable().optional(),
3044
+ verifyingContract: z23.string().nullable().optional(),
3045
+ salt: z23.union([z23.string(), z23.instanceof(Uint8Array)]).nullable().optional()
3046
+ });
3047
+ var TypedDataFieldZod = z23.object({
3048
+ name: z23.string(),
3049
+ type: z23.string()
3050
+ });
3051
+ var TypedDataTypesZod = z23.record(z23.string(), z23.array(TypedDataFieldZod));
3052
+ var TypedDataValueZod = z23.record(z23.string(), z23.any());
3053
+
3054
+ // src/eip-712/Payloads/EIP712Data.ts
3055
+ var EIP712DataPayloadFieldsZod = z24.object({
3056
+ domain: TypedDataDomainZod,
3057
+ types: TypedDataTypesZod,
3058
+ values: TypedDataValueZod
3059
+ });
3060
+ var EIP712DataPayloadSchema = asSchema2("network.xyo.chains.ethereum.eip712.data", true);
3061
+ var isEIP712DataPayload = isPayloadOfZodType(
3062
+ EIP712DataPayloadFieldsZod,
3063
+ EIP712DataPayloadSchema
3064
+ );
3065
+ var asEIP712DataPayload = AsObjectFactory2.create(isEIP712DataPayload);
3066
+
3067
+ // src/eip-712/Payloads/EIP712Signature.ts
3068
+ import { AsObjectFactory as AsObjectFactory3, HashZod } from "@xylabs/sdk-js";
3069
+ import {
3070
+ asSchema as asSchema3,
3071
+ isPayloadOfZodType as isPayloadOfZodType2
3072
+ } from "@xyo-network/sdk-js";
3073
+ import { z as z25 } from "zod";
3074
+ var EIP712SignaturePayloadFieldsZod = z25.object({
3075
+ address: z25.string(),
3076
+ hash: HashZod,
3077
+ signature: z25.string()
3078
+ });
3079
+ var EIP712SignaturePayloadSchema = asSchema3("network.xyo.chains.ethereum.eip712.signature", true);
3080
+ var isEIP712SignaturePayload = isPayloadOfZodType2(
3081
+ EIP712SignaturePayloadFieldsZod,
3082
+ EIP712SignaturePayloadSchema
3083
+ );
3084
+ var asEIP712SignaturePayload = AsObjectFactory3.create(isEIP712SignaturePayload);
3085
+
3086
+ // src/eip-712/sign.ts
3087
+ import { PayloadBuilder as PayloadBuilder14 } from "@xyo-network/sdk-js";
3088
+ var signEIP712Message = async (signer, data) => {
3089
+ const {
3090
+ domain,
3091
+ types,
3092
+ values
3093
+ } = data;
3094
+ const signature = await signer.signTypedData(domain, types, values);
3095
+ const hash = await PayloadBuilder14.hash(data);
3096
+ const address = await signer.getAddress();
3097
+ return {
3098
+ address,
3099
+ hash,
3100
+ schema: EIP712SignaturePayloadSchema,
3101
+ signature
3102
+ };
3103
+ };
3104
+
3105
+ // src/eip-712/verify.ts
3106
+ import { asHash as asHash4, isUndefined as isUndefined5 } from "@xylabs/sdk-js";
3107
+ import { PayloadBuilder as PayloadBuilder15 } from "@xyo-network/sdk-js";
3108
+ import { verifyTypedData } from "ethers";
3109
+ var verifyEIP712Message = async (data, sig) => {
3110
+ const {
3111
+ address,
3112
+ signature,
3113
+ hash
3114
+ } = sig;
3115
+ const { schema, ...fields } = data;
3116
+ const signedHash = asHash4(hash);
3117
+ if (isUndefined5(signedHash) || signedHash !== await PayloadBuilder15.hash(data)) return false;
3118
+ const recoveredAddress = verifyTypedData(fields.domain, fields.types, fields.values, signature);
3119
+ return recoveredAddress.toLowerCase() === address.toLowerCase();
3120
+ };
3121
+
3122
+ // src/multipliers.ts
3123
+ import { asAttoXL1 as asAttoXL14 } from "@xyo-network/xl1-protocol-lib";
3124
+ var XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_EARNED_REWARDS = asAttoXL14(1343884111859145740576652n);
3125
+ var XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_BONUS_REWARDS = asAttoXL14(100000000000000000000000000n);
3126
+ var XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_REWARDS = XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_EARNED_REWARDS + XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_BONUS_REWARDS;
3127
+ var RewardMultipliers = {
3128
+ [`0|${XL1_NETWORK_STAKING_GENESIS_PERIOD_END_XL1_BLOCK}`]: [XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_BONUS_REWARDS, XL1_NETWORK_STAKING_GENESIS_PERIOD_TOTAL_EARNED_REWARDS]
3129
+ };
3130
+
3113
3131
  // src/services/StakeIntentService/ChainIndexingServiceStateSchema.ts
3114
3132
  import { AsObjectFactory as AsObjectFactory4 } from "@xylabs/sdk-js";
3115
3133
  import {