beeline-cli
Version:
A terminal wallet for the Hive blockchain - type, sign, rule the chain
295 lines • 15.3 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransferScreen = TransferScreen;
const react_1 = __importStar(require("react"));
const ink_1 = require("ink");
const hive_js_1 = require("../../utils/hive.js");
function TransferScreen({ keyManager, mock = false, node, setCurrentScreen }) {
const [currentStep, setCurrentStep] = (0, react_1.useState)('recipient');
const [transferData, setTransferData] = (0, react_1.useState)({
recipient: '',
amount: '',
currency: 'HIVE',
memo: ''
});
const [inputValue, setInputValue] = (0, react_1.useState)('');
const [error, setError] = (0, react_1.useState)(null);
const [result, setResult] = (0, react_1.useState)(null);
const [currencySelected, setCurrencySelected] = (0, react_1.useState)(0);
(0, ink_1.useInput)((input, key) => {
if (key.backspace) {
if (currentStep === 'recipient' || currentStep === 'amount' || currentStep === 'memo') {
setInputValue(inputValue.slice(0, -1));
}
else {
goToPreviousStep();
}
}
else if (key.escape || input === 'q') {
setCurrentScreen('dashboard');
}
else if (key.return) {
handleEnter();
}
else if (currentStep === 'currency') {
if (key.upArrow && currencySelected > 0) {
setCurrencySelected(currencySelected - 1);
}
else if (key.downArrow && currencySelected < 1) {
setCurrencySelected(currencySelected + 1);
}
}
else if (currentStep === 'confirm') {
if (input === 'y') {
executeTransfer();
}
else if (input === 'n') {
setCurrentStep('recipient');
resetForm();
}
}
else if (currentStep === 'result') {
if (input === 'n') {
setCurrentStep('recipient');
resetForm();
}
}
else if (currentStep !== 'processing') {
// Regular text input
if (input && input.length === 1 && input.match(/[a-zA-Z0-9.\-@\s]/)) {
setInputValue(inputValue + input);
}
}
});
const resetForm = () => {
setTransferData({
recipient: '',
amount: '',
currency: 'HIVE',
memo: ''
});
setInputValue('');
setError(null);
setResult(null);
setCurrencySelected(0);
};
const goToPreviousStep = () => {
switch (currentStep) {
case 'amount':
setCurrentStep('recipient');
setInputValue(transferData.recipient);
break;
case 'currency':
setCurrentStep('amount');
setInputValue(transferData.amount);
break;
case 'memo':
setCurrentStep('currency');
break;
case 'confirm':
setCurrentStep('memo');
setInputValue(transferData.memo);
break;
case 'result':
setCurrentStep('recipient');
resetForm();
break;
default:
setCurrentStep('recipient');
setInputValue(transferData.recipient);
}
};
const handleEnter = () => {
setError(null);
switch (currentStep) {
case 'recipient':
if (!inputValue.trim()) {
setError('Recipient cannot be empty');
return;
}
const cleanRecipient = inputValue.trim().replace(/^@/, '');
setTransferData({ ...transferData, recipient: cleanRecipient });
setCurrentStep('amount');
setInputValue('');
break;
case 'amount':
if (!inputValue.trim() || isNaN(parseFloat(inputValue))) {
setError('Please enter a valid amount');
return;
}
if (parseFloat(inputValue) <= 0) {
setError('Amount must be greater than 0');
return;
}
setTransferData({ ...transferData, amount: inputValue.trim() });
setCurrentStep('currency');
break;
case 'currency':
const selectedCurrency = currencySelected === 0 ? 'HIVE' : 'HBD';
setTransferData({ ...transferData, currency: selectedCurrency });
setCurrentStep('memo');
setInputValue('');
break;
case 'memo':
setTransferData({ ...transferData, memo: inputValue });
setCurrentStep('confirm');
break;
case 'confirm':
// Handled by 'y' key
break;
case 'result':
setCurrentStep('recipient');
resetForm();
break;
}
};
const executeTransfer = async () => {
setCurrentStep('processing');
setError(null);
try {
const account = keyManager.getDefaultAccount();
if (!account) {
throw new Error('No default account set');
}
if (mock) {
// Simulate processing time
await new Promise(resolve => setTimeout(resolve, 2000));
setResult(`Mock transfer successful!\nSent ${transferData.amount} ${transferData.currency} to @${transferData.recipient}`);
}
else {
const hiveClient = new hive_js_1.HiveClient(keyManager, node);
await hiveClient.transfer(account, transferData.recipient, transferData.amount, transferData.currency, transferData.memo);
setResult(`Transfer successful!\nSent ${transferData.amount} ${transferData.currency} to @${transferData.recipient}`);
}
setCurrentStep('result');
}
catch (err) {
setError(err instanceof Error ? err.message : 'Transfer failed');
setCurrentStep('confirm');
}
};
const renderCurrentStep = () => {
switch (currentStep) {
case 'recipient':
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column" },
react_1.default.createElement(ink_1.Text, { color: "cyan", bold: true }, "Step 1: Enter recipient account name"),
react_1.default.createElement(ink_1.Text, { color: "gray" }, "Type the username (with or without @)"),
react_1.default.createElement(ink_1.Text, { color: "white" },
"Recipient: ",
react_1.default.createElement(ink_1.Text, { color: "cyan" }, inputValue))));
case 'amount':
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column" },
react_1.default.createElement(ink_1.Text, { color: "cyan", bold: true }, "Step 2: Enter amount to send"),
react_1.default.createElement(ink_1.Text, { color: "gray" }, "Enter the amount (numbers and decimal point only)"),
react_1.default.createElement(ink_1.Text, { color: "white" },
"Amount: ",
react_1.default.createElement(ink_1.Text, { color: "cyan" }, inputValue))));
case 'currency':
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column" },
react_1.default.createElement(ink_1.Text, { color: "cyan", bold: true }, "Step 3: Select currency"),
react_1.default.createElement(ink_1.Text, { color: "gray" }, "Use \u2191\u2193 to navigate, Enter to select"),
react_1.default.createElement(ink_1.Box, { flexDirection: "column", marginTop: 1 },
react_1.default.createElement(ink_1.Text, { color: currencySelected === 0 ? 'black' : 'cyan', backgroundColor: currencySelected === 0 ? 'cyan' : undefined },
currencySelected === 0 ? '► ' : ' ',
"HIVE"),
react_1.default.createElement(ink_1.Text, { color: currencySelected === 1 ? 'black' : 'magenta', backgroundColor: currencySelected === 1 ? 'magenta' : undefined },
currencySelected === 1 ? '► ' : ' ',
"HBD"))));
case 'memo':
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column" },
react_1.default.createElement(ink_1.Text, { color: "cyan", bold: true }, "Step 4: Enter memo (optional)"),
react_1.default.createElement(ink_1.Text, { color: "gray" }, "Add a message or leave empty"),
react_1.default.createElement(ink_1.Text, { color: "white" },
"Memo: ",
react_1.default.createElement(ink_1.Text, { color: "cyan" }, inputValue))));
case 'confirm':
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column" },
react_1.default.createElement(ink_1.Text, { color: "yellow", bold: true }, "Step 5: Confirm transfer"),
react_1.default.createElement(ink_1.Box, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "yellow", paddingX: 1 },
react_1.default.createElement(ink_1.Text, { color: "white" },
"To: ",
react_1.default.createElement(ink_1.Text, { color: "cyan" },
"@",
transferData.recipient)),
react_1.default.createElement(ink_1.Text, { color: "white" },
"Amount: ",
react_1.default.createElement(ink_1.Text, { color: "cyan" },
transferData.amount,
" ",
transferData.currency)),
react_1.default.createElement(ink_1.Text, { color: "white" },
"Memo: ",
react_1.default.createElement(ink_1.Text, { color: "cyan" }, transferData.memo || '(empty)')),
react_1.default.createElement(ink_1.Text, { color: "white" },
"From: ",
react_1.default.createElement(ink_1.Text, { color: "cyan" },
"@",
keyManager.getDefaultAccount())),
mock && react_1.default.createElement(ink_1.Text, { color: "yellow" }, "Mode: MOCK (no real transfer)")),
react_1.default.createElement(ink_1.Text, { color: "yellow" }, "Press Y to confirm, N to cancel")));
case 'processing':
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column", justifyContent: "center", alignItems: "center", flexGrow: 1 },
react_1.default.createElement(ink_1.Text, { color: "cyan" }, "\u280B Processing transfer..."),
react_1.default.createElement(ink_1.Text, { color: "gray" }, "Please wait...")));
case 'result':
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column" },
error ? (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(ink_1.Text, { color: "red", bold: true }, "\u2716 Transfer Failed"),
react_1.default.createElement(ink_1.Text, { color: "red" }, error))) : (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(ink_1.Text, { color: "green", bold: true }, "\u2714 Transfer Complete"),
react_1.default.createElement(ink_1.Text, { color: "green" }, result))),
react_1.default.createElement(ink_1.Text, { color: "gray" }, "Press N for new transfer, Q for dashboard")));
default:
return react_1.default.createElement(ink_1.Text, null, "Unknown step");
}
};
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column", paddingX: 2, paddingY: 1 },
react_1.default.createElement(ink_1.Box, { borderStyle: "single", borderColor: "magenta", paddingX: 1, marginBottom: 1 },
react_1.default.createElement(ink_1.Text, { color: "magenta", bold: true }, "\u2593 TRANSFER FUNDS \u2593")),
react_1.default.createElement(ink_1.Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, flexGrow: 1 },
react_1.default.createElement(ink_1.Box, { flexDirection: "column", flexGrow: 1 },
renderCurrentStep(),
error && (react_1.default.createElement(ink_1.Box, { marginTop: 1 },
react_1.default.createElement(ink_1.Text, { color: "red" },
"\u2716 ",
error))))),
react_1.default.createElement(ink_1.Box, { borderStyle: "single", borderColor: "green", paddingX: 1, marginTop: 1 },
react_1.default.createElement(ink_1.Text, { color: "green" }, currentStep === 'processing' ? 'Processing...' :
currentStep === 'confirm' ? 'Y: Confirm | N: Cancel | Backspace: Previous' :
currentStep === 'result' ? 'N: New Transfer | Q: Dashboard' :
'Type to enter | Enter: Next | Backspace: Previous | Q: Dashboard'))));
}
//# sourceMappingURL=TransferScreen.js.map