@xyo-network/chain-reward-redemption 1.15.14 → 1.15.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node/index.mjs +144 -36
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/server/routes/rewardRedemption/middleware/requestHandlerValidator.d.ts +2 -2
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.d.ts.map +1 -1
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/{claim.d.ts → claimAddress.d.ts} +1 -1
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/claimAddress.d.ts.map +1 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.d.ts +3 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.d.ts.map +1 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/index.d.ts +2 -1
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/index.d.ts.map +1 -1
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/getAccountFromConfig.d.ts +4 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/getAccountFromConfig.d.ts.map +1 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/getViewerFromConfig.d.ts +4 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/getViewerFromConfig.d.ts.map +1 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/index.d.ts +4 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/index.d.ts.map +1 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/rewardableSteps.d.ts +2 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/rewardableSteps.d.ts.map +1 -0
- package/package.json +8 -8
- package/src/server/routes/rewardRedemption/middleware/requestHandlerValidator.ts +4 -4
- package/src/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.ts +4 -1
- package/src/server/routes/rewardRedemption/routeDefinitions/routes/{claim.ts → claimAddress.ts} +8 -18
- package/src/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.ts +99 -0
- package/src/server/routes/rewardRedemption/routeDefinitions/routes/index.ts +2 -1
- package/src/server/routes/rewardRedemption/routeDefinitions/util/getAccountFromConfig.ts +15 -0
- package/src/server/routes/rewardRedemption/routeDefinitions/util/getViewerFromConfig.ts +14 -0
- package/src/server/routes/rewardRedemption/routeDefinitions/util/index.ts +3 -0
- package/src/server/routes/rewardRedemption/routeDefinitions/util/rewardableSteps.ts +1 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/claim.d.ts.map +0 -1
package/dist/node/index.mjs
CHANGED
|
@@ -111,19 +111,18 @@ var addDataLakeRoutes = /* @__PURE__ */ __name((app) => {
|
|
|
111
111
|
}));
|
|
112
112
|
}, "addDataLakeRoutes");
|
|
113
113
|
|
|
114
|
-
// src/server/routes/rewardRedemption/routeDefinitions/routes/
|
|
114
|
+
// src/server/routes/rewardRedemption/routeDefinitions/routes/claimAddress.ts
|
|
115
115
|
import { asAddress } from "@xylabs/hex";
|
|
116
|
-
import {
|
|
116
|
+
import { isUndefined } from "@xylabs/typeof";
|
|
117
117
|
import { createTransferPayload } from "@xyo-network/chain-protocol";
|
|
118
118
|
import { PayloadZodLoose } from "@xyo-network/payload-model";
|
|
119
|
-
import { HDWallet } from "@xyo-network/wallet";
|
|
120
119
|
import { asStepIdentity } from "@xyo-network/xl1-protocol";
|
|
121
120
|
import { buildTransaction, completedStepRewardAddress, derivedReceiveAddress } from "@xyo-network/xl1-protocol-sdk";
|
|
122
|
-
import {
|
|
121
|
+
import { SignedHydratedTransactionZod } from "@xyo-network/xl1-rpc";
|
|
123
122
|
import { z as z2 } from "zod";
|
|
124
123
|
|
|
125
124
|
// src/server/routes/rewardRedemption/middleware/requestHandlerValidator.ts
|
|
126
|
-
import { isPromise } from "@xylabs/typeof";
|
|
125
|
+
import { isDefined as isDefined2, isPromise } from "@xylabs/typeof";
|
|
127
126
|
import { ReasonPhrases, StatusCodes } from "http-status-codes";
|
|
128
127
|
import { z } from "zod";
|
|
129
128
|
var EmptyParamsZod = z.object({}).catchall(z.string());
|
|
@@ -134,8 +133,8 @@ var EmptyQueryParamsZod = z.object({}).catchall(z.union([
|
|
|
134
133
|
var ValidateRequestDefaults = {
|
|
135
134
|
params: EmptyParamsZod,
|
|
136
135
|
query: EmptyQueryParamsZod,
|
|
137
|
-
body: z.json(),
|
|
138
|
-
response: z.json()
|
|
136
|
+
body: z.json().optional(),
|
|
137
|
+
response: z.json().optional()
|
|
139
138
|
};
|
|
140
139
|
function requestHandlerValidator(schemas) {
|
|
141
140
|
const validators = {
|
|
@@ -156,7 +155,7 @@ function requestHandlerValidator(schemas) {
|
|
|
156
155
|
const validator = validators[key];
|
|
157
156
|
const result2 = validator.safeParse(req[key]);
|
|
158
157
|
if (result2.success) {
|
|
159
|
-
Object.assign(req[key], result2.data);
|
|
158
|
+
if (isDefined2(result2.data)) Object.assign(req[key], result2.data);
|
|
160
159
|
} else {
|
|
161
160
|
errors.push(...result2.error.issues.map((issue) => issue.path.length === 0 ? `${key}: ${issue.message}` : `${key}.${issue.path.join(".")}: ${issue.message}`));
|
|
162
161
|
}
|
|
@@ -198,7 +197,41 @@ __name(requestHandlerValidator, "requestHandlerValidator");
|
|
|
198
197
|
// src/server/routes/rewardRedemption/routeDefinitions/pathParams/AddressPathParam.ts
|
|
199
198
|
import { EthAddressFromStringZod } from "@xylabs/hex";
|
|
200
199
|
|
|
201
|
-
// src/server/routes/rewardRedemption/routeDefinitions/
|
|
200
|
+
// src/server/routes/rewardRedemption/routeDefinitions/util/getAccountFromConfig.ts
|
|
201
|
+
import { assertEx } from "@xylabs/assert";
|
|
202
|
+
import { isDefined as isDefined3 } from "@xylabs/typeof";
|
|
203
|
+
import { HDWallet } from "@xyo-network/wallet";
|
|
204
|
+
var account;
|
|
205
|
+
var getAccountFromConfig = /* @__PURE__ */ __name(async (config) => {
|
|
206
|
+
if (isDefined3(account)) {
|
|
207
|
+
return account;
|
|
208
|
+
}
|
|
209
|
+
account = await HDWallet.fromPhrase(assertEx(config.rewardRedemptionApi.mnemonic, () => "Mnemonic is required for reward redemption"));
|
|
210
|
+
return account;
|
|
211
|
+
}, "getAccountFromConfig");
|
|
212
|
+
|
|
213
|
+
// src/server/routes/rewardRedemption/routeDefinitions/util/getViewerFromConfig.ts
|
|
214
|
+
import { isDefined as isDefined4 } from "@xylabs/typeof";
|
|
215
|
+
import { HttpRpcTransport, JsonRpcXyoViewer, XyoViewerRpcSchemas } from "@xyo-network/xl1-rpc";
|
|
216
|
+
var viewer;
|
|
217
|
+
var getViewerFromConfig = /* @__PURE__ */ __name((config) => {
|
|
218
|
+
if (isDefined4(viewer)) return viewer;
|
|
219
|
+
const transport = new HttpRpcTransport(config.rewardRedemptionApi.chainRpcApiUrl, XyoViewerRpcSchemas);
|
|
220
|
+
viewer = new JsonRpcXyoViewer(transport);
|
|
221
|
+
return viewer;
|
|
222
|
+
}, "getViewerFromConfig");
|
|
223
|
+
|
|
224
|
+
// src/server/routes/rewardRedemption/routeDefinitions/util/rewardableSteps.ts
|
|
225
|
+
var RewardableSteps = [
|
|
226
|
+
3,
|
|
227
|
+
4,
|
|
228
|
+
5,
|
|
229
|
+
6,
|
|
230
|
+
7,
|
|
231
|
+
8
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
// src/server/routes/rewardRedemption/routeDefinitions/routes/claimAddress.ts
|
|
202
235
|
var scope = "reward-escrow";
|
|
203
236
|
var params = z2.object({
|
|
204
237
|
address: EthAddressFromStringZod
|
|
@@ -210,18 +243,18 @@ var validateRequest = requestHandlerValidator({
|
|
|
210
243
|
body,
|
|
211
244
|
response
|
|
212
245
|
});
|
|
213
|
-
var getStakesForStaker = /* @__PURE__ */ __name(async (
|
|
214
|
-
const stakes = await
|
|
246
|
+
var getStakesForStaker = /* @__PURE__ */ __name(async (viewer2, stakerAddress) => {
|
|
247
|
+
const stakes = await viewer2.stakesByStaker(stakerAddress);
|
|
215
248
|
return stakes;
|
|
216
249
|
}, "getStakesForStaker");
|
|
217
|
-
var getRewardsForStake = /* @__PURE__ */ __name(async (
|
|
250
|
+
var getRewardsForStake = /* @__PURE__ */ __name(async (viewer2, stakes, fromBlock = 0, toBlock) => {
|
|
218
251
|
if (isUndefined(toBlock)) {
|
|
219
|
-
toBlock = await
|
|
252
|
+
toBlock = await viewer2.currentBlockNumber();
|
|
220
253
|
}
|
|
221
254
|
const rewards = [];
|
|
222
255
|
for (const stake of stakes) {
|
|
223
256
|
const { id } = stake;
|
|
224
|
-
const reward = await
|
|
257
|
+
const reward = await viewer2.networkStakeStepRewardsForPosition(id, [
|
|
225
258
|
fromBlock,
|
|
226
259
|
toBlock
|
|
227
260
|
]);
|
|
@@ -246,20 +279,18 @@ var postClaim = {
|
|
|
246
279
|
path: "/rewards/claim/:address",
|
|
247
280
|
handlers: validateRequest(async (req, res) => {
|
|
248
281
|
const { config } = req.app;
|
|
249
|
-
const { mnemonic, chainRpcApiUrl } = config.rewardRedemptionApi;
|
|
250
282
|
const { address } = req.params;
|
|
251
283
|
const stakerAddress = asAddress(address);
|
|
252
284
|
if (!stakerAddress) {
|
|
253
285
|
res.status(400);
|
|
254
286
|
return;
|
|
255
287
|
}
|
|
256
|
-
const
|
|
257
|
-
const
|
|
258
|
-
const
|
|
259
|
-
const stakes = await getStakesForStaker(viewer, stakerAddress);
|
|
288
|
+
const account2 = await getAccountFromConfig(config);
|
|
289
|
+
const viewer2 = getViewerFromConfig(config);
|
|
290
|
+
const stakes = await getStakesForStaker(viewer2, stakerAddress);
|
|
260
291
|
if (stakes.length > 0) {
|
|
261
|
-
const currentBlock = await
|
|
262
|
-
const rewards = await getRewardsForStake(
|
|
292
|
+
const currentBlock = await viewer2.currentBlockNumber();
|
|
293
|
+
const rewards = await getRewardsForStake(viewer2, stakes, 0, currentBlock);
|
|
263
294
|
if (Object.keys(rewards).length > 0) {
|
|
264
295
|
const totalRewards = sumNetworkStakeStepRewards(rewards);
|
|
265
296
|
const totalTransfers = [];
|
|
@@ -268,7 +299,7 @@ var postClaim = {
|
|
|
268
299
|
if (isUndefined(stepIdentity)) continue;
|
|
269
300
|
const stepRewardsAddress = completedStepRewardAddress(stepIdentity);
|
|
270
301
|
const receiveAddress = derivedReceiveAddress(stakerAddress, scope);
|
|
271
|
-
const claimed = await
|
|
302
|
+
const claimed = await viewer2.transferPairBalance([
|
|
272
303
|
stepRewardsAddress,
|
|
273
304
|
receiveAddress
|
|
274
305
|
]);
|
|
@@ -284,8 +315,8 @@ var postClaim = {
|
|
|
284
315
|
totalTransfers.push(transferPayload);
|
|
285
316
|
}
|
|
286
317
|
if (totalTransfers.length > 0) {
|
|
287
|
-
const chainId = await
|
|
288
|
-
const tx = await buildTransaction(chainId, totalTransfers, [],
|
|
318
|
+
const chainId = await viewer2.chainId();
|
|
319
|
+
const tx = await buildTransaction(chainId, totalTransfers, [], account2, currentBlock, currentBlock + 1e3);
|
|
289
320
|
res.json(tx);
|
|
290
321
|
return;
|
|
291
322
|
}
|
|
@@ -295,23 +326,99 @@ var postClaim = {
|
|
|
295
326
|
})
|
|
296
327
|
};
|
|
297
328
|
|
|
329
|
+
// src/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.ts
|
|
330
|
+
import { assertEx as assertEx2 } from "@xylabs/assert";
|
|
331
|
+
import { toAddress } from "@xylabs/hex";
|
|
332
|
+
import { isDefined as isDefined5 } from "@xylabs/typeof";
|
|
333
|
+
import { blockRangeSteps, createTransferPayload as createTransferPayload2 } from "@xyo-network/chain-protocol";
|
|
334
|
+
import { asXL1BlockNumber, XYO_STEP_REWARD_ADDRESS } from "@xyo-network/xl1-protocol";
|
|
335
|
+
import { buildTransaction as buildTransaction2, completedStepRewardAddress as completedStepRewardAddress2, derivedReceiveAddress as derivedReceiveAddress2 } from "@xyo-network/xl1-protocol-sdk";
|
|
336
|
+
import { SignedHydratedTransactionZod as SignedHydratedTransactionZod2 } from "@xyo-network/xl1-rpc";
|
|
337
|
+
import { z as z3 } from "zod";
|
|
338
|
+
var scope2 = "reward-escrow";
|
|
339
|
+
var query = z3.object({
|
|
340
|
+
fromBlock: z3.coerce.number().int().optional(),
|
|
341
|
+
toBlock: z3.coerce.number().int().optional()
|
|
342
|
+
});
|
|
343
|
+
var response2 = SignedHydratedTransactionZod2.optional();
|
|
344
|
+
var validateRequest2 = requestHandlerValidator({
|
|
345
|
+
query,
|
|
346
|
+
response: response2
|
|
347
|
+
});
|
|
348
|
+
var calculateAddressDistributions = /* @__PURE__ */ __name((stakers, balance) => {
|
|
349
|
+
const addressClaims = {};
|
|
350
|
+
const totalRewards = Object.values(stakers).reduce((acc, val) => acc + val, 0n);
|
|
351
|
+
for (const [staker, amount] of Object.entries(stakers)) {
|
|
352
|
+
const reward = balance * amount / totalRewards;
|
|
353
|
+
const stakerAddress = toAddress(staker);
|
|
354
|
+
const receiveAddress = derivedReceiveAddress2(stakerAddress, scope2);
|
|
355
|
+
addressClaims[receiveAddress] = reward;
|
|
356
|
+
}
|
|
357
|
+
const totalClaimed = Object.values(addressClaims).reduce((acc, val) => acc + val, 0n);
|
|
358
|
+
assertEx2(totalClaimed <= balance, () => "Total claimed exceeds claimable balance");
|
|
359
|
+
const unclaimed = balance - totalClaimed;
|
|
360
|
+
if (unclaimed > 0n) {
|
|
361
|
+
addressClaims[XYO_STEP_REWARD_ADDRESS] = unclaimed;
|
|
362
|
+
}
|
|
363
|
+
return addressClaims;
|
|
364
|
+
}, "calculateAddressDistributions");
|
|
365
|
+
var createRewardDistributionTransaction = /* @__PURE__ */ __name(async (stepRewardsAddress, addressDistributions, viewer2, config) => {
|
|
366
|
+
const transferPayload = createTransferPayload2(stepRewardsAddress, addressDistributions);
|
|
367
|
+
const chainId = await viewer2.chainId();
|
|
368
|
+
const account2 = await getAccountFromConfig(config);
|
|
369
|
+
const currentBlock = await viewer2.currentBlockNumber();
|
|
370
|
+
const tx = await buildTransaction2(chainId, [
|
|
371
|
+
transferPayload
|
|
372
|
+
], [], account2, currentBlock, currentBlock + 1e3);
|
|
373
|
+
return tx;
|
|
374
|
+
}, "createRewardDistributionTransaction");
|
|
375
|
+
var postClaimRange = {
|
|
376
|
+
method: "post",
|
|
377
|
+
path: "/rewards/claimRange",
|
|
378
|
+
handlers: validateRequest2(async (req, res) => {
|
|
379
|
+
const { config } = req.app;
|
|
380
|
+
const { fromBlock, toBlock } = req.query;
|
|
381
|
+
const viewer2 = getViewerFromConfig(config);
|
|
382
|
+
const from = isDefined5(fromBlock) ? Number(fromBlock) : 0;
|
|
383
|
+
const to = isDefined5(toBlock) ? Number(toBlock) : await viewer2.currentBlockNumber();
|
|
384
|
+
const range = [
|
|
385
|
+
asXL1BlockNumber(from),
|
|
386
|
+
asXL1BlockNumber(to)
|
|
387
|
+
];
|
|
388
|
+
const stepIdentities = blockRangeSteps(range, RewardableSteps);
|
|
389
|
+
for (const stepIdentity of stepIdentities) {
|
|
390
|
+
const stepRewardsAddress = completedStepRewardAddress2(stepIdentity);
|
|
391
|
+
const balance = await viewer2.accountBalance(stepRewardsAddress);
|
|
392
|
+
if (balance > 0n) {
|
|
393
|
+
const stakers = await viewer2.networkStakeStepRewardPoolRewards(stepIdentity);
|
|
394
|
+
const addressDistributions = calculateAddressDistributions(stakers, balance);
|
|
395
|
+
const tx = await createRewardDistributionTransaction(stepRewardsAddress, addressDistributions, viewer2, config);
|
|
396
|
+
res.status(200);
|
|
397
|
+
res.json(tx);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
res.status(204);
|
|
401
|
+
res.json();
|
|
402
|
+
})
|
|
403
|
+
};
|
|
404
|
+
|
|
298
405
|
// src/server/routes/rewardRedemption/routeDefinitions/routes/redeem.ts
|
|
299
406
|
import { PayloadZodLoose as PayloadZodLoose2 } from "@xyo-network/payload-model";
|
|
300
|
-
import { z as
|
|
301
|
-
var params2 =
|
|
407
|
+
import { z as z4 } from "zod";
|
|
408
|
+
var params2 = z4.object({
|
|
302
409
|
address: EthAddressFromStringZod
|
|
303
410
|
});
|
|
304
411
|
var body2 = PayloadZodLoose2;
|
|
305
|
-
var
|
|
306
|
-
var
|
|
412
|
+
var response3 = PayloadZodLoose2;
|
|
413
|
+
var validateRequest3 = requestHandlerValidator({
|
|
307
414
|
params: params2,
|
|
308
415
|
body: body2,
|
|
309
|
-
response:
|
|
416
|
+
response: response3
|
|
310
417
|
});
|
|
311
418
|
var postRedeem = {
|
|
312
419
|
method: "post",
|
|
313
420
|
path: "/rewards/redeem/:address",
|
|
314
|
-
handlers:
|
|
421
|
+
handlers: validateRequest3(async (req, res) => {
|
|
315
422
|
const { body: body3 } = req;
|
|
316
423
|
await Promise.resolve();
|
|
317
424
|
const bridgeObservation = {
|
|
@@ -324,6 +431,7 @@ var postRedeem = {
|
|
|
324
431
|
// src/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.ts
|
|
325
432
|
var getRouteDefinitions = /* @__PURE__ */ __name(() => {
|
|
326
433
|
return [
|
|
434
|
+
postClaimRange,
|
|
327
435
|
postClaim,
|
|
328
436
|
postRedeem
|
|
329
437
|
];
|
|
@@ -366,13 +474,13 @@ var getApp = /* @__PURE__ */ __name((node, config) => {
|
|
|
366
474
|
}, "getApp");
|
|
367
475
|
|
|
368
476
|
// src/server/server.ts
|
|
369
|
-
import { assertEx } from "@xylabs/assert";
|
|
370
|
-
import { isDefined as
|
|
477
|
+
import { assertEx as assertEx3 } from "@xylabs/assert";
|
|
478
|
+
import { isDefined as isDefined7, isString } from "@xylabs/typeof";
|
|
371
479
|
import { boot } from "@xyo-network/bios";
|
|
372
480
|
import { HDWallet as HDWallet2 } from "@xyo-network/wallet";
|
|
373
481
|
|
|
374
482
|
// src/manifest/getLocator.ts
|
|
375
|
-
import { isDefined as
|
|
483
|
+
import { isDefined as isDefined6 } from "@xylabs/typeof";
|
|
376
484
|
import { MemoryArchivist } from "@xyo-network/archivist-memory";
|
|
377
485
|
import { MongoDBArchivistV2 } from "@xyo-network/archivist-mongodb";
|
|
378
486
|
import { ViewArchivist } from "@xyo-network/archivist-view";
|
|
@@ -396,7 +504,7 @@ var getLocator = /* @__PURE__ */ __name(async (context) => {
|
|
|
396
504
|
port: 9465
|
|
397
505
|
}
|
|
398
506
|
});
|
|
399
|
-
if (
|
|
507
|
+
if (isDefined6(logger)) AbstractModule.defaultLogger = logger;
|
|
400
508
|
const statusReporter = logger ? new LoggerModuleStatusReporter(logger) : void 0;
|
|
401
509
|
const locator = new ModuleFactoryLocator();
|
|
402
510
|
const mongoConfig = config.storage?.mongo;
|
|
@@ -536,13 +644,13 @@ var getSeedPhrase = /* @__PURE__ */ __name(async (bios, config, logger) => {
|
|
|
536
644
|
}
|
|
537
645
|
await bios.seedPhraseStore.set("os", seedPhrase);
|
|
538
646
|
}
|
|
539
|
-
return
|
|
647
|
+
return assertEx3(await bios.seedPhraseStore.get("os"), () => "Unable to acquire mnemonic from bios");
|
|
540
648
|
}, "getSeedPhrase");
|
|
541
649
|
var getServer = /* @__PURE__ */ __name(async (context) => {
|
|
542
650
|
const { logger, config } = context;
|
|
543
651
|
const { port, mnemonic } = config.rewardRedemptionApi;
|
|
544
652
|
const bios = await boot();
|
|
545
|
-
const seedPhrase =
|
|
653
|
+
const seedPhrase = isDefined7(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger);
|
|
546
654
|
const wallet = await HDWallet2.fromPhrase(seedPhrase);
|
|
547
655
|
const nodeContext = {
|
|
548
656
|
wallet,
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -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 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 { asStepIdentity, 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\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","asStepIdentity","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","getStakesForStaker","viewer","stakerAddress","stakes","stakesByStaker","getRewardsForStake","fromBlock","toBlock","isUndefined","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","stepIdentityString","accrued","stepIdentity","asStepIdentity","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
|
+
{"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/claimAddress.ts","../../src/server/routes/rewardRedemption/middleware/requestHandlerValidator.ts","../../src/server/routes/rewardRedemption/routeDefinitions/pathParams/AddressPathParam.ts","../../src/server/routes/rewardRedemption/routeDefinitions/util/getAccountFromConfig.ts","../../src/server/routes/rewardRedemption/routeDefinitions/util/getViewerFromConfig.ts","../../src/server/routes/rewardRedemption/routeDefinitions/util/rewardableSteps.ts","../../src/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.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","import type { Address } from '@xylabs/hex'\nimport { asAddress } from '@xylabs/hex'\nimport { isUndefined } from '@xylabs/typeof'\nimport { createTransferPayload } from '@xyo-network/chain-protocol'\nimport { PayloadZodLoose } from '@xyo-network/payload-model'\nimport {\n asStepIdentity, type Stake, type StepIdentityString, type Transfer,\n} from '@xyo-network/xl1-protocol'\nimport {\n buildTransaction, completedStepRewardAddress, derivedReceiveAddress,\n} from '@xyo-network/xl1-protocol-sdk'\nimport type { JsonRpcXyoViewer } from '@xyo-network/xl1-rpc'\nimport { SignedHydratedTransactionZod } 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'\nimport { getAccountFromConfig, getViewerFromConfig } from '../util/index.ts'\n\nconst scope = 'reward-escrow'\n\nconst params = z.object({ address: AddressPathParam })\nconst body = PayloadZodLoose\nconst response = SignedHydratedTransactionZod\n\nconst validateRequest = requestHandlerValidator({\n params,\n body,\n response,\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 { address } = req.params\n const stakerAddress = asAddress(address)\n if (!stakerAddress) {\n res.status(400)\n return\n }\n const account = await getAccountFromConfig(config)\n // TODO: Prevent redeeming if existing redemption already in progress\n const viewer = getViewerFromConfig(config)\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 { isDefined, 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().optional(),\n response: z.json().optional(),\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 if (isDefined(result.data)) 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 { assertEx } from '@xylabs/assert'\nimport { isDefined } from '@xylabs/typeof'\nimport type { AccountInstance } from '@xyo-network/account-model'\nimport { HDWallet } from '@xyo-network/wallet'\nimport type { Config } from '@xyo-network/xl1-protocol-sdk'\n\nlet account: AccountInstance | undefined\n\nexport const getAccountFromConfig = async (config: Config): Promise<AccountInstance> => {\n if (isDefined(account)) {\n return account\n }\n account = await HDWallet.fromPhrase(assertEx(config.rewardRedemptionApi.mnemonic, () => 'Mnemonic is required for reward redemption'))\n return account\n}\n","import { isDefined } from '@xylabs/typeof'\nimport type { Config } from '@xyo-network/xl1-protocol-sdk'\nimport {\n HttpRpcTransport, JsonRpcXyoViewer, XyoViewerRpcSchemas,\n} from '@xyo-network/xl1-rpc'\n\nlet viewer: JsonRpcXyoViewer | undefined\n\nexport const getViewerFromConfig = (config: Config): JsonRpcXyoViewer => {\n if (isDefined(viewer)) return viewer\n const transport = new HttpRpcTransport(config.rewardRedemptionApi.chainRpcApiUrl, XyoViewerRpcSchemas)\n viewer = new JsonRpcXyoViewer(transport)\n return viewer\n}\n","export const RewardableSteps = [3, 4, 5, 6, 7, 8]\n","import { assertEx } from '@xylabs/assert'\nimport { type Address, toAddress } from '@xylabs/hex'\nimport { isDefined } from '@xylabs/typeof'\nimport { blockRangeSteps, createTransferPayload } from '@xyo-network/chain-protocol'\nimport type {\n AttoXL1, SignedHydratedTransactionWithStorageMeta, XL1BlockRange, XyoViewer,\n} from '@xyo-network/xl1-protocol'\nimport { asXL1BlockNumber, XYO_STEP_REWARD_ADDRESS } from '@xyo-network/xl1-protocol'\nimport type { Config } from '@xyo-network/xl1-protocol-sdk'\nimport {\n buildTransaction, completedStepRewardAddress, derivedReceiveAddress,\n} from '@xyo-network/xl1-protocol-sdk'\nimport { SignedHydratedTransactionZod } from '@xyo-network/xl1-rpc'\nimport { z } from 'zod'\n\nimport { requestHandlerValidator } from '../../middleware/index.ts'\nimport type { RouteDefinition } from '../routeDefinition.ts'\nimport {\n getAccountFromConfig, getViewerFromConfig, RewardableSteps,\n} from '../util/index.ts'\n\nconst scope = 'reward-escrow'\n\nconst query = z.object({\n fromBlock: z.coerce.number().int().optional(),\n toBlock: z.coerce.number().int().optional(),\n})\nconst response = SignedHydratedTransactionZod.optional()\n\nconst validateRequest = requestHandlerValidator({ query, response })\n\nconst calculateAddressDistributions = (stakers: Record<Address, bigint>, balance: AttoXL1): Record<Address, bigint> => {\n const addressClaims: Record<Address, bigint> = {}\n // TODO: Get from viewer instead of calculating\n const totalRewards = Object.values(stakers).reduce((acc, val) => acc + val, 0n)\n for (const [staker, amount] of Object.entries(stakers)) {\n const reward = (balance * amount) / totalRewards\n // Accumulate rewards by address\n const stakerAddress = toAddress(staker)\n const receiveAddress = derivedReceiveAddress(stakerAddress, scope)\n addressClaims[receiveAddress] = reward\n }\n const totalClaimed = Object.values(addressClaims).reduce((acc, val) => acc + val, 0n)\n assertEx(totalClaimed <= balance, () => 'Total claimed exceeds claimable balance')\n const unclaimed = balance - totalClaimed\n if (unclaimed > 0n) {\n // Return anything unclaimed (due to truncation/rounding) to step rewards pool address\n addressClaims[XYO_STEP_REWARD_ADDRESS] = unclaimed\n }\n return addressClaims\n}\n\nconst createRewardDistributionTransaction = async (\n stepRewardsAddress: Address,\n addressDistributions: Record<Address, bigint>,\n viewer: XyoViewer,\n config: Config,\n): Promise<SignedHydratedTransactionWithStorageMeta> => {\n // Create single transfer payload for all claims\n const transferPayload = createTransferPayload(stepRewardsAddress, addressDistributions)\n const chainId = await viewer.chainId()\n const account = await getAccountFromConfig(config)\n const currentBlock = await viewer.currentBlockNumber()\n const tx = await buildTransaction(chainId, [transferPayload], [], account, currentBlock, currentBlock + 1000)\n return tx\n}\n\nexport const postClaimRange: RouteDefinition = {\n method: 'post',\n path: '/rewards/claimRange',\n handlers: validateRequest(async (req, res) => {\n const { config } = req.app\n const { fromBlock, toBlock } = req.query\n const viewer = getViewerFromConfig(config)\n const from = isDefined(fromBlock) ? Number(fromBlock) : 0\n const to = isDefined(toBlock) ? Number(toBlock) : await viewer.currentBlockNumber()\n const range: XL1BlockRange = [asXL1BlockNumber(from), asXL1BlockNumber(to)]\n // For each rewardable step in range\n const stepIdentities = blockRangeSteps(range, RewardableSteps)\n for (const stepIdentity of stepIdentities) {\n // If wallet has balance\n const stepRewardsAddress = completedStepRewardAddress(stepIdentity)\n const balance = await viewer.accountBalance(stepRewardsAddress)\n if (balance > 0n) {\n // For stakers\n // TODO: Right way to get stakers and shares\n const stakers = await viewer.networkStakeStepRewardPoolRewards(stepIdentity)\n // const shares = await viewer.networkStakeStepRewardPoolShares(stepIdentity)\n const addressDistributions = calculateAddressDistributions(stakers, balance)\n // Create single transaction for all claims\n const tx = await createRewardDistributionTransaction(stepRewardsAddress, addressDistributions, viewer, config)\n res.status(200)\n res.json(tx)\n }\n }\n res.status(204)\n res.json()\n }),\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\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 {\n postClaim, postClaimRange, postRedeem,\n} from './routes/index.ts'\n\nexport const getRouteDefinitions = (): RouteDefinition[] => {\n return [\n postClaimRange,\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","isUndefined","createTransferPayload","PayloadZodLoose","asStepIdentity","buildTransaction","completedStepRewardAddress","derivedReceiveAddress","SignedHydratedTransactionZod","z","isDefined","isPromise","ReasonPhrases","StatusCodes","z","EmptyParamsZod","z","object","catchall","string","EmptyQueryParamsZod","union","array","ValidateRequestDefaults","params","query","body","json","optional","response","requestHandlerValidator","schemas","validators","handler","req","res","next","originalJson","bind","errors","keys","key","validator","result","safeParse","success","isDefined","data","Object","assign","push","error","issues","map","issue","path","length","message","join","err","Error","name","ReasonPhrases","BAD_REQUEST","statusCode","StatusCodes","INTERNAL_SERVER_ERROR","isPromise","AddressPathParam","assertEx","isDefined","HDWallet","account","getAccountFromConfig","config","isDefined","HDWallet","fromPhrase","assertEx","rewardRedemptionApi","mnemonic","isDefined","HttpRpcTransport","JsonRpcXyoViewer","XyoViewerRpcSchemas","viewer","getViewerFromConfig","config","isDefined","transport","HttpRpcTransport","rewardRedemptionApi","chainRpcApiUrl","XyoViewerRpcSchemas","JsonRpcXyoViewer","RewardableSteps","scope","params","z","object","address","AddressPathParam","body","PayloadZodLoose","response","SignedHydratedTransactionZod","validateRequest","requestHandlerValidator","getStakesForStaker","viewer","stakerAddress","stakes","stakesByStaker","getRewardsForStake","fromBlock","toBlock","isUndefined","currentBlockNumber","rewards","stake","id","reward","networkStakeStepRewardsForPosition","push","sumNetworkStakeStepRewards","records","totals","record","key","first","Object","entries","postClaim","method","path","handlers","req","res","config","app","asAddress","status","account","getAccountFromConfig","getViewerFromConfig","length","currentBlock","keys","totalRewards","totalTransfers","stepIdentityString","accrued","stepIdentity","asStepIdentity","stepRewardsAddress","completedStepRewardAddress","receiveAddress","derivedReceiveAddress","claimed","transferPairBalance","unclaimed","transferPayload","createTransferPayload","context","chainId","tx","buildTransaction","json","assertEx","toAddress","isDefined","blockRangeSteps","createTransferPayload","asXL1BlockNumber","XYO_STEP_REWARD_ADDRESS","buildTransaction","completedStepRewardAddress","derivedReceiveAddress","SignedHydratedTransactionZod","z","scope","query","z","object","fromBlock","coerce","number","int","optional","toBlock","response","SignedHydratedTransactionZod","validateRequest","requestHandlerValidator","calculateAddressDistributions","stakers","balance","addressClaims","totalRewards","Object","values","reduce","acc","val","staker","amount","entries","reward","stakerAddress","toAddress","receiveAddress","derivedReceiveAddress","totalClaimed","assertEx","unclaimed","XYO_STEP_REWARD_ADDRESS","createRewardDistributionTransaction","stepRewardsAddress","addressDistributions","viewer","config","transferPayload","createTransferPayload","chainId","account","getAccountFromConfig","currentBlock","currentBlockNumber","tx","buildTransaction","postClaimRange","method","path","handlers","req","res","app","getViewerFromConfig","from","isDefined","Number","to","range","asXL1BlockNumber","stepIdentities","blockRangeSteps","RewardableSteps","stepIdentity","completedStepRewardAddress","accountBalance","networkStakeStepRewardPoolRewards","status","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","postClaimRange","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"]}
|
|
@@ -15,8 +15,8 @@ export declare const EmptyQueryParamsZod: z.ZodObject<{}, z.core.$catchall<z.Zod
|
|
|
15
15
|
export declare const ValidateRequestDefaults: {
|
|
16
16
|
params: z.ZodObject<{}, z.core.$catchall<z.ZodString>>;
|
|
17
17
|
query: z.ZodObject<{}, z.core.$catchall<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
|
|
18
|
-
body: z.ZodJSONSchema
|
|
19
|
-
response: z.ZodJSONSchema
|
|
18
|
+
body: z.ZodOptional<z.ZodJSONSchema>;
|
|
19
|
+
response: z.ZodOptional<z.ZodJSONSchema>;
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
22
|
* Factory for Express middleware that validates request and response objects using Zod schemas.
|
package/dist/node/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRouteDefinitions.d.ts","sourceRoot":"","sources":["../../../../../../src/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"getRouteDefinitions.d.ts","sourceRoot":"","sources":["../../../../../../src/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAK3D,eAAO,MAAM,mBAAmB,QAAO,eAAe,EAMrD,CAAA"}
|
package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/claimAddress.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claimAddress.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/routes/claimAddress.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AA0D5D,eAAO,MAAM,SAAS,EAAE,eAyDvB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claimRange.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAmD5D,eAAO,MAAM,cAAc,EAAE,eA+B5B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/routes/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/routes/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA"}
|
package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/getAccountFromConfig.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAccountFromConfig.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/util/getAccountFromConfig.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAEjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAI3D,eAAO,MAAM,oBAAoB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,eAAe,CAMlF,CAAA"}
|
package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/getViewerFromConfig.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getViewerFromConfig.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/util/getViewerFromConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EACa,gBAAgB,EACnC,MAAM,sBAAsB,CAAA;AAI7B,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,KAAG,gBAKpD,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/util/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA;AACzC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA"}
|
package/dist/node/server/routes/rewardRedemption/routeDefinitions/util/rewardableSteps.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewardableSteps.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/rewardRedemption/routeDefinitions/util/rewardableSteps.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,UAAqB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xyo-network/chain-reward-redemption",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.16",
|
|
4
4
|
"description": "XYO Layer One Rewards",
|
|
5
5
|
"homepage": "https://xylabs.com",
|
|
6
6
|
"bugs": {
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"@xyo-network/archivist-view": "~5.1.7",
|
|
63
63
|
"@xyo-network/bios": "~7.1.1",
|
|
64
64
|
"@xyo-network/boundwitness-model": "~5.1.7",
|
|
65
|
-
"@xyo-network/chain-modules": "~1.15.
|
|
66
|
-
"@xyo-network/chain-protocol": "~1.15.
|
|
67
|
-
"@xyo-network/chain-telemetry": "~1.15.
|
|
65
|
+
"@xyo-network/chain-modules": "~1.15.16",
|
|
66
|
+
"@xyo-network/chain-protocol": "~1.15.16",
|
|
67
|
+
"@xyo-network/chain-telemetry": "~1.15.16",
|
|
68
68
|
"@xyo-network/manifest-model": "~5.1.7",
|
|
69
69
|
"@xyo-network/manifest-wrapper": "~5.1.7",
|
|
70
70
|
"@xyo-network/module-abstract": "~5.1.7",
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"@xyo-network/wallet": "~5.1.7",
|
|
79
79
|
"@xyo-network/wallet-model": "~5.1.7",
|
|
80
80
|
"@xyo-network/xl1-protocol": "~1.12.84",
|
|
81
|
-
"@xyo-network/xl1-protocol-sdk": "~1.15.
|
|
82
|
-
"@xyo-network/xl1-rpc": "~1.15.
|
|
81
|
+
"@xyo-network/xl1-protocol-sdk": "~1.15.16",
|
|
82
|
+
"@xyo-network/xl1-rpc": "~1.15.16",
|
|
83
83
|
"compression": "~1.8.1",
|
|
84
84
|
"cors": "~2.8.5",
|
|
85
85
|
"express": "~5.1.0",
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
"@xyo-network/archivist-mongodb": "~5.1.7",
|
|
108
108
|
"@xyo-network/bios-model": "~7.1.1",
|
|
109
109
|
"@xyo-network/boundwitness-builder": "~5.1.7",
|
|
110
|
-
"@xyo-network/chain-protocol": "~1.15.
|
|
111
|
-
"@xyo-network/chain-services": "~1.15.
|
|
110
|
+
"@xyo-network/chain-protocol": "~1.15.16",
|
|
111
|
+
"@xyo-network/chain-services": "~1.15.16",
|
|
112
112
|
"@xyo-network/manifest-wrapper": "~5.1.7",
|
|
113
113
|
"@xyo-network/module-abstract": "~5.1.7",
|
|
114
114
|
"@xyo-network/module-abstract-mongodb": "~5.1.7",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import type { ExpressError } from '@xylabs/express'
|
|
3
|
-
import { isPromise } from '@xylabs/typeof'
|
|
3
|
+
import { isDefined, isPromise } from '@xylabs/typeof'
|
|
4
4
|
import type {
|
|
5
5
|
NextFunction, Request, RequestHandler, Response,
|
|
6
6
|
} from 'express'
|
|
@@ -24,8 +24,8 @@ export const EmptyQueryParamsZod = z.object({}).catchall(z.union([z.string(), z.
|
|
|
24
24
|
export const ValidateRequestDefaults = {
|
|
25
25
|
params: EmptyParamsZod,
|
|
26
26
|
query: EmptyQueryParamsZod,
|
|
27
|
-
body: z.json(),
|
|
28
|
-
response: z.json(),
|
|
27
|
+
body: z.json().optional(),
|
|
28
|
+
response: z.json().optional(),
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
type ValidatableRequestKey = 'params' | 'query' | 'body'
|
|
@@ -63,7 +63,7 @@ export function requestHandlerValidator<
|
|
|
63
63
|
const validator = validators[key]
|
|
64
64
|
const result = validator.safeParse(req[key])
|
|
65
65
|
if (result.success) {
|
|
66
|
-
Object.assign(req[key], result.data)
|
|
66
|
+
if (isDefined(result.data)) Object.assign(req[key], result.data)
|
|
67
67
|
} else {
|
|
68
68
|
errors.push(
|
|
69
69
|
...result.error.issues.map(
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { RouteDefinition } from './routeDefinition.ts'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
postClaim, postClaimRange, postRedeem,
|
|
4
|
+
} from './routes/index.ts'
|
|
3
5
|
|
|
4
6
|
export const getRouteDefinitions = (): RouteDefinition[] => {
|
|
5
7
|
return [
|
|
8
|
+
postClaimRange,
|
|
6
9
|
postClaim,
|
|
7
10
|
postRedeem,
|
|
8
11
|
]
|
package/src/server/routes/rewardRedemption/routeDefinitions/routes/{claim.ts → claimAddress.ts}
RENAMED
|
@@ -1,35 +1,27 @@
|
|
|
1
|
-
/* eslint-disable max-statements */
|
|
2
1
|
import type { Address } from '@xylabs/hex'
|
|
3
2
|
import { asAddress } from '@xylabs/hex'
|
|
4
|
-
import {
|
|
3
|
+
import { isUndefined } from '@xylabs/typeof'
|
|
5
4
|
import { createTransferPayload } from '@xyo-network/chain-protocol'
|
|
6
5
|
import { PayloadZodLoose } from '@xyo-network/payload-model'
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
Stake,
|
|
10
|
-
StepIdentity, StepIdentityString, Transfer,
|
|
6
|
+
import {
|
|
7
|
+
asStepIdentity, type Stake, type StepIdentityString, type Transfer,
|
|
11
8
|
} from '@xyo-network/xl1-protocol'
|
|
12
|
-
import { asStepIdentity, asXL1BlockNumber } from '@xyo-network/xl1-protocol'
|
|
13
9
|
import {
|
|
14
10
|
buildTransaction, completedStepRewardAddress, derivedReceiveAddress,
|
|
15
11
|
} from '@xyo-network/xl1-protocol-sdk'
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
XyoViewerRpcSchemas,
|
|
19
|
-
} from '@xyo-network/xl1-rpc'
|
|
12
|
+
import type { JsonRpcXyoViewer } from '@xyo-network/xl1-rpc'
|
|
13
|
+
import { SignedHydratedTransactionZod } from '@xyo-network/xl1-rpc'
|
|
20
14
|
import { z } from 'zod'
|
|
21
15
|
|
|
22
16
|
import { requestHandlerValidator } from '../../middleware/index.ts'
|
|
23
17
|
import { AddressPathParam } from '../pathParams/index.ts'
|
|
24
18
|
import type { RouteDefinition } from '../routeDefinition.ts'
|
|
19
|
+
import { getAccountFromConfig, getViewerFromConfig } from '../util/index.ts'
|
|
25
20
|
|
|
26
21
|
const scope = 'reward-escrow'
|
|
27
22
|
|
|
28
23
|
const params = z.object({ address: AddressPathParam })
|
|
29
24
|
const body = PayloadZodLoose
|
|
30
|
-
|
|
31
|
-
// const response = z.array(TransferZod)
|
|
32
|
-
// TODO: Transaction BW?
|
|
33
25
|
const response = SignedHydratedTransactionZod
|
|
34
26
|
|
|
35
27
|
const validateRequest = requestHandlerValidator({
|
|
@@ -86,17 +78,15 @@ export const postClaim: RouteDefinition = {
|
|
|
86
78
|
path: '/rewards/claim/:address',
|
|
87
79
|
handlers: validateRequest(async (req, res) => {
|
|
88
80
|
const { config } = req.app
|
|
89
|
-
const { mnemonic, chainRpcApiUrl } = config.rewardRedemptionApi
|
|
90
81
|
const { address } = req.params
|
|
91
82
|
const stakerAddress = asAddress(address)
|
|
92
83
|
if (!stakerAddress) {
|
|
93
84
|
res.status(400)
|
|
94
85
|
return
|
|
95
86
|
}
|
|
96
|
-
const account = await (
|
|
87
|
+
const account = await getAccountFromConfig(config)
|
|
97
88
|
// TODO: Prevent redeeming if existing redemption already in progress
|
|
98
|
-
const
|
|
99
|
-
const viewer = new JsonRpcXyoViewer(transport)
|
|
89
|
+
const viewer = getViewerFromConfig(config)
|
|
100
90
|
const stakes = await getStakesForStaker(viewer, stakerAddress)
|
|
101
91
|
// If they have stakes
|
|
102
92
|
if (stakes.length > 0) {
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { type Address, toAddress } from '@xylabs/hex'
|
|
3
|
+
import { isDefined } from '@xylabs/typeof'
|
|
4
|
+
import { blockRangeSteps, createTransferPayload } from '@xyo-network/chain-protocol'
|
|
5
|
+
import type {
|
|
6
|
+
AttoXL1, SignedHydratedTransactionWithStorageMeta, XL1BlockRange, XyoViewer,
|
|
7
|
+
} from '@xyo-network/xl1-protocol'
|
|
8
|
+
import { asXL1BlockNumber, XYO_STEP_REWARD_ADDRESS } from '@xyo-network/xl1-protocol'
|
|
9
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
10
|
+
import {
|
|
11
|
+
buildTransaction, completedStepRewardAddress, derivedReceiveAddress,
|
|
12
|
+
} from '@xyo-network/xl1-protocol-sdk'
|
|
13
|
+
import { SignedHydratedTransactionZod } from '@xyo-network/xl1-rpc'
|
|
14
|
+
import { z } from 'zod'
|
|
15
|
+
|
|
16
|
+
import { requestHandlerValidator } from '../../middleware/index.ts'
|
|
17
|
+
import type { RouteDefinition } from '../routeDefinition.ts'
|
|
18
|
+
import {
|
|
19
|
+
getAccountFromConfig, getViewerFromConfig, RewardableSteps,
|
|
20
|
+
} from '../util/index.ts'
|
|
21
|
+
|
|
22
|
+
const scope = 'reward-escrow'
|
|
23
|
+
|
|
24
|
+
const query = z.object({
|
|
25
|
+
fromBlock: z.coerce.number().int().optional(),
|
|
26
|
+
toBlock: z.coerce.number().int().optional(),
|
|
27
|
+
})
|
|
28
|
+
const response = SignedHydratedTransactionZod.optional()
|
|
29
|
+
|
|
30
|
+
const validateRequest = requestHandlerValidator({ query, response })
|
|
31
|
+
|
|
32
|
+
const calculateAddressDistributions = (stakers: Record<Address, bigint>, balance: AttoXL1): Record<Address, bigint> => {
|
|
33
|
+
const addressClaims: Record<Address, bigint> = {}
|
|
34
|
+
// TODO: Get from viewer instead of calculating
|
|
35
|
+
const totalRewards = Object.values(stakers).reduce((acc, val) => acc + val, 0n)
|
|
36
|
+
for (const [staker, amount] of Object.entries(stakers)) {
|
|
37
|
+
const reward = (balance * amount) / totalRewards
|
|
38
|
+
// Accumulate rewards by address
|
|
39
|
+
const stakerAddress = toAddress(staker)
|
|
40
|
+
const receiveAddress = derivedReceiveAddress(stakerAddress, scope)
|
|
41
|
+
addressClaims[receiveAddress] = reward
|
|
42
|
+
}
|
|
43
|
+
const totalClaimed = Object.values(addressClaims).reduce((acc, val) => acc + val, 0n)
|
|
44
|
+
assertEx(totalClaimed <= balance, () => 'Total claimed exceeds claimable balance')
|
|
45
|
+
const unclaimed = balance - totalClaimed
|
|
46
|
+
if (unclaimed > 0n) {
|
|
47
|
+
// Return anything unclaimed (due to truncation/rounding) to step rewards pool address
|
|
48
|
+
addressClaims[XYO_STEP_REWARD_ADDRESS] = unclaimed
|
|
49
|
+
}
|
|
50
|
+
return addressClaims
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const createRewardDistributionTransaction = async (
|
|
54
|
+
stepRewardsAddress: Address,
|
|
55
|
+
addressDistributions: Record<Address, bigint>,
|
|
56
|
+
viewer: XyoViewer,
|
|
57
|
+
config: Config,
|
|
58
|
+
): Promise<SignedHydratedTransactionWithStorageMeta> => {
|
|
59
|
+
// Create single transfer payload for all claims
|
|
60
|
+
const transferPayload = createTransferPayload(stepRewardsAddress, addressDistributions)
|
|
61
|
+
const chainId = await viewer.chainId()
|
|
62
|
+
const account = await getAccountFromConfig(config)
|
|
63
|
+
const currentBlock = await viewer.currentBlockNumber()
|
|
64
|
+
const tx = await buildTransaction(chainId, [transferPayload], [], account, currentBlock, currentBlock + 1000)
|
|
65
|
+
return tx
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const postClaimRange: RouteDefinition = {
|
|
69
|
+
method: 'post',
|
|
70
|
+
path: '/rewards/claimRange',
|
|
71
|
+
handlers: validateRequest(async (req, res) => {
|
|
72
|
+
const { config } = req.app
|
|
73
|
+
const { fromBlock, toBlock } = req.query
|
|
74
|
+
const viewer = getViewerFromConfig(config)
|
|
75
|
+
const from = isDefined(fromBlock) ? Number(fromBlock) : 0
|
|
76
|
+
const to = isDefined(toBlock) ? Number(toBlock) : await viewer.currentBlockNumber()
|
|
77
|
+
const range: XL1BlockRange = [asXL1BlockNumber(from), asXL1BlockNumber(to)]
|
|
78
|
+
// For each rewardable step in range
|
|
79
|
+
const stepIdentities = blockRangeSteps(range, RewardableSteps)
|
|
80
|
+
for (const stepIdentity of stepIdentities) {
|
|
81
|
+
// If wallet has balance
|
|
82
|
+
const stepRewardsAddress = completedStepRewardAddress(stepIdentity)
|
|
83
|
+
const balance = await viewer.accountBalance(stepRewardsAddress)
|
|
84
|
+
if (balance > 0n) {
|
|
85
|
+
// For stakers
|
|
86
|
+
// TODO: Right way to get stakers and shares
|
|
87
|
+
const stakers = await viewer.networkStakeStepRewardPoolRewards(stepIdentity)
|
|
88
|
+
// const shares = await viewer.networkStakeStepRewardPoolShares(stepIdentity)
|
|
89
|
+
const addressDistributions = calculateAddressDistributions(stakers, balance)
|
|
90
|
+
// Create single transaction for all claims
|
|
91
|
+
const tx = await createRewardDistributionTransaction(stepRewardsAddress, addressDistributions, viewer, config)
|
|
92
|
+
res.status(200)
|
|
93
|
+
res.json(tx)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
res.status(204)
|
|
97
|
+
res.json()
|
|
98
|
+
}),
|
|
99
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { isDefined } from '@xylabs/typeof'
|
|
3
|
+
import type { AccountInstance } from '@xyo-network/account-model'
|
|
4
|
+
import { HDWallet } from '@xyo-network/wallet'
|
|
5
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
6
|
+
|
|
7
|
+
let account: AccountInstance | undefined
|
|
8
|
+
|
|
9
|
+
export const getAccountFromConfig = async (config: Config): Promise<AccountInstance> => {
|
|
10
|
+
if (isDefined(account)) {
|
|
11
|
+
return account
|
|
12
|
+
}
|
|
13
|
+
account = await HDWallet.fromPhrase(assertEx(config.rewardRedemptionApi.mnemonic, () => 'Mnemonic is required for reward redemption'))
|
|
14
|
+
return account
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isDefined } from '@xylabs/typeof'
|
|
2
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
3
|
+
import {
|
|
4
|
+
HttpRpcTransport, JsonRpcXyoViewer, XyoViewerRpcSchemas,
|
|
5
|
+
} from '@xyo-network/xl1-rpc'
|
|
6
|
+
|
|
7
|
+
let viewer: JsonRpcXyoViewer | undefined
|
|
8
|
+
|
|
9
|
+
export const getViewerFromConfig = (config: Config): JsonRpcXyoViewer => {
|
|
10
|
+
if (isDefined(viewer)) return viewer
|
|
11
|
+
const transport = new HttpRpcTransport(config.rewardRedemptionApi.chainRpcApiUrl, XyoViewerRpcSchemas)
|
|
12
|
+
viewer = new JsonRpcXyoViewer(transport)
|
|
13
|
+
return viewer
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const RewardableSteps = [3, 4, 5, 6, 7, 8]
|
|
@@ -1 +0,0 @@
|
|
|
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;AA4D5D,eAAO,MAAM,SAAS,EAAE,eA2DvB,CAAA"}
|