npm.io
0.3.0 • Published 6d agoCLI

@amitdhoju/meroshare

Licence
MIT
Version
0.3.0
Deps
0
Size
246 kB
Vulns
0
Weekly
49

@amitdhoju/meroshare

Type-safe Meroshare API client for Node.js. Supports login, portfolio, IPO application, and more. Uses the native fetch API — zero runtime dependencies.

What's New

  • Credential Caching — Save BOID + password and CRN + PIN with master PIN encryption. Load credentials automatically on next login/apply.
  • View Credentials — Menu option [v] to view saved credentials (passwords masked).
  • Recent Applications Status — Menu option [b] to quickly view status of last 10 IPO applications (selected, applied, rejected).
  • Save Output to File — Export any menu output to JSON. Saves to ~/.meroshare-exports/.
  • Clean Table Display — All data now shows in formatted tables with console.table() — no more JSON dumps in the CLI.

Installation

npm install @amitdhoju/meroshare

Requirements

  • Node.js >= 20

CLI

Run the interactive menu without writing any code:

npx @amitdhoju/meroshare

Or install globally:

npm install -g @amitdhoju/meroshare
meroshare

The CLI is menu-driven and stays open until you exit. It automatically restores your session on startup (valid for 15 minutes).

Not logged in — guest menu:

── Meroshare ──────────────────────────────────────
  [1] Login
  [0] Exit
──────────────────────────────────────────────────
Choose:

Selecting [1] prompts for your DP Code (or numeric Client ID), BOID username, and password.

Logged in — main menu:

── Meroshare ──────────────────────────────────────
  [1]  Own Detail
  [2]  Portfolio
  [3]  Applicable Issues  (open for application)
  [4]  Current Issues     (all open on market)
  [5]  Issue Detail       (enter ID)
  [6]  Applications / Applied IPOs
  [b]  Recent Applications Status (last 10)
  [a]  Apply IPO
  [7]  Banks
  [8]  Bank Accounts      (enter bank ID)
  [v]  View Credentials
  [h]  Help
  [9]  Logout
  [0]  Exit
──────────────────────────────────────────────────
Choose:

Key Features:

  • Menu options [1-8] — View account, portfolio, issues, applications, and banks
  • Option [a] — Guided IPO application flow with credential caching
  • Option [b] — Quick view of recent 10 application statuses (selected ✓ / applied • / rejected ✗)
  • Option [v] — View saved credentials (passwords masked)
  • Save output — After any menu option, you're prompted to save output as JSON to ~/.meroshare-exports/
  • Formatted tables — All data displays in clean, aligned tables
  • Credential persistence — Saves and loads login/apply credentials with master PIN protection (4-6 digits)
  • Session caching — Token cached for 15 minutes in ~/.meroshare-session.json

Options [5] and [8] prompt for an ID before fetching. Selecting [9] logs out; [0] or Ctrl+C exits.

CLI Features

Credential Caching

Save your login and application credentials locally (encrypted with master PIN):

  • After login, you're prompted: "Save these credentials for next time? [y/N]:"
  • Set a 4-6 digit master PIN to encrypt credentials
  • Next login, you're prompted: "Use saved credentials? [y/N]:"
  • Enter your master PIN to decrypt and use saved BOID + password
  • Same workflow for CRN + PIN during IPO applications
  • Credentials stored in ~/.meroshare-creds.json (AES-256-GCM encrypted)
  • View saved credentials anytime with menu option [v] (passwords masked)
Export Data

After any menu option, you're prompted: "Save output to file? [y/N]:"

  • Exports as formatted JSON to ~/.meroshare-exports/[type]-[timestamp].json
  • Works for: portfolio, issues, applications, banks, account details, etc.
  • Keep records of your applications and holdings
Recent Applications Status

Menu option [b] shows your last 10 IPO applications with quick status view:

Status Legend: ✓ Selected/Allotted | • Applied | ✗ Rejected/Not Selected

