D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Приветствую форумчане, в прошлой статье я рассказал и показал, как сделать расширение для Google Chrome на JavaScript, и получил положительный отклик — статья вызвала интерес у пользователей. Поэтому немного пораскинув мозгами, я решил что почему бы и нет — вернемся в давно забытое детское ощущение, почувствуем себя скрипткиддис и запилим небольшой цикл статей со всякими полезными мини-тулзами. Какие-то из них будут в формате Proof of Concept, какие-то же наоборот будут готовы к работе почти из коробки. Основная моя задача здесь — показать, что программировать это не сложно, программировать может начать каждый и не обязательно для этого сразу целиться в убертехнологии и мегасложный продукт — можно просто писать небольшие программы, которые улучшают или упрощают жизнь коллег по цеху и на хлеб с маслом вам всегда будет хватать.
Сегодня займемся десктопным приложением. На форуме достаточно предложений по проверке сид-фраз, исходя из этого можно предположить, что есть спрос на инструменты для анализа и мониторинга кошельков. Поэтому статья для тех, кто эти сидки добывает (хоть из паблика) и не хочет ни с кем этой информацией делиться.
Перед тем, как приступим, опишу основной функционал приложения:
Архитектура приложения состоит из нескольких ключевых компонентов:
JavaScript: Скопировать в буфер обмена
Обратите внимание на настройки webPreferences: nodeIntegration: false - отключает прямой доступ к Node.js API из рендерер процесса для безопасности; contextIsolation: true - изолирует preload скрипт от рендерер процесса, а путь к скрипту и странице указываем через preload: path.join(__dirname, 'preload.js') и mainWindow.loadFile('index.html') соответственно.
Далее, определяем обработчики для различных системных событий, эти обработчики обеспечивают корректное поведение приложения при запуске, активации и закрытии:
JavaScript: Скопировать в буфер обмена
Следом функции входного(.txt) и выходного(.json) файлов. Эти обработчики позволяют пользователю выбирать файлы для ввода адресов и сохранения результатов анализа. Использование dialog из Electron обеспечивает нативный опыт работы с файловой системой:
JavaScript: Скопировать в буфер обмена
Чтобы можно было контролировать нагрузку и избегать превышения лимитов запросов API, я использовал очередь для обработки запросов. Эта очередь обрабатывает запросы последовательно, с возможностью повторных попыток в случае ошибок. Это особенно важно при работе с внешними API, где могут возникать временные сбои или ограничения на количество запросов:
JavaScript: Скопировать в буфер обмена
Рассмотрим функционал работы с самими API. Принцип простейший – отправлять запросы с номером кошелька, обрабатывать полученные данные и возвращать результат в унифицированном формате. Я начал тестировать с тем, что попало под руку и где можно было без лишних проблем получить ключ. Начал с Mobula (https://mobula.io/apis), для получения ключа необходимо в нижнем левом углу экрана найти FREE API KEY, перейти по ссылке в документацию https://docs.mobula.io/introduction, там подробно описаны дальнейшие действия. На получение ключа ушло около 2-3 минут, сам сервис выдает лимитированные 10000 кредитов в сутки, но забегая вперед могу сказать, что панелька работает криво, количество кредитов в личном кабинет всегда 0, но и работает также медленно, как и считает.
К таким выводам я смог прийти только через пару часов, приняв тот факт, что скорость обработки запросов зависит не от моих красивых рук, бьющих по клавиатуре. Тем не менее результат API выдает, причем в документации изначально были ответы в развернутом формате, но из-за скорости я порезал просто до общего баланса. Полный список запрашиваемой информации:
Код: Скопировать в буфер обмена
Сама же функция выглядит следующим образом:
JavaScript: Скопировать в буфер обмена
Куда более интересней представлена функция processWalletMoralis, которая использует Moralis API для получения детальной информации о балансах кошелька на различных блокчейнах. Это позволяет получить комплексную картину активов пользователя across different chains. На получение ключа ушло около 10 минут, здесь все просто, но пришлось повозиться с документацией, чтобы понять функционал. Заходим на https://developers.moralis.com, жмем Get API Key, регистрируемся и готово. Панелька интуитивно куда более удобная, считает корректно, API работает быстро, но за один запрос может съедать до тысячи местных кредитов. В бесплатном варианте в сутки выдается 40к кредитов, но за 70 деревянных в месяц можно увеличить лимит до 100млн/месяц, а если языком поработать – можно и в космос улететь.
В документации меня интересовал Get Wallet Net Worth. Основными преимуществами являлись пробив по необходимым блокчейнам и примеры кода/ответов. Блокчейны для анализа там же в доках можете посмотреть, в соответствующей графе (для самых ленивых скрин):
Выбрал несколько для теста (по коду понятно какие именно) и поехали:
JavaScript: Скопировать в буфер обмена
Осталось обработать пользовательский ввод и запустить процесс анализа. Эта функция читает адреса кошельков из входного файла, обрабатывает их с помощью выбранного API, отслеживает прогресс и сохраняет результаты в выходной файл. Обратите внимание на использование requestQueue для контроля скорости запросов и отправку обновлений прогресса в рендерер процесс:
JavaScript: Скопировать в буфер обмена
С функионалом main.js закончили, переходим к preload.js. Код сам по себе – пара строк, но сам скрипт играет ключевую роль в обеспечении безопасности приложения, предоставляя контролируемый интерфейс между основным и рендерер процессами. Я использовал contextBridge для создания безопасного API, доступного из рендерер процесса. Это позволяет контролировать, какие именно функции основного процесса доступны для использования в пользовательском интерфейсе:
JavaScript: Скопировать в буфер обмена
Пользовательский интерфейс приложения сделал с простой структурой: возможность выбрать входной файл с адресами кошельков, указать выходной файл для результатов, выбрать метод анализа (Mobula или Moralis) и ввести API ключ.
HTML: Скопировать в буфер обмена
renderer.js - скрипт обрабатывает нажатие на кнопку "Начать анализ", собирает необходимые данные из пользовательского ввода и вызывает функцию processData через API, предоставленный preload скриптом, обновляет прогресс-бар на основе обновлений, получаемых от основного процесса:
JavaScript: Скопировать в буфер обмена
Что же показали нам тесты? Я зашел на DeBank, выбрал 10 первых попавшихся кошельков, залил в текстовый документ.
Сначала поехала Mobula:
Скорость загрузки 0.45 запрос/минута. На 10 запросов реально ушло около 1241 секунда = больше 20 минут (скорость космическая). На скрине не успел поймать время (сами понимаете - нужна реакция), поэтому не видно результатов, рекомендую поверить на слово, а можете смело самостоятельно протестировать. Результат:
Слегка поиграв с тестами Mobula, начал пробовать Ankr, Zapper API – плюс минус аналогичный результат (изначально я внес в приложение эти API, когда собирал архитектуру, пробовал Debank по HTML парсингу пихнуть, как метод сбора данных, но достойного результата по скорости не было, поэтому удалено безвозвратно). Переборов в себе желание воспользоваться сочетанием клавиш shift+delete для корневой папки, добрался до Moralis. Ожиданий особо не было, но результат оказался приятным: 10 запросов обработались меньше чем за 25 секунд (1500 запросов/час), а это почти в 50 раз быстрее. Конечно, я изначально целился в результат около 1000 запросов в минуту, но практика и тесты показали, что за «спасибо» тебе никто таких объемов не даст (хотя если кто знает – сообщите). А для мелких объемов 5000-10000 запросов и домашнего ознакомительного пользования решил, что пойдет.
При этом ответы были подробными по каждому из блокчейнов, чтобы не грузить в основном тексте статьи, файл с ответами тоже добавлю в архив, пока пример одного кошелька на скрине:
Чем же пришлось заплатить за такие скорость и качество? Лимитом в панельке – съело с запасом, хотя ответ выдал по всем запрашиваемым кошелькам.
Да, приложение сразу не сортирует в списки «есть бабки»/«пустой кош», но это точно быстрее, чем ручками проверять. А если учесть, что написалось приложение буквально за два вечера под сериальчик, то результат считаю приемлемым.
Бонусом закину программу для генерации сидфраз, которую писал забавы ради в прошлом году. Выглядит она следующим образом:
Функционал простой:
Скорость генерации 100к/секунду. Есть функционал выбрать определенное слово из списка (например, если вы знаете одно или несколько слов сидфразы). Есть также возможность генерировать по стандартам BIP0039, в этом случае сначала рассчитывается контрольное слово, потом генерируется сидфраза. Общее количество комбинаций выводится после выбора количества слов и длины последовательности. Такое запредельное количество сгенерировать, сохранить и как следствие монетизировать, сможет только машина с огромными вычислительными мощностями (или команда). Для изучающих Python будет полезно, для тех, кому нечем заняться – весело поиграть со словами из своих сидфраз.
На сегодня все, уважаемые форумчане! Архив с файлами программ и результатами тестов во вложении. Кому было полезно и вызвало интерес – лайкайте, оставляйте комментарии, задавайте вопросы. Если у вас уже есть проплаченный API с отсутствием лимитов по запросам - можете интегрировать и пользоваться!
Patr1ck специально для XSS.is.
Сегодня займемся десктопным приложением. На форуме достаточно предложений по проверке сид-фраз, исходя из этого можно предположить, что есть спрос на инструменты для анализа и мониторинга кошельков. Поэтому статья для тех, кто эти сидки добывает (хоть из паблика) и не хочет ни с кем этой информацией делиться.
Перед тем, как приступим, опишу основной функционал приложения:
- Выбор кошелька из списка в текстовом документе
- Разные методы сбора данных (в зависимости от API)
- Асинхронная обработка большого количества адресов
- Сохранение результатов в JSON-формате
- Кроссплатформенность благодаря использованию Electron
- Отображение прогресса анализа в реальном времени
Архитектура приложения состоит из нескольких ключевых компонентов:
- Main process (main.js) - основной процесс Electron, отвечающий за создание окна приложения и обработку системных событий.
- Renderer process (index.html, renderer.js) - процесс рендеринга, отвечающий за пользовательский интерфейс и взаимодействие с пользователем.
- Preload script (preload.js) - скрипт, обеспечивающий безопасное взаимодействие между основным и рендерер процессами.
- API интеграции - модули для работы с различными API (я выбрал Mobula и Moralis).
JavaScript: Скопировать в буфер обмена
Код:
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
const path = require('path');
const fs = require('fs').promises;
const axios = require('axios');
const { chromium } = require('playwright');
const Queue = require('better-queue');
const Moralis = require('moralis').default;
const { EvmChain } = require('@moralisweb3/common-evm-utils');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
},
});
mainWindow.loadFile('index.html');
}
Обратите внимание на настройки webPreferences: nodeIntegration: false - отключает прямой доступ к Node.js API из рендерер процесса для безопасности; contextIsolation: true - изолирует preload скрипт от рендерер процесса, а путь к скрипту и странице указываем через preload: path.join(__dirname, 'preload.js') и mainWindow.loadFile('index.html') соответственно.
Далее, определяем обработчики для различных системных событий, эти обработчики обеспечивают корректное поведение приложения при запуске, активации и закрытии:
JavaScript: Скопировать в буфер обмена
Код:
app.whenReady().then(() => {
createWindow();
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit();
});
Следом функции входного(.txt) и выходного(.json) файлов. Эти обработчики позволяют пользователю выбирать файлы для ввода адресов и сохранения результатов анализа. Использование dialog из Electron обеспечивает нативный опыт работы с файловой системой:
JavaScript: Скопировать в буфер обмена
Код:
ipcMain.handle('select-input-file', async () => {
const result = await dialog.showOpenDialog(mainWindow, {
properties: ['openFile'],
filters: [{ name: 'Text Files', extensions: ['txt'] }],
});
if (result.canceled) {
return null;
}
return result.filePaths[0];
});
ipcMain.handle('select-output-file', async () => {
const result = await dialog.showSaveDialog(mainWindow, {
filters: [{ name: 'JSON Files', extensions: ['json'] }],
});
if (result.canceled) {
return null;
}
return result.filePath;
});
Чтобы можно было контролировать нагрузку и избегать превышения лимитов запросов API, я использовал очередь для обработки запросов. Эта очередь обрабатывает запросы последовательно, с возможностью повторных попыток в случае ошибок. Это особенно важно при работе с внешними API, где могут возникать временные сбои или ограничения на количество запросов:
JavaScript: Скопировать в буфер обмена
Код:
const requestQueue = new Queue(async (task, callback) => {
try {
const result = await processRequest(task);
callback(null, result);
} catch (error) {
callback(error);
}
}, { concurrent: 1, maxRetries: 3, retryDelay: 1000 });
async function processRequest(task) {
const { method, address, apiKey } = task;
switch (method) {
case 'Mobula':
return await processWalletMobula(address, apiKey);
case 'Moralis':
return await processWalletMoralis(address, apiKey);
default:
throw new Error('Неизвестный метод');
}
}
Рассмотрим функционал работы с самими API. Принцип простейший – отправлять запросы с номером кошелька, обрабатывать полученные данные и возвращать результат в унифицированном формате. Я начал тестировать с тем, что попало под руку и где можно было без лишних проблем получить ключ. Начал с Mobula (https://mobula.io/apis), для получения ключа необходимо в нижнем левом углу экрана найти FREE API KEY, перейти по ссылке в документацию https://docs.mobula.io/introduction, там подробно описаны дальнейшие действия. На получение ключа ушло около 2-3 минут, сам сервис выдает лимитированные 10000 кредитов в сутки, но забегая вперед могу сказать, что панелька работает криво, количество кредитов в личном кабинет всегда 0, но и работает также медленно, как и считает.
К таким выводам я смог прийти только через пару часов, приняв тот факт, что скорость обработки запросов зависит не от моих красивых рук, бьющих по клавиатуре. Тем не менее результат API выдает, причем в документации изначально были ответы в развернутом формате, но из-за скорости я порезал просто до общего баланса. Полный список запрашиваемой информации:
Код: Скопировать в буфер обмена
Код:
({
"data": {
"total_wallet_balance": 123,
"wallet": "<string>",
"assets": [
{
"asset": {
"data": {
"id": 123,
"name": "<string>",
"symbol": "<string>",
"contracts": [
"<string>"
],
"blockchains": [
"<string>"
],
"twitter": "<string>",
"website": "<string>",
"logo": "<string>",
"price": 123,
"market_cap": 123,
"liquidity": 123,
"volume": 123,
"description": "<string>",
"kyc": "<string>",
"audit": "<string>",
"total_supply_contracts": [
"<string>"
],
"total_supply": 123,
"circulating_supply": 123,
"circulating_supply_addresses": [
"<string>"
],
"discord": "<string>",
"max_supply": 123,
"chat": "<string>"
}
},
"price": 123,
"estimated_balance": 123,
"token_balance": 123,
"cross_chain_balances": {}
}
]
},
"lastUpdated": {}
}
)
Сама же функция выглядит следующим образом:
JavaScript: Скопировать в буфер обмена
Код:
async function processWalletMobula(address, apiKey) {
try {
const response = await axios.get(`https://api.mobula.io/api/1/wallet/portfolio?wallet=${address}`, {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const balance = response.data.data.total_wallet_balance;
return { address, balance };
} catch (error) {
throw error;
}
}
Куда более интересней представлена функция processWalletMoralis, которая использует Moralis API для получения детальной информации о балансах кошелька на различных блокчейнах. Это позволяет получить комплексную картину активов пользователя across different chains. На получение ключа ушло около 10 минут, здесь все просто, но пришлось повозиться с документацией, чтобы понять функционал. Заходим на https://developers.moralis.com, жмем Get API Key, регистрируемся и готово. Панелька интуитивно куда более удобная, считает корректно, API работает быстро, но за один запрос может съедать до тысячи местных кредитов. В бесплатном варианте в сутки выдается 40к кредитов, но за 70 деревянных в месяц можно увеличить лимит до 100млн/месяц, а если языком поработать – можно и в космос улететь.
В документации меня интересовал Get Wallet Net Worth. Основными преимуществами являлись пробив по необходимым блокчейнам и примеры кода/ответов. Блокчейны для анализа там же в доках можете посмотреть, в соответствующей графе (для самых ленивых скрин):
Выбрал несколько для теста (по коду понятно какие именно) и поехали:
JavaScript: Скопировать в буфер обмена
Код:
async function processWalletMoralis(address, apiKey) {
try {
const response = await Moralis.EvmApi.wallets.getWalletNetWorth({
chains: [
EvmChain.ETHEREUM,
EvmChain.POLYGON,
EvmChain.FANTOM,
EvmChain.ARBITRUM,
EvmChain.BSC,
EvmChain.AVALANCHE,
EvmChain.BASE,
EvmChain.OPTIMISM
],
excludeSpam: false,
excludeUnverifiedContracts: false,
address: address
});
const result = response.raw;
return {
address,
total_networth_usd: result.total_networth_usd,
chains: result.chains.map(chain => ({
chain: chain.chain,
native_balance: chain.native_balance,
native_balance_formatted: chain.native_balance_formatted,
native_balance_usd: chain.native_balance_usd,
token_balance_usd: chain.token_balance_usd,
networth_usd: chain.networth_usd
}))
};
} catch (error) {
console.error(`Error processing wallet ${address} with Moralis API:`, error);
return {
address,
error: error.message
};
}
}
Осталось обработать пользовательский ввод и запустить процесс анализа. Эта функция читает адреса кошельков из входного файла, обрабатывает их с помощью выбранного API, отслеживает прогресс и сохраняет результаты в выходной файл. Обратите внимание на использование requestQueue для контроля скорости запросов и отправку обновлений прогресса в рендерер процесс:
JavaScript: Скопировать в буфер обмена
Код:
ipcMain.handle('process-data', async (event, inputFile, outputFile, apiKey, method) => {
try {
const walletAddresses = (await fs.readFile(inputFile, 'utf-8')).split('\n').map(address => address.trim());
const results = [];
const startTime = Date.now();
let processedRequests = 0;
if (method === 'Moralis') {
await Moralis.start({ apiKey: apiKey });
}
for (const address of walletAddresses) {
await new Promise((resolve, reject) => {
requestQueue.push({
method,
address,
apiKey
}, (err, result) => {
if (err) reject(err);
else {
results.push(result);
processedRequests++;
const progress = (processedRequests / walletAddresses.length) * 100;
const elapsedTime = (Date.now() - startTime) / 1000;
const requestsPerMinute = (processedRequests / elapsedTime) * 60;
mainWindow.webContents.send('progress-update', {
progress,
processedRequests,
elapsedTime,
requestsPerMinute
});
resolve();
}
});
});
}
await fs.writeFile(outputFile, JSON.stringify(results, null, 2), 'utf-8');
return 'Анализ успешно завершен!';
} catch (error) {
return `Ошибка: ${error.message}`;
} finally {
if (method === 'Moralis') {
await Moralis.stop();
}
}
});
С функионалом main.js закончили, переходим к preload.js. Код сам по себе – пара строк, но сам скрипт играет ключевую роль в обеспечении безопасности приложения, предоставляя контролируемый интерфейс между основным и рендерер процессами. Я использовал contextBridge для создания безопасного API, доступного из рендерер процесса. Это позволяет контролировать, какие именно функции основного процесса доступны для использования в пользовательском интерфейсе:
JavaScript: Скопировать в буфер обмена
Код:
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
selectInputFile: () => ipcRenderer.invoke('select-input-file'),
selectOutputFile: () => ipcRenderer.invoke('select-output-file'),
processData: (inputFile, outputFile, apiKey, method) =>
ipcRenderer.invoke('process-data', inputFile, outputFile, apiKey, method),
onProgressUpdate: (callback) => ipcRenderer.on('progress-update', (_event, value) => callback(value))
});
Пользовательский интерфейс приложения сделал с простой структурой: возможность выбрать входной файл с адресами кошельков, указать выходной файл для результатов, выбрать метод анализа (Mobula или Moralis) и ввести API ключ.
HTML: Скопировать в буфер обмена
Код:
<html>
<head>
<title>Анализатор криптокошельков</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
input, select, button { margin: 10px 0; }
#progressBar { width: 100%; background-color: #ddd; }
#progressBar > div { height: 30px; background-color: #4CAF50; text-align: center; line-height: 30px; color: white; }
</style>
</head>
<body>
<h1>Анализатор криптокошельков</h1>
<div>
<label for="inputFile">Входной файл (адреса кошельков):</label>
<input type="text" id="inputFile" readonly>
<button onclick="selectInputFile()">Выбрать файл</button>
</div>
<div>
<label for="outputFile">Выходной файл (JSON):</label>
<input type="text" id="outputFile" readonly>
<button onclick="selectOutputFile()">Выбрать файл</button>
</div>
<div>
Метод сбора данных:
<select id="method">
<option value="Mobula">Mobula API</option>
<option value="Moralis">Moralis API</option>
</select>
</div>
<div>
<label for="apiKey">Ключ API:</label>
<input type="text" id="apiKey">
</div>
<button onclick="startAnalysis()">Начать анализ</button>
<div id="progressBar"><div></div></div>
<div id="statusLabel"></div>
<script>
let inputFile, outputFile;
async function selectInputFile() {
inputFile = await window.electronAPI.selectInputFile();
document.getElementById('inputFile').value = inputFile || '';
}
async function selectOutputFile() {
outputFile = await window.electronAPI.selectOutputFile();
document.getElementById('outputFile').value = outputFile || '';
}
async function startAnalysis() {
const apiKey = document.getElementById('apiKey').value;
const method = document.getElementById('method').value;
if (!inputFile || !outputFile) {
alert('Пожалуйста, выберите входной и выходной файлы');
return;
}
const result = await window.electronAPI.processData(inputFile, outputFile, apiKey, method);
document.getElementById('statusLabel').innerText = result;
}
window.electronAPI.onProgressUpdate((data) => {
const progressBar = document.getElementById('progressBar').firstChild;
progressBar.style.width = `${data.progress}%`;
progressBar.innerText = `${data.progress.toFixed(2)}%`;
document.getElementById('statusLabel').innerText =
`Обработано ${data.processedRequests} запросов за ${data.elapsedTime.toFixed(2)} секунд.
Скорость: ${data.requestsPerMinute.toFixed(2)} запросов/мин`;
});
</script>
</body>
</html>
renderer.js - скрипт обрабатывает нажатие на кнопку "Начать анализ", собирает необходимые данные из пользовательского ввода и вызывает функцию processData через API, предоставленный preload скриптом, обновляет прогресс-бар на основе обновлений, получаемых от основного процесса:
JavaScript: Скопировать в буфер обмена
Код:
document.getElementById('startAnalysis').addEventListener('click', async () => {
const inputFile = document.getElementById('inputFile').files[0].path;
const outputFile = document.getElementById('outputFile').value;
const apiKey = document.getElementById('apiKey').value;
const fullAnalysis = document.getElementById('fullAnalysis').checked;
const method = document.getElementById('apiMethod').value;
document.getElementById('statusLabel').textContent = 'Анализ начат...';
try {
const result = await window.electronAPI.processData(inputFile, outputFile, apiKey, fullAnalysis, method);
document.getElementById('statusLabel').textContent = result;
} catch (error) {
document.getElementById('statusLabel').textContent = `Ошибка: ${error.message}`;
}
});
window.electronAPI.onProgressUpdate((progress) => {
document.querySelector('#progressBar > div').style.width = `${progress}%`;
});
Что же показали нам тесты? Я зашел на DeBank, выбрал 10 первых попавшихся кошельков, залил в текстовый документ.
Сначала поехала Mobula:
Скорость загрузки 0.45 запрос/минута. На 10 запросов реально ушло около 1241 секунда = больше 20 минут (скорость космическая). На скрине не успел поймать время (сами понимаете - нужна реакция), поэтому не видно результатов, рекомендую поверить на слово, а можете смело самостоятельно протестировать. Результат:
Слегка поиграв с тестами Mobula, начал пробовать Ankr, Zapper API – плюс минус аналогичный результат (изначально я внес в приложение эти API, когда собирал архитектуру, пробовал Debank по HTML парсингу пихнуть, как метод сбора данных, но достойного результата по скорости не было, поэтому удалено безвозвратно). Переборов в себе желание воспользоваться сочетанием клавиш shift+delete для корневой папки, добрался до Moralis. Ожиданий особо не было, но результат оказался приятным: 10 запросов обработались меньше чем за 25 секунд (1500 запросов/час), а это почти в 50 раз быстрее. Конечно, я изначально целился в результат около 1000 запросов в минуту, но практика и тесты показали, что за «спасибо» тебе никто таких объемов не даст (хотя если кто знает – сообщите). А для мелких объемов 5000-10000 запросов и домашнего ознакомительного пользования решил, что пойдет.
При этом ответы были подробными по каждому из блокчейнов, чтобы не грузить в основном тексте статьи, файл с ответами тоже добавлю в архив, пока пример одного кошелька на скрине:
Чем же пришлось заплатить за такие скорость и качество? Лимитом в панельке – съело с запасом, хотя ответ выдал по всем запрашиваемым кошелькам.
Да, приложение сразу не сортирует в списки «есть бабки»/«пустой кош», но это точно быстрее, чем ручками проверять. А если учесть, что написалось приложение буквально за два вечера под сериальчик, то результат считаю приемлемым.
Бонусом закину программу для генерации сидфраз, которую писал забавы ради в прошлом году. Выглядит она следующим образом:
Функционал простой:
- Скачиваешь 2048 волшебных слов,
- Добавляешь их в текстовый документ,
- Этот документ загружаешь в программу,
- Выбираешь количество слов, участвующих в составлении сидфраз,
- Выбираешь длину последовательности сидфразы
- Нажимаешь «Сгенерировать последовательности»
- Выбираешь выходной файл
- Наслаждаешься работой железного друга
Скорость генерации 100к/секунду. Есть функционал выбрать определенное слово из списка (например, если вы знаете одно или несколько слов сидфразы). Есть также возможность генерировать по стандартам BIP0039, в этом случае сначала рассчитывается контрольное слово, потом генерируется сидфраза. Общее количество комбинаций выводится после выбора количества слов и длины последовательности. Такое запредельное количество сгенерировать, сохранить и как следствие монетизировать, сможет только машина с огромными вычислительными мощностями (или команда). Для изучающих Python будет полезно, для тех, кому нечем заняться – весело поиграть со словами из своих сидфраз.
На сегодня все, уважаемые форумчане! Архив с файлами программ и результатами тестов во вложении. Кому было полезно и вызвало интерес – лайкайте, оставляйте комментарии, задавайте вопросы. Если у вас уже есть проплаченный API с отсутствием лимитов по запросам - можете интегрировать и пользоваться!
Patr1ck специально для XSS.is.