@antseed/ants 0.1.1
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/LICENSE +674 -0
- package/dist/ants-web/assets/index-BunPfgXh.css +1 -0
- package/dist/ants-web/assets/index-zCPoF694.js +40 -0
- package/dist/ants-web/index.html +13 -0
- package/dist/api-types.d.ts +400 -0
- package/dist/api-types.js +8 -0
- package/dist/api-types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs.d.ts +23 -0
- package/dist/jobs.js +70 -0
- package/dist/jobs.js.map +1 -0
- package/dist/routes.d.ts +12 -0
- package/dist/routes.js +64 -0
- package/dist/routes.js.map +1 -0
- package/dist/server.d.ts +29 -0
- package/dist/server.js +90 -0
- package/dist/server.js.map +1 -0
- package/dist/service/context.d.ts +146 -0
- package/dist/service/context.js +321 -0
- package/dist/service/context.js.map +1 -0
- package/dist/service/emissions.d.ts +3 -0
- package/dist/service/emissions.js +62 -0
- package/dist/service/emissions.js.map +1 -0
- package/dist/service/explorer.d.ts +9 -0
- package/dist/service/explorer.js +44 -0
- package/dist/service/explorer.js.map +1 -0
- package/dist/service/format.d.ts +8 -0
- package/dist/service/format.js +41 -0
- package/dist/service/format.js.map +1 -0
- package/dist/service/index.d.ts +20 -0
- package/dist/service/index.js +15 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/indexer.d.ts +150 -0
- package/dist/service/indexer.js +189 -0
- package/dist/service/indexer.js.map +1 -0
- package/dist/service/json.d.ts +3 -0
- package/dist/service/json.js +8 -0
- package/dist/service/json.js.map +1 -0
- package/dist/service/overview.d.ts +9 -0
- package/dist/service/overview.js +98 -0
- package/dist/service/overview.js.map +1 -0
- package/dist/service/pool-merge.d.ts +26 -0
- package/dist/service/pool-merge.js +101 -0
- package/dist/service/pool-merge.js.map +1 -0
- package/dist/service/pools.d.ts +12 -0
- package/dist/service/pools.js +287 -0
- package/dist/service/pools.js.map +1 -0
- package/dist/service/positions.d.ts +62 -0
- package/dist/service/positions.js +281 -0
- package/dist/service/positions.js.map +1 -0
- package/dist/service/rate-limit.d.ts +17 -0
- package/dist/service/rate-limit.js +42 -0
- package/dist/service/rate-limit.js.map +1 -0
- package/dist/service/rewards.d.ts +46 -0
- package/dist/service/rewards.js +399 -0
- package/dist/service/rewards.js.map +1 -0
- package/dist/service/rpc-provider.d.ts +31 -0
- package/dist/service/rpc-provider.js +99 -0
- package/dist/service/rpc-provider.js.map +1 -0
- package/dist/service/seller.d.ts +14 -0
- package/dist/service/seller.js +104 -0
- package/dist/service/seller.js.map +1 -0
- package/dist/service/steps.d.ts +6 -0
- package/dist/service/steps.js +24 -0
- package/dist/service/steps.js.map +1 -0
- package/dist/service/usage.d.ts +10 -0
- package/dist/service/usage.js +77 -0
- package/dist/service/usage.js.map +1 -0
- package/dist/service/verification.d.ts +12 -0
- package/dist/service/verification.js +69 -0
- package/dist/service/verification.js.map +1 -0
- package/dist/view-cache.d.ts +18 -0
- package/dist/view-cache.js +39 -0
- package/dist/view-cache.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import { ZeroAddress } from 'ethers';
|
|
2
|
+
import { claimEpochRewards, pendingEpochRewards, previewPoolRewards } from '@antseed/node/payments';
|
|
3
|
+
import { closedPositionIds } from './positions.js';
|
|
4
|
+
import { IndexerError } from './indexer.js';
|
|
5
|
+
import { formatAnts } from './format.js';
|
|
6
|
+
import { toJson } from './json.js';
|
|
7
|
+
import { assertAgentId, assertEpochs, assertPositiveIds, silentReporter } from './steps.js';
|
|
8
|
+
const MAX_EPOCH_BREAKDOWN = 64;
|
|
9
|
+
async function safe(read, fallback) {
|
|
10
|
+
try {
|
|
11
|
+
return await read();
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return fallback;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function sameAddress(a, b) {
|
|
18
|
+
return !!a && !!b && a.toLowerCase() === b.toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
async function agentIdOf(ctx) {
|
|
21
|
+
const stack = await ctx.stack();
|
|
22
|
+
const registry = ctx.sellerRegistry();
|
|
23
|
+
const fromRegistry = registry ? await safe(() => registry.getAgentId(ctx.address), 0) : 0;
|
|
24
|
+
if (fromRegistry)
|
|
25
|
+
return fromRegistry;
|
|
26
|
+
const legacy = ctx.legacyStakingAt(stack.legacyStaking);
|
|
27
|
+
return legacy ? safe(() => legacy.getAgentId(ctx.address), 0) : 0;
|
|
28
|
+
}
|
|
29
|
+
/** Recognized epochs in which this wallet has indexed buyer or seller points; all of them without an indexer. */
|
|
30
|
+
async function usageEpochsOf(ctx, recognized) {
|
|
31
|
+
const indexer = ctx.indexer();
|
|
32
|
+
if (!indexer || recognized.length === 0)
|
|
33
|
+
return recognized;
|
|
34
|
+
try {
|
|
35
|
+
const participant = await indexer.participant(ctx.address, recognized.length);
|
|
36
|
+
const active = new Set([...participant.seller.map((row) => row.epoch), ...participant.buyer.map((row) => row.epoch)]);
|
|
37
|
+
return recognized.filter((epoch) => active.has(epoch));
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error instanceof IndexerError)
|
|
41
|
+
return recognized;
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function buyerOperator(ctx) {
|
|
46
|
+
const deposits = ctx.deposits();
|
|
47
|
+
if (!deposits)
|
|
48
|
+
return null;
|
|
49
|
+
const operator = await safe(() => deposits.getOperator(ctx.address), ZeroAddress);
|
|
50
|
+
return sameAddress(operator, ZeroAddress) ? null : operator;
|
|
51
|
+
}
|
|
52
|
+
export async function rewards(ctx) {
|
|
53
|
+
const stack = await ctx.stack();
|
|
54
|
+
const epochs = await ctx.claimableEpochs();
|
|
55
|
+
const pools = ctx.pools();
|
|
56
|
+
const poolRewards = ctx.poolRewards();
|
|
57
|
+
const usageAccounting = ctx.usageAccounting();
|
|
58
|
+
const usageRewards = ctx.usageRewards();
|
|
59
|
+
const legacy = ctx.legacyEmissionsAt(stack.legacyEmissions);
|
|
60
|
+
const locked = ctx.lockedPoolAt(stack.lockedRewardsPool);
|
|
61
|
+
const agentId = await agentIdOf(ctx);
|
|
62
|
+
const closed = await closedPositionIds(ctx);
|
|
63
|
+
const stakerPositions = pools && poolRewards
|
|
64
|
+
? await safe(() => previewPoolRewards(pools, poolRewards, ctx.address, undefined, { includeIds: closed.ids }), [])
|
|
65
|
+
: [];
|
|
66
|
+
const stakerTotal = stakerPositions.reduce((sum, position) => sum + position.amount, 0n);
|
|
67
|
+
const sellerEpochs = [];
|
|
68
|
+
let sellerTotal = 0n;
|
|
69
|
+
const buyerEpochs = [];
|
|
70
|
+
let buyerTotal = 0n;
|
|
71
|
+
if (stack.phase === 'active' && usageAccounting && epochs.recognized.length > 0) {
|
|
72
|
+
const pending = await safe(() => pendingEpochRewards(epochs.recognized, async (batch) => (await usageAccounting.pendingEmissions(ctx.address, batch)).seller), 0n);
|
|
73
|
+
sellerTotal = pending;
|
|
74
|
+
// Only epochs where this wallet actually earned points are checked per
|
|
75
|
+
// epoch; the indexer knows which, so the loop stays bounded.
|
|
76
|
+
const candidates = await usageEpochsOf(ctx, epochs.recognized);
|
|
77
|
+
if (usageRewards && candidates.length <= MAX_EPOCH_BREAKDOWN) {
|
|
78
|
+
const breakdown = await Promise.all(candidates.map(async (epoch) => {
|
|
79
|
+
const [sellerClaimed, buyerClaimed] = await Promise.all([
|
|
80
|
+
agentId ? safe(() => usageRewards.agentEpochClaimed(agentId, epoch), false) : Promise.resolve(false),
|
|
81
|
+
safe(() => usageRewards.buyerEpochClaimed(ctx.address, epoch), false),
|
|
82
|
+
]);
|
|
83
|
+
const [sellerAmount, buyerAmount] = await Promise.all([
|
|
84
|
+
agentId && !sellerClaimed ? safe(() => usageRewards.pendingAgentReward(agentId, epoch), 0n) : Promise.resolve(0n),
|
|
85
|
+
buyerClaimed ? Promise.resolve(0n) : safe(() => usageRewards.pendingBuyerReward(ctx.address, epoch), 0n),
|
|
86
|
+
]);
|
|
87
|
+
return { epoch, sellerAmount, sellerClaimed, buyerAmount, buyerClaimed };
|
|
88
|
+
}));
|
|
89
|
+
for (const row of breakdown) {
|
|
90
|
+
if (row.sellerAmount > 0n || row.sellerClaimed)
|
|
91
|
+
sellerEpochs.push({ epoch: row.epoch, amount: row.sellerAmount.toString(), claimed: row.sellerClaimed });
|
|
92
|
+
if (row.buyerAmount > 0n || row.buyerClaimed)
|
|
93
|
+
buyerEpochs.push({ epoch: row.epoch, amount: row.buyerAmount.toString(), claimed: row.buyerClaimed });
|
|
94
|
+
buyerTotal += row.buyerAmount;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (usageRewards) {
|
|
98
|
+
for (const epoch of candidates) {
|
|
99
|
+
if (await safe(() => usageRewards.buyerEpochClaimed(ctx.address, epoch), false))
|
|
100
|
+
continue;
|
|
101
|
+
buyerTotal += await safe(() => usageRewards.pendingBuyerReward(ctx.address, epoch), 0n);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const operator = await buyerOperator(ctx);
|
|
106
|
+
let legacySeller = 0n;
|
|
107
|
+
let legacyBuyer = 0n;
|
|
108
|
+
if (legacy && epochs.legacy.length > 0) {
|
|
109
|
+
const pending = await safe(() => pendingEpochRewards(epochs.legacy, async (batch) => {
|
|
110
|
+
const result = await legacy.pendingEmissions(ctx.address, batch);
|
|
111
|
+
legacyBuyer += result.buyer;
|
|
112
|
+
return result.seller;
|
|
113
|
+
}), 0n);
|
|
114
|
+
legacySeller = pending;
|
|
115
|
+
}
|
|
116
|
+
const lockedInfo = locked ? await safe(() => locked.claimable(ctx.address), { locked: 0n, claimable: 0n, policy: ZeroAddress }) : { locked: 0n, claimable: 0n, policy: ZeroAddress };
|
|
117
|
+
const total = stakerTotal + sellerTotal + buyerTotal + legacySeller + legacyBuyer + lockedInfo.claimable;
|
|
118
|
+
return toJson({
|
|
119
|
+
currentEpoch: stack.currentEpoch,
|
|
120
|
+
firstRewardedEpoch: stack.effectiveEpoch,
|
|
121
|
+
staker: {
|
|
122
|
+
total: stakerTotal.toString(),
|
|
123
|
+
positions: stakerPositions.filter((position) => position.amount > 0n).map((position) => ({ id: position.id, agentId: position.agentId, amount: position.amount.toString(), closed: position.closedAtEpoch !== 0 })),
|
|
124
|
+
},
|
|
125
|
+
sellerUsage: { total: sellerTotal.toString(), agentId, epochs: sellerEpochs, claimable: stack.phase === 'active' && agentId !== 0 },
|
|
126
|
+
buyerUsage: {
|
|
127
|
+
total: buyerTotal.toString(), epochs: buyerEpochs, operator,
|
|
128
|
+
claimable: stack.phase === 'active' && sameAddress(operator, ctx.address), recipient: operator,
|
|
129
|
+
},
|
|
130
|
+
legacy: { seller: legacySeller.toString(), buyer: legacyBuyer.toString(), contract: stack.legacyEmissions, buyerClaimable: sameAddress(operator, ctx.address) || operator === null },
|
|
131
|
+
locked: {
|
|
132
|
+
locked: lockedInfo.locked.toString(), claimable: lockedInfo.claimable.toString(),
|
|
133
|
+
policy: sameAddress(lockedInfo.policy, ZeroAddress) ? null : lockedInfo.policy, pool: stack.lockedRewardsPool,
|
|
134
|
+
},
|
|
135
|
+
total: total.toString(),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/** Bring every pool's reward index up to the epoch the given positions need before claiming or restaking. */
|
|
139
|
+
async function preparePoolIndexes(pools, poolRewards, signer, targets, report) {
|
|
140
|
+
const currentEpoch = await pools.currentEpoch();
|
|
141
|
+
for (const agentId of new Set(targets.map((target) => target.agentId))) {
|
|
142
|
+
const targetEpoch = targets.filter((target) => target.agentId === agentId)
|
|
143
|
+
.reduce((latest, target) => Math.max(latest, Math.min(currentEpoch, target.closedAtEpoch || currentEpoch)), 0);
|
|
144
|
+
let cursor = await poolRewards.poolRewardIndexNextEpoch(agentId) || await poolRewards.initialIndexEpoch();
|
|
145
|
+
while (cursor < targetEpoch) {
|
|
146
|
+
await report(`Indexing pool ${agentId} rewards (epochs ${cursor}…${Math.min(targetEpoch, cursor + 16) - 1})`);
|
|
147
|
+
const hash = await poolRewards.indexPoolRewards(signer, agentId, Math.min(16, targetEpoch - cursor));
|
|
148
|
+
await report('Index transaction confirmed', hash);
|
|
149
|
+
const next = await poolRewards.poolRewardIndexNextEpoch(agentId);
|
|
150
|
+
if (next <= cursor)
|
|
151
|
+
throw new Error('Reward indexing made no progress; retry later.');
|
|
152
|
+
cursor = next;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export async function claim(ctx, request, report = silentReporter) {
|
|
157
|
+
const signer = ctx.requireSigner();
|
|
158
|
+
const stack = await ctx.stack();
|
|
159
|
+
const epochs = await ctx.claimableEpochs();
|
|
160
|
+
const recipient = request.recipient ?? ctx.address;
|
|
161
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(recipient))
|
|
162
|
+
throw new Error('Recipient must be an address.');
|
|
163
|
+
const buckets = request.buckets.length > 0 ? request.buckets : ['staker', 'seller', 'buyer', 'legacy', 'locked'];
|
|
164
|
+
const token = ctx.antsToken();
|
|
165
|
+
const transactions = [];
|
|
166
|
+
let claimed = 0n;
|
|
167
|
+
const record = async (hash, label, credit = true) => {
|
|
168
|
+
transactions.push(hash);
|
|
169
|
+
if (credit)
|
|
170
|
+
claimed += await safe(() => token.receivedInTransaction(hash, recipient), 0n);
|
|
171
|
+
await report(label, hash);
|
|
172
|
+
};
|
|
173
|
+
if (buckets.includes('staker')) {
|
|
174
|
+
const pools = ctx.pools();
|
|
175
|
+
const poolRewards = ctx.poolRewards();
|
|
176
|
+
if (pools && poolRewards) {
|
|
177
|
+
const closed = await closedPositionIds(ctx);
|
|
178
|
+
const pending = (await previewPoolRewards(pools, poolRewards, ctx.address, undefined, { includeIds: closed.ids })).filter((position) => position.amount > 0n);
|
|
179
|
+
if (pending.length > 0) {
|
|
180
|
+
await preparePoolIndexes(pools, poolRewards, signer, pending, report);
|
|
181
|
+
const ids = [];
|
|
182
|
+
for (const position of pending)
|
|
183
|
+
if (await poolRewards.pendingIndexedStakerReward(position.id) > 0n)
|
|
184
|
+
ids.push(position.id);
|
|
185
|
+
for (let offset = 0; offset < ids.length; offset += 32) {
|
|
186
|
+
const batch = ids.slice(offset, offset + 32);
|
|
187
|
+
await report(`Claiming staker rewards for position(s) ${batch.join(', ')}`);
|
|
188
|
+
await record(await poolRewards.claimStakerRewardsBatch(signer, batch, recipient), 'Staker rewards claimed');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (buckets.includes('seller') && stack.phase === 'active') {
|
|
194
|
+
const usageAccounting = ctx.usageAccounting();
|
|
195
|
+
if (usageAccounting && epochs.recognized.length > 0) {
|
|
196
|
+
await claimEpochRewards(epochs.recognized, async (batch) => (await usageAccounting.pendingEmissions(ctx.address, batch)).seller, async (batch) => { await report(`Claiming seller usage rewards for epochs ${batch[0]}…${batch[batch.length - 1]}`); return usageAccounting.claimSellerEmissions(signer, batch); }, async (hash) => record(hash, 'Seller usage rewards claimed'));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (buckets.includes('buyer') && stack.phase === 'active') {
|
|
200
|
+
const usageRewards = ctx.usageRewards();
|
|
201
|
+
if (usageRewards) {
|
|
202
|
+
const operator = await buyerOperator(ctx);
|
|
203
|
+
if (operator && !sameAddress(operator, ctx.address)) {
|
|
204
|
+
await report(`Buyer usage rewards are paid to the deposits operator ${operator}; claim them from that wallet.`);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
for (const epoch of epochs.recognized) {
|
|
208
|
+
if (await safe(() => usageRewards.buyerEpochClaimed(ctx.address, epoch), true))
|
|
209
|
+
continue;
|
|
210
|
+
if (await safe(() => usageRewards.pendingBuyerReward(ctx.address, epoch), 0n) === 0n)
|
|
211
|
+
continue;
|
|
212
|
+
await report(`Claiming buyer usage reward for epoch ${epoch}`);
|
|
213
|
+
await record(await usageRewards.claimBuyerReward(signer, ctx.address, epoch), 'Buyer usage reward claimed');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (buckets.includes('legacy')) {
|
|
219
|
+
const legacy = ctx.legacyEmissionsAt(stack.legacyEmissions);
|
|
220
|
+
if (legacy && epochs.legacy.length > 0) {
|
|
221
|
+
await claimEpochRewards(epochs.legacy, async (batch) => (await legacy.pendingEmissions(ctx.address, batch)).seller, async (batch) => { await report(`Claiming legacy seller emissions for epochs ${batch[0]}…${batch[batch.length - 1]}`); return legacy.claimSellerEmissions(signer, batch); }, async (hash) => record(hash, 'Legacy seller emissions claimed'));
|
|
222
|
+
await claimEpochRewards(epochs.legacy, async (batch) => (await legacy.pendingEmissions(ctx.address, batch)).buyer, async (batch) => { await report(`Claiming legacy buyer emissions for epochs ${batch[0]}…${batch[batch.length - 1]}`); return legacy.claimBuyerEmissions(signer, ctx.address, batch); }, async (hash) => record(hash, 'Legacy buyer emissions claimed'));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (buckets.includes('locked')) {
|
|
226
|
+
const locked = ctx.lockedPoolAt(stack.lockedRewardsPool);
|
|
227
|
+
if (locked) {
|
|
228
|
+
const info = await safe(() => locked.claimable(ctx.address), { locked: 0n, claimable: 0n, policy: ZeroAddress });
|
|
229
|
+
if (info.claimable > 0n) {
|
|
230
|
+
await report(`Releasing ${formatAnts(info.claimable)} ANTS from the locked legacy rewards pool`);
|
|
231
|
+
await record(await locked.claim(signer, recipient), 'Locked rewards released');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
ctx.invalidate();
|
|
236
|
+
return { claimed: claimed.toString(), transactions, buckets };
|
|
237
|
+
}
|
|
238
|
+
export async function restake(ctx, request, report = silentReporter) {
|
|
239
|
+
const signer = ctx.requireSigner();
|
|
240
|
+
const pools = ctx.requirePools();
|
|
241
|
+
const poolRewards = ctx.requirePoolRewards();
|
|
242
|
+
const config = await pools.poolConfig();
|
|
243
|
+
const epochs = assertEpochs(request.epochs, config.minStakeEpochs, config.maxStakeEpochs);
|
|
244
|
+
const requested = request.positionIds && request.positionIds.length > 0 ? assertPositiveIds(request.positionIds) : null;
|
|
245
|
+
const includeIds = requested ?? (await closedPositionIds(ctx)).ids;
|
|
246
|
+
const pending = (await previewPoolRewards(pools, poolRewards, ctx.address, undefined, { includeIds }))
|
|
247
|
+
.filter((position) => position.amount > 0n && (!requested || requested.includes(position.id)));
|
|
248
|
+
if (pending.length === 0)
|
|
249
|
+
throw new Error('No staker rewards to restake.');
|
|
250
|
+
await preparePoolIndexes(pools, poolRewards, signer, pending, report);
|
|
251
|
+
const ids = [];
|
|
252
|
+
for (const position of pending)
|
|
253
|
+
if (await poolRewards.pendingIndexedStakerReward(position.id) > 0n)
|
|
254
|
+
ids.push(position.id);
|
|
255
|
+
if (ids.length === 0)
|
|
256
|
+
throw new Error('Rewards are not indexed yet; retry after the next epoch.');
|
|
257
|
+
const transactions = [];
|
|
258
|
+
for (let offset = 0; offset < ids.length; offset += 32) {
|
|
259
|
+
const batch = ids.slice(offset, offset + 32);
|
|
260
|
+
await report(`Restaking rewards from position(s) ${batch.join(', ')} for ${epochs} epoch(s)`);
|
|
261
|
+
const hash = await poolRewards.restakeStakerRewardsBatch(signer, batch, epochs);
|
|
262
|
+
transactions.push(hash);
|
|
263
|
+
await report('Restake confirmed', hash);
|
|
264
|
+
}
|
|
265
|
+
ctx.invalidate();
|
|
266
|
+
return { transactions, positionIds: ids, epochs };
|
|
267
|
+
}
|
|
268
|
+
export async function stakeUsageRewards(ctx, request, report = silentReporter) {
|
|
269
|
+
const signer = ctx.requireSigner();
|
|
270
|
+
const stack = await ctx.stack();
|
|
271
|
+
if (stack.phase !== 'active')
|
|
272
|
+
throw new Error('Usage rewards can be staked once recognized usage is active.');
|
|
273
|
+
const pools = ctx.requirePools();
|
|
274
|
+
const usageRewards = ctx.usageRewards();
|
|
275
|
+
if (!usageRewards)
|
|
276
|
+
throw new Error('Usage rewards contract is not configured.');
|
|
277
|
+
const config = await pools.poolConfig();
|
|
278
|
+
const epochs = assertEpochs(request.epochs, config.minStakeEpochs, config.maxStakeEpochs);
|
|
279
|
+
const claimable = await ctx.claimableEpochs();
|
|
280
|
+
const transactions = [];
|
|
281
|
+
const epochsStaked = [];
|
|
282
|
+
if (request.side === 'seller') {
|
|
283
|
+
const agentId = await agentIdOf(ctx);
|
|
284
|
+
if (!agentId)
|
|
285
|
+
throw new Error('This wallet has no seller agent.');
|
|
286
|
+
for (const epoch of claimable.recognized) {
|
|
287
|
+
if (await safe(() => usageRewards.agentEpochClaimed(agentId, epoch), true))
|
|
288
|
+
continue;
|
|
289
|
+
if (await safe(() => usageRewards.pendingAgentReward(agentId, epoch), 0n) === 0n)
|
|
290
|
+
continue;
|
|
291
|
+
await report(`Staking seller usage reward for epoch ${epoch} into agent ${agentId}`);
|
|
292
|
+
const hash = await usageRewards.stakeAgentReward(signer, agentId, epoch, epochs);
|
|
293
|
+
transactions.push(hash);
|
|
294
|
+
epochsStaked.push(epoch);
|
|
295
|
+
await report('Reward staked', hash);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
const stakeAgentId = assertAgentId(request.stakeAgentId);
|
|
300
|
+
const operator = await buyerOperator(ctx);
|
|
301
|
+
if (operator && !sameAddress(operator, ctx.address))
|
|
302
|
+
throw new Error(`Buyer usage rewards belong to the deposits operator ${operator}; stake them from that wallet.`);
|
|
303
|
+
for (const epoch of claimable.recognized) {
|
|
304
|
+
if (await safe(() => usageRewards.buyerEpochClaimed(ctx.address, epoch), true))
|
|
305
|
+
continue;
|
|
306
|
+
if (await safe(() => usageRewards.pendingBuyerReward(ctx.address, epoch), 0n) === 0n)
|
|
307
|
+
continue;
|
|
308
|
+
await report(`Staking buyer usage reward for epoch ${epoch} into agent ${stakeAgentId}`);
|
|
309
|
+
const hash = await usageRewards.stakeBuyerReward(signer, ctx.address, epoch, stakeAgentId, epochs);
|
|
310
|
+
transactions.push(hash);
|
|
311
|
+
epochsStaked.push(epoch);
|
|
312
|
+
await report('Reward staked', hash);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (transactions.length === 0)
|
|
316
|
+
throw new Error('No unclaimed usage rewards to stake.');
|
|
317
|
+
ctx.invalidate();
|
|
318
|
+
return { transactions, epochsStaked };
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Restake everything that can be restaked in one job: indexed staker rewards
|
|
322
|
+
* (with the restake weight bonus, into their source pools), seller usage
|
|
323
|
+
* rewards into the seller's own pool, and buyer usage rewards into
|
|
324
|
+
* `stakeAgentId` (default `targetAgentId`) when this wallet is the deposits
|
|
325
|
+
* operator. When `targetAgentId` is given, every new position that landed in
|
|
326
|
+
* another pool is then moved there (principal, lock, and bonus preserved;
|
|
327
|
+
* the move takes effect next epoch). Legacy and locked-pool rewards have no
|
|
328
|
+
* stake path and are left for `claim`.
|
|
329
|
+
*/
|
|
330
|
+
export async function compound(ctx, request, report = silentReporter) {
|
|
331
|
+
const pools = ctx.requirePools();
|
|
332
|
+
const targetAgentId = request.targetAgentId === undefined ? null : assertAgentId(request.targetAgentId);
|
|
333
|
+
if (targetAgentId !== null) {
|
|
334
|
+
const registry = ctx.sellerRegistry();
|
|
335
|
+
const seller = registry ? await safe(() => registry.agentSeller(targetAgentId), ZeroAddress) : ZeroAddress;
|
|
336
|
+
if (sameAddress(seller, ZeroAddress))
|
|
337
|
+
throw new Error(`Agent ${targetAgentId} has no seller bound in the seller registry, so it has no stakeable pool.`);
|
|
338
|
+
}
|
|
339
|
+
const before = new Set(await pools.allStakerPositionIds(ctx.address));
|
|
340
|
+
const result = { transactions: [], restakedPositionIds: [], sellerEpochs: [], buyerEpochs: [], newPositionIds: [], movedPositionIds: [], targetAgentId };
|
|
341
|
+
try {
|
|
342
|
+
const restaked = await restake(ctx, { epochs: request.epochs }, report);
|
|
343
|
+
result.transactions.push(...restaked.transactions);
|
|
344
|
+
result.restakedPositionIds = restaked.positionIds;
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
if (!/No staker rewards|not indexed/.test(error.message))
|
|
348
|
+
throw error;
|
|
349
|
+
await report('No staker rewards to restake');
|
|
350
|
+
}
|
|
351
|
+
const stack = await ctx.stack();
|
|
352
|
+
if (stack.phase === 'active') {
|
|
353
|
+
const agentId = await agentIdOf(ctx);
|
|
354
|
+
if (agentId) {
|
|
355
|
+
try {
|
|
356
|
+
const seller = await stakeUsageRewards(ctx, { side: 'seller', epochs: request.epochs }, report);
|
|
357
|
+
result.transactions.push(...seller.transactions);
|
|
358
|
+
result.sellerEpochs = seller.epochsStaked;
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
if (!/No unclaimed usage rewards/.test(error.message))
|
|
362
|
+
throw error;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
const operator = await buyerOperator(ctx);
|
|
366
|
+
if (sameAddress(operator, ctx.address)) {
|
|
367
|
+
const stakeAgentId = request.stakeAgentId ?? targetAgentId ?? agentId;
|
|
368
|
+
if (stakeAgentId) {
|
|
369
|
+
try {
|
|
370
|
+
const buyer = await stakeUsageRewards(ctx, { side: 'buyer', epochs: request.epochs, stakeAgentId }, report);
|
|
371
|
+
result.transactions.push(...buyer.transactions);
|
|
372
|
+
result.buyerEpochs = buyer.epochsStaked;
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
if (!/No unclaimed usage rewards/.test(error.message))
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
if (result.transactions.length === 0)
|
|
382
|
+
throw new Error('Nothing to restake.');
|
|
383
|
+
const created = (await pools.allStakerPositionIds(ctx.address)).filter((id) => !before.has(id));
|
|
384
|
+
result.newPositionIds = created;
|
|
385
|
+
if (targetAgentId !== null && created.length > 0) {
|
|
386
|
+
const positions = await pools.positionsBatch(created);
|
|
387
|
+
const toMove = positions.filter((position) => position.agentId !== targetAgentId).map((position) => position.id);
|
|
388
|
+
if (toMove.length > 0) {
|
|
389
|
+
await report(`Moving ${toMove.length} new position(s) into agent ${targetAgentId} (effective next epoch)`);
|
|
390
|
+
const hash = await pools.moveStakes(ctx.requireSigner(), toMove, targetAgentId);
|
|
391
|
+
result.transactions.push(hash);
|
|
392
|
+
result.movedPositionIds = toMove;
|
|
393
|
+
await report('Move confirmed', hash);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
ctx.invalidate();
|
|
397
|
+
return result;
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=rewards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewards.js","sourceRoot":"","sources":["../../src/service/rewards.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { JsonRpcProvider, type JsonRpcPayload, type JsonRpcResult } from 'ethers';
|
|
2
|
+
export interface RpcTransportResponse {
|
|
3
|
+
status: number;
|
|
4
|
+
/** Parsed JSON body, or null when the body is not JSON. */
|
|
5
|
+
body: unknown;
|
|
6
|
+
}
|
|
7
|
+
export type RpcTransport = (url: string, body: string) => Promise<RpcTransportResponse>;
|
|
8
|
+
/**
|
|
9
|
+
* JSON-RPC provider over several endpoints that sends each call to the first
|
|
10
|
+
* endpoint not cooling down. An endpoint that answers 429 (or a JSON-RPC
|
|
11
|
+
* rate-limit error) is put on a cooldown and paced afterwards, and the call
|
|
12
|
+
* moves to the next one; the ethers failover provider instead fans a stalled
|
|
13
|
+
* call out to every endpoint and waits for the slowest. When every endpoint
|
|
14
|
+
* is cooling down the call fails fast rather than waiting out a cooldown.
|
|
15
|
+
* Endpoints are tried in the order given, so pass them best first.
|
|
16
|
+
*/
|
|
17
|
+
export declare class RotatingJsonRpcProvider extends JsonRpcProvider {
|
|
18
|
+
private readonly endpoints;
|
|
19
|
+
private readonly transport;
|
|
20
|
+
private readonly now;
|
|
21
|
+
constructor(urls: string[], evmChainId?: number, options?: {
|
|
22
|
+
transport?: RpcTransport;
|
|
23
|
+
now?: () => number;
|
|
24
|
+
});
|
|
25
|
+
/** Endpoint the next call would go to (the first one once everything is cooling down). */
|
|
26
|
+
get activeUrl(): string;
|
|
27
|
+
get urls(): string[];
|
|
28
|
+
_send(payload: JsonRpcPayload | JsonRpcPayload[]): Promise<JsonRpcResult[]>;
|
|
29
|
+
private pick;
|
|
30
|
+
private cool;
|
|
31
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { FetchRequest, JsonRpcProvider } from 'ethers';
|
|
2
|
+
import { TokenBucket } from './rate-limit.js';
|
|
3
|
+
const REQUEST_TIMEOUT_MS = 10_000;
|
|
4
|
+
const THROTTLE_COOLDOWN_MS = 20_000;
|
|
5
|
+
/** Once an endpoint has throttled, its calls are paced below the budget the public gateways were measured to allow. */
|
|
6
|
+
const PACED_CALLS_PER_SECOND = 12;
|
|
7
|
+
const RATE_LIMIT_CODE = -32005;
|
|
8
|
+
/**
|
|
9
|
+
* JSON-RPC provider over several endpoints that sends each call to the first
|
|
10
|
+
* endpoint not cooling down. An endpoint that answers 429 (or a JSON-RPC
|
|
11
|
+
* rate-limit error) is put on a cooldown and paced afterwards, and the call
|
|
12
|
+
* moves to the next one; the ethers failover provider instead fans a stalled
|
|
13
|
+
* call out to every endpoint and waits for the slowest. When every endpoint
|
|
14
|
+
* is cooling down the call fails fast rather than waiting out a cooldown.
|
|
15
|
+
* Endpoints are tried in the order given, so pass them best first.
|
|
16
|
+
*/
|
|
17
|
+
export class RotatingJsonRpcProvider extends JsonRpcProvider {
|
|
18
|
+
endpoints;
|
|
19
|
+
transport;
|
|
20
|
+
now;
|
|
21
|
+
constructor(urls, evmChainId, options = {}) {
|
|
22
|
+
if (urls.length === 0)
|
|
23
|
+
throw new Error('At least one RPC endpoint is required.');
|
|
24
|
+
super(urls[0], evmChainId, { staticNetwork: !!evmChainId, batchMaxCount: 1 });
|
|
25
|
+
this.endpoints = urls.map((url) => ({ url, coolingUntil: 0, bucket: null }));
|
|
26
|
+
this.transport = options.transport ?? fetchTransport;
|
|
27
|
+
this.now = options.now ?? Date.now;
|
|
28
|
+
}
|
|
29
|
+
/** Endpoint the next call would go to (the first one once everything is cooling down). */
|
|
30
|
+
get activeUrl() {
|
|
31
|
+
return (this.pick() ?? this.endpoints[0]).url;
|
|
32
|
+
}
|
|
33
|
+
get urls() {
|
|
34
|
+
return this.endpoints.map((endpoint) => endpoint.url);
|
|
35
|
+
}
|
|
36
|
+
async _send(payload) {
|
|
37
|
+
const calls = Array.isArray(payload) ? payload.length : 1;
|
|
38
|
+
const body = JSON.stringify(payload);
|
|
39
|
+
let lastError = null;
|
|
40
|
+
for (let attempt = 0; attempt < this.endpoints.length; attempt++) {
|
|
41
|
+
const endpoint = this.pick();
|
|
42
|
+
if (!endpoint)
|
|
43
|
+
break;
|
|
44
|
+
if (endpoint.bucket)
|
|
45
|
+
await endpoint.bucket.take(calls);
|
|
46
|
+
let response;
|
|
47
|
+
try {
|
|
48
|
+
response = await this.transport(endpoint.url, body);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
lastError = error;
|
|
52
|
+
this.cool(endpoint);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (response.status === 429 || isRateLimited(response.body)) {
|
|
56
|
+
lastError = new Error(`${endpoint.url} is rate limiting requests`);
|
|
57
|
+
this.cool(endpoint);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (response.status < 200 || response.status >= 300) {
|
|
61
|
+
throw new Error(`${endpoint.url} responded with HTTP ${response.status}`);
|
|
62
|
+
}
|
|
63
|
+
return (Array.isArray(response.body) ? response.body : [response.body]);
|
|
64
|
+
}
|
|
65
|
+
throw lastError ?? new Error('Every RPC endpoint is rate limiting requests; retry in a few seconds.');
|
|
66
|
+
}
|
|
67
|
+
pick() {
|
|
68
|
+
const now = this.now();
|
|
69
|
+
return this.endpoints.find((endpoint) => endpoint.coolingUntil <= now);
|
|
70
|
+
}
|
|
71
|
+
cool(endpoint) {
|
|
72
|
+
endpoint.coolingUntil = this.now() + THROTTLE_COOLDOWN_MS;
|
|
73
|
+
endpoint.bucket ??= new TokenBucket(PACED_CALLS_PER_SECOND, PACED_CALLS_PER_SECOND);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function isRateLimited(body) {
|
|
77
|
+
const entries = Array.isArray(body) ? body : [body];
|
|
78
|
+
return entries.some((entry) => {
|
|
79
|
+
const error = entry?.error;
|
|
80
|
+
return !!error && (error.code === RATE_LIMIT_CODE || /rate limit/i.test(String(error.message ?? '')));
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async function fetchTransport(url, body) {
|
|
84
|
+
const request = new FetchRequest(url);
|
|
85
|
+
request.timeout = REQUEST_TIMEOUT_MS;
|
|
86
|
+
request.retryFunc = async () => false;
|
|
87
|
+
request.setHeader('content-type', 'application/json');
|
|
88
|
+
request.body = body;
|
|
89
|
+
const response = await request.send();
|
|
90
|
+
let parsed = null;
|
|
91
|
+
try {
|
|
92
|
+
parsed = response.bodyJson;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
parsed = null;
|
|
96
|
+
}
|
|
97
|
+
return { status: response.statusCode, body: parsed };
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=rpc-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-provider.js","sourceRoot":"","sources":["../../src/service/rpc-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AntsContext } from './context.js';
|
|
2
|
+
import type { SellerView } from '../api-types.js';
|
|
3
|
+
import { type StepReporter } from './steps.js';
|
|
4
|
+
export declare function seller(ctx: AntsContext): Promise<SellerView>;
|
|
5
|
+
export declare function registerBinding(ctx: AntsContext, agentIdInput?: number, report?: StepReporter): Promise<{
|
|
6
|
+
agentId: number;
|
|
7
|
+
sent: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function claimStarter(ctx: AntsContext, report?: StepReporter): Promise<{
|
|
10
|
+
hash: string;
|
|
11
|
+
agentId: number;
|
|
12
|
+
amount: string;
|
|
13
|
+
endEpoch: number;
|
|
14
|
+
}>;
|