Skip to content

Commit

Permalink
Merge pull request #103 from rsksmart/feat/DV-762-address-book
Browse files Browse the repository at this point in the history
Feat/DV-762 address book
  • Loading branch information
ivegabr authored Feb 5, 2025
2 parents d8535cb + 95167eb commit a938d3c
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 6 deletions.
27 changes: 23 additions & 4 deletions bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Address } from "viem";
import { bridgeCommand } from "../src/commands/bridge.js";
import { batchTransferCommand } from "../src/commands/batchTransfer.js";
import { historyCommand } from "../src/commands/history.js";
import { selectAddress } from "../src/commands/selectAddress.js";

interface CommandOptions {
testnet?: boolean;
Expand Down Expand Up @@ -50,7 +51,7 @@ const program = new Command();
program
.name("rsk-cli")
.description("CLI tool for interacting with Rootstock blockchain")
.version("1.0.8", "-v, --version", "Display the current version");
.version("1.0.9", "-v, --version", "Display the current version");

program
.command("wallet")
Expand All @@ -76,10 +77,30 @@ program
.description("Transfer rBTC to the provided address")
.option("-t, --testnet", "Transfer on the testnet")
.option("--wallet <wallet>", "Name of the wallet")
.requiredOption("-a, --address <address>", "Recipient address")
.option("-a, --address <address>", "Recipient address")
.requiredOption("--value <value>", "Amount to transfer in rBTC")
.action(async (options: CommandOptions) => {
try {
if (!options.value) {
throw new Error("Value is required for the transfer.");
}

const value = parseFloat(options.value);

if (isNaN(value) || value <= 0) {
throw new Error("Invalid value specified for transfer.");
}

const address = options.address
? (`0x${options.address.replace(/^0x/, "")}` as `0x${string}`)
: await selectAddress();

await transferCommand(!!options.testnet, address, value);
} catch (error: any) {
console.error(
chalk.red("Error during transfer:"),
error.message || error
);
const address = `0x${options.address!.replace(
/^0x/,
""
Expand All @@ -90,8 +111,6 @@ program
parseFloat(options.value!),
options.wallet!
);
} catch (error) {
console.error(chalk.red("Error during transfer:"), error);
}
});

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rsksmart/rsk-cli",
"version": "1.0.8",
"version": "1.0.9",
"description": "CLI tool for Rootstock network using Viem",
"repository": {
"type": "git",
Expand Down
117 changes: 117 additions & 0 deletions src/commands/addressbook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import inquirer from "inquirer";
import chalk from "chalk";
import { loadWallets } from "../utils/index.js";
import { walletFilePath } from "../utils/constants.js";
import { writeWalletData } from "./wallet.js";

export async function addressBookCommand() {
try {
const walletsDataString = loadWallets();
const walletsData = JSON.parse(walletsDataString);
walletsData.addressBook = walletsData.addressBook || {};

const actions = [
"➕ Add Address",
"📖 View Address Book",
"✏️ Update Address",
"🗑️ Delete Address",
];

const { action } = await inquirer.prompt([
{
type: "list",
name: "action",
message: "What would you like to do with your address book?",
choices: actions,
},
]);

if (action === "➕ Add Address") {
const { label, address } = await inquirer.prompt([
{
type: "input",
name: "label",
message: "Enter a label for the address:",
},
{
type: "input",
name: "address",
message: "Enter the address:",
},
]);

if (walletsData.addressBook[label]) {
console.log(chalk.red(`❌ Label "${label}" already exists.`));
return;
}

walletsData.addressBook[label] = address;
console.log(chalk.green(`✅ Address added under label "${label}".`));
}

if (action === "📖 View Address Book") {
const addressBook = walletsData.addressBook;
if (Object.keys(addressBook).length === 0) {
console.log(chalk.red("❌ Address book is empty."));
return;
}

console.log(chalk.green("📖 Address Book:"));
Object.entries(addressBook).forEach(([label, address]) => {
console.log(chalk.blue(`- ${label}: ${address}`));
});
}

if (action === "✏️ Update Address") {
const labels = Object.keys(walletsData.addressBook);
if (labels.length === 0) {
console.log(chalk.red("❌ Address book is empty."));
return;
}

const { label } = await inquirer.prompt([
{
type: "list",
name: "label",
message: "Select the address you want to update:",
choices: labels,
},
]);

const { newAddress } = await inquirer.prompt([
{
type: "input",
name: "newAddress",
message: `Enter the new address for "${label}":`,
},
]);

walletsData.addressBook[label] = newAddress;
console.log(chalk.green(`✅ Address for "${label}" updated.`));
}

if (action === "🗑️ Delete Address") {
const labels = Object.keys(walletsData.addressBook);
if (labels.length === 0) {
console.log(chalk.red("❌ Address book is empty."));
return;
}

const { label } = await inquirer.prompt([
{
type: "list",
name: "label",
message: "Select the address you want to delete:",
choices: labels,
},
]);

delete walletsData.addressBook[label];
console.log(chalk.red(`🗑️ Address with label "${label}" deleted.`));
}

writeWalletData(walletFilePath, walletsData);
} catch (error: any) {
console.error(chalk.red("❌ Error managing address book:"), error.message);
}
}
51 changes: 51 additions & 0 deletions src/commands/selectAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { loadWallets } from "../utils/index.js";
import inquirer from "inquirer";
import chalk from "chalk";
import { Address } from "viem";

export async function selectAddress(): Promise<Address> {
try {
const walletsDataString = loadWallets();
const walletsData = JSON.parse(walletsDataString);
walletsData.addressBook = walletsData.addressBook || {};

const addressBook = walletsData.addressBook;
const addressBookLabels = Object.keys(addressBook);

const addressChoices = [
...addressBookLabels.map((label) => ({
name: `${label} (${addressBook[label]})`,
value: addressBook[label],
})),
{ name: "Enter a custom address", value: "custom" },
];

const { selectedAddress } = await inquirer.prompt([
{
type: "list",
name: "selectedAddress",
message: "Select an address:",
choices: addressChoices,
},
]);

if (selectedAddress === "custom") {
const { customAddress } = await inquirer.prompt([
{
type: "input",
name: "customAddress",
message: "Enter the address:",
},
]);
return customAddress;
}

return selectedAddress;
} catch (error: any) {
console.error(
chalk.red("❌ Error selecting address:"),
chalk.yellow(error.message || error)
);
throw error;
}
}
8 changes: 7 additions & 1 deletion src/commands/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import crypto from "crypto";
import { loadWallets } from "../utils/index.js";
import { walletFilePath } from "../utils/constants.js";
import path from "path";
import { addressBookCommand } from "./addressbook.js";

type InquirerAnswers = {
action?: string;
Expand Down Expand Up @@ -51,6 +52,7 @@ export async function walletCommand() {
"📝 Update wallet name",
"📂 Backup wallet data",
"❌ Delete wallet",
"📖 Address Book",
],
},
];
Expand Down Expand Up @@ -505,6 +507,10 @@ export async function walletCommand() {

await backupCommand(backupPath);
}

if (action === "📖 Address Book") {
await addressBookCommand();
}
} catch (error: any) {
console.error(
chalk.red("❌ Error creating or managing wallets:"),
Expand All @@ -513,7 +519,7 @@ export async function walletCommand() {
}
}

async function writeWalletData(filePath: string, data: any) {
export async function writeWalletData(filePath: string, data: any) {
try {
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf8");
console.log(chalk.green(`💾 Changes saved at ${filePath}`));
Expand Down

0 comments on commit a938d3c

Please sign in to comment.