nigig-org/crates/apps/nigig-mpesa
andodeki a264f53eb7
Some checks failed
Payment domain, storage, platform and UI / isolated-payment-tests (push) Waiting to run
Payment domain, storage, platform and UI / payment-ui-tests (push) Waiting to run
repo hygiene / hygiene (push) Has been cancelled
feat(pay): complete phase R1 of the remaining-work plan
All four R1 items. Two of them uncovered defects that were not in the
review, and R1.4's corpus found a live bug.

## R1.1 versioned fee policy (U9)

The band table is a static "effective Jan 2024" snapshot. When Safaricom
revises a tariff, nothing notices: the old number is quoted and the user
authorises a total they are not charged.

FeePolicy attaches provenance and a 400-day trust horizon. Past it,
fee_for returns FeeError::PolicyOutOfDate rather than a number, and the
sheet refuses to quote exactly as it already does for an unknown band —
"no band for this amount" and "our table is old" stay distinguishable
because they need different messages. Verified by disabling the check:
4 tests fail. Domain tests 137 -> 148.

## R1.2 quality gate for nigig-pay-ui (Q2)

Correcting my own earlier count: 9 of the 10 unwraps were in tests. The one
production case, on the dispatch path inside the biometric branch, is now a
fail-closed path — no request, no prompt, no dispatch.

nigig-pay-ui now denies unwrap_used/expect_used outside tests and CI runs
clippy --no-deps -D warnings. Scoped with --no-deps because matrix_client
and robius-ussd carry pre-existing warnings that are not this crate's to
fix, and a gate that fails on someone else's code gets disabled.

Turning the lint on surfaced 13 more issues, one a real defect:
normalise_phone had two identical branches, and the 13-digit "254…" arm
produced an 11-digit result — not a valid MSISDN, but non-empty, so it
flowed on as a recipient. The duplication was hiding it.

## R1.3 exchange API (S7/S8/S10)

The client forged origin/referer for api2.bybit.com and p2p.binance.com,
impersonating those exchanges' own web clients against internal endpoints.
Removed from both copies (nigig-pay and nigig-mpesa — item A5 again), along
with the framework-identifying User-Agent. CI rejects either regrowing.

Requests are still made, now honestly identified. If those endpoints reject
an honest client the P2P panes fall back to their offline cache, which is
the true state of the integration rather than a disguised one.

Not done, deliberately: certificate pinning. Pinning an endpoint the
product may drop is wasted work, and whether to keep these endpoints is a
product call recorded in the plan.

## R1.4 adversarial CSV corpus (7.5)

parse_csv turns an untrusted file into a payment list. Corpus covers empty
input, injection-shaped fields, overflow, NUL, RTL override, full-width
digits, a 5,000-row file and malformed numbers. The bar is not "parses
correctly" but "never silently produces a payment nobody intended".
Verified it can fail. UI tests 61 -> 66.

## Validation

  domain 148 / storage 41 / platform 64 / mpesa 29 / pay-ui 66   pass
  clippy -p nigig-pay-ui --no-deps -D warnings                    0 errors
  builds: pay-ui, pay, mpesa, core; default and --no-default      pass
  pin-capture guard                                               pass
  fee-policy injection: 4 tests fail with the check removed       pass
  corpus injection: catches a fabricating normaliser              pass
2026-08-02 08:33:16 +00:00
..
src feat(pay): complete phase R1 of the remaining-work plan 2026-08-02 08:33:16 +00:00
tests build: consume Makepad sibling APIs through widgets 2026-07-27 04:22:42 +00:00
Cargo.toml feat(pay): USSD automation on by default; containment moves to packaging 2026-08-02 08:06:43 +00:00
README.md Initial commit 2026-07-26 19:38:26 +03:00

similar to this sms crate in attached code lets create two crate for robius-ussd and robius-fingerprinting for registering fingerprint and ussd actions in android see androidkotlin.txt for what we are trying to do and add to out code fab icon and fingerprinnting also be one of the security feature before allowing money transaction

see example for ussd app attached androidkotlin.txt we need for makepad 2.0 ui to be used

since we need a fab icon "Pay" which pull up a bottom sheet like in the screenshot appear topic New Expense to be able to pay via ussd for mpesa on the mpesa tracker code attached in mpesa.txt . use the nigig-uikit and nigig-core for ui commom ui and a sample of a bottom sheet we can reuse in out new fab action functionality where we are supposed to have a tabbed menu for New Expense(Meaning Paid Cash or by someone else or other payment option) or Payment (process new Payment)

also capture the transaction cost for a certain transaction also see the mpesa tracker screen we have tab like transaction | Expenses | Taxes etc

we need one for Pay | New Expense
in pay for mpesa we should aslo have the bands shown to the user for the transaction to be made when the user has entered the amount to be transacted. otherwise we should implement the kotline code for all the mpesa transaction possible available there and each transaction offline recorded for the cost of each transaction also and an expense to and wil be included to the user analysis check the shared uikit style ui for the common ui use cases kit button icons and the tabbed menu or the bottom sheet we have used.

use offline first architecture befire doing or proceeding with a transaction as a principle in the app architecture which then can be verified after the transaction is done.

Offline-first — For data that should survive offline (transaction, receipts, earnings history), always write to Room first and emit from a local Flow. Network responses update the local store, which then propagates to the UI.

From the makepad_table/ workspace root:

Full invoicer app

cargo run -p makepad-invoicer --release

Just the Table widget demo (the "Random table" UI)

cargo run -p makepad-invoicer --example table_demo --release

Run doc-model unit tests (no GUI needed)

cargo test -p makepad-doc-model

Band: - (enter amount) section we should not have a card and should only show the transaction cost not the band the band should just work in the background and display the amount for transaction cost and the default amount to be shown is Ksh 0.

so in a row (Ksh 0 Deduct [Toggle] Widthraw [Toggle])

th Pick CSV button does not open the file picker and does not show visually if its trully dissabled the No file selected should not appear below the button row but in one row (Button [Toggle]) - when disabled (Button Select File [Toggle]) - when enabled

we should add a step to show the name of the person receiving the amount of money to be sent usually at the screen where one needs to type in 1 to proceed with the transaction or 2 not to proceed with the transaction. so i think a Toggle to give the green light to proceed with the transaction. also the toggle should be disabled by default which should indicate that each transaction should be confirmed by the user before we proceed with option 1 showing confidence we can type 1 and end the transaction. now the name need to be captured or the entity receiving the transaction needs to be captured by the systems and save the entity as the entry receiving the money transacted we should also have a category with the dropdown list of possible categories we have. also a dropdown for the spending if it personal or which project in out project list or on behalf of someone or company or project. We should have a modal for the user to proceed with the transaction by clicking ok of cancel with the name of recepient and amount. check robrix how it has the copy button in the setting screen we need a copy button in the modal besides the recepient to copy