┌────────┬──────┬────────────────────────┬──────────────┬────────────────┐
│ Status │ ID   │ Scrip                  │ Company      │ Share Status   │
├────────┼──────┼────────────────────────┼──────────────┼────────────────┤
│ ✓ Sel. │ 1001 │ SAMPLE                 │ Sample Ltd   │ Allotted       │
│ • App. │ 1002 │ TEST                   │ Test Inc     │ Applied        │
│ ✗ Rej. │ 1003 │ DEMO                   │ Demo Corp    │ Not Selected   │
└────────┴──────┴────────────────────────┴──────────────┴────────────────┘

Quick Start

No config files or env vars needed — credentials are passed directly.

import { MeroshareClient, MeroshareError } from "@amitdhoju/meroshare";

const client = new MeroshareClient();

// Step 1: find your numeric clientId from the DP list (one-time lookup)
const dps = await client.getDPList();
const { id: clientId } = client.getDPId("13010", dps); // your DP code string

// Step 2: login — token is stored internally on the client instance
await client.login(clientId, "00549011", "your-password");

// Step 3: call any endpoint
const me = await client.getOwnDetail();
const portfolio = await client.getPortfolio(me.demat, me.clientCode);

// Step 4: logout when done
await client.logout();
JavaScript (ESM)
import { MeroshareClient } from "@amitdhoju/meroshare";

const client = new MeroshareClient();
const dps = await client.getDPList();
const { id: clientId } = client.getDPId("13010", dps);
await client.login(clientId, "00549011", "your-password");
const me = await client.getOwnDetail();
console.log(me.name, me.demat);
await client.logout();
JavaScript (CommonJS)
const { MeroshareClient } = require("@amitdhoju/meroshare");

// top-level await not available in CJS — wrap in async function
async function main() {
  const client = new MeroshareClient();
  const dps = await client.getDPList();
  const { id: clientId } = client.getDPId("13010", dps);
  await client.login(clientId, "00549011", "your-password");
  const me = await client.getOwnDetail();
  console.log(me.name);
  await client.logout();
}

main().catch(console.error);
If you already know your clientId

If you've run getDPList() before and know your numeric clientId (e.g. 164), skip the lookup:

const client = new MeroshareClient();
await client.login(164, "00549011", "your-password");
Persisting the session token

To avoid re-logging in on every run (e.g. in a serverless function or cron job):

import { MeroshareClient } from "@amitdhoju/meroshare";

// After first login, save the token somewhere (env, DB, secrets manager, etc.)
const client = new MeroshareClient();
await client.login(164, "00549011", "your-password");
const token = client.getToken(); // save this

// On the next run, restore the token instead of logging in again
const client2 = new MeroshareClient();
client2.setToken(token!);
const me = await client2.getOwnDetail(); // works immediately
Error handling
import { MeroshareClient, MeroshareError } from "@amitdhoju/meroshare";

const client = new MeroshareClient();
try {
  await client.login(164, "00549011", "wrong-password");
} catch (e) {
  if (e instanceof MeroshareError) {
    console.log(e.status);  // HTTP status code, e.g. 401
    console.log(e.message); // clean message from the server
  }
}

API Reference

MeroshareClient

All methods require login first, except getDPList.


Auth
getDPList(): Promise<DP[]>

Fetch all registered depository participants (brokers). Use this to find your clientId.

Endpoint: GET /meroShare/capital/

const dps = await client.getDPList();
// [{ code: "13010", id: 164, name: "Nabil Investment Banking Ltd." }, ...]

login(clientId, username, password): Promise<LoginResponse>

Login and store the session token internally.

Endpoint: POST /meroShare/auth/

await client.login(164, "00549011", "your-password");

getOwnDetail(): Promise<OwnDetail>

Fetch the logged-in user's profile (boid, demat, clientCode, etc).

Endpoint: GET /meroShare/ownDetail/

const detail = await client.getOwnDetail();
// { boid, demat, clientCode, name, email, ... }

logout(): Promise<void>

Logout and clear the stored token.

Endpoint: GET /meroShare/logout/


Portfolio
getPortfolio(demat, clientCode, options?): Promise<PortfolioResponse>

Fetch the user's stock portfolio.

Endpoint: POST /meroShareView/myPortfolio/

