@dydxfoundation/governance
Version:
dYdX governance smart contracts
83 lines (82 loc) • 3.59 kB
JavaScript
;
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;