A3E9 logoA3E9
// AUDIENCE_FILTERShowing content for NIST / standards conformance. De-emphasized: Competitive positioning, the industry-landscape framing, and on-chain market operations — none of it is conformance evidence.

// TINL · UAT_PROCEDURE · ANDROID

Android mobile UAT — the procedure, in full

The acceptance test for TINL's in-wallet Android path: the demo app's built-in scenarios evaluated through a local TINL service over REST. Published with its limits attached — this build evaluates via Mode B, on-device Mode A is not wired, and live WalletConnect relay pairing is stubbed in v0.

Read-only · This is the procedure, published in full and without a login. It is not a test result and not a claim that the steps pass — it states what this project considers a correct outcome, so that a reader can judge the standard before judging the system against it. Nothing on this page calls an API; the endpoints named below still require an evaluator token.

// TINL_MOBILE_UAT_GUIDE

Mobile UAT — Android in-wallet path

Separate track from the Chrome / portal UAT Guide. Use this when you have the TINL demo wallet on an Android emulator or device. Part 1 explains the path; Part 2 is the test.

This guide is only for the TINL Android demo wallet (in-wallet path). It is not the Chrome extension UAT and not the portal Wallet Demo 25-step guide. For MetaMask / Phantom in the browser, use the portal tab “UAT Guide” (Chrome / portal) instead. This build evaluates via Mode B (local TINL service over REST). On-device Mode A is not wired yet. Use the app’s built-in scenario buttons — live WalletConnect relay pairing is stubbed in v0.

Download PDF saves TINL-Mobile-UAT-Guide-Android.pdf — mobile steps only. Generated from this same tab so the printout cannot disagree with the portal.

Part 1 — How the mobile track is laid out, and why

Sign path: dApp → WalletConnect → demo wallet → TINL evaluateSessionRequest → in-app decision sheet → only then optional native sign. No window.ethereum inject.

Portal tab — Mobile UAT Guide (this document)

Kept as its own tab so Chrome/portal checks and Android checks never share a step list. Mixing them would force MetaMask/Phantom steps on a phone path that does not use those extensions.

Demo wallet home — profile + scenarios + Deep Signal chrome

Profile is the policy variable (Retail — Strict default). Scenario cards are real session_request fixtures through evaluateSessionRequest — not mocked decisions. UI is Deep Signal (dark navy, teal), not stock Expo.

WalletConnect pair screen (v0 stub)

Accepts a wc: URI and documents the seam, but live relay pairing needs WalletKit + RN crypto polyfills (out of scope for this build). Security property under test does not depend on pairing — scenarios exercise the same evaluate() path.

TINL decision sheet (in-app)

BLOCK / WARN / NORMALIZE / ALLOW UI lives inside the wallet process. A hostile website cannot skip or forge this sheet via page JavaScript. BLOCK shows Dismiss only — no proceed affordance.

Normalized payload panel (NORMALIZE only)

NORMALIZE is auto-applied by @a3e9/tinl-walletconnect (headless package). This build does not yet offer the portal’s interactive amount picker. The sheet shows the rewritten params the app would sign.

Before you begin

  • Android emulator on Linux/WSL (or a physical Android device). Android-first; iPhone via Expo EAS is optional later.
  • TINL service running for Mode B: cargo run -p a3e9-tinl (default A3E9_TINL_LISTEN=0.0.0.0:8090 — same port as extension Mode B).
  • Demo app from a3e9-tinl apps/mobile: ./scripts/android-demo.sh (Linux+KVM) or ./scripts/android-demo-wsl-windows.sh (WSL+Windows AVD). Emulator API base must be http://10.0.2.2:8090/api/v1 (includes /api/v1; port 8090 not 8080).
  • Your evaluator token, used only to open this portal guide — the mobile app does not import seed phrases from this website.
  • You never enter a private key or seed into any website for this test. If any web screen asks for one, stop and report it.

Part 2 — The test, steps 1–19

Work top to bottom. Steps marked RELEASE BLOCKER stop the mobile demo path if they fail. Optional Solana / outage steps may be marked skipped when the build does not expose them yet.

Steps 1–3Access, install, and open the right track

Confirms you are evaluating the Android in-wallet path, not the browser extension. Wrong track = wrong expectations on WARN/NORMALIZE enforcement.

#Do thisInputExpected output
1Open the TINL evaluator and sign in.https://a3e9.com/tinl/evaluator — paste the evaluator token you were issued.Portal loads at /tinl/evaluator/portal. Tabs include Wallet Demo, Price Impact, UAT Guide (Chrome / portal), and Mobile UAT Guide. Open Mobile UAT Guide for this track.
2Install or launch the TINL mobile demo on Android.From monorepo: ./scripts/android-demo.sh (or npm run android with service on :8090).App opens with Deep Signal styling (dark background, teal accents). Home shows profile selector defaulting to Retail — Strict. Honesty banner states Mode B (REST), not on-device Mode A. No seed phrase request from a3e9.com.
3Confirm you are not using the Chrome UAT Guide for this run.None — scope check.You are not following MetaMask/Phantom connect steps. Those belong only to the Chrome / portal UAT Guide tab.
Steps 4–5Baseline — ALLOW still works

Before testing what TINL stops, confirm ordinary activity still reaches a normal confirm path. A tool that blocks everything is not a control.