Option Type Default Description
page number 1 Page number
size number 200 Results per page
const portfolio = await client.getPortfolio(detail.demat, detail.clientCode);
// { meroShareMyPortfolio: [...], totalItems, totalValueOfLastTransPrice, ... }

Issues
getApplicableIssues(options?): Promise<IssueListResponse>

Fetch IPO/FPO issues currently open for application.

Endpoint: POST /meroShare/companyShare/applicableIssue/

const { object: issues } = await client.getApplicableIssues();
// [{ companyShareId, scrip, companyName, shareTypeName, ... }]

getCurrentIssues(options?): Promise<IssueListResponse>

Fetch all currently open share issues.

Endpoint: POST /meroShare/companyShare/currentIssue


getIssueDetail(companyShareId): Promise<IssueDetail>

Fetch details for a specific issue (min/max units, share value, etc).

Endpoint: GET /meroShare/active/:companyShareId

const detail = await client.getIssueDetail(787);
// { minUnit, maxUnit, multipleOf, shareValue, scrip, ... }

Applications
getApplications(options?): Promise<ApplicationsResponse>

Fetch all IPO/FPO applications submitted by the logged-in user.

Endpoint: POST /meroShare/applicantForm/active/search/

const { object: apps } = await client.getApplications();
// [{ companyShareId, scrip, companyName, statusName, applicantFormId, ... }]

checkAlreadyApplied(companyShareId): Promise<boolean>

Check whether the user has already applied for a specific issue.

Endpoint: POST /meroShare/applicantForm/active/search/

const applied = await client.checkAlreadyApplied(787);

getAppliedIPOs(options?): Promise<AppliedIPOsResponse>

Fetch the applied IPO history report.

Endpoint: POST /meroShare/applicantForm/report/applied/search/

const { object: history } = await client.getAppliedIPOs({ page: 1, size: 20 });
// [{ companyName, appliedKitta, appliedDate, statusName, ... }]

Banks
getBankList(): Promise<Bank[]>

Fetch the user's linked banks.

Endpoint: GET /meroShare/bank/

const banks = await client.getBankList();
// [{ id: 37, code: "401", name: "Nabil Bank Ltd." }]

getBankAccounts(bankId): Promise<BankAccount[]>

Fetch accounts for a specific bank.

Endpoint: GET /meroShare/bank/:bankId

const accounts = await client.getBankAccounts(37);
// [{ id, accountNumber, accountBranchId, accountTypeId, accountTypeName, branchName }]

Apply
applyIPO(payload): Promise<ApplyIPOResponse>

Apply for an open IPO/FPO.

Endpoint: POST /meroShare/applicantForm/share/apply

await client.applyIPO({
  demat: detail.demat,
  boid: detail.boid,
  accountNumber: bankAccount.accountNumber,
  customerId: bankAccount.id,
  accountBranchId: bankAccount.accountBranchId,
  accountTypeId: bankAccount.accountTypeId,
  appliedKitta: "10",
  crnNumber: "your-crn",
  transactionPIN: "1234",
  companyShareId: "787",
  bankId: "37",
});

Helpers
getDPId(dpCode, dpList): { id: number; name: string }

Find a DP's numeric id and name from a list by its string code.

const { id, name } = client.getDPId("13010", dps);

All Endpoints

Method Endpoint Description
GET /meroShare/capital/ DP / broker list
POST /meroShare/auth/ Login
GET /meroShare/ownDetail/ Logged-in user profile
GET /meroShare/logout/ Logout
POST /meroShareView/myPortfolio/ Portfolio
POST /meroShare/companyShare/applicableIssue/ Open IPOs for application
POST /meroShare/companyShare/currentIssue All current issues
GET /meroShare/active/:id Issue detail
POST /meroShare/applicantForm/active/search/ My applications
POST /meroShare/applicantForm/report/applied/search/ Applied IPO history
GET /meroShare/bank/ Linked banks
GET /meroShare/bank/:bankId Bank accounts
POST /meroShare/applicantForm/share/apply Apply for IPO

All endpoints use base URL: https://webbackend.cdsc.com.np/api

License

MIT

Keywords