InstaCash external API + eSign headless test path (bin/instacash-cli) — 2026-06-01
Summary
How to drive the InstaCash external API (the integration the bank calls into vuer_oss) and the downstream eSign contract-upload plumbing headlessly from the vuer_oss container on the dev box, using the branch-only tool bin/instacash-cli.js. Section A is a reusable how-to (prereqs, every command, the SSH path, gotchas). Section B is the concrete 2026-06-01 verified run with its findings and one open question. Everything below was verified live on the lederera dev box on 2026-06-01.
Hard limitation — the actual signature CANNOT be driven headless
instacash-cli proves the external API + EsignRPC plumbing end-to-end, but it cannot complete an eSign signature. The signature is interactive: a human opens the inviteUrl (css), does video identification, authenticates (mock /auth + SMS code), and signs in the eSign UI. See § Hard limitation.
Quick recipe
Drive the InstaCash external API headlessly (dev box)
# 0. SSH in (kaku shadows ssh → use `command ssh`; fk-dev = the current docker host)command ssh ops@fk-dev.taild4189d.ts.net # old `ssh Facekom` box is DEAD — see [[dev-build-host]]# helper: every cli cmd runs INSIDE the vuer_oss container, in the app diric() { docker exec vuer_oss sh -c "cd /workspace/vuer_oss && node bin/instacash-cli $*"; }# 1. Start the MOCK bank /auth + /status server (DETACHED — it blocks)docker exec -d vuer_oss sh -c \ 'cd /workspace/vuer_oss && node bin/instacash-cli start-server > /tmp/ic-mock.log 2>&1'# → /tmp/ic-mock.log: "InstaCash external server is listening on 8189"# 2. Create an application (faker customer data) → returns customerId + URLsic post-application rt mkb_szemelyi_kolcson# → { customerId, customerProfileUrl, inviteUrl }# 3. Inspectic get-invite <customerId> # → { url: <videochat invite> }ic get-customer <customerId> # → full customer data (product, state, …)# 4. Upload a contract (built-in dummy base64 PDF if no path) → ic-contract flow → EsignRPCic post-contract <customerId> [pdfPath]ic get-contract <contractId>ic revoke-contract <contractId>
Prereqs (all must hold): healthy stack (vuer_oss + esign_css + esign_oss + postgresql + rabbitmq + vuer_cv all Up/healthy); config.instacash.external present (apiKey = the Bearer token; authMock); settings.allowSelfSignedCerts: true. Every command exceptstart-serverboots the full vuer_oss service in-process and makes real HTTPS calls — it needs a live, conflict-free stack.
Section A — General how-to (reusable)
What the tool actually is
bin/instacash-cli.js (Node + commander; deps request-promise-native, express, faker) does two distinct jobs:
Mocks the bank’s external endpoints — start-server stands up a small Express server exposing the bank-side /auth and /status endpoints that vuer_oss/eSign call out to during the flow.
Drives the InstaCash external API — the rest of the subcommands act as the bank calling into vuer_oss, hitting https://${hosts.oss}/external/....
It is NOT just an HTTP client — every command (except start-server) boots the whole service
Each subcommand other than start-serverboots the full vuer_oss service container in-process (keystore + Postgres + RabbitMQ amqps://localhost:5671), and only then makes the HTTPS call to https://${hosts.oss}/external/.... Consequences:
It requires a healthy, running stack and conflict-free config (e.g. nothing else holding the same ports / RabbitMQ already up).
Startup is not instant — expect the keystore/Postgres/RabbitMQ boot lines before the HTTP response.
A failure can come from the in-process boot, not just the remote endpoint — read the full output, not only the last line.
For Agents — orientation
Branch-only script.bin/instacash-cli.js exists only on customization/instacash (and its update/... branches); git show devel:bin/instacash-cli.js fails. It is not on devel. See customization-branches (per-customer bin: instacash → instacash-cli.js) and instacash-update-2026-05-27-status.
Where it runs: inside the vuer_oss container on the dev box. App dir /workspace/vuer_oss, branch customization/instacash, NODE_ENV=dev.
Auth:config.get('instacash.external.apiKey') is sent as the Bearer token to /external/....
TLS: the CLI sets NODE_TLS_REJECT_UNAUTHORIZED=0 for the dev self-signed certs; pair with settings.allowSelfSignedCerts: true in config.
If photo processing fails during identification, vuer_cv may be stopped or hairpin-NAT may be biting — see dev-box-cv-photo-processing-failures.
Config instacash.external present:
instacash.external.apiKey → sent as the Bearer token on every /external/... call.
instacash.external.authMock → mock-auth settings the bank /auth endpoint uses.
settings.allowSelfSignedCerts: true — the dev box uses self-signed certs; the CLI also sets NODE_TLS_REJECT_UNAUTHORIZED=0. Without this the HTTPS calls to https://${hosts.oss}/external/... fail TLS.
SSH to the dev box (from Claude’s shell)
Host changed (2026-07-01)
This session ran on the old ssh Facekom box (lederera@localhost via ProxyJump FKJumpBox → lederera-447-fk-hardver), now decommissioned. Current host: fk-dev — command ssh ops@fk-dev.taild4189d.ts.net (Tailscale SSH, no keypair, no jump box). The recipe is otherwise unchanged. See dev-build-host.
STILL TRUE — use command ssh (a kaku wrapper shadows plain ssh)
In Claude’s non-interactive shell the user’s kaku alias resolves to _kaku_wrapped_ssh: command not found, so plain ssh fails. Bypass with command ssh / command scp.
For non-interactive batches use a login shell so docker is on PATH:
Always docker exec vuer_oss sh -c 'cd /workspace/vuer_oss && node bin/instacash-cli <cmd>'. The cd matters — the script resolves config relative to the app dir.
start-server [port=8189] — mock bank /auth + /status
Stands up the mock bank-side endpoints. It blocks (long-running Express server), so run detached:
docker exec -d vuer_oss sh -c \ 'cd /workspace/vuer_oss && node bin/instacash-cli start-server > /tmp/ic-mock.log 2>&1'# /tmp/ic-mock.log → "InstaCash external server is listening on 8189"
This is the only command that does not boot the full vuer_oss service in-process.
States: none → initial → applied → identification → identified → signature → signed, plus terminal/branch states aborted, rejected, accepted. instacash-cli can move a customer to created/applied (post-application) and exercise the contract API (post-contract), but identification → identified → signature → signed needs the interactive browser flow.
Section B — InstaCash-specific run (verified 2026-06-01)
Environment
lederera dev box, vuer_oss container, app dir /workspace/vuer_oss, branch customization/instacash, NODE_ENV=dev. Run during the InstaCash 2026-05-27 devel-update testing wave (after applying the nginx-PID fix to bring esign containers healthy).
The run, step by step
1. Mock server up
start-server → "InstaCash external server is listening on 8189"
get-invite 28 → { url: https://css-lederera.facekomdev.net/dch/eL90QmqJbqWXOjVd } # same invite
get-customer 28 → product: loan, state: created
4. Upload contract — HTTP 400, blocked
post-contract 28
→ HTTP 400 with a clean JSON body:
{"error":"Contract flow is in progress"}
This is a clean rejection, not a crash
The 400 was served through nginx → vuer_oss as well-formed JSON. The plumbing (external API → nginx → vuer_oss → contract-flow logic) is working; the request was rejected by business logic, not a stack failure.
Open question to verify — flag for intended InstaCash behaviour
Why does a freshly-created application already have a contract flow "in progress"?
Customer 28 was just created via post-application and has not been identified (state: created). Yet post-contract is rejected with {"error":"Contract flow is in progress"} — implying a contract flow already exists/blocks the external upload at this stage.
This conflicts with developer-guide-hu.md, which states that contract upload happens AFTER identification. So either:
a contract flow is auto-created at application time (and the external upload is meant to wait until after identification), or
the guide and the current customization/instacash behaviour have drifted.
Action: verify the intended InstaCash sequencing — is post-contract expected to fail pre-identification, or should the external contract upload be allowed (and the “in progress” flow is the bug)? Reconcile against developer-guide-hu.md and the ic-contract (“IC - Szerződés ajánlat feltöltése”) flow creation point.
What this run proved (and didn’t)
Proved
Not proved (interactive only)
External API reachable: POST /external/application, get-invite, get-customer all return clean responses through nginx → vuer_oss
Video identification (identification → identified)
vuer_oss in-process boot (keystore, Postgres, RabbitMQ) works from the CLI
Authentication (mock /auth + SMS 123456)
Contract endpoint is wired and returns structured errors (the 400 was clean JSON, not a 5xx/crash)
The actual eSign signature (signature → signed)
Mock bank server (/auth, /status) starts on 8189
A successful post-contract (blocked by the “in progress” flow this run)
Related
instacash-update-2026-05-27-status — the InstaCash 2026-05-27 devel-update wave this testing belongs to; per-repo branch/conflict topology (vuer_oss is on update/customization/instacash-2026-05-27).
dev-build-host — current dev/build host (fk-dev Tailscale VM); the old ssh Facekom box is decommissioned.
dev-box-cv-photo-processing-failures — if identification’s photo step fails (vuer_cv stopped / hairpin NAT); the /etc/hosts remap that also keeps bin/instacash-cli’s oss-lederera/external/... path reachable after a docker restart.
sms-verification-code-dev-testing — the SMS code (123456, test.security.tempTokenSms) needed in the interactive auth step the CLI can’t drive.
esign — Electronic Signature System (esign_css / esign_oss) overview; what post-contract ultimately drives via EsignRPC.