@xyo-network/chain-reward-redemption 1.15.11 → 1.15.13

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.
@@ -91,6 +91,9 @@ var archivistMiddleware = /* @__PURE__ */ __name((options) => {
91
91
  if (isAnyPayload(payload)) {
92
92
  res.json(payload);
93
93
  return;
94
+ } else {
95
+ res.status(404).send();
96
+ return;
94
97
  }
95
98
  }
96
99
  res.status(400).send();
@@ -101,7 +104,7 @@ var archivistMiddleware = /* @__PURE__ */ __name((options) => {
101
104
  // src/server/routes/dataLake/addDataLakeRoutes.ts
102
105
  var addDataLakeRoutes = /* @__PURE__ */ __name((app) => {
103
106
  const { node } = app;
104
- const archivistModuleIdentifier = "RewardsArchivist";
107
+ const archivistModuleIdentifier = "Data";
105
108
  app.use("/data", archivistMiddleware({
106
109
  node,
107
110
  archivistModuleIdentifier
@@ -109,7 +112,14 @@ var addDataLakeRoutes = /* @__PURE__ */ __name((app) => {
109
112
  }, "addDataLakeRoutes");
110
113
 
111
114
  // src/server/routes/rewardRedemption/routeDefinitions/routes/claim.ts
115
+ import { asAddress } from "@xylabs/hex";
116
+ import { isDefined as isDefined2, isUndefined } from "@xylabs/typeof";
117
+ import { createTransferPayload } from "@xyo-network/chain-protocol";
112
118
  import { PayloadZodLoose } from "@xyo-network/payload-model";
119
+ import { HDWallet } from "@xyo-network/wallet";
120
+ import { asXL1BlockNumber } from "@xyo-network/xl1-protocol";
121
+ import { buildTransaction, completedStepRewardAddress, derivedReceiveAddress } from "@xyo-network/xl1-protocol-sdk";
122
+ import { HttpRpcTransport, JsonRpcXyoViewer, SignedHydratedTransactionZod, XyoViewerRpcSchemas } from "@xyo-network/xl1-rpc";
113
123
  import { z as z2 } from "zod";
114
124
 
115
125
  // src/server/routes/rewardRedemption/middleware/requestHandlerValidator.ts
@@ -189,26 +199,125 @@ __name(requestHandlerValidator, "requestHandlerValidator");
189
199
  import { EthAddressFromStringZod } from "@xylabs/hex";
190
200
 
191
201
  // src/server/routes/rewardRedemption/routeDefinitions/routes/claim.ts
202
+ var scope = "reward-escrow";
192
203
  var params = z2.object({
193
204
  address: EthAddressFromStringZod
194
205
  });
195
206
  var body = PayloadZodLoose;
196
- var response = PayloadZodLoose;
207
+ var response = SignedHydratedTransactionZod;
197
208
  var validateRequest = requestHandlerValidator({
198
209
  params,
199
210
  body,
200
211
  response
201
212
  });
213
+ function tryParseInt(value) {
214
+ if (value === "") return void 0;
215
+ const num = Number(value);
216
+ return Number.isInteger(num) ? num : void 0;
217
+ }
218
+ __name(tryParseInt, "tryParseInt");
219
+ var asStepIdentity = /* @__PURE__ */ __name((stepIdentityString) => {
220
+ try {
221
+ const [blockNumberString, stepString] = stepIdentityString.split("|");
222
+ if (isUndefined(blockNumberString) || isUndefined(stepString)) {
223
+ return void 0;
224
+ }
225
+ const step = tryParseInt(stepString);
226
+ const blockNumber = tryParseInt(blockNumberString);
227
+ if (isUndefined(blockNumber) || isUndefined(step)) {
228
+ return void 0;
229
+ }
230
+ const block = asXL1BlockNumber(blockNumber);
231
+ return {
232
+ block,
233
+ step
234
+ };
235
+ } catch {
236
+ return void 0;
237
+ }
238
+ }, "asStepIdentity");
239
+ var getStakesForStaker = /* @__PURE__ */ __name(async (viewer, stakerAddress) => {
240
+ const stakes = await viewer.stakesByStaker(stakerAddress);
241
+ return stakes;
242
+ }, "getStakesForStaker");
243
+ var getRewardsForStake = /* @__PURE__ */ __name(async (viewer, stakes, fromBlock = 0, toBlock) => {
244
+ if (isUndefined(toBlock)) {
245
+ toBlock = await viewer.currentBlockNumber();
246
+ }
247
+ const rewards = [];
248
+ for (const stake of stakes) {
249
+ const { id } = stake;
250
+ const reward = await viewer.networkStakeStepRewardsForPosition(id, [
251
+ fromBlock,
252
+ toBlock
253
+ ]);
254
+ rewards.push(reward);
255
+ }
256
+ return rewards;
257
+ }, "getRewardsForStake");
258
+ var sumNetworkStakeStepRewards = /* @__PURE__ */ __name((records) => {
259
+ const totals = {};
260
+ for (const record of records) {
261
+ for (const [key, [first]] of Object.entries(record)) {
262
+ if (isUndefined(totals[key])) {
263
+ totals[key] = 0n;
264
+ }
265
+ totals[key] += first;
266
+ }
267
+ }
268
+ return totals;
269
+ }, "sumNetworkStakeStepRewards");
202
270
  var postClaim = {
203
271
  method: "post",
204
272
  path: "/rewards/claim/:address",
205
273
  handlers: validateRequest(async (req, res) => {
274
+ const { config } = req.app;
275
+ const { mnemonic, chainRpcApiUrl } = config.rewardRedemptionApi;
206
276
  const { address } = req.params;
207
- await Promise.resolve();
208
- const observation = {
209
- schema: "network.xyo.test"
210
- };
211
- res.json(observation);
277
+ const stakerAddress = asAddress(address);
278
+ if (!stakerAddress) {
279
+ res.status(400);
280
+ return;
281
+ }
282
+ const account = await (isDefined2(mnemonic) ? HDWallet.fromPhrase(mnemonic) : HDWallet.random());
283
+ const transport = new HttpRpcTransport(chainRpcApiUrl, XyoViewerRpcSchemas);
284
+ const viewer = new JsonRpcXyoViewer(transport);
285
+ const stakes = await getStakesForStaker(viewer, stakerAddress);
286
+ if (stakes.length > 0) {
287
+ const currentBlock = await viewer.currentBlockNumber();
288
+ const rewards = await getRewardsForStake(viewer, stakes, 0, currentBlock);
289
+ if (Object.keys(rewards).length > 0) {
290
+ const totalRewards = sumNetworkStakeStepRewards(rewards);
291
+ const totalTransfers = [];
292
+ for (const [stepIdentityString, accrued] of Object.entries(totalRewards)) {
293
+ const stepIdentity = asStepIdentity(stepIdentityString);
294
+ if (isUndefined(stepIdentity)) continue;
295
+ const stepRewardsAddress = completedStepRewardAddress(stepIdentity);
296
+ const receiveAddress = derivedReceiveAddress(stakerAddress, scope);
297
+ const claimed = await viewer.transferPairBalance([
298
+ stepRewardsAddress,
299
+ receiveAddress
300
+ ]);
301
+ const unclaimed = accrued - claimed;
302
+ if (unclaimed <= 0n) continue;
303
+ const transferPayload = createTransferPayload(stepRewardsAddress, {
304
+ [receiveAddress]: unclaimed
305
+ });
306
+ transferPayload.context = {
307
+ address: stakerAddress,
308
+ scope
309
+ };
310
+ totalTransfers.push(transferPayload);
311
+ }
312
+ if (totalTransfers.length > 0) {
313
+ const chainId = await viewer.chainId();
314
+ const tx = await buildTransaction(chainId, totalTransfers, [], account, currentBlock, currentBlock + 1e3);
315
+ res.json(tx);
316
+ return;
317
+ }
318
+ }
319
+ }
320
+ res.status(204);
212
321
  })
213
322
  };
214
323
 
@@ -261,7 +370,7 @@ var addRoutes = /* @__PURE__ */ __name((app) => {
261
370
  }, "addRoutes");
262
371
 
263
372
  // src/server/app.ts
264
- var getApp = /* @__PURE__ */ __name((node) => {
373
+ var getApp = /* @__PURE__ */ __name((node, config) => {
265
374
  addInstrumentation();
266
375
  const app = express2();
267
376
  app.set("etag", false);
@@ -275,6 +384,7 @@ var getApp = /* @__PURE__ */ __name((node) => {
275
384
  disableExpressDefaultPoweredByHeader(app);
276
385
  app.use(customPoweredByHeader);
277
386
  disableCaseSensitiveRouting(app);
387
+ app.config = config;
278
388
  app.node = node;
279
389
  addRoutes(app);
280
390
  app.use(standardErrors);
@@ -283,12 +393,12 @@ var getApp = /* @__PURE__ */ __name((node) => {
283
393
 
284
394
  // src/server/server.ts
285
395
  import { assertEx } from "@xylabs/assert";
286
- import { isDefined as isDefined3, isString } from "@xylabs/typeof";
396
+ import { isDefined as isDefined4, isString } from "@xylabs/typeof";
287
397
  import { boot } from "@xyo-network/bios";
288
- import { HDWallet } from "@xyo-network/wallet";
398
+ import { HDWallet as HDWallet2 } from "@xyo-network/wallet";
289
399
 
290
400
  // src/manifest/getLocator.ts
291
- import { isDefined as isDefined2 } from "@xylabs/typeof";
401
+ import { isDefined as isDefined3 } from "@xylabs/typeof";
292
402
  import { MemoryArchivist } from "@xyo-network/archivist-memory";
293
403
  import { MongoDBArchivistV2 } from "@xyo-network/archivist-mongodb";
294
404
  import { ViewArchivist } from "@xyo-network/archivist-view";
@@ -312,7 +422,7 @@ var getLocator = /* @__PURE__ */ __name(async (context) => {
312
422
  port: 9465
313
423
  }
314
424
  });
315
- if (isDefined2(logger)) AbstractModule.defaultLogger = logger;
425
+ if (isDefined3(logger)) AbstractModule.defaultLogger = logger;
316
426
  const statusReporter = logger ? new LoggerModuleStatusReporter(logger) : void 0;
317
427
  const locator = new ModuleFactoryLocator();
318
428
  const mongoConfig = config.storage?.mongo;
@@ -370,12 +480,11 @@ var node_default = {
370
480
  schema: "network.xyo.node.config"
371
481
  },
372
482
  modules: {
373
- private: [],
374
- public: [
483
+ private: [
375
484
  {
376
485
  config: {
377
- accountPath: "1/1/1",
378
- name: "Data",
486
+ accountPath: "1/1'/1'",
487
+ name: "DataPrivate",
379
488
  getCache: {
380
489
  enabled: true,
381
490
  maxEntries: 5e3
@@ -386,6 +495,24 @@ var node_default = {
386
495
  schema: "network.xyo.archivist.config"
387
496
  }
388
497
  }
498
+ ],
499
+ public: [
500
+ {
501
+ config: {
502
+ accountPath: "1/1/1",
503
+ name: "Data",
504
+ allowedQueries: [
505
+ "network.xyo.query.archivist.get",
506
+ "network.xyo.query.archivist.next"
507
+ ],
508
+ getCache: {
509
+ enabled: true,
510
+ maxEntries: 5e3
511
+ },
512
+ originArchivist: "DataPrivate",
513
+ schema: "network.xyo.archivist.view.config"
514
+ }
515
+ }
389
516
  ]
390
517
  }
391
518
  }
@@ -429,7 +556,7 @@ var getSeedPhrase = /* @__PURE__ */ __name(async (bios, config, logger) => {
429
556
  if (isString(mnemonic)) {
430
557
  seedPhrase = mnemonic;
431
558
  } else {
432
- seedPhrase = HDWallet.generateMnemonic();
559
+ seedPhrase = HDWallet2.generateMnemonic();
433
560
  logger?.log("[Bridge] No mnemonic provided, using random mnemonic. This is not recommended for production use.");
434
561
  logger?.log(`[Bridge] Mnemonic: ${seedPhrase}`);
435
562
  }
@@ -441,17 +568,17 @@ var getServer = /* @__PURE__ */ __name(async (context) => {
441
568
  const { logger, config } = context;
442
569
  const { port, mnemonic } = config.rewardRedemptionApi;
443
570
  const bios = await boot();
444
- const seedPhrase = isDefined3(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger);
445
- const wallet = await HDWallet.fromPhrase(seedPhrase);
571
+ const seedPhrase = isDefined4(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger);
572
+ const wallet = await HDWallet2.fromPhrase(seedPhrase);
446
573
  const nodeContext = {
447
574
  wallet,
448
575
  logger,
449
576
  config
450
577
  };
451
578
  const node = context.node ?? await getNode(nodeContext);
452
- const app = getApp(node);
579
+ const app = getApp(node, config);
453
580
  const server = app.listen(port, hostname, () => logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`));
454
- server.setTimeout(2e4);
581
+ server.setTimeout(12e4);
455
582
  return server;
456
583
  }, "getServer");
457
584
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server/app.ts","../../src/server/instrumentation.ts","../../src/server/routes/dataLake/archivistMiddleware.ts","../../src/server/routes/dataLake/addDataLakeRoutes.ts","../../src/server/routes/rewardRedemption/routeDefinitions/routes/claim.ts","../../src/server/routes/rewardRedemption/middleware/requestHandlerValidator.ts","../../src/server/routes/rewardRedemption/routeDefinitions/pathParams/AddressPathParam.ts","../../src/server/routes/rewardRedemption/routeDefinitions/routes/redeem.ts","../../src/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.ts","../../src/server/routes/rewardRedemption/addRewardRoutes.ts","../../src/server/routes/addRoutes.ts","../../src/server/server.ts","../../src/manifest/getLocator.ts","../../src/manifest/getNode.ts","../../src/manifest/node.json","../../src/manifest/nodeManifest.ts","../../src/manifest/private/index.ts","../../src/manifest/public/index.ts"],"sourcesContent":["import {\n customPoweredByHeader, disableCaseSensitiveRouting, disableExpressDefaultPoweredByHeader, getJsonBodyParser, getJsonBodyParserOptions, responseProfiler,\n standardErrors, standardResponses,\n} from '@xylabs/express'\nimport type { NodeInstance } from '@xyo-network/node-model'\nimport compression from 'compression'\nimport cors from 'cors'\nimport type { Express } from 'express'\nimport express from 'express'\n\nimport { addInstrumentation } from './instrumentation.ts'\nimport { addRoutes } from './routes/index.ts'\n\nexport const getApp = (node: NodeInstance): Express => {\n addInstrumentation()\n const app = express()\n app.set('etag', false)\n app.use(cors())\n app.use(compression())\n app.use(responseProfiler)\n app.use(getJsonBodyParser(getJsonBodyParserOptions({ limit: '1mb' })))\n app.use(standardResponses)\n disableExpressDefaultPoweredByHeader(app)\n app.use(customPoweredByHeader)\n disableCaseSensitiveRouting(app)\n app.node = node\n addRoutes(app)\n app.use(standardErrors)\n return app\n}\n","import { registerInstrumentations } from '@opentelemetry/instrumentation'\nimport { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'\nimport { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\n\n/**\n * Registers OpenTelemetry instrumentations for HTTP and Express.\n * This function is used to set up the necessary instrumentations for monitoring\n * HTTP requests and Express applications. Since it monkey patches the Express\n * router & middleware system, it should be called before any Express applications\n * are defined.\n */\nexport const addInstrumentation = () => {\n const instrumentations = [new HttpInstrumentation(), new ExpressInstrumentation()]\n registerInstrumentations({ instrumentations })\n}\n","import { setRawResponseFormat } from '@xylabs/express'\nimport { asHash } from '@xylabs/hex'\nimport { isDefined } from '@xylabs/typeof'\nimport type {\n ArchivistInstance,\n ArchivistNextOptions, NextOptions,\n} from '@xyo-network/archivist-model'\nimport { asArchivistInstance } from '@xyo-network/archivist-model'\nimport type { ModuleIdentifier } from '@xyo-network/module-model'\nimport type { NodeInstance } from '@xyo-network/node-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type { Payload } from '@xyo-network/payload-model'\nimport { isAnyPayload, isSequence } from '@xyo-network/payload-model'\nimport type { Router } from 'express'\nimport express from 'express'\nimport type { Request } from 'express-serve-static-core'\n\nconst resolveArchivist = async (node: NodeInstance, archivistModuleIdentifier: ModuleIdentifier): Promise<ArchivistInstance> => {\n const mod = await node.resolve(archivistModuleIdentifier)\n return asArchivistInstance(mod, { required: true })\n}\n\nlet archivistInstance: ArchivistInstance | undefined\n\nconst getArchivist = async (node: NodeInstance, archivistModuleIdentifier: ModuleIdentifier): Promise<ArchivistInstance> => {\n if (isDefined(archivistInstance)) return archivistInstance\n archivistInstance = await resolveArchivist(node, archivistModuleIdentifier)\n return archivistInstance\n}\n\ntype ArchivistMiddlewareOptions = {\n archivistModuleIdentifier: ModuleIdentifier\n node: NodeInstance\n}\n\nexport const archivistMiddleware = (options: ArchivistMiddlewareOptions): Router => {\n const { node, archivistModuleIdentifier } = options\n const router = express.Router({ mergeParams: true })\n\n router.post('/insert', async (req, res) => {\n setRawResponseFormat(res)\n const body = Array.isArray(req.body) ? req.body : [req.body]\n const payloads = (await PayloadBuilder.hashPairs<Payload>(body)).map(p => p[0])\n const archivist = await getArchivist(node, archivistModuleIdentifier)\n const result = await archivist.insert(payloads)\n res.status(200).json(result)\n })\n\n router.get('/next', async (req: Request<Partial<NextOptions>>, res) => {\n setRawResponseFormat(res)\n const cursor = isSequence(req.query.cursor) ? req.query.cursor : undefined\n const limit = isDefined(req.query.limit) ? Number(req.query.limit) : undefined\n const open = isDefined(req.query.open) ? Boolean(req.query.open) : undefined\n const order = req.query.order === 'asc' ? 'asc' : 'desc'\n const options: ArchivistNextOptions = {\n limit, open, order, cursor,\n }\n const archivist = await getArchivist(node, archivistModuleIdentifier)\n const result = await archivist.next(options)\n res.status(200).json(result)\n })\n router.post('/next', async (req: Request<{}, {}, ArchivistNextOptions | undefined>, res) => {\n setRawResponseFormat(res)\n const options = req.body\n const archivist = await getArchivist(node, archivistModuleIdentifier)\n const result = await (isDefined(options) ? archivist.next(options) : archivist.next())\n res.status(200).json(result)\n })\n\n router.get('/get/:hash', async (req, res) => {\n setRawResponseFormat(res)\n const { hash: rawHash } = req.params\n const hash = asHash(rawHash)\n if (isDefined(hash)) {\n const archivist = await getArchivist(node, archivistModuleIdentifier)\n const [payload] = await archivist.get([hash])\n if (isAnyPayload(payload)) {\n res.json(payload)\n return\n }\n }\n res.status(400).send()\n })\n\n return router\n}\n","import type { Express } from 'express'\n\nimport { archivistMiddleware } from './archivistMiddleware.ts'\n\nexport const addDataLakeRoutes = (app: Express) => {\n const { node } = app\n const archivistModuleIdentifier = 'RewardsArchivist'\n app.use('/data', archivistMiddleware({ node, archivistModuleIdentifier }))\n}\n","import { PayloadZodLoose } from '@xyo-network/payload-model'\nimport { z } from 'zod'\n\nimport { requestHandlerValidator } from '../../middleware/index.ts'\nimport { AddressPathParam } from '../pathParams/index.ts'\nimport type { RouteDefinition } from '../routeDefinition.ts'\n\nconst params = z.object({ address: AddressPathParam })\nconst body = PayloadZodLoose\n\nconst response = PayloadZodLoose\n\nconst validateRequest = requestHandlerValidator({\n params,\n body,\n response,\n})\n\nexport const postClaim: RouteDefinition = {\n method: 'post',\n path: '/rewards/claim/:address',\n handlers: validateRequest(async (req, res) => {\n const { address } = req.params\n // TODO: Validate ETH address\n // TODO: Redeem claim for existing rewards\n // TODO: Return response payload\n await Promise.resolve()\n const observation = { schema: 'network.xyo.test' }\n res.json(observation)\n }),\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { ExpressError } from '@xylabs/express'\nimport { isPromise } from '@xylabs/typeof'\nimport type {\n NextFunction, Request, RequestHandler, Response,\n} from 'express'\nimport { ReasonPhrases, StatusCodes } from 'http-status-codes'\nimport type { ZodType } from 'zod'\nimport { z } from 'zod'\n\n/**\n * Empty Zod schema for requests with no parameters.\n */\nexport const EmptyParamsZod = z.object({}).catchall(z.string())\n\n/**\n * Empty Zod schema for requests with no query parameters.\n */\nexport const EmptyQueryParamsZod = z.object({}).catchall(z.union([z.string(), z.array(z.string())]))\n\n/**\n * Default validation schemas for request handler validator.\n */\nexport const ValidateRequestDefaults = {\n params: EmptyParamsZod,\n query: EmptyQueryParamsZod,\n body: z.json(),\n response: z.json(),\n}\n\ntype ValidatableRequestKey = 'params' | 'query' | 'body'\n\n/**\n * Factory for Express middleware that validates request and response objects using Zod schemas.\n * @param schemas The Zod schemas to use for validation.\n * @returns A middleware function for validating requests and responses.\n */\nexport function requestHandlerValidator<\n TParams extends typeof EmptyQueryParamsZod | ZodType<Record<string, string>> = typeof EmptyQueryParamsZod,\n TQuery extends typeof EmptyQueryParamsZod | ZodType<Record<string, string | string[]>> = typeof EmptyQueryParamsZod,\n TBody extends ZodType<unknown> = ZodType<unknown>,\n TResponse extends ZodType<unknown> = ZodType<unknown>,\n>(schemas?: Partial<{\n body: TBody\n params: TParams\n query: TQuery\n response: TResponse\n}>) {\n type Params = z.infer<TParams>\n type Query = z.infer<TQuery>\n type Body = z.infer<TBody>\n type Res = z.infer<TResponse>\n const validators = { ...ValidateRequestDefaults, ...schemas }\n\n return (handler: (req: Request<Params, Res, Body, Query>, res: Response<Res>, next: NextFunction) => unknown): RequestHandler => {\n return async (req: Request, res: Response, next: NextFunction) => {\n const originalJson = res.json.bind(res)\n try {\n // Validate incoming request\n const errors: string[] = []\n const keys: ValidatableRequestKey[] = ['params', 'query', 'body']\n for (const key of keys) {\n const validator = validators[key]\n const result = validator.safeParse(req[key])\n if (result.success) {\n Object.assign(req[key], result.data)\n } else {\n errors.push(\n ...result.error.issues.map(\n issue => (issue.path.length === 0)\n ? `${key}: ${issue.message}`\n : `${key}.${issue.path.join('.')}: ${issue.message}`,\n ),\n )\n }\n }\n\n // If there were validation errors, short-circuit and return Bad Request\n if (errors.length > 0) {\n const message = errors.join('; ')\n const err: ExpressError = new Error(message)\n err.name = ReasonPhrases.BAD_REQUEST\n err.statusCode = StatusCodes.BAD_REQUEST\n next(err)\n return false\n }\n\n // Wrap res.json to validate outgoing response\n res.json = (data: any) => {\n const result = validators.response.safeParse(data)\n if (result.success) {\n return originalJson(result.data)\n } else {\n const message = result.error.issues.map(\n issue => (issue.path.length === 0)\n ? `response: ${issue.message}`\n : `response.${issue.path.join('.')}: ${issue.message}`,\n ).join('; ')\n const err: ExpressError = new Error(message)\n err.name = ReasonPhrases.INTERNAL_SERVER_ERROR\n err.statusCode = StatusCodes.INTERNAL_SERVER_ERROR\n\n // Restore original json function in case the error handler wants to use it\n res.json = originalJson\n throw err\n }\n }\n\n // Automatically handle async errors\n const result = handler(req as any, res as any, next)\n if (result && isPromise(result)) {\n await result\n }\n } catch (err) {\n res.json = originalJson\n next(err)\n }\n }\n }\n}\n","export { EthAddressFromStringZod as AddressPathParam } from '@xylabs/hex'\n","import { PayloadZodLoose } from '@xyo-network/payload-model'\nimport { z } from 'zod'\n\nimport { requestHandlerValidator } from '../../middleware/index.ts'\nimport { AddressPathParam } from '../pathParams/index.ts'\nimport type { RouteDefinition } from '../routeDefinition.ts'\n\nconst params = z.object({ address: AddressPathParam })\nconst body = PayloadZodLoose\nconst response = PayloadZodLoose\nconst validateRequest = requestHandlerValidator({\n params,\n body,\n response,\n})\n\nexport const postRedeem: RouteDefinition = {\n method: 'post',\n path: '/rewards/redeem/:address',\n handlers: validateRequest(async (req, res) => {\n const { body } = req\n await Promise.resolve()\n const bridgeObservation = { schema: 'network.xyo.test' }\n res.json(bridgeObservation)\n }),\n}\n","import type { RouteDefinition } from './routeDefinition.ts'\nimport { postClaim, postRedeem } from './routes/index.ts'\n\nexport const getRouteDefinitions = (): RouteDefinition[] => {\n return [\n postClaim,\n postRedeem,\n ]\n}\n","import type { Express } from 'express'\n\nimport { getRouteDefinitions } from './routeDefinitions/index.ts'\n\nexport const addRewardRedemptionRoutes = (app: Express) => {\n const routeDefinitions = getRouteDefinitions()\n for (const definition of routeDefinitions) {\n app[definition.method](definition.path, definition.handlers)\n }\n}\n","import type { Express } from 'express'\n\nimport { addDataLakeRoutes } from './dataLake/index.ts'\nimport { addRewardRedemptionRoutes } from './rewardRedemption/index.ts'\n\nexport const addRoutes = (app: Express) => {\n addDataLakeRoutes(app)\n addRewardRedemptionRoutes(app)\n}\n","import { assertEx } from '@xylabs/assert'\nimport type { Logger } from '@xylabs/logger'\nimport { isDefined, isString } from '@xylabs/typeof'\nimport { boot } from '@xyo-network/bios'\nimport type { BiosExternalInterface } from '@xyo-network/bios-model'\nimport type { NodeInstance } from '@xyo-network/node-model'\nimport { HDWallet } from '@xyo-network/wallet'\nimport { type Config } from '@xyo-network/xl1-protocol-sdk'\n\nimport { getNode } from '../manifest/index.ts'\nimport { getApp } from './app.ts'\n\nconst hostname = '::'\n// const hostname = '0.0.0.0'\n\n// TODO: Make nodejs version of bios support round tripping mnemonic between boots\nconst getSeedPhrase = async (bios: BiosExternalInterface, config: Config, logger?: Logger): Promise<string> => {\n const storedSeedPhrase = await bios.seedPhraseStore.get('os')\n logger?.debug(`[Bridge] Stored mnemonic: ${storedSeedPhrase}`)\n const { mnemonic } = config.api\n if (isString(storedSeedPhrase) && isString(mnemonic)) {\n logger?.warn('[Bridge] Stored mnemonic does not match supplied. Updating stored mnemonic to supplied.')\n await bios.seedPhraseStore.set('os', mnemonic)\n } else {\n let seedPhrase: string\n if (isString(mnemonic)) {\n seedPhrase = mnemonic\n } else {\n seedPhrase = HDWallet.generateMnemonic()\n logger?.log('[Bridge] No mnemonic provided, using random mnemonic. This is not recommended for production use.')\n logger?.log(`[Bridge] Mnemonic: ${seedPhrase}`)\n }\n await bios.seedPhraseStore.set('os', seedPhrase)\n }\n return assertEx(await bios.seedPhraseStore.get('os'), () => 'Unable to acquire mnemonic from bios')\n}\n\ninterface GetServerContext {\n config: Config\n logger?: Logger\n node?: NodeInstance\n}\n\nexport const getServer = async (context: GetServerContext) => {\n const { logger, config } = context\n const { port, mnemonic } = config.rewardRedemptionApi\n const bios = await boot()\n const seedPhrase = isDefined(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger)\n const wallet = await HDWallet.fromPhrase(seedPhrase)\n const nodeContext = {\n wallet, logger, config,\n }\n const node = context.node ?? await getNode(nodeContext)\n const app = getApp(node)\n const server = app.listen(port, hostname, () => logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`))\n server.setTimeout(20_000)\n return server\n}\n","import type { Logger } from '@xylabs/logger'\nimport { type BaseMongoSdkPrivateConfig } from '@xylabs/mongo'\nimport { isDefined } from '@xylabs/typeof'\nimport { MemoryArchivist } from '@xyo-network/archivist-memory'\nimport { MongoDBArchivistV2 } from '@xyo-network/archivist-mongodb'\nimport { ViewArchivist } from '@xyo-network/archivist-view'\nimport { ArchivistSyncDiviner } from '@xyo-network/chain-modules'\nimport { initTelemetry } from '@xyo-network/chain-telemetry'\nimport { AbstractModule, LoggerModuleStatusReporter } from '@xyo-network/module-abstract'\nimport { ModuleFactoryLocator } from '@xyo-network/module-factory-locator'\nimport type { MongoDBModuleParamsV2 } from '@xyo-network/module-model-mongodb'\nimport { MemorySentinel } from '@xyo-network/sentinel-memory'\nimport type { Config } from '@xyo-network/xl1-protocol-sdk'\nimport { hasMongoConfig } from '@xyo-network/xl1-protocol-sdk'\n\nexport interface GetLocatorContext {\n config: Config\n logger?: Logger\n}\n\n/**\n * Used for retrieving a locator with the necessary modules registered for testing\n * operation of the node (entirely in memory)\n * @returns A locator with the necessary modules registered\n */\nexport const getLocator = async (context: GetLocatorContext) => {\n const { config, logger } = context\n const { otlpEndpoint } = config.telemetry?.otel ?? {}\n const { traceProvider, meterProvider } = await initTelemetry({\n attributes: {\n serviceName: 'xl1-rewards',\n serviceVersion: '1.0.0',\n },\n otlpEndpoint,\n metricsConfig: {\n endpoint: '/metrics',\n port: 9465,\n },\n })\n\n if (isDefined(logger)) AbstractModule.defaultLogger = logger\n const statusReporter = logger ? new LoggerModuleStatusReporter(logger) : undefined\n\n const locator = new ModuleFactoryLocator()\n // If there's a MongoDB configuration\n const mongoConfig = config.storage?.mongo\n if (hasMongoConfig(mongoConfig)) {\n // Create the MongoDB SDK from the configuration\n const {\n connectionString: dbConnectionString, database: dbName, domain: dbDomain, password: dbPassword, username: dbUserName,\n } = mongoConfig\n const payloadSdkConfig: BaseMongoSdkPrivateConfig = {\n dbConnectionString, dbDomain, dbName, dbPassword, dbUserName,\n }\n const params: Partial<MongoDBModuleParamsV2> = {\n meterProvider, payloadSdkConfig, statusReporter, traceProvider,\n }\n // Register the MongoDB Archivist as the default\n locator.register(MongoDBArchivistV2.factory(params), undefined, true)\n }\n\n locator.register(MemoryArchivist.factory({\n traceProvider, meterProvider, statusReporter,\n }))\n locator.register(MemorySentinel.factory({\n traceProvider, meterProvider, statusReporter,\n }))\n locator.register(ViewArchivist.factory({\n traceProvider, meterProvider, statusReporter,\n }))\n locator.register(ArchivistSyncDiviner.factory({\n traceProvider, meterProvider, statusReporter,\n }))\n return locator\n}\n","import type { Logger } from '@xylabs/logger'\nimport { ManifestWrapper } from '@xyo-network/manifest-wrapper'\nimport type { WalletInstance } from '@xyo-network/wallet-model'\nimport type { Config } from '@xyo-network/xl1-protocol-sdk'\n\nimport { getLocator } from './getLocator.ts'\nimport { NodeManifest } from './nodeManifest.ts'\nimport { PrivateChildManifests } from './private/index.ts'\nimport { PublicChildManifests } from './public/index.ts'\n\nexport interface GetNodeContext {\n config: Config\n logger?: Logger\n wallet: WalletInstance\n}\n\n/**\n * Creates a node with the xyo-chain modules registered\n * @param context The context to use for the node\n * @returns A node with the xyo-chain modules registered\n */\nexport const getNode = async (context: GetNodeContext) => {\n const { wallet } = context\n const locator = await getLocator(context)\n const wrapper = new ManifestWrapper(NodeManifest, wallet, locator, PublicChildManifests, PrivateChildManifests)\n const [node, ...childNodes] = await wrapper.loadNodes()\n if (childNodes?.length > 0) {\n await Promise.all(childNodes.map(childNode => node.register(childNode)))\n await Promise.all(childNodes.map(childNode => node.attach(childNode.address, true)))\n }\n return node\n}\n","{\n \"$schema\": \"https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json\",\n \"nodes\": [\n {\n \"config\": {\n \"accountPath\": \"44'/60'/1\",\n \"name\": \"XYORewardRedemptionNode\",\n \"schema\": \"network.xyo.node.config\"\n },\n \"modules\": {\n \"private\": [],\n \"public\": [\n {\n \"config\": {\n \"accountPath\": \"1/1/1\",\n \"name\": \"Data\",\n \"getCache\": {\n \"enabled\": true,\n \"maxEntries\": 5000\n },\n \"payloadSdkConfig\": {\n \"collection\": \"reward_redemption_api_datalake\"\n },\n \"schema\": \"network.xyo.archivist.config\"\n }\n }\n ]\n }\n }\n ],\n \"schema\": \"network.xyo.manifest\"\n}\n","import type { PackageManifestPayload } from '@xyo-network/manifest-model'\n\nimport node from './node.json' with { type: 'json' }\n\n/**\n * Root Node Manifest\n */\nexport const NodeManifest = node as PackageManifestPayload\n","/**\n * Private Child Manifests\n */\nexport const PrivateChildManifests = []\n","import type { ModuleManifest, PackageManifestPayload } from '@xyo-network/manifest-model'\n\n/**\n * Public Child Manifests\n */\nexport const PublicChildManifests: ModuleManifest[] = []\n"],"mappings":"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","names":["customPoweredByHeader","disableCaseSensitiveRouting","disableExpressDefaultPoweredByHeader","getJsonBodyParser","getJsonBodyParserOptions","responseProfiler","standardErrors","standardResponses","compression","cors","express","registerInstrumentations","ExpressInstrumentation","HttpInstrumentation","addInstrumentation","instrumentations","HttpInstrumentation","ExpressInstrumentation","registerInstrumentations","setRawResponseFormat","asHash","isDefined","asArchivistInstance","PayloadBuilder","isAnyPayload","isSequence","express","resolveArchivist","node","archivistModuleIdentifier","mod","resolve","asArchivistInstance","required","archivistInstance","getArchivist","isDefined","archivistMiddleware","options","router","express","Router","mergeParams","post","req","res","setRawResponseFormat","body","Array","isArray","payloads","PayloadBuilder","hashPairs","map","p","archivist","result","insert","status","json","get","cursor","isSequence","query","undefined","limit","Number","open","Boolean","order","next","hash","rawHash","params","asHash","payload","isAnyPayload","send","addDataLakeRoutes","app","node","archivistModuleIdentifier","use","archivistMiddleware","PayloadZodLoose","z","isPromise","ReasonPhrases","StatusCodes","z","EmptyParamsZod","z","object","catchall","string","EmptyQueryParamsZod","union","array","ValidateRequestDefaults","params","query","body","json","response","requestHandlerValidator","schemas","validators","handler","req","res","next","originalJson","bind","errors","keys","key","validator","result","safeParse","success","Object","assign","data","push","error","issues","map","issue","path","length","message","join","err","Error","name","ReasonPhrases","BAD_REQUEST","statusCode","StatusCodes","INTERNAL_SERVER_ERROR","isPromise","AddressPathParam","params","z","object","address","AddressPathParam","body","PayloadZodLoose","response","validateRequest","requestHandlerValidator","postClaim","method","path","handlers","req","res","Promise","resolve","observation","schema","json","PayloadZodLoose","z","params","z","object","address","AddressPathParam","body","PayloadZodLoose","response","validateRequest","requestHandlerValidator","postRedeem","method","path","handlers","req","res","Promise","resolve","bridgeObservation","schema","json","getRouteDefinitions","postClaim","postRedeem","addRewardRedemptionRoutes","app","routeDefinitions","getRouteDefinitions","definition","method","path","handlers","addRoutes","app","addDataLakeRoutes","addRewardRedemptionRoutes","getApp","node","addInstrumentation","app","express","set","use","cors","compression","responseProfiler","getJsonBodyParser","getJsonBodyParserOptions","limit","standardResponses","disableExpressDefaultPoweredByHeader","customPoweredByHeader","disableCaseSensitiveRouting","addRoutes","standardErrors","assertEx","isDefined","isString","boot","HDWallet","isDefined","MemoryArchivist","MongoDBArchivistV2","ViewArchivist","ArchivistSyncDiviner","initTelemetry","AbstractModule","LoggerModuleStatusReporter","ModuleFactoryLocator","MemorySentinel","hasMongoConfig","getLocator","context","config","logger","otlpEndpoint","telemetry","otel","traceProvider","meterProvider","initTelemetry","attributes","serviceName","serviceVersion","metricsConfig","endpoint","port","isDefined","AbstractModule","defaultLogger","statusReporter","LoggerModuleStatusReporter","undefined","locator","ModuleFactoryLocator","mongoConfig","storage","mongo","hasMongoConfig","connectionString","dbConnectionString","database","dbName","domain","dbDomain","password","dbPassword","username","dbUserName","payloadSdkConfig","params","register","MongoDBArchivistV2","factory","MemoryArchivist","MemorySentinel","ViewArchivist","ArchivistSyncDiviner","ManifestWrapper","NodeManifest","node","PrivateChildManifests","PublicChildManifests","getNode","context","wallet","locator","getLocator","wrapper","ManifestWrapper","NodeManifest","PublicChildManifests","PrivateChildManifests","node","childNodes","loadNodes","length","Promise","all","map","childNode","register","attach","address","hostname","getSeedPhrase","bios","config","logger","storedSeedPhrase","seedPhraseStore","get","debug","mnemonic","api","isString","warn","set","seedPhrase","HDWallet","generateMnemonic","log","assertEx","getServer","context","port","rewardRedemptionApi","boot","isDefined","wallet","fromPhrase","nodeContext","node","getNode","app","getApp","server","listen","setTimeout"]}
1
+ {"version":3,"sources":["../../src/server/app.ts","../../src/server/instrumentation.ts","../../src/server/routes/dataLake/archivistMiddleware.ts","../../src/server/routes/dataLake/addDataLakeRoutes.ts","../../src/server/routes/rewardRedemption/routeDefinitions/routes/claim.ts","../../src/server/routes/rewardRedemption/middleware/requestHandlerValidator.ts","../../src/server/routes/rewardRedemption/routeDefinitions/pathParams/AddressPathParam.ts","../../src/server/routes/rewardRedemption/routeDefinitions/routes/redeem.ts","../../src/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.ts","../../src/server/routes/rewardRedemption/addRewardRoutes.ts","../../src/server/routes/addRoutes.ts","../../src/server/server.ts","../../src/manifest/getLocator.ts","../../src/manifest/getNode.ts","../../src/manifest/node.json","../../src/manifest/nodeManifest.ts","../../src/manifest/private/index.ts","../../src/manifest/public/index.ts"],"sourcesContent":["import {\n customPoweredByHeader, disableCaseSensitiveRouting, disableExpressDefaultPoweredByHeader, getJsonBodyParser, getJsonBodyParserOptions, responseProfiler,\n standardErrors, standardResponses,\n} from '@xylabs/express'\nimport type { NodeInstance } from '@xyo-network/node-model'\nimport type { Config } from '@xyo-network/xl1-protocol-sdk'\nimport compression from 'compression'\nimport cors from 'cors'\nimport type { Express } from 'express'\nimport express from 'express'\n\nimport { addInstrumentation } from './instrumentation.ts'\nimport { addRoutes } from './routes/index.ts'\n\nexport const getApp = (node: NodeInstance, config: Config): Express => {\n addInstrumentation()\n const app = express()\n app.set('etag', false)\n app.use(cors())\n app.use(compression())\n app.use(responseProfiler)\n app.use(getJsonBodyParser(getJsonBodyParserOptions({ limit: '1mb' })))\n app.use(standardResponses)\n disableExpressDefaultPoweredByHeader(app)\n app.use(customPoweredByHeader)\n disableCaseSensitiveRouting(app)\n app.config = config\n app.node = node\n addRoutes(app)\n app.use(standardErrors)\n return app\n}\n","import { registerInstrumentations } from '@opentelemetry/instrumentation'\nimport { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'\nimport { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\n\n/**\n * Registers OpenTelemetry instrumentations for HTTP and Express.\n * This function is used to set up the necessary instrumentations for monitoring\n * HTTP requests and Express applications. Since it monkey patches the Express\n * router & middleware system, it should be called before any Express applications\n * are defined.\n */\nexport const addInstrumentation = () => {\n const instrumentations = [new HttpInstrumentation(), new ExpressInstrumentation()]\n registerInstrumentations({ instrumentations })\n}\n","import { setRawResponseFormat } from '@xylabs/express'\nimport { asHash } from '@xylabs/hex'\nimport { isDefined } from '@xylabs/typeof'\nimport type {\n ArchivistInstance,\n ArchivistNextOptions, NextOptions,\n} from '@xyo-network/archivist-model'\nimport { asArchivistInstance } from '@xyo-network/archivist-model'\nimport type { ModuleIdentifier } from '@xyo-network/module-model'\nimport type { NodeInstance } from '@xyo-network/node-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport type { Payload } from '@xyo-network/payload-model'\nimport { isAnyPayload, isSequence } from '@xyo-network/payload-model'\nimport type { Router } from 'express'\nimport express from 'express'\nimport type { Request } from 'express-serve-static-core'\n\nconst resolveArchivist = async (node: NodeInstance, archivistModuleIdentifier: ModuleIdentifier): Promise<ArchivistInstance> => {\n const mod = await node.resolve(archivistModuleIdentifier)\n return asArchivistInstance(mod, { required: true })\n}\n\nlet archivistInstance: ArchivistInstance | undefined\n\nconst getArchivist = async (node: NodeInstance, archivistModuleIdentifier: ModuleIdentifier): Promise<ArchivistInstance> => {\n if (isDefined(archivistInstance)) return archivistInstance\n archivistInstance = await resolveArchivist(node, archivistModuleIdentifier)\n return archivistInstance\n}\n\ntype ArchivistMiddlewareOptions = {\n archivistModuleIdentifier: ModuleIdentifier\n node: NodeInstance\n}\n\nexport const archivistMiddleware = (options: ArchivistMiddlewareOptions): Router => {\n const { node, archivistModuleIdentifier } = options\n const router = express.Router({ mergeParams: true })\n\n router.post('/insert', async (req, res) => {\n setRawResponseFormat(res)\n const body = Array.isArray(req.body) ? req.body : [req.body]\n const payloads = (await PayloadBuilder.hashPairs<Payload>(body)).map(p => p[0])\n const archivist = await getArchivist(node, archivistModuleIdentifier)\n const result = await archivist.insert(payloads)\n res.status(200).json(result)\n })\n\n router.get('/next', async (req: Request<Partial<NextOptions>>, res) => {\n setRawResponseFormat(res)\n const cursor = isSequence(req.query.cursor) ? req.query.cursor : undefined\n const limit = isDefined(req.query.limit) ? Number(req.query.limit) : undefined\n const open = isDefined(req.query.open) ? Boolean(req.query.open) : undefined\n const order = req.query.order === 'asc' ? 'asc' : 'desc'\n const options: ArchivistNextOptions = {\n limit, open, order, cursor,\n }\n const archivist = await getArchivist(node, archivistModuleIdentifier)\n const result = await archivist.next(options)\n res.status(200).json(result)\n })\n router.post('/next', async (req: Request<{}, {}, ArchivistNextOptions | undefined>, res) => {\n setRawResponseFormat(res)\n const options = req.body\n const archivist = await getArchivist(node, archivistModuleIdentifier)\n const result = await (isDefined(options) ? archivist.next(options) : archivist.next())\n res.status(200).json(result)\n })\n\n router.get('/get/:hash', async (req, res) => {\n setRawResponseFormat(res)\n const { hash: rawHash } = req.params\n const hash = asHash(rawHash)\n if (isDefined(hash)) {\n const archivist = await getArchivist(node, archivistModuleIdentifier)\n const [payload] = await archivist.get([hash])\n if (isAnyPayload(payload)) {\n res.json(payload)\n return\n } else {\n res.status(404).send()\n return\n }\n }\n res.status(400).send()\n })\n\n return router\n}\n","import type { Express } from 'express'\n\nimport { archivistMiddleware } from './archivistMiddleware.ts'\n\nexport const addDataLakeRoutes = (app: Express) => {\n const { node } = app\n const archivistModuleIdentifier = 'Data'\n app.use('/data', archivistMiddleware({ node, archivistModuleIdentifier }))\n}\n","/* eslint-disable max-statements */\nimport type { Address } from '@xylabs/hex'\nimport { asAddress } from '@xylabs/hex'\nimport { isDefined, isUndefined } from '@xylabs/typeof'\nimport { createTransferPayload } from '@xyo-network/chain-protocol'\nimport { PayloadZodLoose } from '@xyo-network/payload-model'\nimport { HDWallet } from '@xyo-network/wallet'\nimport type {\n Stake,\n StepIdentity, StepIdentityString, Transfer,\n} from '@xyo-network/xl1-protocol'\nimport { asXL1BlockNumber } from '@xyo-network/xl1-protocol'\nimport {\n buildTransaction, completedStepRewardAddress, derivedReceiveAddress,\n} from '@xyo-network/xl1-protocol-sdk'\nimport {\n HttpRpcTransport, JsonRpcXyoViewer, SignedHydratedTransactionZod,\n XyoViewerRpcSchemas,\n} from '@xyo-network/xl1-rpc'\nimport { z } from 'zod'\n\nimport { requestHandlerValidator } from '../../middleware/index.ts'\nimport { AddressPathParam } from '../pathParams/index.ts'\nimport type { RouteDefinition } from '../routeDefinition.ts'\n\nconst scope = 'reward-escrow'\n\nconst params = z.object({ address: AddressPathParam })\nconst body = PayloadZodLoose\n\n// const response = z.array(TransferZod)\n// TODO: Transaction BW?\nconst response = SignedHydratedTransactionZod\n\nconst validateRequest = requestHandlerValidator({\n params,\n body,\n response,\n})\n\nfunction tryParseInt(value: string): number | undefined {\n // Prevent coercion of empty strings to 0\n if (value === '') return undefined\n // Parse number\n const num = Number(value)\n // Check if integer\n return Number.isInteger(num) ? num : undefined\n}\n\nconst asStepIdentity = (stepIdentityString: string): StepIdentity | undefined => {\n try {\n const [blockNumberString, stepString] = stepIdentityString.split('|')\n if (isUndefined(blockNumberString) || isUndefined(stepString)) {\n return undefined\n }\n const step = tryParseInt(stepString)\n const blockNumber = tryParseInt(blockNumberString)\n if (isUndefined(blockNumber) || isUndefined(step)) {\n return undefined\n }\n const block = asXL1BlockNumber(blockNumber)\n return { block, step }\n } catch {\n return undefined\n }\n}\n\nconst getStakesForStaker = async (\n viewer: JsonRpcXyoViewer,\n stakerAddress: Address,\n) => {\n const stakes = await viewer.stakesByStaker(stakerAddress)\n return stakes\n}\n\nconst getRewardsForStake = async (\n viewer: JsonRpcXyoViewer,\n stakes: Stake[],\n fromBlock: number = 0,\n toBlock?: number,\n) => {\n if (isUndefined(toBlock)) {\n toBlock = await viewer.currentBlockNumber()\n }\n const rewards: Record<StepIdentityString, [bigint, bigint]>[] = []\n for (const stake of stakes) {\n const { id } = stake\n const reward = await viewer.networkStakeStepRewardsForPosition(id, [fromBlock, toBlock])\n rewards.push(reward)\n }\n return rewards\n}\n\nconst sumNetworkStakeStepRewards = (\n records: Record<string, [bigint, bigint]>[],\n): Record<string, bigint> => {\n const totals: Record<string, bigint> = {}\n\n for (const record of records) {\n for (const [key, [first]] of Object.entries(record)) {\n if (isUndefined(totals[key])) {\n totals[key] = 0n\n }\n totals[key] += first\n }\n }\n\n return totals\n}\n\nexport const postClaim: RouteDefinition = {\n method: 'post',\n path: '/rewards/claim/:address',\n handlers: validateRequest(async (req, res) => {\n const { config } = req.app\n const { mnemonic, chainRpcApiUrl } = config.rewardRedemptionApi\n const { address } = req.params\n const stakerAddress = asAddress(address)\n if (!stakerAddress) {\n res.status(400)\n return\n }\n const account = await (isDefined(mnemonic) ? HDWallet.fromPhrase(mnemonic) : HDWallet.random())\n // TODO: Prevent redeeming if existing redemption already in progress\n const transport = new HttpRpcTransport(chainRpcApiUrl, XyoViewerRpcSchemas)\n const viewer = new JsonRpcXyoViewer(transport)\n const stakes = await getStakesForStaker(viewer, stakerAddress)\n // If they have stakes\n if (stakes.length > 0) {\n // Get rewards for those stakes\n const currentBlock = await viewer.currentBlockNumber()\n const rewards = await getRewardsForStake(viewer, stakes, 0, currentBlock)\n // If there are rewards\n if (Object.keys(rewards).length > 0) {\n const totalRewards = sumNetworkStakeStepRewards(rewards)\n const totalTransfers: Transfer[] = []\n for (const [stepIdentityString, accrued] of Object.entries(totalRewards)) {\n const stepIdentity = asStepIdentity(stepIdentityString)\n if (isUndefined(stepIdentity)) continue\n const stepRewardsAddress = completedStepRewardAddress(stepIdentity)\n const receiveAddress = derivedReceiveAddress(stakerAddress, scope)\n // Validate against already redeemed rewards\n const claimed = await viewer.transferPairBalance([stepRewardsAddress, receiveAddress])\n const unclaimed = accrued - claimed\n if (unclaimed <= 0n) continue\n const transferPayload = createTransferPayload(stepRewardsAddress, { [receiveAddress]: unclaimed })\n // Add appropriate transfer context\n transferPayload.context = { address: stakerAddress, scope }\n totalTransfers.push(transferPayload)\n }\n if (totalTransfers.length > 0) {\n const chainId = await viewer.chainId()\n const tx = await buildTransaction(\n chainId,\n totalTransfers,\n [],\n account,\n currentBlock,\n currentBlock + 1000,\n )\n // Return response payload\n res.json(tx)\n return\n }\n }\n }\n\n res.status(204)\n }),\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { ExpressError } from '@xylabs/express'\nimport { isPromise } from '@xylabs/typeof'\nimport type {\n NextFunction, Request, RequestHandler, Response,\n} from 'express'\nimport { ReasonPhrases, StatusCodes } from 'http-status-codes'\nimport type { ZodType } from 'zod'\nimport { z } from 'zod'\n\n/**\n * Empty Zod schema for requests with no parameters.\n */\nexport const EmptyParamsZod = z.object({}).catchall(z.string())\n\n/**\n * Empty Zod schema for requests with no query parameters.\n */\nexport const EmptyQueryParamsZod = z.object({}).catchall(z.union([z.string(), z.array(z.string())]))\n\n/**\n * Default validation schemas for request handler validator.\n */\nexport const ValidateRequestDefaults = {\n params: EmptyParamsZod,\n query: EmptyQueryParamsZod,\n body: z.json(),\n response: z.json(),\n}\n\ntype ValidatableRequestKey = 'params' | 'query' | 'body'\n\n/**\n * Factory for Express middleware that validates request and response objects using Zod schemas.\n * @param schemas The Zod schemas to use for validation.\n * @returns A middleware function for validating requests and responses.\n */\nexport function requestHandlerValidator<\n TParams extends typeof EmptyQueryParamsZod | ZodType<Record<string, string>> = typeof EmptyQueryParamsZod,\n TQuery extends typeof EmptyQueryParamsZod | ZodType<Record<string, string | string[]>> = typeof EmptyQueryParamsZod,\n TBody extends ZodType<unknown> = ZodType<unknown>,\n TResponse extends ZodType<unknown> = ZodType<unknown>,\n>(schemas?: Partial<{\n body: TBody\n params: TParams\n query: TQuery\n response: TResponse\n}>) {\n type Params = z.infer<TParams>\n type Query = z.infer<TQuery>\n type Body = z.infer<TBody>\n type Res = z.infer<TResponse>\n const validators = { ...ValidateRequestDefaults, ...schemas }\n\n return (handler: (req: Request<Params, Res, Body, Query>, res: Response<Res>, next: NextFunction) => unknown): RequestHandler => {\n return async (req: Request, res: Response, next: NextFunction) => {\n const originalJson = res.json.bind(res)\n try {\n // Validate incoming request\n const errors: string[] = []\n const keys: ValidatableRequestKey[] = ['params', 'query', 'body']\n for (const key of keys) {\n const validator = validators[key]\n const result = validator.safeParse(req[key])\n if (result.success) {\n Object.assign(req[key], result.data)\n } else {\n errors.push(\n ...result.error.issues.map(\n issue => (issue.path.length === 0)\n ? `${key}: ${issue.message}`\n : `${key}.${issue.path.join('.')}: ${issue.message}`,\n ),\n )\n }\n }\n\n // If there were validation errors, short-circuit and return Bad Request\n if (errors.length > 0) {\n const message = errors.join('; ')\n const err: ExpressError = new Error(message)\n err.name = ReasonPhrases.BAD_REQUEST\n err.statusCode = StatusCodes.BAD_REQUEST\n next(err)\n return false\n }\n\n // Wrap res.json to validate outgoing response\n res.json = (data: any) => {\n const result = validators.response.safeParse(data)\n if (result.success) {\n return originalJson(result.data)\n } else {\n const message = result.error.issues.map(\n issue => (issue.path.length === 0)\n ? `response: ${issue.message}`\n : `response.${issue.path.join('.')}: ${issue.message}`,\n ).join('; ')\n const err: ExpressError = new Error(message)\n err.name = ReasonPhrases.INTERNAL_SERVER_ERROR\n err.statusCode = StatusCodes.INTERNAL_SERVER_ERROR\n\n // Restore original json function in case the error handler wants to use it\n res.json = originalJson\n throw err\n }\n }\n\n // Automatically handle async errors\n const result = handler(req as any, res as any, next)\n if (result && isPromise(result)) {\n await result\n }\n } catch (err) {\n res.json = originalJson\n next(err)\n }\n }\n }\n}\n","export { EthAddressFromStringZod as AddressPathParam } from '@xylabs/hex'\n","import { PayloadZodLoose } from '@xyo-network/payload-model'\nimport { z } from 'zod'\n\nimport { requestHandlerValidator } from '../../middleware/index.ts'\nimport { AddressPathParam } from '../pathParams/index.ts'\nimport type { RouteDefinition } from '../routeDefinition.ts'\n\nconst params = z.object({ address: AddressPathParam })\nconst body = PayloadZodLoose\nconst response = PayloadZodLoose\nconst validateRequest = requestHandlerValidator({\n params,\n body,\n response,\n})\n\nexport const postRedeem: RouteDefinition = {\n method: 'post',\n path: '/rewards/redeem/:address',\n handlers: validateRequest(async (req, res) => {\n const { body } = req\n await Promise.resolve()\n const bridgeObservation = { schema: 'network.xyo.test' }\n res.json(bridgeObservation)\n }),\n}\n","import type { RouteDefinition } from './routeDefinition.ts'\nimport { postClaim, postRedeem } from './routes/index.ts'\n\nexport const getRouteDefinitions = (): RouteDefinition[] => {\n return [\n postClaim,\n postRedeem,\n ]\n}\n","import type { Express } from 'express'\n\nimport { getRouteDefinitions } from './routeDefinitions/index.ts'\n\nexport const addRewardRedemptionRoutes = (app: Express) => {\n const routeDefinitions = getRouteDefinitions()\n for (const definition of routeDefinitions) {\n app[definition.method](definition.path, definition.handlers)\n }\n}\n","import type { Express } from 'express'\n\nimport { addDataLakeRoutes } from './dataLake/index.ts'\nimport { addRewardRedemptionRoutes } from './rewardRedemption/index.ts'\n\nexport const addRoutes = (app: Express) => {\n addDataLakeRoutes(app)\n addRewardRedemptionRoutes(app)\n}\n","import { assertEx } from '@xylabs/assert'\nimport type { Logger } from '@xylabs/logger'\nimport { isDefined, isString } from '@xylabs/typeof'\nimport { boot } from '@xyo-network/bios'\nimport type { BiosExternalInterface } from '@xyo-network/bios-model'\nimport type { NodeInstance } from '@xyo-network/node-model'\nimport { HDWallet } from '@xyo-network/wallet'\nimport { type Config } from '@xyo-network/xl1-protocol-sdk'\n\nimport { getNode } from '../manifest/index.ts'\nimport { getApp } from './app.ts'\n\nconst hostname = '::'\n// const hostname = '0.0.0.0'\n\n// TODO: Make nodejs version of bios support round tripping mnemonic between boots\nconst getSeedPhrase = async (bios: BiosExternalInterface, config: Config, logger?: Logger): Promise<string> => {\n const storedSeedPhrase = await bios.seedPhraseStore.get('os')\n logger?.debug(`[Bridge] Stored mnemonic: ${storedSeedPhrase}`)\n const { mnemonic } = config.api\n if (isString(storedSeedPhrase) && isString(mnemonic)) {\n logger?.warn('[Bridge] Stored mnemonic does not match supplied. Updating stored mnemonic to supplied.')\n await bios.seedPhraseStore.set('os', mnemonic)\n } else {\n let seedPhrase: string\n if (isString(mnemonic)) {\n seedPhrase = mnemonic\n } else {\n seedPhrase = HDWallet.generateMnemonic()\n logger?.log('[Bridge] No mnemonic provided, using random mnemonic. This is not recommended for production use.')\n logger?.log(`[Bridge] Mnemonic: ${seedPhrase}`)\n }\n await bios.seedPhraseStore.set('os', seedPhrase)\n }\n return assertEx(await bios.seedPhraseStore.get('os'), () => 'Unable to acquire mnemonic from bios')\n}\n\ninterface GetServerContext {\n config: Config\n logger?: Logger\n node?: NodeInstance\n}\n\nexport const getServer = async (context: GetServerContext) => {\n const { logger, config } = context\n const { port, mnemonic } = config.rewardRedemptionApi\n const bios = await boot()\n const seedPhrase = isDefined(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger)\n const wallet = await HDWallet.fromPhrase(seedPhrase)\n const nodeContext = {\n wallet, logger, config,\n }\n const node = context.node ?? await getNode(nodeContext)\n const app = getApp(node, config)\n const server = app.listen(port, hostname, () => logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`))\n server.setTimeout(120_000)\n return server\n}\n","import type { Logger } from '@xylabs/logger'\nimport { type BaseMongoSdkPrivateConfig } from '@xylabs/mongo'\nimport { isDefined } from '@xylabs/typeof'\nimport { MemoryArchivist } from '@xyo-network/archivist-memory'\nimport { MongoDBArchivistV2 } from '@xyo-network/archivist-mongodb'\nimport { ViewArchivist } from '@xyo-network/archivist-view'\nimport { ArchivistSyncDiviner } from '@xyo-network/chain-modules'\nimport { initTelemetry } from '@xyo-network/chain-telemetry'\nimport { AbstractModule, LoggerModuleStatusReporter } from '@xyo-network/module-abstract'\nimport { ModuleFactoryLocator } from '@xyo-network/module-factory-locator'\nimport type { MongoDBModuleParamsV2 } from '@xyo-network/module-model-mongodb'\nimport { MemorySentinel } from '@xyo-network/sentinel-memory'\nimport type { Config } from '@xyo-network/xl1-protocol-sdk'\nimport { hasMongoConfig } from '@xyo-network/xl1-protocol-sdk'\n\nexport interface GetLocatorContext {\n config: Config\n logger?: Logger\n}\n\n/**\n * Used for retrieving a locator with the necessary modules registered for testing\n * operation of the node (entirely in memory)\n * @returns A locator with the necessary modules registered\n */\nexport const getLocator = async (context: GetLocatorContext) => {\n const { config, logger } = context\n const { otlpEndpoint } = config.telemetry?.otel ?? {}\n const { traceProvider, meterProvider } = await initTelemetry({\n attributes: {\n serviceName: 'xl1-rewards',\n serviceVersion: '1.0.0',\n },\n otlpEndpoint,\n metricsConfig: {\n endpoint: '/metrics',\n port: 9465,\n },\n })\n\n if (isDefined(logger)) AbstractModule.defaultLogger = logger\n const statusReporter = logger ? new LoggerModuleStatusReporter(logger) : undefined\n\n const locator = new ModuleFactoryLocator()\n // If there's a MongoDB configuration\n const mongoConfig = config.storage?.mongo\n if (hasMongoConfig(mongoConfig)) {\n // Create the MongoDB SDK from the configuration\n const {\n connectionString: dbConnectionString, database: dbName, domain: dbDomain, password: dbPassword, username: dbUserName,\n } = mongoConfig\n const payloadSdkConfig: BaseMongoSdkPrivateConfig = {\n dbConnectionString, dbDomain, dbName, dbPassword, dbUserName,\n }\n const params: Partial<MongoDBModuleParamsV2> = {\n meterProvider, payloadSdkConfig, statusReporter, traceProvider,\n }\n // Register the MongoDB Archivist as the default\n locator.register(MongoDBArchivistV2.factory(params), undefined, true)\n }\n\n locator.register(MemoryArchivist.factory({\n traceProvider, meterProvider, statusReporter,\n }))\n locator.register(MemorySentinel.factory({\n traceProvider, meterProvider, statusReporter,\n }))\n locator.register(ViewArchivist.factory({\n traceProvider, meterProvider, statusReporter,\n }))\n locator.register(ArchivistSyncDiviner.factory({\n traceProvider, meterProvider, statusReporter,\n }))\n return locator\n}\n","import type { Logger } from '@xylabs/logger'\nimport { ManifestWrapper } from '@xyo-network/manifest-wrapper'\nimport type { WalletInstance } from '@xyo-network/wallet-model'\nimport type { Config } from '@xyo-network/xl1-protocol-sdk'\n\nimport { getLocator } from './getLocator.ts'\nimport { NodeManifest } from './nodeManifest.ts'\nimport { PrivateChildManifests } from './private/index.ts'\nimport { PublicChildManifests } from './public/index.ts'\n\nexport interface GetNodeContext {\n config: Config\n logger?: Logger\n wallet: WalletInstance\n}\n\n/**\n * Creates a node with the xyo-chain modules registered\n * @param context The context to use for the node\n * @returns A node with the xyo-chain modules registered\n */\nexport const getNode = async (context: GetNodeContext) => {\n const { wallet } = context\n const locator = await getLocator(context)\n const wrapper = new ManifestWrapper(NodeManifest, wallet, locator, PublicChildManifests, PrivateChildManifests)\n const [node, ...childNodes] = await wrapper.loadNodes()\n if (childNodes?.length > 0) {\n await Promise.all(childNodes.map(childNode => node.register(childNode)))\n await Promise.all(childNodes.map(childNode => node.attach(childNode.address, true)))\n }\n return node\n}\n","{\n \"$schema\": \"https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json\",\n \"nodes\": [\n {\n \"config\": {\n \"accountPath\": \"44'/60'/1\",\n \"name\": \"XYORewardRedemptionNode\",\n \"schema\": \"network.xyo.node.config\"\n },\n \"modules\": {\n \"private\": [\n {\n \"config\": {\n \"accountPath\": \"1/1'/1'\",\n \"name\": \"DataPrivate\",\n \"getCache\": {\n \"enabled\": true,\n \"maxEntries\": 5000\n },\n \"payloadSdkConfig\": {\n \"collection\": \"reward_redemption_api_datalake\"\n },\n \"schema\": \"network.xyo.archivist.config\"\n }\n }\n ],\n \"public\": [\n {\n \"config\": {\n \"accountPath\": \"1/1/1\",\n \"name\": \"Data\",\n \"allowedQueries\": [\n \"network.xyo.query.archivist.get\",\n \"network.xyo.query.archivist.next\"\n ],\n \"getCache\": {\n \"enabled\": true,\n \"maxEntries\": 5000\n },\n \"originArchivist\": \"DataPrivate\",\n \"schema\": \"network.xyo.archivist.view.config\"\n }\n }\n ]\n }\n }\n ],\n \"schema\": \"network.xyo.manifest\"\n}\n","import type { PackageManifestPayload } from '@xyo-network/manifest-model'\n\nimport node from './node.json' with { type: 'json' }\n\n/**\n * Root Node Manifest\n */\nexport const NodeManifest = node as PackageManifestPayload\n","/**\n * Private Child Manifests\n */\nexport const PrivateChildManifests = []\n","import type { ModuleManifest, PackageManifestPayload } from '@xyo-network/manifest-model'\n\n/**\n * Public Child Manifests\n */\nexport const PublicChildManifests: ModuleManifest[] = []\n"],"mappings":"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","names":["customPoweredByHeader","disableCaseSensitiveRouting","disableExpressDefaultPoweredByHeader","getJsonBodyParser","getJsonBodyParserOptions","responseProfiler","standardErrors","standardResponses","compression","cors","express","registerInstrumentations","ExpressInstrumentation","HttpInstrumentation","addInstrumentation","instrumentations","HttpInstrumentation","ExpressInstrumentation","registerInstrumentations","setRawResponseFormat","asHash","isDefined","asArchivistInstance","PayloadBuilder","isAnyPayload","isSequence","express","resolveArchivist","node","archivistModuleIdentifier","mod","resolve","asArchivistInstance","required","archivistInstance","getArchivist","isDefined","archivistMiddleware","options","router","express","Router","mergeParams","post","req","res","setRawResponseFormat","body","Array","isArray","payloads","PayloadBuilder","hashPairs","map","p","archivist","result","insert","status","json","get","cursor","isSequence","query","undefined","limit","Number","open","Boolean","order","next","hash","rawHash","params","asHash","payload","isAnyPayload","send","addDataLakeRoutes","app","node","archivistModuleIdentifier","use","archivistMiddleware","asAddress","isDefined","isUndefined","createTransferPayload","PayloadZodLoose","HDWallet","asXL1BlockNumber","buildTransaction","completedStepRewardAddress","derivedReceiveAddress","HttpRpcTransport","JsonRpcXyoViewer","SignedHydratedTransactionZod","XyoViewerRpcSchemas","z","isPromise","ReasonPhrases","StatusCodes","z","EmptyParamsZod","z","object","catchall","string","EmptyQueryParamsZod","union","array","ValidateRequestDefaults","params","query","body","json","response","requestHandlerValidator","schemas","validators","handler","req","res","next","originalJson","bind","errors","keys","key","validator","result","safeParse","success","Object","assign","data","push","error","issues","map","issue","path","length","message","join","err","Error","name","ReasonPhrases","BAD_REQUEST","statusCode","StatusCodes","INTERNAL_SERVER_ERROR","isPromise","AddressPathParam","scope","params","z","object","address","AddressPathParam","body","PayloadZodLoose","response","SignedHydratedTransactionZod","validateRequest","requestHandlerValidator","tryParseInt","value","undefined","num","Number","isInteger","asStepIdentity","stepIdentityString","blockNumberString","stepString","split","isUndefined","step","blockNumber","block","asXL1BlockNumber","getStakesForStaker","viewer","stakerAddress","stakes","stakesByStaker","getRewardsForStake","fromBlock","toBlock","currentBlockNumber","rewards","stake","id","reward","networkStakeStepRewardsForPosition","push","sumNetworkStakeStepRewards","records","totals","record","key","first","Object","entries","postClaim","method","path","handlers","req","res","config","app","mnemonic","chainRpcApiUrl","rewardRedemptionApi","asAddress","status","account","isDefined","HDWallet","fromPhrase","random","transport","HttpRpcTransport","XyoViewerRpcSchemas","JsonRpcXyoViewer","length","currentBlock","keys","totalRewards","totalTransfers","accrued","stepIdentity","stepRewardsAddress","completedStepRewardAddress","receiveAddress","derivedReceiveAddress","claimed","transferPairBalance","unclaimed","transferPayload","createTransferPayload","context","chainId","tx","buildTransaction","json","PayloadZodLoose","z","params","z","object","address","AddressPathParam","body","PayloadZodLoose","response","validateRequest","requestHandlerValidator","postRedeem","method","path","handlers","req","res","Promise","resolve","bridgeObservation","schema","json","getRouteDefinitions","postClaim","postRedeem","addRewardRedemptionRoutes","app","routeDefinitions","getRouteDefinitions","definition","method","path","handlers","addRoutes","app","addDataLakeRoutes","addRewardRedemptionRoutes","getApp","node","config","addInstrumentation","app","express","set","use","cors","compression","responseProfiler","getJsonBodyParser","getJsonBodyParserOptions","limit","standardResponses","disableExpressDefaultPoweredByHeader","customPoweredByHeader","disableCaseSensitiveRouting","addRoutes","standardErrors","assertEx","isDefined","isString","boot","HDWallet","isDefined","MemoryArchivist","MongoDBArchivistV2","ViewArchivist","ArchivistSyncDiviner","initTelemetry","AbstractModule","LoggerModuleStatusReporter","ModuleFactoryLocator","MemorySentinel","hasMongoConfig","getLocator","context","config","logger","otlpEndpoint","telemetry","otel","traceProvider","meterProvider","initTelemetry","attributes","serviceName","serviceVersion","metricsConfig","endpoint","port","isDefined","AbstractModule","defaultLogger","statusReporter","LoggerModuleStatusReporter","undefined","locator","ModuleFactoryLocator","mongoConfig","storage","mongo","hasMongoConfig","connectionString","dbConnectionString","database","dbName","domain","dbDomain","password","dbPassword","username","dbUserName","payloadSdkConfig","params","register","MongoDBArchivistV2","factory","MemoryArchivist","MemorySentinel","ViewArchivist","ArchivistSyncDiviner","ManifestWrapper","NodeManifest","node","PrivateChildManifests","PublicChildManifests","getNode","context","wallet","locator","getLocator","wrapper","ManifestWrapper","NodeManifest","PublicChildManifests","PrivateChildManifests","node","childNodes","loadNodes","length","Promise","all","map","childNode","register","attach","address","hostname","getSeedPhrase","bios","config","logger","storedSeedPhrase","seedPhraseStore","get","debug","mnemonic","api","isString","warn","set","seedPhrase","HDWallet","generateMnemonic","log","assertEx","getServer","context","port","rewardRedemptionApi","boot","isDefined","wallet","fromPhrase","nodeContext","node","getNode","app","getApp","server","listen","setTimeout"]}
@@ -1,4 +1,5 @@
1
1
  import type { NodeInstance } from '@xyo-network/node-model';
2
+ import type { Config } from '@xyo-network/xl1-protocol-sdk';
2
3
  import type { Express } from 'express';
3
- export declare const getApp: (node: NodeInstance) => Express;
4
+ export declare const getApp: (node: NodeInstance, config: Config) => Express;
4
5
  //# sourceMappingURL=app.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/server/app.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAG3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAMtC,eAAO,MAAM,MAAM,GAAI,MAAM,YAAY,KAAG,OAgB3C,CAAA"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/server/app.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAG3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAMtC,eAAO,MAAM,MAAM,GAAI,MAAM,YAAY,EAAE,QAAQ,MAAM,KAAG,OAiB3D,CAAA"}
@@ -1,9 +1,11 @@
1
1
  export * from './app.ts';
2
2
  export * from './server.ts';
3
3
  import type { NodeInstance } from '@xyo-network/node-model';
4
+ import type { Config } from '@xyo-network/xl1-protocol-sdk';
4
5
  declare global {
5
6
  namespace Express {
6
7
  interface Application {
8
+ config: Config;
7
9
  node: NodeInstance;
8
10
  }
9
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAE3D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,WAAW;YACnB,IAAI,EAAE,YAAY,CAAA;SACnB;KACF;CACF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAE3D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,WAAW;YACnB,MAAM,EAAE,MAAM,CAAA;YACd,IAAI,EAAE,YAAY,CAAA;SACnB;KACF;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"archivistMiddleware.d.ts","sourceRoot":"","sources":["../../../../../src/server/routes/dataLake/archivistMiddleware.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAI3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAiBrC,KAAK,0BAA0B,GAAG;IAChC,yBAAyB,EAAE,gBAAgB,CAAA;IAC3C,IAAI,EAAE,YAAY,CAAA;CACnB,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,SAAS,0BAA0B,KAAG,MAkDzE,CAAA"}
1
+ {"version":3,"file":"archivistMiddleware.d.ts","sourceRoot":"","sources":["../../../../../src/server/routes/dataLake/archivistMiddleware.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAI3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAiBrC,KAAK,0BAA0B,GAAG;IAChC,yBAAyB,EAAE,gBAAgB,CAAA;IAC3C,IAAI,EAAE,YAAY,CAAA;CACnB,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,SAAS,0BAA0B,KAAG,MAqDzE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"claim.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/routes/claim.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAa5D,eAAO,MAAM,SAAS,EAAE,eAYvB,CAAA"}
1
+ {"version":3,"file":"claim.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/routes/claim.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAuF5D,eAAO,MAAM,SAAS,EAAE,eA2DvB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/chain-reward-redemption",
3
- "version": "1.15.11",
3
+ "version": "1.15.13",
4
4
  "description": "XYO Layer One Rewards",
5
5
  "homepage": "https://xylabs.com",
6
6
  "bugs": {
@@ -49,43 +49,43 @@
49
49
  "@opentelemetry/instrumentation": "~0.207.0",
50
50
  "@opentelemetry/instrumentation-express": "~0.56.0",
51
51
  "@opentelemetry/instrumentation-http": "~0.207.0",
52
- "@xylabs/assert": "~5.0.12",
53
- "@xylabs/creatable": "~5.0.12",
54
- "@xylabs/express": "~5.0.12",
55
- "@xylabs/hex": "~5.0.12",
56
- "@xylabs/logger": "~5.0.12",
57
- "@xylabs/mongo": "~5.0.12",
58
- "@xylabs/typeof": "~5.0.12",
59
- "@xyo-network/archivist-memory": "~5.1.6",
60
- "@xyo-network/archivist-model": "~5.1.6",
61
- "@xyo-network/archivist-mongodb": "~5.1.6",
62
- "@xyo-network/archivist-view": "~5.1.6",
52
+ "@xylabs/assert": "~5.0.13",
53
+ "@xylabs/creatable": "~5.0.13",
54
+ "@xylabs/express": "~5.0.13",
55
+ "@xylabs/hex": "~5.0.13",
56
+ "@xylabs/logger": "~5.0.13",
57
+ "@xylabs/mongo": "~5.0.13",
58
+ "@xylabs/typeof": "~5.0.13",
59
+ "@xyo-network/archivist-memory": "~5.1.7",
60
+ "@xyo-network/archivist-model": "~5.1.7",
61
+ "@xyo-network/archivist-mongodb": "~5.1.7",
62
+ "@xyo-network/archivist-view": "~5.1.7",
63
63
  "@xyo-network/bios": "~7.1.1",
64
- "@xyo-network/boundwitness-model": "~5.1.6",
65
- "@xyo-network/chain-modules": "~1.15.11",
66
- "@xyo-network/chain-protocol": "~1.15.11",
67
- "@xyo-network/chain-telemetry": "~1.15.11",
68
- "@xyo-network/manifest-model": "~5.1.6",
69
- "@xyo-network/manifest-wrapper": "~5.1.6",
70
- "@xyo-network/module-abstract": "~5.1.6",
71
- "@xyo-network/module-factory-locator": "~5.1.6",
72
- "@xyo-network/module-model": "~5.1.6",
73
- "@xyo-network/node-model": "~5.1.6",
74
- "@xyo-network/payload-builder": "~5.1.6",
75
- "@xyo-network/payload-model": "~5.1.6",
76
- "@xyo-network/sentinel-memory": "~5.1.6",
64
+ "@xyo-network/boundwitness-model": "~5.1.7",
65
+ "@xyo-network/chain-modules": "~1.15.13",
66
+ "@xyo-network/chain-protocol": "~1.15.13",
67
+ "@xyo-network/chain-telemetry": "~1.15.13",
68
+ "@xyo-network/manifest-model": "~5.1.7",
69
+ "@xyo-network/manifest-wrapper": "~5.1.7",
70
+ "@xyo-network/module-abstract": "~5.1.7",
71
+ "@xyo-network/module-factory-locator": "~5.1.7",
72
+ "@xyo-network/module-model": "~5.1.7",
73
+ "@xyo-network/node-model": "~5.1.7",
74
+ "@xyo-network/payload-builder": "~5.1.7",
75
+ "@xyo-network/payload-model": "~5.1.7",
76
+ "@xyo-network/sentinel-memory": "~5.1.7",
77
77
  "@xyo-network/typechain": "~4.0.10",
78
- "@xyo-network/wallet": "~5.1.6",
79
- "@xyo-network/wallet-model": "~5.1.6",
80
- "@xyo-network/xl1-protocol": "~1.12.81",
81
- "@xyo-network/xl1-protocol-sdk": "~1.15.11",
78
+ "@xyo-network/wallet": "~5.1.7",
79
+ "@xyo-network/wallet-model": "~5.1.7",
80
+ "@xyo-network/xl1-protocol": "~1.12.84",
81
+ "@xyo-network/xl1-protocol-sdk": "~1.15.13",
82
+ "@xyo-network/xl1-rpc": "~1.15.13",
82
83
  "compression": "~1.8.1",
83
84
  "cors": "~2.8.5",
84
85
  "express": "~5.1.0",
85
86
  "http-status-codes": "~2.3.0",
86
87
  "mongodb": "~6.20.0",
87
88
  "rxjs": "~7.8.2",
88
- "uuid": "~13.0.0",
89
89
  "zod": "~4.1.12"
90
90
  },
91
91
  "devDependencies": {
@@ -94,29 +94,29 @@
94
94
  "@types/express": "5.0.3",
95
95
  "@types/express-serve-static-core": "~5.1.0",
96
96
  "@types/node": "~24.9.1",
97
- "@xylabs/base": "~5.0.12",
98
- "@xylabs/delay": "~5.0.12",
99
- "@xylabs/object": "~5.0.12",
100
- "@xylabs/promise": "~5.0.12",
97
+ "@xylabs/base": "~5.0.13",
98
+ "@xylabs/delay": "~5.0.13",
99
+ "@xylabs/object": "~5.0.13",
100
+ "@xylabs/promise": "~5.0.13",
101
101
  "@xylabs/ts-scripts-yarn3": "~7.1.8",
102
102
  "@xylabs/tsconfig": "~7.1.8",
103
- "@xyo-network/account": "~5.1.6",
104
- "@xyo-network/account-model": "~5.1.6",
105
- "@xyo-network/archivist-abstract": "~5.1.6",
106
- "@xyo-network/archivist-memory": "~5.1.6",
107
- "@xyo-network/archivist-mongodb": "~5.1.6",
103
+ "@xyo-network/account": "~5.1.7",
104
+ "@xyo-network/account-model": "~5.1.7",
105
+ "@xyo-network/archivist-abstract": "~5.1.7",
106
+ "@xyo-network/archivist-memory": "~5.1.7",
107
+ "@xyo-network/archivist-mongodb": "~5.1.7",
108
108
  "@xyo-network/bios-model": "~7.1.1",
109
- "@xyo-network/boundwitness-builder": "~5.1.6",
110
- "@xyo-network/chain-protocol": "~1.15.11",
111
- "@xyo-network/chain-services": "~1.15.11",
112
- "@xyo-network/manifest-wrapper": "~5.1.6",
113
- "@xyo-network/module-abstract": "~5.1.6",
114
- "@xyo-network/module-abstract-mongodb": "~5.1.6",
115
- "@xyo-network/module-model-mongodb": "~5.1.6",
116
- "@xyo-network/node-memory": "~5.1.6",
117
- "@xyo-network/payload-builder": "~5.1.6",
118
- "@xyo-network/sentinel-memory": "~5.1.6",
119
- "@xyo-network/xl1-protocol": "~1.12.81",
109
+ "@xyo-network/boundwitness-builder": "~5.1.7",
110
+ "@xyo-network/chain-protocol": "~1.15.13",
111
+ "@xyo-network/chain-services": "~1.15.13",
112
+ "@xyo-network/manifest-wrapper": "~5.1.7",
113
+ "@xyo-network/module-abstract": "~5.1.7",
114
+ "@xyo-network/module-abstract-mongodb": "~5.1.7",
115
+ "@xyo-network/module-model-mongodb": "~5.1.7",
116
+ "@xyo-network/node-memory": "~5.1.7",
117
+ "@xyo-network/payload-builder": "~5.1.7",
118
+ "@xyo-network/sentinel-memory": "~5.1.7",
119
+ "@xyo-network/xl1-protocol": "~1.12.84",
120
120
  "dotenv": "~17.2.3",
121
121
  "eslint": "^9.38.0",
122
122
  "ethers": "~6.15.0",
@@ -8,12 +8,11 @@
8
8
  "schema": "network.xyo.node.config"
9
9
  },
10
10
  "modules": {
11
- "private": [],
12
- "public": [
11
+ "private": [
13
12
  {
14
13
  "config": {
15
- "accountPath": "1/1/1",
16
- "name": "Data",
14
+ "accountPath": "1/1'/1'",
15
+ "name": "DataPrivate",
17
16
  "getCache": {
18
17
  "enabled": true,
19
18
  "maxEntries": 5000
@@ -24,6 +23,24 @@
24
23
  "schema": "network.xyo.archivist.config"
25
24
  }
26
25
  }
26
+ ],
27
+ "public": [
28
+ {
29
+ "config": {
30
+ "accountPath": "1/1/1",
31
+ "name": "Data",
32
+ "allowedQueries": [
33
+ "network.xyo.query.archivist.get",
34
+ "network.xyo.query.archivist.next"
35
+ ],
36
+ "getCache": {
37
+ "enabled": true,
38
+ "maxEntries": 5000
39
+ },
40
+ "originArchivist": "DataPrivate",
41
+ "schema": "network.xyo.archivist.view.config"
42
+ }
43
+ }
27
44
  ]
28
45
  }
29
46
  }
package/src/server/app.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  standardErrors, standardResponses,
4
4
  } from '@xylabs/express'
5
5
  import type { NodeInstance } from '@xyo-network/node-model'
6
+ import type { Config } from '@xyo-network/xl1-protocol-sdk'
6
7
  import compression from 'compression'
7
8
  import cors from 'cors'
8
9
  import type { Express } from 'express'
@@ -11,7 +12,7 @@ import express from 'express'
11
12
  import { addInstrumentation } from './instrumentation.ts'
12
13
  import { addRoutes } from './routes/index.ts'
13
14
 
14
- export const getApp = (node: NodeInstance): Express => {
15
+ export const getApp = (node: NodeInstance, config: Config): Express => {
15
16
  addInstrumentation()
16
17
  const app = express()
17
18
  app.set('etag', false)
@@ -23,6 +24,7 @@ export const getApp = (node: NodeInstance): Express => {
23
24
  disableExpressDefaultPoweredByHeader(app)
24
25
  app.use(customPoweredByHeader)
25
26
  disableCaseSensitiveRouting(app)
27
+ app.config = config
26
28
  app.node = node
27
29
  addRoutes(app)
28
30
  app.use(standardErrors)
@@ -2,11 +2,13 @@ export * from './app.ts'
2
2
  export * from './server.ts'
3
3
 
4
4
  import type { NodeInstance } from '@xyo-network/node-model'
5
+ import type { Config } from '@xyo-network/xl1-protocol-sdk'
5
6
 
6
7
  declare global {
7
8
  // eslint-disable-next-line @typescript-eslint/no-namespace
8
9
  namespace Express {
9
10
  interface Application {
11
+ config: Config
10
12
  node: NodeInstance
11
13
  }
12
14
  }
@@ -4,6 +4,6 @@ import { archivistMiddleware } from './archivistMiddleware.ts'
4
4
 
5
5
  export const addDataLakeRoutes = (app: Express) => {
6
6
  const { node } = app
7
- const archivistModuleIdentifier = 'RewardsArchivist'
7
+ const archivistModuleIdentifier = 'Data'
8
8
  app.use('/data', archivistMiddleware({ node, archivistModuleIdentifier }))
9
9
  }
@@ -77,6 +77,9 @@ export const archivistMiddleware = (options: ArchivistMiddlewareOptions): Router
77
77
  if (isAnyPayload(payload)) {
78
78
  res.json(payload)
79
79
  return
80
+ } else {
81
+ res.status(404).send()
82
+ return
80
83
  }
81
84
  }
82
85
  res.status(400).send()
@@ -1,14 +1,36 @@
1
+ /* eslint-disable max-statements */
2
+ import type { Address } from '@xylabs/hex'
3
+ import { asAddress } from '@xylabs/hex'
4
+ import { isDefined, isUndefined } from '@xylabs/typeof'
5
+ import { createTransferPayload } from '@xyo-network/chain-protocol'
1
6
  import { PayloadZodLoose } from '@xyo-network/payload-model'
7
+ import { HDWallet } from '@xyo-network/wallet'
8
+ import type {
9
+ Stake,
10
+ StepIdentity, StepIdentityString, Transfer,
11
+ } from '@xyo-network/xl1-protocol'
12
+ import { asXL1BlockNumber } from '@xyo-network/xl1-protocol'
13
+ import {
14
+ buildTransaction, completedStepRewardAddress, derivedReceiveAddress,
15
+ } from '@xyo-network/xl1-protocol-sdk'
16
+ import {
17
+ HttpRpcTransport, JsonRpcXyoViewer, SignedHydratedTransactionZod,
18
+ XyoViewerRpcSchemas,
19
+ } from '@xyo-network/xl1-rpc'
2
20
  import { z } from 'zod'
3
21
 
4
22
  import { requestHandlerValidator } from '../../middleware/index.ts'
5
23
  import { AddressPathParam } from '../pathParams/index.ts'
6
24
  import type { RouteDefinition } from '../routeDefinition.ts'
7
25
 
26
+ const scope = 'reward-escrow'
27
+
8
28
  const params = z.object({ address: AddressPathParam })
9
29
  const body = PayloadZodLoose
10
30
 
11
- const response = PayloadZodLoose
31
+ // const response = z.array(TransferZod)
32
+ // TODO: Transaction BW?
33
+ const response = SignedHydratedTransactionZod
12
34
 
13
35
  const validateRequest = requestHandlerValidator({
14
36
  params,
@@ -16,16 +38,133 @@ const validateRequest = requestHandlerValidator({
16
38
  response,
17
39
  })
18
40
 
41
+ function tryParseInt(value: string): number | undefined {
42
+ // Prevent coercion of empty strings to 0
43
+ if (value === '') return undefined
44
+ // Parse number
45
+ const num = Number(value)
46
+ // Check if integer
47
+ return Number.isInteger(num) ? num : undefined
48
+ }
49
+
50
+ const asStepIdentity = (stepIdentityString: string): StepIdentity | undefined => {
51
+ try {
52
+ const [blockNumberString, stepString] = stepIdentityString.split('|')
53
+ if (isUndefined(blockNumberString) || isUndefined(stepString)) {
54
+ return undefined
55
+ }
56
+ const step = tryParseInt(stepString)
57
+ const blockNumber = tryParseInt(blockNumberString)
58
+ if (isUndefined(blockNumber) || isUndefined(step)) {
59
+ return undefined
60
+ }
61
+ const block = asXL1BlockNumber(blockNumber)
62
+ return { block, step }
63
+ } catch {
64
+ return undefined
65
+ }
66
+ }
67
+
68
+ const getStakesForStaker = async (
69
+ viewer: JsonRpcXyoViewer,
70
+ stakerAddress: Address,
71
+ ) => {
72
+ const stakes = await viewer.stakesByStaker(stakerAddress)
73
+ return stakes
74
+ }
75
+
76
+ const getRewardsForStake = async (
77
+ viewer: JsonRpcXyoViewer,
78
+ stakes: Stake[],
79
+ fromBlock: number = 0,
80
+ toBlock?: number,
81
+ ) => {
82
+ if (isUndefined(toBlock)) {
83
+ toBlock = await viewer.currentBlockNumber()
84
+ }
85
+ const rewards: Record<StepIdentityString, [bigint, bigint]>[] = []
86
+ for (const stake of stakes) {
87
+ const { id } = stake
88
+ const reward = await viewer.networkStakeStepRewardsForPosition(id, [fromBlock, toBlock])
89
+ rewards.push(reward)
90
+ }
91
+ return rewards
92
+ }
93
+
94
+ const sumNetworkStakeStepRewards = (
95
+ records: Record<string, [bigint, bigint]>[],
96
+ ): Record<string, bigint> => {
97
+ const totals: Record<string, bigint> = {}
98
+
99
+ for (const record of records) {
100
+ for (const [key, [first]] of Object.entries(record)) {
101
+ if (isUndefined(totals[key])) {
102
+ totals[key] = 0n
103
+ }
104
+ totals[key] += first
105
+ }
106
+ }
107
+
108
+ return totals
109
+ }
110
+
19
111
  export const postClaim: RouteDefinition = {
20
112
  method: 'post',
21
113
  path: '/rewards/claim/:address',
22
114
  handlers: validateRequest(async (req, res) => {
115
+ const { config } = req.app
116
+ const { mnemonic, chainRpcApiUrl } = config.rewardRedemptionApi
23
117
  const { address } = req.params
24
- // TODO: Validate ETH address
25
- // TODO: Redeem claim for existing rewards
26
- // TODO: Return response payload
27
- await Promise.resolve()
28
- const observation = { schema: 'network.xyo.test' }
29
- res.json(observation)
118
+ const stakerAddress = asAddress(address)
119
+ if (!stakerAddress) {
120
+ res.status(400)
121
+ return
122
+ }
123
+ const account = await (isDefined(mnemonic) ? HDWallet.fromPhrase(mnemonic) : HDWallet.random())
124
+ // TODO: Prevent redeeming if existing redemption already in progress
125
+ const transport = new HttpRpcTransport(chainRpcApiUrl, XyoViewerRpcSchemas)
126
+ const viewer = new JsonRpcXyoViewer(transport)
127
+ const stakes = await getStakesForStaker(viewer, stakerAddress)
128
+ // If they have stakes
129
+ if (stakes.length > 0) {
130
+ // Get rewards for those stakes
131
+ const currentBlock = await viewer.currentBlockNumber()
132
+ const rewards = await getRewardsForStake(viewer, stakes, 0, currentBlock)
133
+ // If there are rewards
134
+ if (Object.keys(rewards).length > 0) {
135
+ const totalRewards = sumNetworkStakeStepRewards(rewards)
136
+ const totalTransfers: Transfer[] = []
137
+ for (const [stepIdentityString, accrued] of Object.entries(totalRewards)) {
138
+ const stepIdentity = asStepIdentity(stepIdentityString)
139
+ if (isUndefined(stepIdentity)) continue
140
+ const stepRewardsAddress = completedStepRewardAddress(stepIdentity)
141
+ const receiveAddress = derivedReceiveAddress(stakerAddress, scope)
142
+ // Validate against already redeemed rewards
143
+ const claimed = await viewer.transferPairBalance([stepRewardsAddress, receiveAddress])
144
+ const unclaimed = accrued - claimed
145
+ if (unclaimed <= 0n) continue
146
+ const transferPayload = createTransferPayload(stepRewardsAddress, { [receiveAddress]: unclaimed })
147
+ // Add appropriate transfer context
148
+ transferPayload.context = { address: stakerAddress, scope }
149
+ totalTransfers.push(transferPayload)
150
+ }
151
+ if (totalTransfers.length > 0) {
152
+ const chainId = await viewer.chainId()
153
+ const tx = await buildTransaction(
154
+ chainId,
155
+ totalTransfers,
156
+ [],
157
+ account,
158
+ currentBlock,
159
+ currentBlock + 1000,
160
+ )
161
+ // Return response payload
162
+ res.json(tx)
163
+ return
164
+ }
165
+ }
166
+ }
167
+
168
+ res.status(204)
30
169
  }),
31
170
  }
@@ -51,8 +51,8 @@ export const getServer = async (context: GetServerContext) => {
51
51
  wallet, logger, config,
52
52
  }
53
53
  const node = context.node ?? await getNode(nodeContext)
54
- const app = getApp(node)
54
+ const app = getApp(node, config)
55
55
  const server = app.listen(port, hostname, () => logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`))
56
- server.setTimeout(20_000)
56
+ server.setTimeout(120_000)
57
57
  return server
58
58
  }