UNPKG

bitcore-node

Version:

A blockchain indexing node with extended capabilities using bitcore

225 lines (211 loc) 7.08 kB
import { Validation } from 'crypto-wallet-core'; import { Request, Response, Router } from 'express'; import config from '../../config'; import logger from '../../logger'; import { ChainStateProvider } from '../../providers/chain-state'; import { StreamWalletAddressesParams } from '../../types/namespaces/ChainStateProvider'; import { Auth, AuthenticatedRequest } from '../../utils/auth'; const router = Router({ mergeParams: true }); function isTooLong(field, maxLength = 255) { return field && field.toString().length >= maxLength; } // create wallet router.post('/', async function(req: Request, res: Response) { try { let { chain, network } = req.params; let { name, pubKey, path, singleAddress } = req.body; const existingWallet = await ChainStateProvider.getWallet({ chain, network, pubKey }); if (existingWallet) { return res.status(200).send('Wallet already exists'); } if (isTooLong(name) || isTooLong(pubKey) || isTooLong(path) || isTooLong(singleAddress)) { return res.status(413).send('String length exceeds limit'); } let result = await ChainStateProvider.createWallet({ chain, network, singleAddress, name, pubKey, path }); return res.send(result); } catch (err: any) { logger.error('Error getting wallet: %o', err.stack || err.message || err); return res.status(500).send(err.message || err); } }); router.get('/:pubKey/addresses/missing', Auth.authenticateMiddleware, async (req: AuthenticatedRequest, res) => { try { let { chain, network, pubKey } = req.params; let payload = { chain, network, pubKey, res }; return await ChainStateProvider.streamMissingWalletAddresses(payload); } catch (err: any) { logger.error('Error streaming missing wallets: %o', err.stack || err.message || err); return res.status(500).send(err.message || err); } }); router.get('/:pubKey/addresses', Auth.authenticateMiddleware, async (req: AuthenticatedRequest, res: Response) => { try { const { wallet } = req; let { chain, network } = req.params; let { limit } = req.query as any; let payload: StreamWalletAddressesParams = { chain, network, walletId: wallet!._id!, limit, req, res }; return await ChainStateProvider.streamWalletAddresses(payload); } catch (err: any) { logger.error('Error streaming wallet addresses: %o', err.stack || err.message || err); return res.status(500).send(err.message || err); } }); router.get('/:pubKey/check', Auth.authenticateMiddleware, async (req: AuthenticatedRequest, res: Response) => { try { let { chain, network } = req.params; const wallet = req.wallet!._id!; const result = await ChainStateProvider.walletCheck({ chain, network, wallet }); return res.send(result); } catch (err: any) { logger.error('Error checking wallet: %o', err.stack || err.message || err); return res.status(500).json(err); } }); // update wallet router.post('/:pubKey', Auth.authenticateMiddleware, async (req: AuthenticatedRequest, res: Response) => { let keepAlive; try { const { chain, network, pubKey } = req.params; const addressLines: { address: string }[] = req.body.filter(line => !!line.address); const addresses = addressLines.map(({ address }) => address); for (const address of addresses) { if (isTooLong(address) || !Validation.validateAddress(chain, network, address)) { return res.status(413).send('Invalid address'); } } let reprocess = false; if (req.headers['x-reprocess']) { const reprocessOk = Auth.verifyRequestSignature({ message: ['reprocess', '/addAddresses' + pubKey, JSON.stringify(req.body)].join('|'), pubKey: config.services.socket.bwsKeys[0], signature: req.headers['x-reprocess'] }); if (!reprocessOk) { return res.status(401).send('Authentication failed'); } reprocess = true; } res.status(200); keepAlive = setInterval(() => { res.write('\n'); }, 1000); await ChainStateProvider.updateWallet({ chain, network, wallet: req.wallet!, addresses, reprocess }); clearInterval(keepAlive); return res.end(); } catch (err: any) { clearInterval(keepAlive); logger.error('Error updating wallet: %o', err.stack || err.message || err); return res.status(500).send(err.message || err); } }); router.get('/:pubKey/transactions', Auth.authenticateMiddleware, async (req: AuthenticatedRequest, res: Response) => { try { let { chain, network } = req.params; return await ChainStateProvider.streamWalletTransactions({ chain, network, wallet: req.wallet!, req, res, args: req.query }); } catch (err: any) { logger.error('Error streaming wallet txs: %o', err.stack || err.message || err); return res.status(500).send(err.message || err); } }); router.get('/:pubKey/balance', Auth.authenticateMiddleware, async (req: AuthenticatedRequest, res: Response) => { let { chain, network } = req.params; try { const result = await ChainStateProvider.getWalletBalance({ chain, network, wallet: req.wallet!, args: req.query }); return res.send(result || { confirmed: 0, unconfirmed: 0, balance: 0 }); } catch (err: any) { logger.error('Error getting wallet balance: %o', err.stack || err.message || err); return res.status(500).json(err); } }); router.get('/:pubKey/balance/:time', Auth.authenticateMiddleware, async (req: AuthenticatedRequest, res: Response) => { let { chain, network, time } = req.params; try { const result = await ChainStateProvider.getWalletBalanceAtTime({ chain, network, wallet: req.wallet!, time, args: req.query }); return res.send(result || { confirmed: 0, unconfirmed: 0, balance: 0 }); } catch (err: any) { logger.error('Error getting wallet: %o', err.stack || err.message || err); return res.status(500).json(err); } }); router.get('/:pubKey/utxos', Auth.authenticateMiddleware, async (req: AuthenticatedRequest, res: Response) => { let { chain, network } = req.params; let { limit } = req.query as any; try { return ChainStateProvider.streamWalletUtxos({ chain, network, wallet: req.wallet!, limit, req, res, args: req.query }); } catch (err: any) { logger.error('Error streaming wallet utxos: %o', err.stack || err.message || err); return res.status(500).send(err.message || err); } }); router.get('/:pubKey', Auth.authenticateMiddleware, async function(req: AuthenticatedRequest, res: Response) { try { let wallet = req.wallet; return res.send(wallet); } catch (err: any) { logger.error('Error getting wallet: %o', err.stack || err.message || err); return res.status(500).send(err.message || err); } }); module.exports = { router, path: '/wallet' };