@liskhq/lisk-framework-faucet-plugin
Version:
A plugin for distributing testnet tokens from a newly developed blockchain application.
150 lines • 7.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.App = exports.getConfig = void 0;
const React = require("react");
const lisk_client_1 = require("@liskhq/lisk-client");
const logo_svg_1 = require("./logo.svg");
const illustration_svg_1 = require("./illustration.svg");
const app_module_scss_1 = require("./app.module.scss");
const validateAddress = (address, prefix) => {
try {
return lisk_client_1.cryptography.address.validateLisk32Address(address, prefix);
}
catch (error) {
return false;
}
};
const defaultFaucetConfig = {
amount: '10000000000',
applicationUrl: 'ws://localhost:8080/ws',
tokenPrefix: 'lsk',
};
const getConfig = async () => {
if (process.env.NODE_ENV === 'development') {
return defaultFaucetConfig;
}
const apiResponse = await fetch('/api/config');
const result = await apiResponse.json();
return result;
};
exports.getConfig = getConfig;
const WarningIcon = () => React.createElement("span", { className: `${app_module_scss_1.default.icon} ${app_module_scss_1.default.warning}` }, "\uE8B2");
const SuccessDialog = props => {
return (React.createElement("div", { className: `${app_module_scss_1.default.dialogRoot} ${props.open ? app_module_scss_1.default.dialogOpen : app_module_scss_1.default.dialogClose}` },
React.createElement("div", { className: app_module_scss_1.default.dialogBackground },
React.createElement("div", { className: app_module_scss_1.default.dialogModal },
React.createElement("div", { className: app_module_scss_1.default.dialogHeader },
React.createElement("div", { className: app_module_scss_1.default.dialogHeaderContent }, "Success"),
React.createElement("div", { className: app_module_scss_1.default.iconButton, onClick: props.onClose },
React.createElement("span", { className: app_module_scss_1.default.icon }, "close"),
";")),
React.createElement("div", { className: app_module_scss_1.default.dialogBody }, props.children)))));
};
const App = () => {
var _a;
const [input, updateInput] = React.useState('');
const [errorMsg, updateErrorMsg] = React.useState('');
const [showSuccessDialog, updateShowSuccessDialog] = React.useState(false);
const [token, updateToken] = React.useState();
const [recaptchaReady, updateRecaptchaReady] = React.useState(false);
const [config, setConfig] = React.useState(defaultFaucetConfig);
React.useEffect(() => {
const initConfig = async () => {
const fetchedConfig = await (0, exports.getConfig)();
setConfig({ ...fetchedConfig });
};
initConfig().catch(console.error);
}, []);
React.useEffect(() => {
if (config.captchaSitekey === undefined) {
return () => { };
}
const script = document.createElement('script');
script.src = 'https://www.google.com/recaptcha/api.js';
script.async = true;
script.defer = true;
document.body.appendChild(script);
const id = setInterval(() => {
if (typeof window.grecaptcha !== 'undefined' &&
typeof window.grecaptcha.render === 'function') {
clearInterval(id);
if (recaptchaReady) {
return;
}
window.grecaptcha.render('recapcha', {
sitekey: config.captchaSitekey,
callback: (newToken) => updateToken(newToken),
});
updateRecaptchaReady(true);
}
}, 1000);
return () => {
document.body.removeChild(script);
};
}, [config]);
const onChange = (val) => {
updateInput(val);
if (val === '') {
updateErrorMsg('');
}
};
const onSubmit = async () => {
var _a;
if (token === undefined) {
updateErrorMsg('Recaptcha must be checked.');
return;
}
try {
const client = await lisk_client_1.apiClient.createWSClient(config.applicationUrl);
await client.invoke('faucet_fundTokens', {
address: lisk_client_1.cryptography.address
.getAddressFromLisk32Address(input, config.tokenPrefix)
.toString('hex'),
token,
});
updateErrorMsg('');
updateShowSuccessDialog(true);
}
catch (error) {
updateErrorMsg((_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : 'Fail to connect to server');
}
};
return (React.createElement("div", { className: app_module_scss_1.default.root },
React.createElement("header", { className: app_module_scss_1.default.header },
React.createElement("img", { src: (_a = config.logoURL) !== null && _a !== void 0 ? _a : logo_svg_1.default, className: app_module_scss_1.default.logo, alt: "logo" })),
React.createElement("section", { className: app_module_scss_1.default.content },
React.createElement(SuccessDialog, { open: showSuccessDialog, onClose: () => {
updateInput('');
updateShowSuccessDialog(false);
} },
React.createElement("p", null,
"Successfully submitted to transfer funds to:",
React.createElement("br", null),
input,
".")),
React.createElement("div", { className: app_module_scss_1.default.main },
React.createElement("h1", null, "All tokens are for testing purposes only"),
React.createElement("h2", null,
"Please enter your address to receive ",
config.amount,
' ',
config.tokenPrefix.toLocaleUpperCase(),
" tokens for free"),
React.createElement("div", { className: app_module_scss_1.default.inputArea },
React.createElement("div", { className: app_module_scss_1.default.input },
React.createElement("input", { className: `${errorMsg !== '' ? app_module_scss_1.default.error : ''}`, placeholder: config.faucetAddress, value: input, onChange: e => onChange(e.target.value) }),
errorMsg ? React.createElement(WarningIcon, null) : React.createElement("span", null),
errorMsg ? React.createElement("span", { className: app_module_scss_1.default.errorMsg }, errorMsg) : React.createElement("span", null)),
React.createElement("button", { disabled: !validateAddress(input, config.tokenPrefix) || !recaptchaReady, onClick: onSubmit }, "Receive")),
React.createElement("div", { id: "recapcha", className: app_module_scss_1.default.capcha }),
React.createElement("div", { className: app_module_scss_1.default.address },
React.createElement("p", null,
React.createElement("span", { className: app_module_scss_1.default.addressLabel }, "Faucet address:"),
React.createElement("span", { className: app_module_scss_1.default.addressValue }, config.faucetAddress)))),
React.createElement("div", { className: app_module_scss_1.default.background },
React.createElement("img", { src: illustration_svg_1.default, className: app_module_scss_1.default.illustration, alt: "illustration" }))),
React.createElement("footer", null,
React.createElement("p", { className: app_module_scss_1.default.copyright }, "\u00A9 2023 Lisk Foundation"))));
};
exports.App = App;
//# sourceMappingURL=app.js.map