UNPKG

@dydxfoundation/governance

Version:
83 lines (82 loc) 3.59 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMerkleTreeBalancesFromIpfs = exports.getProposalMetadata = exports.ipfsHashBytesToIpfsHashString = exports.getLink = void 0; const axios_1 = __importDefault(require("axios")); const cids_1 = __importDefault(require("cids")); const ethers_1 = require("ethers"); const utils_1 = require("ethers/lib/utils"); const IPFS_ENDPOINT = 'https://cloudflare-ipfs.com/ipfs'; function getLink(hash) { return `${IPFS_ENDPOINT}/${hash}`; } exports.getLink = getLink; const MEMORIZE = {}; function ipfsHashBytesToIpfsHashString(ipfsHashBytes, isBytes32) { const trimmedHexString = ipfsHashBytes.slice(2); if (isBytes32) { // bytes32 has the first two bytes (encoding) removed, so assumed it's base58 encoded return utils_1.base58.encode(Buffer.from(`1220${trimmedHexString}`, 'hex')); } else { const buf = Buffer.from(trimmedHexString, 'hex'); const cid = new cids_1.default(buf.toString()); return cid.toV1().toString(); } } exports.ipfsHashBytesToIpfsHashString = ipfsHashBytesToIpfsHashString; async function getProposalMetadata(ipfsHashBytes, ipfsTimeoutMs) { const ipfsHash = ipfsHashBytesToIpfsHashString(ipfsHashBytes, true); if (MEMORIZE[ipfsHash]) return MEMORIZE[ipfsHash]; try { const { data } = await axios_1.default.get(getLink(ipfsHash), { timeout: ipfsTimeoutMs }); if (!(data === null || data === void 0 ? void 0 : data.title)) { throw Error('Missing `title` field at proposal metadata.'); } if (!(data === null || data === void 0 ? void 0 : data.description)) { throw Error('Missing `description` field at proposal metadata.'); } if (!(data === null || data === void 0 ? void 0 : data.shortDescription) && !data['short description']) { throw Error('Missing `shortDescription` field at proposal metadata.'); } MEMORIZE[ipfsHash] = { ipfsHash, dipId: data.DIP ? parseInt(data.DIP) : undefined, title: data.title, description: data.description, shortDescription: data.shortDescription || data['short description'], }; return MEMORIZE[ipfsHash]; } catch (e) { console.error(`@dydxfoundation/governance-js: IPFS fetch Error: ${e.message}`); return { ipfsHash, dipId: -1, title: `Proposal - ${ipfsHash}`, description: 'Proposal with invalid metadata format or IPFS gateway is down', shortDescription: 'Proposal with invalid metadata format or IPFS gateway is down', }; } } exports.getProposalMetadata = getProposalMetadata; async function getMerkleTreeBalancesFromIpfs(ipfsHashBytes, ipfsTimeoutMs) { try { const ipfsHash = ipfsHashBytesToIpfsHashString(ipfsHashBytes, false); const { data } = await axios_1.default.get(getLink(ipfsHash), { timeout: ipfsTimeoutMs }); const balances = {}; data.forEach((balance) => { const address = balance[0]; const amount = ethers_1.BigNumber.from(balance[1]); balances[address] = amount; }); return balances; } catch (e) { throw new Error('Could not fetch user reward balances from ipfs hash'); } } exports.getMerkleTreeBalancesFromIpfs = getMerkleTreeBalancesFromIpfs;