@xyo-network/chain-reward-redemption 1.15.16 → 1.15.18
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 +300 -211
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/manifest/getLocator.d.ts.map +1 -1
- package/dist/node/modules/ChainRewardsClaimSentinel.d.ts +33 -0
- package/dist/node/modules/ChainRewardsClaimSentinel.d.ts.map +1 -0
- package/dist/node/modules/StepIdentityPayload.d.ts +14 -0
- package/dist/node/modules/StepIdentityPayload.d.ts.map +1 -0
- package/dist/node/modules/index.d.ts +3 -0
- package/dist/node/modules/index.d.ts.map +1 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.d.ts.map +1 -1
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.d.ts.map +1 -1
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/redeem.d.ts +22 -0
- package/dist/node/server/routes/rewardRedemption/routeDefinitions/routes/redeem.d.ts.map +1 -1
- package/package.json +12 -8
- package/src/manifest/getLocator.ts +29 -4
- package/src/manifest/node.json +7 -0
- package/src/modules/ChainRewardsClaimSentinel.ts +171 -0
- package/src/modules/StepIdentityPayload.ts +19 -0
- package/src/modules/index.ts +2 -0
- package/src/server/routes/rewardRedemption/routeDefinitions/getRouteDefinitions.ts +2 -4
- package/src/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.ts +39 -74
- package/src/server/routes/rewardRedemption/routeDefinitions/routes/redeem.ts +99 -9
package/dist/node/index.mjs
CHANGED
|
@@ -48,10 +48,10 @@ var archivistMiddleware = /* @__PURE__ */ __name((options) => {
|
|
|
48
48
|
});
|
|
49
49
|
router.post("/insert", async (req, res) => {
|
|
50
50
|
setRawResponseFormat(res);
|
|
51
|
-
const
|
|
51
|
+
const body2 = Array.isArray(req.body) ? req.body : [
|
|
52
52
|
req.body
|
|
53
53
|
];
|
|
54
|
-
const payloads = (await PayloadBuilder.hashPairs(
|
|
54
|
+
const payloads = (await PayloadBuilder.hashPairs(body2)).map((p) => p[0]);
|
|
55
55
|
const archivist = await getArchivist(node, archivistModuleIdentifier);
|
|
56
56
|
const result = await archivist.insert(payloads);
|
|
57
57
|
res.status(200).json(result);
|
|
@@ -111,16 +111,6 @@ var addDataLakeRoutes = /* @__PURE__ */ __name((app) => {
|
|
|
111
111
|
}));
|
|
112
112
|
}, "addDataLakeRoutes");
|
|
113
113
|
|
|
114
|
-
// src/server/routes/rewardRedemption/routeDefinitions/routes/claimAddress.ts
|
|
115
|
-
import { asAddress } from "@xylabs/hex";
|
|
116
|
-
import { isUndefined } from "@xylabs/typeof";
|
|
117
|
-
import { createTransferPayload } from "@xyo-network/chain-protocol";
|
|
118
|
-
import { PayloadZodLoose } from "@xyo-network/payload-model";
|
|
119
|
-
import { asStepIdentity } from "@xyo-network/xl1-protocol";
|
|
120
|
-
import { buildTransaction, completedStepRewardAddress, derivedReceiveAddress } from "@xyo-network/xl1-protocol-sdk";
|
|
121
|
-
import { SignedHydratedTransactionZod } from "@xyo-network/xl1-rpc";
|
|
122
|
-
import { z as z2 } from "zod";
|
|
123
|
-
|
|
124
114
|
// src/server/routes/rewardRedemption/middleware/requestHandlerValidator.ts
|
|
125
115
|
import { isDefined as isDefined2, isPromise } from "@xylabs/typeof";
|
|
126
116
|
import { ReasonPhrases, StatusCodes } from "http-status-codes";
|
|
@@ -194,28 +184,12 @@ function requestHandlerValidator(schemas) {
|
|
|
194
184
|
}
|
|
195
185
|
__name(requestHandlerValidator, "requestHandlerValidator");
|
|
196
186
|
|
|
197
|
-
// src/server/routes/rewardRedemption/routeDefinitions/pathParams/AddressPathParam.ts
|
|
198
|
-
import { EthAddressFromStringZod } from "@xylabs/hex";
|
|
199
|
-
|
|
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
187
|
// src/server/routes/rewardRedemption/routeDefinitions/util/getViewerFromConfig.ts
|
|
214
|
-
import { isDefined as
|
|
188
|
+
import { isDefined as isDefined3 } from "@xylabs/typeof";
|
|
215
189
|
import { HttpRpcTransport, JsonRpcXyoViewer, XyoViewerRpcSchemas } from "@xyo-network/xl1-rpc";
|
|
216
190
|
var viewer;
|
|
217
191
|
var getViewerFromConfig = /* @__PURE__ */ __name((config) => {
|
|
218
|
-
if (
|
|
192
|
+
if (isDefined3(viewer)) return viewer;
|
|
219
193
|
const transport = new HttpRpcTransport(config.rewardRedemptionApi.chainRpcApiUrl, XyoViewerRpcSchemas);
|
|
220
194
|
viewer = new JsonRpcXyoViewer(transport);
|
|
221
195
|
return viewer;
|
|
@@ -231,200 +205,293 @@ var RewardableSteps = [
|
|
|
231
205
|
8
|
|
232
206
|
];
|
|
233
207
|
|
|
234
|
-
// src/server/routes/rewardRedemption/routeDefinitions/routes/
|
|
208
|
+
// src/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.ts
|
|
209
|
+
import { assertEx as assertEx2 } from "@xylabs/assert";
|
|
210
|
+
import { isDefined as isDefined5 } from "@xylabs/typeof";
|
|
211
|
+
import { blockRangeSteps as blockRangeSteps2 } from "@xyo-network/chain-protocol";
|
|
212
|
+
import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/payload-builder";
|
|
213
|
+
import { PayloadZodLoose } from "@xyo-network/payload-model";
|
|
214
|
+
import { asSentinelInstance } from "@xyo-network/sentinel-model";
|
|
215
|
+
import { asXL1BlockNumber as asXL1BlockNumber2 } from "@xyo-network/xl1-protocol";
|
|
216
|
+
import { z as z2 } from "zod";
|
|
217
|
+
|
|
218
|
+
// src/modules/ChainRewardsClaimSentinel.ts
|
|
219
|
+
import { assertEx } from "@xylabs/assert";
|
|
220
|
+
import { toAddress } from "@xylabs/hex";
|
|
221
|
+
import { isDefined as isDefined4, isUndefined } from "@xylabs/typeof";
|
|
222
|
+
import { blockRangeSteps, createTransferPayload } from "@xyo-network/chain-protocol";
|
|
223
|
+
import { AbstractSentinel } from "@xyo-network/sentinel-abstract";
|
|
224
|
+
import { asXL1BlockNumber, XYO_STEP_REWARD_ADDRESS } from "@xyo-network/xl1-protocol";
|
|
225
|
+
import { completedStepRewardAddress, derivedReceiveAddress, flattenHydratedTransaction, flattenHydratedTransactions } from "@xyo-network/xl1-protocol-sdk";
|
|
226
|
+
import { Mutex } from "async-mutex";
|
|
227
|
+
|
|
228
|
+
// src/modules/StepIdentityPayload.ts
|
|
229
|
+
import { AsObjectFactory } from "@xylabs/object";
|
|
230
|
+
import { isPayloadOfZodType } from "@xyo-network/payload-model";
|
|
231
|
+
import { StepIdentityZod } from "@xyo-network/xl1-rpc";
|
|
232
|
+
var StepIdentitySchema = "network.xyo.chain.step.identity";
|
|
233
|
+
var isStepIdentityPayload = isPayloadOfZodType(StepIdentityZod, StepIdentitySchema);
|
|
234
|
+
var asStepIdentityPayload = AsObjectFactory.create(isStepIdentityPayload);
|
|
235
|
+
|
|
236
|
+
// src/modules/ChainRewardsClaimSentinel.ts
|
|
237
|
+
var ChainRewardsClaimSentinelConfigSchema = "network.xyo.sentinel.chain.rewards.claim.config";
|
|
235
238
|
var scope = "reward-escrow";
|
|
236
|
-
var
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const stakes = await viewer2.stakesByStaker(stakerAddress);
|
|
248
|
-
return stakes;
|
|
249
|
-
}, "getStakesForStaker");
|
|
250
|
-
var getRewardsForStake = /* @__PURE__ */ __name(async (viewer2, stakes, fromBlock = 0, toBlock) => {
|
|
251
|
-
if (isUndefined(toBlock)) {
|
|
252
|
-
toBlock = await viewer2.currentBlockNumber();
|
|
253
|
-
}
|
|
254
|
-
const rewards = [];
|
|
255
|
-
for (const stake of stakes) {
|
|
256
|
-
const { id } = stake;
|
|
257
|
-
const reward = await viewer2.networkStakeStepRewardsForPosition(id, [
|
|
258
|
-
fromBlock,
|
|
259
|
-
toBlock
|
|
260
|
-
]);
|
|
261
|
-
rewards.push(reward);
|
|
239
|
+
var RewardableSteps2 = [
|
|
240
|
+
3,
|
|
241
|
+
4,
|
|
242
|
+
5,
|
|
243
|
+
6,
|
|
244
|
+
7,
|
|
245
|
+
8
|
|
246
|
+
];
|
|
247
|
+
var ChainRewardsClaimSentinel = class extends AbstractSentinel {
|
|
248
|
+
static {
|
|
249
|
+
__name(this, "ChainRewardsClaimSentinel");
|
|
262
250
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
totals[key] = 0n;
|
|
271
|
-
}
|
|
272
|
-
totals[key] += first;
|
|
273
|
-
}
|
|
251
|
+
static configSchemas = [
|
|
252
|
+
ChainRewardsClaimSentinelConfigSchema
|
|
253
|
+
];
|
|
254
|
+
static defaultConfigSchema = ChainRewardsClaimSentinelConfigSchema;
|
|
255
|
+
_reportMutex = new Mutex();
|
|
256
|
+
get gateway() {
|
|
257
|
+
return this.params.gateway;
|
|
274
258
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
path: "/rewards/claim/:address",
|
|
280
|
-
handlers: validateRequest(async (req, res) => {
|
|
281
|
-
const { config } = req.app;
|
|
282
|
-
const { address } = req.params;
|
|
283
|
-
const stakerAddress = asAddress(address);
|
|
284
|
-
if (!stakerAddress) {
|
|
285
|
-
res.status(400);
|
|
286
|
-
return;
|
|
259
|
+
async reportHandler(payloads) {
|
|
260
|
+
if (this._reportMutex.isLocked()) {
|
|
261
|
+
this.logger?.debug(`ChainRewardsClaimSentinel [${this.id}] is already running, skipping divine [${Date.now()}]`);
|
|
262
|
+
return [];
|
|
287
263
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (isUndefined(stepIdentity)) continue;
|
|
300
|
-
const stepRewardsAddress = completedStepRewardAddress(stepIdentity);
|
|
301
|
-
const receiveAddress = derivedReceiveAddress(stakerAddress, scope);
|
|
302
|
-
const claimed = await viewer2.transferPairBalance([
|
|
303
|
-
stepRewardsAddress,
|
|
304
|
-
receiveAddress
|
|
305
|
-
]);
|
|
306
|
-
const unclaimed = accrued - claimed;
|
|
307
|
-
if (unclaimed <= 0n) continue;
|
|
308
|
-
const transferPayload = createTransferPayload(stepRewardsAddress, {
|
|
309
|
-
[receiveAddress]: unclaimed
|
|
310
|
-
});
|
|
311
|
-
transferPayload.context = {
|
|
312
|
-
address: stakerAddress,
|
|
313
|
-
scope
|
|
264
|
+
return await this._reportMutex.runExclusive(async () => {
|
|
265
|
+
const response3 = [];
|
|
266
|
+
if (isUndefined(payloads) || payloads.length === 0) {
|
|
267
|
+
await this.claimAllSteps();
|
|
268
|
+
} else {
|
|
269
|
+
const stepIdentities = payloads.filter(isStepIdentityPayload).map((p) => {
|
|
270
|
+
const { step, block: blockNumber } = p;
|
|
271
|
+
const block = asXL1BlockNumber(blockNumber);
|
|
272
|
+
return {
|
|
273
|
+
step,
|
|
274
|
+
block
|
|
314
275
|
};
|
|
315
|
-
|
|
276
|
+
}).filter((stepIdentity) => RewardableSteps2.includes(stepIdentity.step));
|
|
277
|
+
for (const stepIdentity of stepIdentities) {
|
|
278
|
+
const result = await this.claimStepIdentity(stepIdentity);
|
|
279
|
+
if (isDefined4(result)) response3.push(...flattenHydratedTransaction(result));
|
|
316
280
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
281
|
+
}
|
|
282
|
+
return response3;
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
calculateAddressDistributions(rewardsByStaker, balance) {
|
|
286
|
+
const addressClaims = {};
|
|
287
|
+
const totalRewards = Object.values(rewardsByStaker).reduce((acc, val) => acc + val, 0n);
|
|
288
|
+
for (const [staker, amount] of Object.entries(rewardsByStaker)) {
|
|
289
|
+
if (amount <= 0n) continue;
|
|
290
|
+
const reward = balance * amount / totalRewards;
|
|
291
|
+
if (reward <= 0n) continue;
|
|
292
|
+
const receiveAddress = derivedReceiveAddress(toAddress(staker), scope);
|
|
293
|
+
addressClaims[receiveAddress] = reward;
|
|
294
|
+
}
|
|
295
|
+
const totalClaimed = Object.values(addressClaims).reduce((acc, val) => acc + val, 0n);
|
|
296
|
+
assertEx(totalClaimed <= balance, () => "Total claimed exceeds claimable balance");
|
|
297
|
+
const unclaimed = balance - totalClaimed;
|
|
298
|
+
if (unclaimed > 0n) {
|
|
299
|
+
addressClaims[XYO_STEP_REWARD_ADDRESS] = unclaimed;
|
|
300
|
+
}
|
|
301
|
+
return addressClaims;
|
|
302
|
+
}
|
|
303
|
+
async claimAllSteps() {
|
|
304
|
+
const results = [];
|
|
305
|
+
const connection = await this.gateway.connection();
|
|
306
|
+
const signer = await this.gateway.signer();
|
|
307
|
+
const { viewer: viewer2, runner } = connection;
|
|
308
|
+
if (isDefined4(viewer2) && isDefined4(runner) && isDefined4(signer)) {
|
|
309
|
+
for (const step of RewardableSteps2) {
|
|
310
|
+
const from = 0;
|
|
311
|
+
const to = await viewer2.currentBlockNumber();
|
|
312
|
+
const range = [
|
|
313
|
+
asXL1BlockNumber(from),
|
|
314
|
+
asXL1BlockNumber(to)
|
|
315
|
+
];
|
|
316
|
+
const stepIdentities = blockRangeSteps(range, [
|
|
317
|
+
step
|
|
318
|
+
]);
|
|
319
|
+
for (const stepIdentity of stepIdentities) {
|
|
320
|
+
const result = await this.claimStepIdentity(stepIdentity);
|
|
321
|
+
if (isDefined4(result)) results.push(result);
|
|
322
322
|
}
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
|
-
|
|
326
|
-
}
|
|
325
|
+
return flattenHydratedTransactions(results);
|
|
326
|
+
}
|
|
327
|
+
async claimStepIdentity(stepIdentity) {
|
|
328
|
+
const connection = await this.gateway.connection();
|
|
329
|
+
const signer = await this.gateway.signer();
|
|
330
|
+
const { viewer: viewer2, runner } = connection;
|
|
331
|
+
if (isDefined4(viewer2) && isDefined4(runner) && isDefined4(signer)) {
|
|
332
|
+
const stepRewardsAddress = completedStepRewardAddress(stepIdentity);
|
|
333
|
+
const balance = await viewer2.accountBalance(stepRewardsAddress);
|
|
334
|
+
if (balance > 0n) {
|
|
335
|
+
const rewardsByStaker = await viewer2.networkStakeStepRewardPoolRewards(stepIdentity);
|
|
336
|
+
const addressDistributions = this.calculateAddressDistributions(rewardsByStaker, balance);
|
|
337
|
+
const tx = await this.submitRewardDistributionTransaction(stepRewardsAddress, addressDistributions, stepIdentity, this.gateway);
|
|
338
|
+
return tx;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
async submitRewardDistributionTransaction(stepRewardsAddress, addressDistributions, step, gateway) {
|
|
343
|
+
const transferPayload = createTransferPayload(stepRewardsAddress, addressDistributions);
|
|
344
|
+
transferPayload.context = {
|
|
345
|
+
step
|
|
346
|
+
};
|
|
347
|
+
const connection = await gateway.connection();
|
|
348
|
+
const viewer2 = assertEx(connection.viewer, () => "Viewer is not defined in gateway connection");
|
|
349
|
+
const chainId = await viewer2.chainId();
|
|
350
|
+
const currentBlock = await viewer2.currentBlockNumber();
|
|
351
|
+
const result = await gateway.addPayloadsToChain?.([
|
|
352
|
+
transferPayload
|
|
353
|
+
], [], {
|
|
354
|
+
chain: chainId,
|
|
355
|
+
nbf: currentBlock,
|
|
356
|
+
exp: currentBlock + 1e3
|
|
357
|
+
});
|
|
358
|
+
if (isDefined4(result)) return result[1];
|
|
359
|
+
}
|
|
327
360
|
};
|
|
328
361
|
|
|
329
362
|
// src/server/routes/rewardRedemption/routeDefinitions/routes/claimRange.ts
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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()
|
|
363
|
+
var query = z2.object({
|
|
364
|
+
fromBlock: z2.coerce.number().int().min(0).optional(),
|
|
365
|
+
toBlock: z2.coerce.number().int().min(0).optional(),
|
|
366
|
+
step: z2.coerce.number().min(Math.min(...RewardableSteps)).max(Math.max(...RewardableSteps)).int().optional().default(3)
|
|
342
367
|
});
|
|
343
|
-
var
|
|
344
|
-
var
|
|
368
|
+
var response = z2.array(PayloadZodLoose);
|
|
369
|
+
var validateRequest = requestHandlerValidator({
|
|
345
370
|
query,
|
|
346
|
-
response
|
|
371
|
+
response
|
|
347
372
|
});
|
|
348
|
-
var
|
|
349
|
-
const
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
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");
|
|
373
|
+
var getChainRewardsClaimSentinel = /* @__PURE__ */ __name(async (node) => {
|
|
374
|
+
const mod = await node.resolve("XYORewardRedemptionNode:ChainRewardsClaimSentinel");
|
|
375
|
+
const sentinel = asSentinelInstance(mod);
|
|
376
|
+
return assertEx2(sentinel, () => "ChainRewardsClaimSentinel not found on node");
|
|
377
|
+
}, "getChainRewardsClaimSentinel");
|
|
375
378
|
var postClaimRange = {
|
|
376
379
|
method: "post",
|
|
377
380
|
path: "/rewards/claimRange",
|
|
378
|
-
handlers:
|
|
379
|
-
const { config } = req.app;
|
|
380
|
-
const
|
|
381
|
+
handlers: validateRequest(async (req, res) => {
|
|
382
|
+
const { config, node } = req.app;
|
|
383
|
+
const mod = await getChainRewardsClaimSentinel(node);
|
|
384
|
+
const { fromBlock, toBlock, step } = z2.parse(query, req.query);
|
|
381
385
|
const viewer2 = getViewerFromConfig(config);
|
|
382
|
-
const from = isDefined5(fromBlock) ?
|
|
383
|
-
const
|
|
386
|
+
const from = isDefined5(fromBlock) ? fromBlock : 0;
|
|
387
|
+
const currentBlock = await viewer2.currentBlockNumber();
|
|
388
|
+
const to = isDefined5(toBlock) ? Math.min(toBlock, currentBlock) : currentBlock;
|
|
389
|
+
if (to <= from) {
|
|
390
|
+
res.status(400);
|
|
391
|
+
res.json([]);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
384
394
|
const range = [
|
|
385
|
-
|
|
386
|
-
|
|
395
|
+
asXL1BlockNumber2(from),
|
|
396
|
+
asXL1BlockNumber2(to)
|
|
387
397
|
];
|
|
388
|
-
const stepIdentities =
|
|
398
|
+
const stepIdentities = blockRangeSteps2(range, [
|
|
399
|
+
step
|
|
400
|
+
]);
|
|
401
|
+
const results = [];
|
|
389
402
|
for (const stepIdentity of stepIdentities) {
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
res.json(tx);
|
|
398
|
-
}
|
|
403
|
+
const stepIdentityPayload = new PayloadBuilder2({
|
|
404
|
+
schema: StepIdentitySchema
|
|
405
|
+
}).fields(stepIdentity).build();
|
|
406
|
+
const result = await mod.report([
|
|
407
|
+
stepIdentityPayload
|
|
408
|
+
]);
|
|
409
|
+
results.push(...result);
|
|
399
410
|
}
|
|
400
|
-
res.status(
|
|
401
|
-
res.json();
|
|
411
|
+
res.status(200);
|
|
412
|
+
res.json(results);
|
|
402
413
|
})
|
|
403
414
|
};
|
|
404
415
|
|
|
405
416
|
// src/server/routes/rewardRedemption/routeDefinitions/routes/redeem.ts
|
|
406
|
-
import {
|
|
407
|
-
import {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
+
import { assertEx as assertEx3 } from "@xylabs/assert";
|
|
418
|
+
import { hexToBigInt, toAddress as toAddress2, toHex } from "@xylabs/hex";
|
|
419
|
+
import { isDefined as isDefined6 } from "@xylabs/typeof";
|
|
420
|
+
import { createTransferPayload as createTransferPayload2 } from "@xyo-network/chain-protocol";
|
|
421
|
+
import { HDWallet } from "@xyo-network/wallet";
|
|
422
|
+
import { verifyEIP712Message } from "@xyo-network/xl1-protocol-sdk";
|
|
423
|
+
import { HttpRpcXyoConnection, MemoryXyoGateway, MemoryXyoSigner, SignedHydratedTransactionZod } from "@xyo-network/xl1-rpc";
|
|
424
|
+
import { z as z3 } from "zod";
|
|
425
|
+
var body = z3.any();
|
|
426
|
+
var response2 = SignedHydratedTransactionZod;
|
|
427
|
+
var validateRequest2 = requestHandlerValidator({
|
|
428
|
+
body,
|
|
429
|
+
response: response2
|
|
417
430
|
});
|
|
431
|
+
var getGateway = /* @__PURE__ */ __name(async (config) => {
|
|
432
|
+
const { mnemonic, chainRpcApiUrl: endpoint } = config.rewardRedemptionApi;
|
|
433
|
+
const account = await HDWallet.fromPhrase(assertEx3(mnemonic, () => ""));
|
|
434
|
+
const signer = new MemoryXyoSigner(account);
|
|
435
|
+
const connection = new HttpRpcXyoConnection({
|
|
436
|
+
endpoint,
|
|
437
|
+
account
|
|
438
|
+
});
|
|
439
|
+
const gateway = new MemoryXyoGateway(signer, connection);
|
|
440
|
+
return gateway;
|
|
441
|
+
}, "getGateway");
|
|
442
|
+
var submitRewardDistributionTransaction = /* @__PURE__ */ __name(async (to, amount, nbf, exp, gateway) => {
|
|
443
|
+
const signer = assertEx3(await gateway.signer(), () => "Signer is not defined in gateway");
|
|
444
|
+
const from = await signer.address();
|
|
445
|
+
const transferPayload = createTransferPayload2(from, {
|
|
446
|
+
[to]: hexToBigInt(toHex(amount))
|
|
447
|
+
});
|
|
448
|
+
const connection = await gateway.connection();
|
|
449
|
+
const viewer2 = assertEx3(connection.viewer, () => "Viewer is not defined in gateway connection");
|
|
450
|
+
const chain = await viewer2.chainId();
|
|
451
|
+
const result = await gateway.addPayloadsToChain?.([
|
|
452
|
+
transferPayload
|
|
453
|
+
], [], {
|
|
454
|
+
chain,
|
|
455
|
+
nbf,
|
|
456
|
+
exp
|
|
457
|
+
});
|
|
458
|
+
if (isDefined6(result)) return result[1];
|
|
459
|
+
}, "submitRewardDistributionTransaction");
|
|
460
|
+
var parseConfirmedClaimValues = /* @__PURE__ */ __name((values) => {
|
|
461
|
+
return {
|
|
462
|
+
from: toAddress2(values.from),
|
|
463
|
+
to: values["To XL1 Address"],
|
|
464
|
+
amount: values["XL1 Amount (Hex)"],
|
|
465
|
+
nbf: values["XL1 Not before block"],
|
|
466
|
+
exp: values["XL1 Not after block"]
|
|
467
|
+
};
|
|
468
|
+
}, "parseConfirmedClaimValues");
|
|
418
469
|
var postRedeem = {
|
|
419
470
|
method: "post",
|
|
420
|
-
path: "/rewards/redeem
|
|
421
|
-
handlers:
|
|
422
|
-
const {
|
|
423
|
-
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
471
|
+
path: "/rewards/redeem",
|
|
472
|
+
handlers: validateRequest2(async (req, res) => {
|
|
473
|
+
const { config } = req.app;
|
|
474
|
+
const { body: body2 } = req;
|
|
475
|
+
const [payload, signature] = body2;
|
|
476
|
+
const valid = await verifyEIP712Message(payload, signature);
|
|
477
|
+
if (valid) {
|
|
478
|
+
const values = payload.values;
|
|
479
|
+
const { from, to, amount, nbf, exp } = parseConfirmedClaimValues(values);
|
|
480
|
+
assertEx3(toAddress2(signature.address) === toAddress2(from), () => "Signature does not match from address");
|
|
481
|
+
const gateway = await getGateway(config);
|
|
482
|
+
const receiver = toAddress2(to);
|
|
483
|
+
const tx = await submitRewardDistributionTransaction(receiver, amount, nbf, exp, gateway);
|
|
484
|
+
if (isDefined6(tx)) {
|
|
485
|
+
res.status(200);
|
|
486
|
+
res.json(tx);
|
|
487
|
+
} else {
|
|
488
|
+
res.status(500);
|
|
489
|
+
res.json();
|
|
490
|
+
}
|
|
491
|
+
} else {
|
|
492
|
+
res.status(404);
|
|
493
|
+
res.json();
|
|
494
|
+
}
|
|
428
495
|
})
|
|
429
496
|
};
|
|
430
497
|
|
|
@@ -432,7 +499,7 @@ var postRedeem = {
|
|
|
432
499
|
var getRouteDefinitions = /* @__PURE__ */ __name(() => {
|
|
433
500
|
return [
|
|
434
501
|
postClaimRange,
|
|
435
|
-
postClaim,
|
|
502
|
+
// postClaim,
|
|
436
503
|
postRedeem
|
|
437
504
|
];
|
|
438
505
|
}, "getRouteDefinitions");
|
|
@@ -474,22 +541,23 @@ var getApp = /* @__PURE__ */ __name((node, config) => {
|
|
|
474
541
|
}, "getApp");
|
|
475
542
|
|
|
476
543
|
// src/server/server.ts
|
|
477
|
-
import { assertEx as
|
|
478
|
-
import { isDefined as
|
|
544
|
+
import { assertEx as assertEx4 } from "@xylabs/assert";
|
|
545
|
+
import { isDefined as isDefined8, isString } from "@xylabs/typeof";
|
|
479
546
|
import { boot } from "@xyo-network/bios";
|
|
480
|
-
import { HDWallet as
|
|
547
|
+
import { HDWallet as HDWallet3 } from "@xyo-network/wallet";
|
|
481
548
|
|
|
482
549
|
// src/manifest/getLocator.ts
|
|
483
|
-
import { isDefined as
|
|
550
|
+
import { isDefined as isDefined7 } from "@xylabs/typeof";
|
|
484
551
|
import { MemoryArchivist } from "@xyo-network/archivist-memory";
|
|
485
552
|
import { MongoDBArchivistV2 } from "@xyo-network/archivist-mongodb";
|
|
486
553
|
import { ViewArchivist } from "@xyo-network/archivist-view";
|
|
487
|
-
import { ArchivistSyncDiviner } from "@xyo-network/chain-modules";
|
|
488
554
|
import { initTelemetry } from "@xyo-network/chain-telemetry";
|
|
489
555
|
import { AbstractModule, LoggerModuleStatusReporter } from "@xyo-network/module-abstract";
|
|
490
556
|
import { ModuleFactoryLocator } from "@xyo-network/module-factory-locator";
|
|
491
557
|
import { MemorySentinel } from "@xyo-network/sentinel-memory";
|
|
558
|
+
import { HDWallet as HDWallet2 } from "@xyo-network/wallet";
|
|
492
559
|
import { hasMongoConfig } from "@xyo-network/xl1-protocol-sdk";
|
|
560
|
+
import { HttpRpcXyoConnection as HttpRpcXyoConnection2, MemoryXyoGateway as MemoryXyoGateway2, MemoryXyoSigner as MemoryXyoSigner2 } from "@xyo-network/xl1-rpc";
|
|
493
561
|
var getLocator = /* @__PURE__ */ __name(async (context) => {
|
|
494
562
|
const { config, logger } = context;
|
|
495
563
|
const { otlpEndpoint } = config.telemetry?.otel ?? {};
|
|
@@ -504,7 +572,7 @@ var getLocator = /* @__PURE__ */ __name(async (context) => {
|
|
|
504
572
|
port: 9465
|
|
505
573
|
}
|
|
506
574
|
});
|
|
507
|
-
if (
|
|
575
|
+
if (isDefined7(logger)) AbstractModule.defaultLogger = logger;
|
|
508
576
|
const statusReporter = logger ? new LoggerModuleStatusReporter(logger) : void 0;
|
|
509
577
|
const locator = new ModuleFactoryLocator();
|
|
510
578
|
const mongoConfig = config.storage?.mongo;
|
|
@@ -517,13 +585,13 @@ var getLocator = /* @__PURE__ */ __name(async (context) => {
|
|
|
517
585
|
dbPassword,
|
|
518
586
|
dbUserName
|
|
519
587
|
};
|
|
520
|
-
const
|
|
588
|
+
const params = {
|
|
521
589
|
meterProvider,
|
|
522
590
|
payloadSdkConfig,
|
|
523
591
|
statusReporter,
|
|
524
592
|
traceProvider
|
|
525
593
|
};
|
|
526
|
-
locator.register(MongoDBArchivistV2.factory(
|
|
594
|
+
locator.register(MongoDBArchivistV2.factory(params), void 0, true);
|
|
527
595
|
}
|
|
528
596
|
locator.register(MemoryArchivist.factory({
|
|
529
597
|
traceProvider,
|
|
@@ -540,13 +608,27 @@ var getLocator = /* @__PURE__ */ __name(async (context) => {
|
|
|
540
608
|
meterProvider,
|
|
541
609
|
statusReporter
|
|
542
610
|
}));
|
|
543
|
-
locator
|
|
611
|
+
await registerChainRewardsClaimSentinel(locator, config, traceProvider, meterProvider, statusReporter);
|
|
612
|
+
return locator;
|
|
613
|
+
}, "getLocator");
|
|
614
|
+
var registerChainRewardsClaimSentinel = /* @__PURE__ */ __name(async (locator, config, traceProvider, meterProvider, statusReporter) => {
|
|
615
|
+
const { mnemonic, chainRpcApiUrl: endpoint } = config.rewardRedemptionApi;
|
|
616
|
+
const walletPromise = isDefined7(mnemonic) ? HDWallet2.fromPhrase(mnemonic) : HDWallet2.random();
|
|
617
|
+
const account = await walletPromise;
|
|
618
|
+
const signer = new MemoryXyoSigner2(account);
|
|
619
|
+
const connection = new HttpRpcXyoConnection2({
|
|
620
|
+
endpoint,
|
|
621
|
+
account
|
|
622
|
+
});
|
|
623
|
+
const gateway = new MemoryXyoGateway2(signer, connection);
|
|
624
|
+
const chainRewardsClaimSentinelParams = {
|
|
625
|
+
gateway,
|
|
544
626
|
traceProvider,
|
|
545
627
|
meterProvider,
|
|
546
628
|
statusReporter
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
}, "
|
|
629
|
+
};
|
|
630
|
+
locator.register(ChainRewardsClaimSentinel.factory(chainRewardsClaimSentinelParams));
|
|
631
|
+
}, "registerChainRewardsClaimSentinel");
|
|
550
632
|
|
|
551
633
|
// src/manifest/getNode.ts
|
|
552
634
|
import { ManifestWrapper } from "@xyo-network/manifest-wrapper";
|
|
@@ -576,6 +658,13 @@ var node_default = {
|
|
|
576
658
|
},
|
|
577
659
|
schema: "network.xyo.archivist.config"
|
|
578
660
|
}
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
config: {
|
|
664
|
+
accountPath: "1/1'/2'",
|
|
665
|
+
name: "ChainRewardsClaimSentinel",
|
|
666
|
+
schema: "network.xyo.sentinel.chain.rewards.claim.config"
|
|
667
|
+
}
|
|
579
668
|
}
|
|
580
669
|
],
|
|
581
670
|
public: [
|
|
@@ -638,20 +727,20 @@ var getSeedPhrase = /* @__PURE__ */ __name(async (bios, config, logger) => {
|
|
|
638
727
|
if (isString(mnemonic)) {
|
|
639
728
|
seedPhrase = mnemonic;
|
|
640
729
|
} else {
|
|
641
|
-
seedPhrase =
|
|
730
|
+
seedPhrase = HDWallet3.generateMnemonic();
|
|
642
731
|
logger?.log("[Bridge] No mnemonic provided, using random mnemonic. This is not recommended for production use.");
|
|
643
732
|
logger?.log(`[Bridge] Mnemonic: ${seedPhrase}`);
|
|
644
733
|
}
|
|
645
734
|
await bios.seedPhraseStore.set("os", seedPhrase);
|
|
646
735
|
}
|
|
647
|
-
return
|
|
736
|
+
return assertEx4(await bios.seedPhraseStore.get("os"), () => "Unable to acquire mnemonic from bios");
|
|
648
737
|
}, "getSeedPhrase");
|
|
649
738
|
var getServer = /* @__PURE__ */ __name(async (context) => {
|
|
650
739
|
const { logger, config } = context;
|
|
651
740
|
const { port, mnemonic } = config.rewardRedemptionApi;
|
|
652
741
|
const bios = await boot();
|
|
653
|
-
const seedPhrase =
|
|
654
|
-
const wallet = await
|
|
742
|
+
const seedPhrase = isDefined8(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger);
|
|
743
|
+
const wallet = await HDWallet3.fromPhrase(seedPhrase);
|
|
655
744
|
const nodeContext = {
|
|
656
745
|
wallet,
|
|
657
746
|
logger,
|