@helium/helium-admin-cli 0.11.7 → 0.11.8
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/lib/cjs/close-auto-topoff.js +122 -0
- package/lib/cjs/close-auto-topoff.js.map +1 -0
- package/lib/cjs/issue-service-rewards-nft.js +1 -1
- package/lib/cjs/issue-service-rewards-nft.js.map +1 -1
- package/lib/esm/src/close-auto-topoff.js +81 -0
- package/lib/esm/src/close-auto-topoff.js.map +1 -0
- package/lib/esm/src/issue-service-rewards-nft.js +1 -1
- package/lib/esm/src/issue-service-rewards-nft.js.map +1 -1
- package/lib/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/src/close-auto-topoff.d.ts +2 -0
- package/lib/types/src/close-auto-topoff.d.ts.map +1 -0
- package/package.json +15 -15
- package/lib/cjs/claim-and-close-subscriber-key-to-assets.js +0 -664
- package/lib/cjs/claim-and-close-subscriber-key-to-assets.js.map +0 -1
- package/lib/cjs/close-all-subscriber-recipients.js +0 -329
- package/lib/cjs/close-all-subscriber-recipients.js.map +0 -1
- package/lib/esm/src/claim-and-close-subscriber-key-to-assets.js +0 -616
- package/lib/esm/src/claim-and-close-subscriber-key-to-assets.js.map +0 -1
- package/lib/esm/src/close-all-subscriber-recipients.js +0 -287
- package/lib/esm/src/close-all-subscriber-recipients.js.map +0 -1
- package/lib/types/src/claim-and-close-subscriber-key-to-assets.d.ts +0 -2
- package/lib/types/src/claim-and-close-subscriber-key-to-assets.d.ts.map +0 -1
- package/lib/types/src/close-all-subscriber-recipients.d.ts +0 -2
- package/lib/types/src/close-all-subscriber-recipients.d.ts.map +0 -1
|
@@ -1,616 +0,0 @@
|
|
|
1
|
-
import * as anchor from "@coral-xyz/anchor";
|
|
2
|
-
import * as client from "@helium/distributor-oracle";
|
|
3
|
-
import { init as initHem, keyToAssetForAsset, rewardableEntityConfigKey, iotInfoKey, mobileInfoKey, decodeEntityKey, } from "@helium/helium-entity-manager-sdk";
|
|
4
|
-
import { daoKey, subDaoKey } from "@helium/helium-sub-daos-sdk";
|
|
5
|
-
import { init as initLazy, lazyDistributorKey, recipientKey, } from "@helium/lazy-distributor-sdk";
|
|
6
|
-
import { init as initRewards } from "@helium/rewards-oracle-sdk";
|
|
7
|
-
import { init as initMem } from "@helium/mobile-entity-manager-sdk";
|
|
8
|
-
import { HNT_MINT, MOBILE_MINT, IOT_MINT, getAssetsByGroup, batchInstructionsToTxsWithPriorityFee, bulkSendTransactions, bulkSendRawTransactions, chunks, truthy, } from "@helium/spl-utils";
|
|
9
|
-
import { PublicKey } from "@solana/web3.js";
|
|
10
|
-
import BN from "bn.js";
|
|
11
|
-
import bs58 from "bs58";
|
|
12
|
-
import os from "os";
|
|
13
|
-
import pLimit from "p-limit";
|
|
14
|
-
import yargs from "yargs/yargs";
|
|
15
|
-
import { loadKeypair } from "./utils";
|
|
16
|
-
// Hardcoded key_to_asset addresses from initial migration that need special handling
|
|
17
|
-
// These can be closed even if they have iot_info or mobile_info accounts
|
|
18
|
-
const HARDCODED_KEY_TO_ASSETS = [
|
|
19
|
-
new PublicKey("AcKpRTmy6YKpQaWfLDBUaduQU1kHhNVLrPkW3TmEEqsc"),
|
|
20
|
-
new PublicKey("3stUgrUq4j5BbamGdy7X2Y3dee24EeY5u1F7RHrrmaoP"),
|
|
21
|
-
new PublicKey("4v7nfEN2Wj342Zm6V1Jwk9i5YCUHu6zBAJFENk6Gxzvr"),
|
|
22
|
-
new PublicKey("2RtR6aVt6QgCSdV8LEH6ogWtDXGJpL73aB72DevJKgFC"),
|
|
23
|
-
];
|
|
24
|
-
export async function run(args = process.argv) {
|
|
25
|
-
const yarg = yargs(args).options({
|
|
26
|
-
wallet: {
|
|
27
|
-
alias: "k",
|
|
28
|
-
describe: "Anchor wallet keypair",
|
|
29
|
-
default: `${os.homedir()}/.config/solana/id.json`,
|
|
30
|
-
},
|
|
31
|
-
url: {
|
|
32
|
-
alias: "u",
|
|
33
|
-
default: "http://127.0.0.1:8899",
|
|
34
|
-
describe: "The solana url",
|
|
35
|
-
},
|
|
36
|
-
authority: {
|
|
37
|
-
type: "string",
|
|
38
|
-
describe: "Path to the authority keypair. Defaults to wallet.",
|
|
39
|
-
},
|
|
40
|
-
commit: {
|
|
41
|
-
type: "boolean",
|
|
42
|
-
describe: "Actually claim and close accounts. Otherwise dry-run",
|
|
43
|
-
default: false,
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
const argv = await yarg.argv;
|
|
47
|
-
process.env.ANCHOR_WALLET = argv.wallet;
|
|
48
|
-
process.env.ANCHOR_PROVIDER_URL = argv.url;
|
|
49
|
-
anchor.setProvider(anchor.AnchorProvider.local(argv.url));
|
|
50
|
-
const provider = anchor.getProvider();
|
|
51
|
-
const lazyProgram = await initLazy(provider);
|
|
52
|
-
const hemProgram = await initHem(provider);
|
|
53
|
-
const rewardsOracleProgram = await initRewards(provider);
|
|
54
|
-
const memProgram = await initMem(provider);
|
|
55
|
-
const authority = argv.authority
|
|
56
|
-
? loadKeypair(argv.authority)
|
|
57
|
-
: loadKeypair(argv.wallet);
|
|
58
|
-
const dao = daoKey(HNT_MINT)[0];
|
|
59
|
-
const mobileSubDao = subDaoKey(MOBILE_MINT)[0];
|
|
60
|
-
const iotSubDao = subDaoKey(IOT_MINT)[0];
|
|
61
|
-
const mobileConfig = rewardableEntityConfigKey(mobileSubDao, "MOBILE")[0];
|
|
62
|
-
const iotConfig = rewardableEntityConfigKey(iotSubDao, "IOT")[0];
|
|
63
|
-
const lazyDistributor = lazyDistributorKey(MOBILE_MINT)[0];
|
|
64
|
-
// ========== STEP 1: Find all subscriber assets AND hardcoded key_to_assets ==========
|
|
65
|
-
console.log("=== STEP 1: FINDING KEY_TO_ASSET ACCOUNTS ===\n");
|
|
66
|
-
// Build list of key_to_asset info
|
|
67
|
-
const keyToAssetInfos = [];
|
|
68
|
-
// Process hardcoded key_to_assets FIRST
|
|
69
|
-
// Note: We fetch these to get assetId and asset data (for entityKey)
|
|
70
|
-
console.log(`Checking ${HARDCODED_KEY_TO_ASSETS.length} hardcoded accounts...`);
|
|
71
|
-
const hardcodedAccounts = await Promise.all(HARDCODED_KEY_TO_ASSETS.map(async (keyToAssetAddr) => {
|
|
72
|
-
try {
|
|
73
|
-
const keyToAssetAcc = await hemProgram.account.keyToAssetV0.fetch(keyToAssetAddr);
|
|
74
|
-
return {
|
|
75
|
-
keyToAsset: keyToAssetAddr,
|
|
76
|
-
assetId: keyToAssetAcc.asset,
|
|
77
|
-
entityKey: Buffer.from(keyToAssetAcc.entityKey),
|
|
78
|
-
isHardcoded: true,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
catch (err) {
|
|
82
|
-
return null; // Already closed
|
|
83
|
-
}
|
|
84
|
-
}));
|
|
85
|
-
keyToAssetInfos.push(...hardcodedAccounts.filter((a) => a !== null));
|
|
86
|
-
if (keyToAssetInfos.length > 0) {
|
|
87
|
-
console.log(` Found ${keyToAssetInfos.length} hardcoded key_to_assets\n`);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
console.log(` All hardcoded accounts already closed\n`);
|
|
91
|
-
}
|
|
92
|
-
// Find all subscriber assets using DAS
|
|
93
|
-
// Strategy: Fetch all MakerV0 accounts, identify subscriber collections, search by those
|
|
94
|
-
console.log("Finding all subscriber assets via DAS...");
|
|
95
|
-
const allSubscriberAssets = new Map(); // Dedupe by asset ID
|
|
96
|
-
try {
|
|
97
|
-
// Fetch all CarrierV0 accounts to get subscriber collections
|
|
98
|
-
console.log("Fetching CarrierV0 accounts...");
|
|
99
|
-
const carriers = await memProgram.account.carrierV0.all();
|
|
100
|
-
const subscriberCollections = new Set();
|
|
101
|
-
for (const carrier of carriers) {
|
|
102
|
-
subscriberCollections.add(carrier.account.collection.toBase58());
|
|
103
|
-
}
|
|
104
|
-
console.log(` Found ${subscriberCollections.size} subscriber collection(s) from ${carriers.length} carriers`);
|
|
105
|
-
if (subscriberCollections.size === 0) {
|
|
106
|
-
console.log(" No subscriber collections found");
|
|
107
|
-
}
|
|
108
|
-
// Search each subscriber collection using cursor-based pagination
|
|
109
|
-
console.log("Searching DAS for subscriber assets...");
|
|
110
|
-
// Retry wrapper for DAS calls with exponential backoff
|
|
111
|
-
async function getAssetsWithRetry(endpoint, params, maxRetries = 5) {
|
|
112
|
-
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
113
|
-
try {
|
|
114
|
-
return await getAssetsByGroup(endpoint, params);
|
|
115
|
-
}
|
|
116
|
-
catch (err) {
|
|
117
|
-
if (attempt === maxRetries - 1) {
|
|
118
|
-
throw err;
|
|
119
|
-
}
|
|
120
|
-
// Exponential backoff: 2s, 4s, 8s, 16s, 30s
|
|
121
|
-
const delay = Math.min(2000 * Math.pow(2, attempt), 30000);
|
|
122
|
-
const errorMsg = err.message || err.toString();
|
|
123
|
-
console.log(` Error: ${errorMsg.substring(0, 80)}... retrying in ${delay / 1000}s (attempt ${attempt + 1}/${maxRetries})`);
|
|
124
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
throw new Error("Max retries exceeded");
|
|
128
|
-
}
|
|
129
|
-
for (const collection of subscriberCollections) {
|
|
130
|
-
const limit = 1000;
|
|
131
|
-
const startSize = allSubscriberAssets.size;
|
|
132
|
-
let cursor = undefined;
|
|
133
|
-
let fetchCount = 0;
|
|
134
|
-
const startTime = Date.now();
|
|
135
|
-
console.log(` Collection ${collection}: Starting...`);
|
|
136
|
-
while (true) {
|
|
137
|
-
const result = await getAssetsWithRetry(provider.connection.rpcEndpoint, {
|
|
138
|
-
groupValue: collection,
|
|
139
|
-
limit,
|
|
140
|
-
cursor,
|
|
141
|
-
});
|
|
142
|
-
for (const asset of result.items) {
|
|
143
|
-
allSubscriberAssets.set(asset.id.toBase58(), asset);
|
|
144
|
-
}
|
|
145
|
-
fetchCount++;
|
|
146
|
-
const collectionTotal = allSubscriberAssets.size - startSize;
|
|
147
|
-
// Show progress: first 3 fetches, then every 25 fetches
|
|
148
|
-
if (fetchCount <= 3 || fetchCount % 25 === 0) {
|
|
149
|
-
console.log(` ${fetchCount} fetches: ${collectionTotal.toLocaleString()} assets`);
|
|
150
|
-
}
|
|
151
|
-
// Stop if no cursor returned (indicates end of data)
|
|
152
|
-
if (!result.cursor) {
|
|
153
|
-
break;
|
|
154
|
-
}
|
|
155
|
-
cursor = result.cursor;
|
|
156
|
-
// Small delay to avoid rate limits (100ms between fetches)
|
|
157
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
158
|
-
}
|
|
159
|
-
const thisCollectionTotal = allSubscriberAssets.size - startSize;
|
|
160
|
-
const totalTime = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
161
|
-
console.log(` Complete: ${thisCollectionTotal.toLocaleString()} assets in ${fetchCount} fetches (${totalTime}s, cumulative: ${allSubscriberAssets.size.toLocaleString()})`);
|
|
162
|
-
}
|
|
163
|
-
console.log(`\nTotal unique subscriber assets found: ${allSubscriberAssets.size}`);
|
|
164
|
-
console.log("Processing assets into key_to_asset accounts...");
|
|
165
|
-
const existingKeyToAssetSet = new Set(keyToAssetInfos.map((k) => k.keyToAsset.toBase58()));
|
|
166
|
-
let processed = 0;
|
|
167
|
-
for (const asset of allSubscriberAssets.values()) {
|
|
168
|
-
const keyToAssetAddr = keyToAssetForAsset(asset, dao);
|
|
169
|
-
// Ensure keyToAssetAddr is a PublicKey
|
|
170
|
-
const keyToAssetPubkey = typeof keyToAssetAddr === "string"
|
|
171
|
-
? new PublicKey(keyToAssetAddr)
|
|
172
|
-
: keyToAssetAddr;
|
|
173
|
-
// Skip if already in list (from hardcoded)
|
|
174
|
-
const keyToAssetStr = keyToAssetPubkey.toBase58();
|
|
175
|
-
if (!existingKeyToAssetSet.has(keyToAssetStr)) {
|
|
176
|
-
keyToAssetInfos.push({
|
|
177
|
-
keyToAsset: keyToAssetPubkey,
|
|
178
|
-
assetId: asset.id,
|
|
179
|
-
asset: asset,
|
|
180
|
-
isHardcoded: false,
|
|
181
|
-
});
|
|
182
|
-
existingKeyToAssetSet.add(keyToAssetStr);
|
|
183
|
-
}
|
|
184
|
-
processed++;
|
|
185
|
-
// Show progress every 100k assets
|
|
186
|
-
if (processed % 100000 === 0) {
|
|
187
|
-
console.log(` Processed ${processed.toLocaleString()} / ${allSubscriberAssets.size.toLocaleString()} assets...`);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
console.log(` Processed all ${allSubscriberAssets.size.toLocaleString()} assets\n`);
|
|
191
|
-
// Free memory - no longer need full asset objects or dedup set
|
|
192
|
-
allSubscriberAssets.clear();
|
|
193
|
-
existingKeyToAssetSet.clear();
|
|
194
|
-
}
|
|
195
|
-
catch (err) {
|
|
196
|
-
console.log(`\n⚠️ DAS search failed: ${err.message}`);
|
|
197
|
-
console.log(` Continuing with ${keyToAssetInfos.length} hardcoded key_to_assets only.`);
|
|
198
|
-
}
|
|
199
|
-
const hardcodedCount = keyToAssetInfos.filter((k) => k.isHardcoded).length;
|
|
200
|
-
const subscriberCount = keyToAssetInfos.filter((k) => !k.isHardcoded).length;
|
|
201
|
-
console.log(`\nTotal: ${keyToAssetInfos.length.toLocaleString()} key_to_asset accounts (${hardcodedCount} hardcoded, ${subscriberCount.toLocaleString()} subscribers)`);
|
|
202
|
-
// Extract entity keys (try URI first, fetch as fallback)
|
|
203
|
-
console.log("Extracting entity keys from asset data...");
|
|
204
|
-
const existingKeyToAssets = [];
|
|
205
|
-
const needsFetch = [];
|
|
206
|
-
// Try to extract from URI first
|
|
207
|
-
keyToAssetInfos.forEach((info) => {
|
|
208
|
-
if (info.entityKey) {
|
|
209
|
-
// Hardcoded account - already have entity key
|
|
210
|
-
existingKeyToAssets.push({
|
|
211
|
-
keyToAsset: info.keyToAsset,
|
|
212
|
-
assetId: info.assetId,
|
|
213
|
-
entityKey: info.entityKey,
|
|
214
|
-
isHardcoded: info.isHardcoded,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
else if (info.asset?.content?.json_uri) {
|
|
218
|
-
// Try to extract from URI
|
|
219
|
-
const entityKeyStr = info.asset.content.json_uri.split("/").slice(-1)[0];
|
|
220
|
-
const cleanEntityKeyStr = entityKeyStr
|
|
221
|
-
.split(".")[0]
|
|
222
|
-
.split("?")[0]
|
|
223
|
-
.split("#")[0];
|
|
224
|
-
try {
|
|
225
|
-
const entityKey = Buffer.from(bs58.decode(cleanEntityKeyStr));
|
|
226
|
-
existingKeyToAssets.push({
|
|
227
|
-
keyToAsset: info.keyToAsset,
|
|
228
|
-
assetId: info.assetId,
|
|
229
|
-
entityKey,
|
|
230
|
-
isHardcoded: info.isHardcoded,
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
catch (err) {
|
|
234
|
-
// URI extraction failed - need to fetch
|
|
235
|
-
needsFetch.push(info);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
// No URI - need to fetch
|
|
240
|
-
needsFetch.push(info);
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
console.log(` Extracted ${existingKeyToAssets.length.toLocaleString()} entity keys from URIs`);
|
|
244
|
-
// Fetch the ones that failed URI extraction
|
|
245
|
-
if (needsFetch.length > 0) {
|
|
246
|
-
console.log(` Fetching ${needsFetch.length.toLocaleString()} keyToAssetV0 accounts (URI extraction failed)...`);
|
|
247
|
-
async function fetchKeyToAssetsWithRetry(chunk, maxRetries = 3) {
|
|
248
|
-
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
249
|
-
try {
|
|
250
|
-
const accountInfos = await hemProgram.account.keyToAssetV0.fetchMultiple(chunk.map((k) => k.keyToAsset));
|
|
251
|
-
return { accountInfos, chunk };
|
|
252
|
-
}
|
|
253
|
-
catch (err) {
|
|
254
|
-
if (attempt === maxRetries - 1)
|
|
255
|
-
throw err;
|
|
256
|
-
const delay = Math.min(1000 * Math.pow(2, attempt), 5000);
|
|
257
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
throw new Error("Max retries exceeded");
|
|
261
|
-
}
|
|
262
|
-
const keyToAssetChunks = chunks(needsFetch, 100);
|
|
263
|
-
const keyToAssetLimiter = pLimit(10);
|
|
264
|
-
let keyToAssetFetchedCount = 0;
|
|
265
|
-
let keyToAssetBatchIndex = 0;
|
|
266
|
-
const keyToAssetBatchResults = await Promise.all(keyToAssetChunks.map((chunk) => keyToAssetLimiter(async () => {
|
|
267
|
-
const result = await fetchKeyToAssetsWithRetry(chunk);
|
|
268
|
-
keyToAssetFetchedCount += chunk.length;
|
|
269
|
-
keyToAssetBatchIndex++;
|
|
270
|
-
// Show progress
|
|
271
|
-
if (keyToAssetBatchIndex <= 3 ||
|
|
272
|
-
keyToAssetBatchIndex % 10 === 0 ||
|
|
273
|
-
keyToAssetFetchedCount === needsFetch.length) {
|
|
274
|
-
console.log(` ${keyToAssetBatchIndex} batches: ${keyToAssetFetchedCount.toLocaleString()} accounts`);
|
|
275
|
-
}
|
|
276
|
-
return result;
|
|
277
|
-
})));
|
|
278
|
-
// Process fetched accounts
|
|
279
|
-
keyToAssetBatchResults.forEach(({ accountInfos, chunk }) => {
|
|
280
|
-
accountInfos.forEach((account, index) => {
|
|
281
|
-
if (account) {
|
|
282
|
-
existingKeyToAssets.push({
|
|
283
|
-
keyToAsset: chunk[index].keyToAsset,
|
|
284
|
-
assetId: chunk[index].assetId,
|
|
285
|
-
entityKey: Buffer.from(account.entityKey),
|
|
286
|
-
isHardcoded: chunk[index].isHardcoded,
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
console.log(` Fetched ${keyToAssetFetchedCount.toLocaleString()} entity keys from accounts`);
|
|
292
|
-
}
|
|
293
|
-
console.log(` Total: ${existingKeyToAssets.length.toLocaleString()} entity keys\n`);
|
|
294
|
-
// Free memory - no longer need original key_to_asset infos or assets
|
|
295
|
-
keyToAssetInfos.length = 0;
|
|
296
|
-
// ========== STEP 2: Claim all rewards until none remain ==========
|
|
297
|
-
console.log("\n=== STEP 2: CLAIMING REWARDS ===\n");
|
|
298
|
-
let claimIteration = 0;
|
|
299
|
-
let totalClaimedAmount = new BN(0);
|
|
300
|
-
let totalClaimedTransactions = 0;
|
|
301
|
-
// Build recipient lookup
|
|
302
|
-
console.log(`Fetching ${existingKeyToAssets.length.toLocaleString()} recipient accounts...`);
|
|
303
|
-
const existingRecipients = new Set();
|
|
304
|
-
const recipientKeys = existingKeyToAssets.map(({ assetId }) => recipientKey(lazyDistributor, assetId)[0]);
|
|
305
|
-
async function fetchRecipientsWithRetry(chunk, maxRetries = 3) {
|
|
306
|
-
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
307
|
-
try {
|
|
308
|
-
const accountInfos = await lazyProgram.account.recipientV0.fetchMultiple(chunk);
|
|
309
|
-
return { accountInfos, chunk };
|
|
310
|
-
}
|
|
311
|
-
catch (err) {
|
|
312
|
-
if (attempt === maxRetries - 1)
|
|
313
|
-
throw err;
|
|
314
|
-
const delay = Math.min(1000 * Math.pow(2, attempt), 5000);
|
|
315
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
throw new Error("Max retries exceeded");
|
|
319
|
-
}
|
|
320
|
-
// Fetch recipients with concurrency limit
|
|
321
|
-
const recipientChunks = chunks(recipientKeys, 1000);
|
|
322
|
-
const limiter = pLimit(10);
|
|
323
|
-
let fetchedCount = 0;
|
|
324
|
-
let batchIndex = 0;
|
|
325
|
-
// Build assetsWithRecipients directly while fetching (no extra loops!)
|
|
326
|
-
const assetsWithRecipients = [];
|
|
327
|
-
await Promise.all(recipientChunks.map((chunk, chunkIndex) => limiter(async () => {
|
|
328
|
-
const result = await fetchRecipientsWithRetry(chunk);
|
|
329
|
-
fetchedCount += chunk.length;
|
|
330
|
-
batchIndex++;
|
|
331
|
-
// Calculate starting index for this chunk
|
|
332
|
-
const chunkStartIndex = chunkIndex * 1000;
|
|
333
|
-
// Build assetsWithRecipients directly from results
|
|
334
|
-
result.accountInfos.forEach((info, index) => {
|
|
335
|
-
if (info) {
|
|
336
|
-
const recipientAddr = chunk[index].toBase58();
|
|
337
|
-
existingRecipients.add(recipientAddr);
|
|
338
|
-
// Use index to get corresponding asset (no map lookup!)
|
|
339
|
-
assetsWithRecipients.push(existingKeyToAssets[chunkStartIndex + index]);
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
// Show progress: first 3 batches, then every 25 batches
|
|
343
|
-
if (batchIndex <= 3 ||
|
|
344
|
-
batchIndex % 25 === 0 ||
|
|
345
|
-
fetchedCount === recipientKeys.length) {
|
|
346
|
-
console.log(` ${batchIndex} batches: ${fetchedCount.toLocaleString()} accounts`);
|
|
347
|
-
}
|
|
348
|
-
return result;
|
|
349
|
-
})));
|
|
350
|
-
console.log(` Found ${existingRecipients.size.toLocaleString()} existing recipients\n`);
|
|
351
|
-
console.log(`Checking rewards for ${assetsWithRecipients.length.toLocaleString()} assets with recipients (skipping ${(existingKeyToAssets.length - assetsWithRecipients.length).toLocaleString()} without recipients)\n`);
|
|
352
|
-
while (true) {
|
|
353
|
-
claimIteration++;
|
|
354
|
-
console.log(`--- Claim Iteration ${claimIteration} ---`);
|
|
355
|
-
// Check pending rewards using bulk API
|
|
356
|
-
let assetsWithRewards = 0;
|
|
357
|
-
let assetsWithZeroRewards = 0;
|
|
358
|
-
let totalPendingRewards = new BN(0);
|
|
359
|
-
const assetsToClaim = [];
|
|
360
|
-
// Create map of entityKey -> asset info for lookup
|
|
361
|
-
const entityKeyToAsset = new Map();
|
|
362
|
-
assetsWithRecipients.forEach(({ assetId, entityKey }) => {
|
|
363
|
-
// Decode entity key to string format that oracle expects (b58 for subscriber assets)
|
|
364
|
-
const entityKeyStr = decodeEntityKey(entityKey, { b58: {} });
|
|
365
|
-
if (entityKeyStr) {
|
|
366
|
-
entityKeyToAsset.set(entityKeyStr, {
|
|
367
|
-
assetId,
|
|
368
|
-
entityKey,
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
});
|
|
372
|
-
// Get bulk rewards in chunks
|
|
373
|
-
const entityKeys = Array.from(entityKeyToAsset.keys());
|
|
374
|
-
const rewardsChunks = chunks(entityKeys, 5000);
|
|
375
|
-
const rewardsLimiter = pLimit(5);
|
|
376
|
-
let checkedCount = 0;
|
|
377
|
-
let rewardsBatchIndex = 0;
|
|
378
|
-
const bulkRewardsResults = await Promise.all(rewardsChunks.map((chunk) => rewardsLimiter(async () => {
|
|
379
|
-
try {
|
|
380
|
-
const bulkRewards = await client.getBulkRewards(lazyProgram, lazyDistributor, chunk);
|
|
381
|
-
rewardsBatchIndex++;
|
|
382
|
-
checkedCount += chunk.length;
|
|
383
|
-
// Show progress
|
|
384
|
-
if (rewardsBatchIndex <= 3 ||
|
|
385
|
-
rewardsBatchIndex % 5 === 0 ||
|
|
386
|
-
checkedCount === entityKeys.length) {
|
|
387
|
-
console.log(` ${rewardsBatchIndex} batches: ${checkedCount.toLocaleString()} assets`);
|
|
388
|
-
}
|
|
389
|
-
return { chunk, bulkRewards };
|
|
390
|
-
}
|
|
391
|
-
catch (err) {
|
|
392
|
-
console.error(`Error fetching bulk rewards: ${err.message}`);
|
|
393
|
-
return { chunk, bulkRewards: [] };
|
|
394
|
-
}
|
|
395
|
-
})));
|
|
396
|
-
// Merge bulk rewards from all chunks
|
|
397
|
-
// Each chunk has the same oracle keys but different entity key data
|
|
398
|
-
const mergedBulkRewards = [];
|
|
399
|
-
if (bulkRewardsResults.length > 0 &&
|
|
400
|
-
bulkRewardsResults[0].bulkRewards.length > 0) {
|
|
401
|
-
const numOracles = bulkRewardsResults[0].bulkRewards.length;
|
|
402
|
-
for (let oracleIdx = 0; oracleIdx < numOracles; oracleIdx++) {
|
|
403
|
-
const mergedRewards = {};
|
|
404
|
-
// Merge rewards from all chunks for this oracle
|
|
405
|
-
bulkRewardsResults.forEach(({ bulkRewards }) => {
|
|
406
|
-
if (bulkRewards[oracleIdx]) {
|
|
407
|
-
Object.assign(mergedRewards, bulkRewards[oracleIdx].currentRewards);
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
mergedBulkRewards.push({
|
|
411
|
-
currentRewards: mergedRewards,
|
|
412
|
-
oracleKey: bulkRewardsResults[0].bulkRewards[oracleIdx].oracleKey,
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
// Process rewards using merged bulk rewards
|
|
417
|
-
entityKeys.forEach((entityKey) => {
|
|
418
|
-
const assetInfo = entityKeyToAsset.get(entityKey);
|
|
419
|
-
if (!assetInfo)
|
|
420
|
-
return;
|
|
421
|
-
// Aggregate rewards across all oracles for this entity
|
|
422
|
-
const rewards = mergedBulkRewards.map((oracle) => ({
|
|
423
|
-
currentRewards: oracle.currentRewards[entityKey] || "0",
|
|
424
|
-
oracleKey: oracle.oracleKey,
|
|
425
|
-
}));
|
|
426
|
-
const totalRewards = rewards.reduce((sum, r) => {
|
|
427
|
-
return sum.add(new BN(r.currentRewards));
|
|
428
|
-
}, new BN(0));
|
|
429
|
-
if (totalRewards.gt(new BN(0))) {
|
|
430
|
-
assetsWithRewards++;
|
|
431
|
-
totalPendingRewards = totalPendingRewards.add(totalRewards);
|
|
432
|
-
assetsToClaim.push({
|
|
433
|
-
asset: assetInfo.assetId,
|
|
434
|
-
rewards,
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
assetsWithZeroRewards++;
|
|
439
|
-
}
|
|
440
|
-
});
|
|
441
|
-
const pendingMobile = totalPendingRewards.div(new BN(100000000)).toString();
|
|
442
|
-
console.log(`\nPending: ${assetsWithRewards} assets with ${pendingMobile} MOBILE (${assetsWithZeroRewards} with zero)`);
|
|
443
|
-
// If no more rewards, break out of loop
|
|
444
|
-
if (assetsWithRewards === 0) {
|
|
445
|
-
console.log("\n✓ All rewards have been claimed!");
|
|
446
|
-
break;
|
|
447
|
-
}
|
|
448
|
-
if (!argv.commit) {
|
|
449
|
-
console.log(`\nDry run: would claim rewards for ${assetsWithRewards} assets`);
|
|
450
|
-
break;
|
|
451
|
-
}
|
|
452
|
-
console.log(`\nClaiming rewards for ${assetsWithRewards} assets...`);
|
|
453
|
-
// Batch claim rewards using formBulkTransactions (up to 100 assets per call)
|
|
454
|
-
console.log(`Preparing ${assetsToClaim.length} claim transactions...`);
|
|
455
|
-
const claimChunks = chunks(assetsToClaim, 100); // formBulkTransactions supports up to 100
|
|
456
|
-
const claimTxLimiter = pLimit(10);
|
|
457
|
-
let preparedCount = 0;
|
|
458
|
-
const allBatchTxns = await Promise.all(claimChunks.map((chunk) => claimTxLimiter(async () => {
|
|
459
|
-
try {
|
|
460
|
-
const assets = chunk.map((c) => c.asset);
|
|
461
|
-
// Use formBulkTransactions which is more efficient than individual formTransaction calls
|
|
462
|
-
const txns = await client.formBulkTransactions({
|
|
463
|
-
program: lazyProgram,
|
|
464
|
-
rewardsOracleProgram: rewardsOracleProgram,
|
|
465
|
-
rewards: mergedBulkRewards,
|
|
466
|
-
assets,
|
|
467
|
-
lazyDistributor,
|
|
468
|
-
wallet: authority.publicKey,
|
|
469
|
-
});
|
|
470
|
-
preparedCount += chunk.length;
|
|
471
|
-
// Show progress every 100 or at end
|
|
472
|
-
if (preparedCount % 100 === 0 ||
|
|
473
|
-
preparedCount === assetsToClaim.length) {
|
|
474
|
-
console.log(` Prepared ${preparedCount}/${assetsToClaim.length} transactions`);
|
|
475
|
-
}
|
|
476
|
-
return txns;
|
|
477
|
-
}
|
|
478
|
-
catch (err) {
|
|
479
|
-
console.error(`Error forming bulk transactions for batch: ${err.message}`);
|
|
480
|
-
return [];
|
|
481
|
-
}
|
|
482
|
-
})));
|
|
483
|
-
const txns = allBatchTxns.flat().filter(truthy);
|
|
484
|
-
console.log(`Sending ${txns.length} transactions...`);
|
|
485
|
-
for (const tx of txns) {
|
|
486
|
-
tx.sign([authority]);
|
|
487
|
-
}
|
|
488
|
-
await bulkSendRawTransactions(provider.connection, txns.map((tx) => Buffer.from(tx.serialize())), (status) => {
|
|
489
|
-
// Only show every 10 batches for mainnet scale
|
|
490
|
-
if (status.totalProgress % 10 === 0 ||
|
|
491
|
-
status.totalProgress === txns.length) {
|
|
492
|
-
console.log(` Sent ${status.totalProgress} / ${txns.length}`);
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
totalClaimedAmount = totalClaimedAmount.add(totalPendingRewards);
|
|
496
|
-
totalClaimedTransactions += txns.length;
|
|
497
|
-
console.log(`Iteration ${claimIteration} complete. Claimed ${totalPendingRewards
|
|
498
|
-
.div(new BN(100000000))
|
|
499
|
-
.toString()} MOBILE across ${txns.length} transactions.`);
|
|
500
|
-
// Free memory for next iteration
|
|
501
|
-
assetsToClaim.length = 0;
|
|
502
|
-
txns.length = 0;
|
|
503
|
-
// Wait a bit before next iteration to let chain settle
|
|
504
|
-
console.log("\nWaiting 5 seconds before next check...");
|
|
505
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
506
|
-
}
|
|
507
|
-
const claimedMobile = totalClaimedAmount.div(new BN(100000000)).toString();
|
|
508
|
-
console.log(`\nClaimed ${claimedMobile} MOBILE in ${claimIteration} iteration(s), ${totalClaimedTransactions} tx(s)`);
|
|
509
|
-
// Free memory - no longer need recipient data
|
|
510
|
-
existingRecipients.clear();
|
|
511
|
-
recipientKeys.length = 0;
|
|
512
|
-
// ========== STEP 3: Close all KeyToAssetV0 accounts ==========
|
|
513
|
-
console.log("\n=== STEP 3: CLOSING ACCOUNTS ===\n");
|
|
514
|
-
if (!argv.commit) {
|
|
515
|
-
const closingHardcoded = existingKeyToAssets.filter((k) => k.isHardcoded).length;
|
|
516
|
-
const closingSubscribers = existingKeyToAssets.filter((k) => !k.isHardcoded).length;
|
|
517
|
-
console.log(`Dry run: would close ${existingKeyToAssets.length} accounts (${closingHardcoded} hardcoded, ${closingSubscribers} subscribers)`);
|
|
518
|
-
console.log(`\nRe-run with --commit to execute`);
|
|
519
|
-
console.log(`Then run close-all-subscriber-recipients to close RecipientV0 accounts`);
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
console.log(`Closing ${existingKeyToAssets.length.toLocaleString()} accounts...`);
|
|
523
|
-
// Build close instructions
|
|
524
|
-
const instructions = [];
|
|
525
|
-
// Separate hardcoded (need info checks) from subscribers (no checks needed)
|
|
526
|
-
const hardcodedAccountsToClose = existingKeyToAssets.filter((k) => k.isHardcoded);
|
|
527
|
-
const subscriberAccounts = existingKeyToAssets.filter((k) => !k.isHardcoded);
|
|
528
|
-
console.log(` Hardcoded: ${hardcodedAccountsToClose.length}, Subscribers: ${subscriberAccounts.length.toLocaleString()}`);
|
|
529
|
-
// Process hardcoded accounts (check info accounts)
|
|
530
|
-
if (hardcodedAccountsToClose.length > 0) {
|
|
531
|
-
console.log("Processing hardcoded accounts...");
|
|
532
|
-
for (const { keyToAsset, assetId, entityKey } of hardcodedAccountsToClose) {
|
|
533
|
-
const [mobileInfo] = mobileInfoKey(mobileConfig, entityKey);
|
|
534
|
-
const [iotInfo] = iotInfoKey(iotConfig, entityKey);
|
|
535
|
-
const [mobileInfoAcc, iotInfoAcc] = await Promise.all([
|
|
536
|
-
provider.connection.getAccountInfo(mobileInfo),
|
|
537
|
-
provider.connection.getAccountInfo(iotInfo),
|
|
538
|
-
]);
|
|
539
|
-
console.log(` ${keyToAsset.toBase58()}`);
|
|
540
|
-
console.log(` Mobile Info: ${mobileInfoAcc ? "exists (will close)" : "does not exist"}`);
|
|
541
|
-
console.log(` IoT Info: ${iotInfoAcc ? "exists (will close)" : "does not exist"}`);
|
|
542
|
-
const ix = await hemProgram.methods
|
|
543
|
-
.tempCloseKeyToAssetV0()
|
|
544
|
-
.accountsPartial({
|
|
545
|
-
keyToAsset,
|
|
546
|
-
dao,
|
|
547
|
-
authority: authority.publicKey,
|
|
548
|
-
asset: assetId,
|
|
549
|
-
mobileConfig,
|
|
550
|
-
iotConfig,
|
|
551
|
-
mobileInfo,
|
|
552
|
-
iotInfo,
|
|
553
|
-
iotSubDao,
|
|
554
|
-
mobileSubDao,
|
|
555
|
-
})
|
|
556
|
-
.instruction();
|
|
557
|
-
instructions.push(ix);
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
// Process subscriber accounts (no info checks - they shouldn't have info accounts)
|
|
561
|
-
if (subscriberAccounts.length > 0) {
|
|
562
|
-
console.log(`Processing ${subscriberAccounts.length.toLocaleString()} subscriber accounts...`);
|
|
563
|
-
let processed = 0;
|
|
564
|
-
const subscriberChunks = chunks(subscriberAccounts, 100);
|
|
565
|
-
const instructionLimiter = pLimit(50);
|
|
566
|
-
const allBatchInstructions = await Promise.all(subscriberChunks.map((chunk) => instructionLimiter(async () => {
|
|
567
|
-
const batchInstructions = await Promise.all(chunk.map(async ({ keyToAsset, assetId, entityKey }) => {
|
|
568
|
-
const [mobileInfo] = mobileInfoKey(mobileConfig, entityKey);
|
|
569
|
-
const [iotInfo] = iotInfoKey(iotConfig, entityKey);
|
|
570
|
-
return await hemProgram.methods
|
|
571
|
-
.tempCloseKeyToAssetV0()
|
|
572
|
-
.accountsPartial({
|
|
573
|
-
keyToAsset,
|
|
574
|
-
dao,
|
|
575
|
-
authority: authority.publicKey,
|
|
576
|
-
asset: assetId,
|
|
577
|
-
mobileConfig,
|
|
578
|
-
iotConfig,
|
|
579
|
-
mobileInfo,
|
|
580
|
-
iotInfo,
|
|
581
|
-
iotSubDao,
|
|
582
|
-
mobileSubDao,
|
|
583
|
-
})
|
|
584
|
-
.instruction();
|
|
585
|
-
}));
|
|
586
|
-
processed += chunk.length;
|
|
587
|
-
// Show progress every 10k instructions
|
|
588
|
-
if (processed % 10000 === 0 ||
|
|
589
|
-
processed === subscriberAccounts.length) {
|
|
590
|
-
console.log(` Prepared ${processed.toLocaleString()} / ${subscriberAccounts.length.toLocaleString()} instructions...`);
|
|
591
|
-
}
|
|
592
|
-
return batchInstructions;
|
|
593
|
-
})));
|
|
594
|
-
instructions.push(...allBatchInstructions.flat().filter(truthy));
|
|
595
|
-
}
|
|
596
|
-
console.log(`\nBatching ${instructions.length.toLocaleString()} instructions into transactions...`);
|
|
597
|
-
// Free memory - no longer need existingKeyToAssets
|
|
598
|
-
existingKeyToAssets.length = 0;
|
|
599
|
-
const closeTxns = await batchInstructionsToTxsWithPriorityFee(provider, instructions, {
|
|
600
|
-
useFirstEstimateForAll: true,
|
|
601
|
-
computeUnitLimit: 600000,
|
|
602
|
-
});
|
|
603
|
-
// Free memory - instructions now in transactions
|
|
604
|
-
instructions.length = 0;
|
|
605
|
-
console.log(`\nSending ${closeTxns.length} transactions...`);
|
|
606
|
-
// Sign with authority and send
|
|
607
|
-
await bulkSendTransactions(provider, closeTxns, (status) => {
|
|
608
|
-
console.log(`Sending ${status.currentBatchProgress} / ${status.currentBatchSize} in batch. ${status.totalProgress} / ${closeTxns.length}`);
|
|
609
|
-
}, 10, [authority]);
|
|
610
|
-
const finalClaimedMobile = totalClaimedAmount
|
|
611
|
-
.div(new BN(100000000))
|
|
612
|
-
.toString();
|
|
613
|
-
console.log(`\n✓ Complete: Claimed ${finalClaimedMobile} MOBILE, closed ${instructions.length} accounts`);
|
|
614
|
-
console.log(`Next: run close-all-subscriber-recipients`);
|
|
615
|
-
}
|
|
616
|
-
//# sourceMappingURL=claim-and-close-subscriber-key-to-assets.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"claim-and-close-subscriber-key-to-assets.js","sourceRoot":"","sources":["../../../src/claim-and-close-subscriber-key-to-assets.ts"],"names":[],"mappings":"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"}
|