Single source of truth for agents working in this repo. CLAUDE.md imports this file via
@AGENTS.md, so Claude Code, Codex, and any other agent that reads AGENTS.md share the same
instructions.
- State assumptions when ambiguity affects implementation, public API, security, or release behavior.
- Keep changes surgical and traceable to the request. Avoid speculative abstractions, broad refactors, and formatting churn.
- Preserve user work in the tree and match the local style of the files you touch.
- Define success criteria for non-trivial work and choose verification proportional to the risk.
For non-trivial or version-sensitive third-party library questions, prefer context7 or official documentation over training-data recall. If context7 is unavailable, use official docs or local package sources and note the fallback; do not block ordinary repo work just to install extra tooling.
This repository is an Android/Kotlin SDK for OMS Wallet wallet, auth, signing, indexer, and API integrations. It contains the publishable Android library module plus a small Android sample app used for manual flows.
Use the Gradle wrapper for all build and verification work. Main CI runs SDK unit tests, Android lint for both modules, and sample app assembly.
oms-wallet-kotlin-sdk/- Android library module and public SDK surface.oms-wallet-kotlin-sdk/src/main/java/technology/polygon/omswallet/- SDK entry point, wallet/indexer clients, session storage, networking, utilities, and models.oms-wallet-kotlin-sdk/src/main/java/technology/polygon/omswallet/internal/generated/waas/- generated WaaS WebRPC client/types.
oms-wallet-kotlin-sdk/src/test/- JVM unit tests for SDK behavior, serialization, service clients, signing vectors, and utility helpers.oms-wallet-kotlin-sdk/src/androidTest/- instrumented Android tests for Android Keystore credential behavior.app/- Android sample app for auth, signing, transaction, and testbed flows.docs/- public API notes, public error contracts, session-expiry notes, and request-signing parity vectors..github/workflows/android-ci.yml- CI workflow for PRs andmaster..github/workflows/claude-review.yml- Claude review workflow. It runs once for non-Dependabot PRs when opened or marked ready for review, and can be requested later with@claude reviewin a PR or review comment.
./gradlew --build-cache verify- Full SDK verification, matching
.github/workflows/android-ci.yml.
- Full SDK verification, matching
./gradlew :oms-wallet-kotlin-sdk:testDebugUnitTest- Run SDK JVM unit tests. Use for most library logic changes.
./gradlew :oms-wallet-kotlin-sdk:lintDebug- Run Android lint for the SDK module.
./gradlew :app:lintDebug- Run Android lint for the sample app.
./gradlew :app:assembleDebug- Build the sample debug APK and verify the SDK integrates into the app.
- To run the sample app on an emulator, prefer a reusable repo script or a short command that installs the debug APK and launches the manifest-declared launcher activity. Existing project/local run commands that launch the known sample activity are fine; do not invent new hardcoded activity names when the manifest or a project run configuration can provide them. Keep an already-running emulator open when possible instead of cold-booting it for every run.
./gradlew ktlintCheck- Run local Kotlin style lint for both modules. New violations should fail this check.
tools/install-git-hooks.sh- Configure this checkout to use
tools/git-hooks; the pre-push hook runs./gradlew ktlintCheck.
- Configure this checkout to use
./gradlew ktlintFormat- Auto-format Kotlin files where ktlint can safely correct violations.
./gradlew :oms-wallet-kotlin-sdk:connectedDebugAndroidTest- Run local/manual instrumented SDK tests on a connected Android device or emulator. Use this when changing Android Keystore, credential, nonce, or platform session behavior.
./gradlew :oms-wallet-kotlin-sdk:publishToMavenLocal- Publish the SDK artifact to the local Maven cache for packaging checks.
Use the Gradle wrapper; it resolves dependencies from Google Maven, Maven Central, and the Gradle Plugin Portal.
Choose the smallest relevant checks before reporting completion. For
README/API/docs-only edits, use source-backed spot checks plus
git diff --check; run Gradle checks only when the docs claim changed source
behavior, public API shape, or runnable sample code.
- Kotlin style:
./gradlew ktlintCheck. - SDK logic:
./gradlew :oms-wallet-kotlin-sdk:testDebugUnitTest. - Sample app, manifest, or resource changes:
./gradlew :app:lintDebugand./gradlew :app:assembleDebug. - Broad or cross-module changes: run the full CI-equivalent command listed in Development Commands.
Run only when relevant:
- Android Keystore, credential, nonce, or platform session changes:
./gradlew :oms-wallet-kotlin-sdk:connectedDebugAndroidTestlocally with a connected emulator or device. This is an intentional local/manual gate, not a GitHub CI requirement. - Publishing/package validation:
./gradlew :oms-wallet-kotlin-sdk:publishToMavenLocalwhen changing publication metadata or release packaging.
Add or update focused tests under oms-wallet-kotlin-sdk/src/test/ for behavior
changes. Do not claim a check passed unless you ran it and have the command
result.
OMSWalletis the main public entry point. Keep public API changes aligned withREADME.mdanddocs/api.md.WalletClient, request signing, auth completion, wallet selection, fee selection, and transaction status polling are central library behavior; prefer small, tested changes there.- Treat returned wallet-auth action objects such as
PendingWalletSelectionas public SDK operation boundaries. Wrap their network-backed actions withrunOMSWalletOperationand the matchingPendingWalletSelection...operation so generated WebRPC and transport exceptions are classified asOMSWalletException. OMSWalletEnvironment,OMSWalletHttpClient, andOMSWalletJsondefine service routing and JSON behavior. Preserve existing serialization defaults unless tests and API docs are updated together.- Public auth, wallet selection, and signing APIs should expose client-facing
SDK models documented in
docs/api.md, not generated WaaS classes. Some public models are client-facing aliases inOMSWalletModels.kt; check the docs and tests before changing that public boundary. - Search for existing models, helper functions, serializers, and test fixtures before adding new ones. Do not add shallow wrappers unless they enforce a real invariant or isolate a real external boundary.
- Refactors should be thin vertical slices that leave the project compiling and testable after each step.
oms-wallet-kotlin-sdk/src/main/java/technology/polygon/omswallet/internal/generated/waas/WaasWalletClient.ktis generated WebRPC code and the largest production source file. Do not hand edit it casually. The upstream source of truth is thehttps://github.com/0xsequence/waasproject; update this generated client from upstream as needed.WalletClient.kt,WalletRequestSigner.kt,WalletAuthChallenge.kt,AndroidKeystoreP256CredentialSigner.kt, andAndroidKeystoreSessionStore.kthandle auth state, credentials, nonces, signing, and persisted sessions. Treat behavior changes here as security-sensitive and add regression tests.- Wallet auth, signing, access, session, and transaction tests live under
oms-wallet-kotlin-sdk/src/test/java/technology/polygon/omswallet/wallet/. Add narrowly scoped tests near the behavior being changed instead of broad setup rewrites.
- Kotlin code style is set to
officialingradle.properties. - Android modules target Java 17 and declare Android
minSdk 24; live runtime/manual SDK flows require Android 10 / API 29 or newer. - The repo uses Gradle Kotlin DSL and version catalog dependencies in
gradle/libs.versions.toml. - Ktlint is configured through
org.jlleitschuh.gradle.ktlintand.editorconfig, withktlint_code_style = ktlint_official. ktlint_standard_package-nameis disabled to avoid churn from package-name rules if generated or legacy Android names are introduced.ktlint_standard_property-namingis disabled because the repo intentionally uses lowerCamel companion constants for internal wire/header names such asOMSWalletEnvironment.accessKeyHeaderName; renaming those would add needless churn.- Do not change ktlint rule exceptions casually. If a rule starts enforcing a real project invariant, remove the exception in the same change that fixes the affected code.
- Public SDK APIs use KDoc comments in existing entry points; preserve that style for new public members.
- There is no detekt static-analysis check configured.
See TESTING.md for full testing conventions, unit vs. integration boundaries, and the execution command reference.
- Use
TESTING.mdas the source of truth for test boundaries and public error contract rules. - Unit tests live in
oms-wallet-kotlin-sdk/src/test/java/...and use JUnit 4. - Network-facing client tests use MockWebServer where local HTTP behavior is needed.
- Signing parity tests are documented in
docs/complete_auth_vectors.md; keep request payload, preimage, digest, signature, and authorization header behavior deterministic. - Prefer tests through public or internal SDK interfaces that callers actually exercise. Avoid tests that only assert private call ordering.
- Mock true external boundaries such as network, time, randomness, and Android platform services. Prefer deterministic local fixtures for signing vectors.
- Add regression tests for bug fixes before or alongside the fix when practical.
- Follow
TESTING.mdbefore adding or updating public error contract tests. - Use
docs/error-contracts.mdas the audit matrix for public SDK error surfaces, recovery semantics,upstreamErrorexpectations, and owning tests. - Keep serialized public error shape assertions centralized in
PublicErrorContractsTest; focused tests should cover behavior or edge cases without duplicating the full matrix. - Exercise real public runtime APIs and mock only external boundaries.
- Do not assert manually constructed
OMSWalletExceptionsubclasses unless the error class or helper is the unit under test. - Assert stable public fields only; do not assert raw
cause, stacks, generated internals, headers, timestamps, or full backend payloads as public contract. - Keep backend and upstream mapping tests representative rather than exhaustive per method; cover each transport family through real public calls.
- Include
upstreamErroronly when the path crosses a remote service response or transport boundary. SDK-local failures should not expose upstream details. - Android storage and Keystore signer internals belong in focused platform tests unless they are intentionally normalized through documented public SDK errors.
oms-wallet-kotlin-sdk/src/main/java/technology/polygon/omswallet/internal/generated/waas/WaasWalletClient.ktis generated bywebrpc-genfrom the upstream0xsequence/waasproject. Treat that upstream repository as the source of truth and update the generated client here only when the SDK needs a WaaS API refresh.build/,*/build/,.gradle/,.gradle-user/,.npm-cache/,.android-user/,.kotlin/,.idea/,.codex/, andlocal.propertiesare ignored local artifacts.- Android launcher images and XML resources in
app/src/main/res/are sample app assets. Change them only for sample app work. tools/git-hooks/pre-pushis a versioned local hook. Runtools/install-git-hooks.shafter cloning to enable it for a checkout.
- Do not commit secrets, access keys, signing keys,
local.properties, Android Studio state, or local Gradle/cache files. publishableKeyandprojectIdare public identifiers required by SDK consumers and sample flows. Concrete sandbox publishable keys may be checked into sample app configs when intentionally provided for runnable examples; do not flag or replace them solely because they are concrete values.- Android Keystore credential and session code must continue to avoid persisting private key material in app storage.
- Publishing/signing properties are read from Gradle properties. Do not add real publishing credentials or PGP material to the repo.
- Inspect relevant code, tests, docs, and Gradle configuration before editing.
- Keep changes narrowly scoped to the requested behavior.
- Preserve user changes in the working tree; never revert unrelated edits.
- Prefer existing package structure, naming, serializers, HTTP helpers, and session/signing abstractions.
- Update tests and docs when behavior or public API changes.
- Keep task specs durable: behavior, contracts, inputs/outputs, and acceptance criteria matter more than stale file or line references.
- Ask before making product, architecture, or security trade-offs that are not answered by the request or existing docs.
- Run the relevant verification commands before reporting completion.
- Branch names should be plain and descriptive, such as
fix-login-timeoutoradd-wallet-tests. Do not add acodex/prefix unless the user explicitly asks for that exact prefix.