UNPKG

@substrate/api-sidecar

Version:

REST service that makes it easy to interact with blockchain nodes built using Substrate's FRAME framework.

112 lines 5 kB
"use strict"; // Copyright 2017-2025 Parity Technologies (UK) Ltd. // This file is part of Substrate API Sidecar. // // Substrate API Sidecar is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. Object.defineProperty(exports, "__esModule", { value: true }); exports.validateAddressQueryParamMiddleware = exports.validateAddressMiddleware = void 0; const util_1 = require("@polkadot/util"); const util_crypto_1 = require("@polkadot/util-crypto"); const defaults_1 = require("@polkadot/util-crypto/address/defaults"); const http_errors_1 = require("http-errors"); /** * Express Middleware to validate that an `:address` param is properly formatted. */ const validateAddressMiddleware = (req, _res, next) => { if (!('address' in req.params)) { return next(); } const [isValid, error] = checkAddress(req.params.address); if (!isValid && error) { return next(new http_errors_1.BadRequest(error)); } return next(); }; exports.validateAddressMiddleware = validateAddressMiddleware; /** * Express Middleware to validate that an `:address` given as a query parameter is properly formatted. * It also does the following checks: * - that the query parameter name is `addresses`. * - that the query parameter is given as an array of addresses or a string of comma separated addresses. * - validates all addresses found in the query parameter. */ const validateAddressQueryParamMiddleware = (req, _res, next) => { // Check that the query parameter name is `addresses`. const queryParamKey = Object.keys(req.query); const validParamKey = queryParamKey.filter((key) => /^addresses$/.test(key)); if (validParamKey.length != queryParamKey.length || validParamKey.length === 0) { return next(new http_errors_1.BadRequest(`Please use the query parameter key 'addresses' to provide the addresses values.`)); } // Check that the addresses are valid. Same check as in the `validateAddressMiddleware` but for query parameters. for (const param of validParamKey) { const addresses = req.query[param]; // Check if the address is a string of comma separated addresses or an array of addresses. if (typeof addresses === 'string') { const addressesArray = addresses.split(','); if (addressesArray.length <= 1) { return next(new http_errors_1.BadRequest(`At least two addresses are required for comparison.`)); } for (const address of addressesArray) { const [isValid, error] = checkAddress(address); if (!isValid && error) { return next(new http_errors_1.BadRequest(`Invalid ${param}: ${error}`)); } } } else if (Array.isArray(addresses)) { if (addresses.length <= 1) { return next(new http_errors_1.BadRequest(`At least two addresses are required for comparison.`)); } for (const address of addresses) { const [isValid, error] = checkAddress(address); if (!isValid && error) { return next(new http_errors_1.BadRequest(`Invalid ${param}: ${error}`)); } } } } return next(); }; exports.validateAddressQueryParamMiddleware = validateAddressQueryParamMiddleware; /** * Verify that an address is a valid substrate address. * * Note: this is very similar '@polkadot/util-crypto/address/checkAddress, * except it does not check the ss58 prefix and supports H256/H160 raw address. * * @param address potential ss58 or raw address */ function checkAddress(address) { let u8Address; if ((0, util_1.isHex)(address)) { u8Address = Uint8Array.from(Buffer.from(address.slice(2), 'hex')); } else { try { u8Address = (0, util_crypto_1.base58Decode)(address); } catch (error) { return [false, error.message]; } } if (defaults_1.defaults.allowedEncodedLengths.includes(u8Address.length)) { const [isValid] = (0, util_crypto_1.checkAddressChecksum)(u8Address); return [isValid, isValid ? undefined : 'Invalid decoded address checksum']; } if ((0, util_crypto_1.isEthereumAddress)(address)) { return [true, undefined]; } return [false, 'Invalid address format']; } //# sourceMappingURL=validateAddressMiddleware.js.map