#Do thisInputExpected output
4Set profile to Retail — Strict. Tap scenario “Transfer WETH to another account”.Profile: Retail — Strict. Scenario button on Home (canned session_request).TINL decision is ALLOW, rule ERC20_TRANSFER (or equivalent transfer rule). Sheet offers Proceed / Cancel. You may dismiss — no need to “sign” for real.
5Note where the TINL decision appeared.None — visual check.Any TINL UI appeared inside the mobile app, not as a browser extension popup and not as a page overlay on a dApp site.
Steps 6–9NORMALIZE and BLOCK on unlimited approve — headline checks

Same policy intent as the Chrome guide’s unlimited-approve sequence, but enforcement is stronger on this path: consent and BLOCK live in the wallet process. Step 8 proves the rewritten payload is not unlimited; step 9 proves BLOCK never offers a proceed path.

#Do thisInputExpected output
6Tap scenario “Approve UNLIMITED WETH spend”.Profile: Retail — Strict.In-app TINL sheet opens. Decision: NORMALIZE. Rule: ERC20_UNLIMITED_APPROVE. Action from evaluateSessionRequest is proceed-normalized.
7Read the NORMALIZE sheet (no amount picker in this build).None — read-only.Sheet shows a NORMALIZED PAYLOAD panel (JSON of rewritten params). There is no portal-style “Only this much / Nothing / Unlimited” chooser yet — auto-normalize by the WC package is intentional. Button label: “Sign the normalized request”.
8Confirm the normalized payload is not the original unlimited approve. Release blockerNone — inspect the payload panel.The data field is not the original max-uint256 approve (engine rewrote the amount). Cancel is available. Primary button only signs the normalized params — never the original unlimited request.
9Tap scenario “setApprovalForAll on an NFT collection”. Release blockerProfile: Retail — Strict.TINL shows BLOCK, rule ERC721_SET_APPROVAL_ALL. Only a Dismiss control — no Proceed. No raw private-key / seed sign sheet opens.
Steps 10–12WARN in-app — enforced, not advisory against the page

On Chrome, WARN consent can be advisory against a hostile page (documented extension limit). On this mobile path, WARN is rendered by the app’s own UI; the page cannot postMessage a forge. That honesty difference is why this guide is separate.

#Do thisInputExpected output
10Tap scenario “Call an unrecognized function”.Profile: Retail — Strict.In-app WARN sheet. Rule SELECTOR_UNKNOWN. Proceed and Cancel are controlled by the app.
11Tap Cancel on the WARN sheet.None.Sheet closes. No signature is produced.
12Re-read the mobile scope note / in-app honesty banner.None — visual check.Claims stay scoped to users of this in-wallet path. It does not claim that installing the Chrome extension alone gives the same guarantees. Mode B is disclosed.
Steps 13–15Profile change and optional Solana

Proves policy is profile-driven. Solana scenario buttons are not in the EVM-first demo vector set yet — mark skipped.

#Do thisInputExpected output
13Switch profile to Active DeFi User — Balanced and re-run a scenario that was BLOCK or NORMALIZE under Retail — Strict.Same scenario button, different profile.Decision can change with profile. Same input, different posture — profile is the policy.
14(Optional) Solana unlimited SPL approve.Not available as a Home scenario in this build.Record “skipped — EVM-only demo vectors”. Engine and @a3e9/tinl-walletconnect already support Solana when a live payload is supplied.
15(Optional) Benign SOL transfer → ALLOW.Not available as a Home scenario in this build.Record skipped — same reason as step 14.
Steps 16–17On-device / outage posture

Mode A native binding over core/ is the next milestone. This demo is Mode B only and says so in the UI.

#Do thisInputExpected output
16Look for offline / Mode A / outage simulation controls.None in current apps/mobile.Record “N/A — Mode B only”. Stopping the local service should make scenarios fail with a clear evaluation error, not silent ALLOW.
17Confirm native mode is not silently selected.None.App does not offer a fake on-device mode. nativeEvaluatorUnavailable() throws if forced — no silent REST fallback while claiming Mode A.
Steps 18–19What this track does not prove

Honesty fence for App Store / Play / NIST-facing notes. Closing Chrome races for users of this wallet does not certify every phone wallet on earth.

#Do thisInputExpected output
18Confirm residual non-claims.None — read-only.This run does not prove: Chrome extension MAIN-world consent is fixed; MetaMask Mobile native hooks without WalletConnect; iOS Simulator without a Mac; Play/App Store listing already live; HSM a3e9-attestation running on the phone; on-device offline evaluation.
19Record build identity for the report.git rev-parse --short HEAD from a3e9-tinl (and branch name).You can name exactly which monorepo SHA was evaluated. A report without a build id is not reproducible.

Record the result

Date / evaluator 
Android emulator or device + OS version 
Mobile app monorepo git SHA / branch 
Step 8 — normalized payload not unlimited (RELEASE BLOCKER) 
Step 9 — BLOCK never offered proceed (RELEASE BLOCKER) 
Steps 14–15 — Solana path (or marked skipped — expected for this build) 
Were you ever asked for a private key or seed on a website? 
Did you use this guide (Mobile) rather than Chrome UAT by mistake? 

Any failure at step 8 or step 9 is a release blocker for the mobile demo path. Do not mark Chrome extension UAT complete based on this guide, or vice versa — the tracks stay separate. Keep this module aligned with a3e9-tinl/doc/TINL_MOBILE_UAT_CHECKLIST.md and apps/mobile scenario labels; re-issue the PDF from the portal after content changes.

// WHAT_A_TOKEN_ADDS

A token runs this procedure rather than reads it: signing in to the TINL evaluator lets you drive the same policy engine this guide predicts, submit your own calldata to /api/tinl/normalize, and compare the returned decision against the expected outcome printed at each step. The steps and their stated limits are public; a decision returned for a transaction you chose is what the token adds.