Skip to content

Latest commit

 

History

History
266 lines (225 loc) · 13.5 KB

File metadata and controls

266 lines (225 loc) · 13.5 KB

AGENTS.md

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.


Working Principles

  • 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.

Third-Party Library Docs

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.


Project Overview

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.

Repository Layout

  • 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 and master.
  • .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 review in a PR or review comment.

Development Commands

  • ./gradlew --build-cache verify
    • Full SDK verification, matching .github/workflows/android-ci.yml.
  • ./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.
  • ./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.

Verification Workflow

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.

  1. Kotlin style: ./gradlew ktlintCheck.
  2. SDK logic: ./gradlew :oms-wallet-kotlin-sdk:testDebugUnitTest.
  3. Sample app, manifest, or resource changes: ./gradlew :app:lintDebug and ./gradlew :app:assembleDebug.
  4. 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:connectedDebugAndroidTest locally 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:publishToMavenLocal when 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.

Architecture and Boundaries

  • OMSWallet is the main public entry point. Keep public API changes aligned with README.md and docs/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 PendingWalletSelection as public SDK operation boundaries. Wrap their network-backed actions with runOMSWalletOperation and the matching PendingWalletSelection... operation so generated WebRPC and transport exceptions are classified as OMSWalletException.
  • OMSWalletEnvironment, OMSWalletHttpClient, and OMSWalletJson define 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 in OMSWalletModels.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.

High-Risk Areas

  • oms-wallet-kotlin-sdk/src/main/java/technology/polygon/omswallet/internal/generated/waas/WaasWalletClient.kt is generated WebRPC code and the largest production source file. Do not hand edit it casually. The upstream source of truth is the https://github.com/0xsequence/waas project; update this generated client from upstream as needed.
  • WalletClient.kt, WalletRequestSigner.kt, WalletAuthChallenge.kt, AndroidKeystoreP256CredentialSigner.kt, and AndroidKeystoreSessionStore.kt handle 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.

Code Style

  • Kotlin code style is set to official in gradle.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.ktlint and .editorconfig, with ktlint_code_style = ktlint_official.
  • ktlint_standard_package-name is disabled to avoid churn from package-name rules if generated or legacy Android names are introduced.
  • ktlint_standard_property-naming is disabled because the repo intentionally uses lowerCamel companion constants for internal wire/header names such as OMSWalletEnvironment.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.

Testing Guidance

See TESTING.md for full testing conventions, unit vs. integration boundaries, and the execution command reference.

  • Use TESTING.md as 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.

Public Error Contract Tests

  • Follow TESTING.md before adding or updating public error contract tests.
  • Use docs/error-contracts.md as the audit matrix for public SDK error surfaces, recovery semantics, upstreamError expectations, 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 OMSWalletException subclasses 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 upstreamError only 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.

Generated Files and External Artifacts

  • oms-wallet-kotlin-sdk/src/main/java/technology/polygon/omswallet/internal/generated/waas/WaasWalletClient.kt is generated by webrpc-gen from the upstream 0xsequence/waas project. 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/, and local.properties are 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-push is a versioned local hook. Run tools/install-git-hooks.sh after cloning to enable it for a checkout.

Security and Configuration

  • Do not commit secrets, access keys, signing keys, local.properties, Android Studio state, or local Gradle/cache files.
  • publishableKey and projectId are 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.

Agent Workflow Rules

  • 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.

PR / Commit Guidance

  • Branch names should be plain and descriptive, such as fix-login-timeout or add-wallet-tests. Do not add a codex/ prefix unless the user explicitly asks for that exact prefix.