Skip to content

feat!: add Tron support and replace walletAddress with activeWallet - #100

Draft
tolgahan-arikan wants to merge 36 commits into
masterfrom
add-tron-support
Draft

tolgahan-arikan wants to merge 36 commits into
masterfrom
add-tron-support

Conversation

@tolgahan-arikan

@tolgahan-arikan tolgahan-arikan commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds Tron wallet support to the Kotlin SDK, matching the TypeScript SDK (0xPolygon/oms-wallet-typescript-sdk#104): create, import and sign in with Tron wallets, sign and verify, send TRX and TRC-20 transfers, and read balances from the OMS Tron indexer. It also replaces walletAddress with activeWallet and makes session nullable. This is a breaking change; see MIGRATION.md (0.4.0). A separate commit upgrades CBOR Java to 4.5.6 for CVE-2024-23684.

Changes

Tron (feat! commit)

  • Generated client: regenerated from upstream waas origin/master @ 54d91262 with webrpc-gen v0.47.0's built-in kotlin target (which replaced gen-kotlin v0.3.2 upstream); apart from the package name (technology.polygon.omswallet.internal.generated.waas), it is identical to upstream's proto/clients/waas.gen.kt. The hand-built Webrpc header now matches (webrpc@v0.47.0;kotlin@v0.47.0;waas@…).
  • Wallets and networks: WalletType.Tron, TronNetwork (Mainnet, Nile) / TronNetworks. Tron import (WalletImportPrivateKey.Tron / TronBytes) uses the same secp256k1 key format as Ethereum.
  • Transactions: sendTronTransaction and callTronContract, always native mode. data is forwarded exactly: omitted means no data field (plain TRX transfer), "0x" calls the payable fallback.
  • Signing: signTronMessage, signTronTypedData, isValidTronMessageSignature and isValidTronTypedDataSignature (networkFamily: tron).
  • Balances: getTronBalances calls /v1/TronIndexerGateway/GetTokenBalancesDetails, with the URL derived from the publishable key like the Solana gateway. Models mirror the Solana ones. When a selectFeeOption selector is passed, the fee-option balance lookup uses it for unsponsored Tron fees.
  • Wallet-type checks: methods check the stored wallet type instead of the address shape, before any request.
  • Contract method names: callContract and callTronContract reject a full signature ("transfer(address,uint256)") locally. WaaS only accepts the bare name and builds the signature from args.
  • Wallet responses: an Ethereum wallet whose address isn't valid hex is rejected as an invalid response.

Breaking changes (0.4.0)

  • WalletClient.walletAddress is replaced by activeWallet: Wallet?.
  • OMSWalletSessionState is renamed to OMSWalletSession; session is nullable, with non-null expiresAt and auth. The internal class that already had that name is now OMSWalletSessionStateMachine.
  • walletAddress is removed from the wallet activation result (now WalletActivationResult, see below) and CompleteAuthResult.WalletSelected. The session-expired event gains wallet.
  • The persisted session record moves to version 2 and stores the full wallet. Older records are discarded, so users sign in once after upgrading.

Sample apps (feat(app) commit)

  • app: an Ethereum/Tron picker in the Wallet card and a Tron panel (Nile by default, with a Nile ↔ Mainnet switch; the Solana panel has a Devnet ↔ Mainnet switch). It shows TRX and USDT balances with faucet links, signs and verifies a message, sends TRX / USDT / custom TRC-20 and shows "Transaction submitted.", and links to Tronscan.
  • trails-actions: moved to activeWallet. The explorer button now uses only the on-chain txnHash.

Security (fix(deps) commit)

  • Upgrades com.upokecenter:cbor 4.4.4 → 4.5.6 for CVE-2024-23684: crafted CBOR could make decoding use excessive CPU. The SDK decodes CBOR only when verifying wallet-import attestations. This also brings in numbers 1.8.2 and datautilities 1.1.0 as transitive dependencies. The commit only touches gradle/libs.versions.toml, and it ships in the same release as Tron.

Differences from the TypeScript SDK

  • Kotlin keeps its single Wallet model rather than a separate Tron wallet type.
  • The Tron gateway Webrpc header uses gen-kotlin, like the Kotlin Solana header.

Cross-SDK API alignment (refactor! and feat(app) commits)

Aligns the public API with the TypeScript and Swift SDKs after a cited three-way API review. Breaking changes are made directly, with no deprecated aliases, and each one has a MIGRATION.md 0.4.0 entry.

  • Signature verification: all isValid…Signature methods take an optional walletAddress and no longer take walletId. When the address is omitted, the active wallet's address is used. Requests never send a wallet ID.
  • contractAddress replaces contract on callContract and callTronContract.
  • Renames:
    • WalletActivationResult (was WalletSelectionResult);
    • BalancesResult (was TokenBalancesResult);
    • OidcAuthMode (was OidcRedirectAuthMode; wire values unchanged);
    • the TransactionStatusPollingOptions fields timeoutMs, intervalMs and fastIntervalMs (same defaults).
  • Additions:
    • mode on sendTransaction(network, to, value, …);
    • CompleteAuthResult.wallet and credential;
    • balance paging column/before/after/sort, with SortBy and SortOrder;
    • OMSWalletUpstreamService.wireValue.
  • Error codes: the new WalletAddressAlreadyImported maps WaaS error 7313 to status 409.
  • Parameter order: signInWithOidcIdToken and the custom-provider startOidcRedirectAuth now use the same order as Swift and TypeScript.
  • Docs fixes: the includeMetadata default, the Tron balance wording, and the trails-actions session label.
  • Sample app: Solana Devnet support (SOL and USDC balances, sign/verify, transfers with fee options) alongside Ethereum and Tron.
  • Changes with no compile error, all covered in MIGRATION:
    • verification sends an address and works while signed out when one is given;
    • a mismatched active wallet type now fails locally;
    • the error code for 7313;
    • the polling validation messages;
    • strict parsing of sort in indexer pages;
    • TokenBalancesPage equality now includes the new fields.

Review fixes and cleanup

After an outsider review and a simplicity review, every finding was re-checked against the code before changing it. The commits fall into these groups:

  • Fixes:

    • a given but empty or whitespace-only walletAddress in the isValid…Signature methods throws OMSWalletValidationException before any request, as in TypeScript and Swift;
    • the leftover isEthereumAddressValue alias is removed, and isEthereumHexAddress is hidden from Java;
    • MIGRATION notes that wallet is the new first OMSWalletSessionExpiredEvent property;
    • in the sample app, the Tron panel guards against double taps and shows Nile indexer errors instead of 0 balances.
  • Cleanup of code this PR added: Solana/Tron fee-balance enrichment is shared, and executePreparedTransaction takes one enricher instead of three nullable networks.

  • Compat leftovers removed (0.4.0 is breaking):

    • the indexer parser reads only the gateway's field names (balance, tokenID, metaTxnID, tokenIds, tokenId), dropping old alternate spellings the gateway never sends;
    • default storage names from before storage was scoped per project, which no release ever used, were removed from internal storage classes. The public API is unchanged. The indexer parser no longer reads old alternate field spellings (balanceWei, tokenIDs, metaTxnId) that the gateway never sends.
  • Cleanup of code already on master:

    • unused JSON helpers, MonotonicNonceGenerator, synchronizationKey, initialSnapshot and a private OIDC helper removed;
    • always-true clearSession flags removed;
    • the WalletClient polling parameters are folded into TransactionStatusPollingOptions;
    • one writeTextAtomically;
    • OMSWalletHex is reused;
    • small IndexerClient duplications removed;
    • a shared javap runner, and no POM fallbacks (the stale 0.3.2-SNAPSHOT one is gone);
    • small sample-app simplifications.
  • Sample apps: the Tron and Solana panels label the WaaS txnId as "Last transaction ID" when no on-chain hash exists yet, and trails-actions no longer opens an explorer link built from txnId.

  • Docs pass:

    • MIGRATION corrects the 0.3.x Tron statement and adds the blank walletAddress validation;
    • the README Tron example uses a placeholder recipient, and the README lists Solana and Tron in the capabilities and sample app;
    • the AGENTS.md file reference is fixed.

The public API is unchanged by these commits.

Public API baseline (build commit)

public-api.txt was produced with javap -public, which treats Kotlin internal declarations as public. As a result it listed:

  • internal classes such as OMSWalletSessionStateMachine, PersistedSessionRecord and OMSWalletJson;
  • private classes' companions and serializers;
  • name-mangled internal members and synthetic accessors.

This was already the case on master. The dump now uses the binary-compatibility-validator library (0.18.1, with kotlin-metadata-jvm 2.2.10), which reads Kotlin metadata. It is build-time only and nothing is added to the AAR. The baseline drops from 177 classes on master (188 on this branch before the change) to 122, and no public API is removed. Every top-level type in the new dump matches docs/api.md, and all 65 documented members are present (checked by hand; the build guard compares top-level names).

The validator also keeps three synthetic constructor bridges of non-public constructors, which name internal types. Nothing outside the SDK can call them, so they are dropped.

To keep the baseline from regressing, the dump task fails in three cases:

  • it contains mangled internal members or synthetic accessors;
  • it mentions an SDK type that isn't itself public, such as a leaked generated WaaS type;
  • its top-level declarations differ from the source-generated docs/api.md.

I confirmed the dump task catches a newly public class, a changed docs heading and a leaked generated type, and that the baseline check still catches a new public member.

Alternatives considered:

  • the validator's Gradle plugin doesn't apply to AGP 9's built-in Kotlin;
  • Kotlin Gradle plugin 2.2.10's built-in abiValidation isn't available for Android modules.

When it is, the dump can switch to it.

Wallet-import attestation fix (fix commit)

The attestation verifier rejected a real AWS Nitro document captured from WaaS, so importWallet could not succeed against live WaaS. This was already the case on master. There were three faults:

  • it required CBOR tag 18, but Nitro sends an untagged COSE_Sign1;
  • it built the certificate path from the root-first cabundle without reversing the intermediates;
  • it checked CA path-length constraints in that same order.

The path now runs from the leaf through the reversed intermediates to the pinned AWS Nitro root, as in TypeScript and Swift. A wrong COSE tag is still rejected. A positive test verifies the real document, using the same fixture as the Swift SDK.

Test audit (test commits)

An audit of every test: test-only commits, then a second mutation-based review pass. Every new or rewritten test was checked to fail when the behaviour it covers is broken. A test was removed or merged only when its partner already asserts everything it checked.

  • Exact request bodies now asserted:
    • the Solana transfer (recipient and amount);
    • EVM SignMessage (network);
    • AuthorizeRemoteAccess (grants and credentialId);
    • Solana balance filters.
  • The signature-header vectors use literal headers instead of the production builder.
  • Wallet response validation: one parameterized test now covers a non-hex Ethereum address and a missing or unknown networkFamily / keyOrigin; each case was checked to fail with its production check removed.
  • The projectId derivation test now asserts the derived scope in a real request body.
  • Assertions that could not fail were removed (self-comparisons, duplicated lines, defaults the test itself built), and TESTING.md / docs/error-contracts.md now name only tests that exist.
  • Count: JVM tests 215 → 192 (200 with the sliding-expiry tests).
  • No production code changed in these commits.

Sliding session expiry (chore(waas) and feat(session) commits)

WaaS now extends a login credential while it is in use (0xsequence/waas#144): the requested lifetime is a hard ceiling, and a 10-day idle window slides forward with use. CompleteAuth returns the current (sliding) expiry, and the new GetCredential reads it back (0xsequence/waas#152). Without this change, a session longer than 10 days would be signed out locally on day 10 even while in use.

  • Refresh: the SDK reads the current expiry with GetCredential after restoring a session, when the local expiry is reached (before signing out), before an operation on a locally expired session, and in the background at most every 6 hours after successful wallet calls. The new value is saved and the expiry timer rescheduled. Concurrent callers share one request, and a result is applied only while the same session is current.
  • Old servers: a server without GetCredential (WebrpcBadRoute, e.g. v1.1.1) keeps the previous behaviour, which is exact there.
  • Offline: if WaaS is unreachable at the local expiry, the session is kept and checked again later (60 s, backing off to 15 min); an operation on a locally expired session then fails with the network error, not OMS_SESSION_EXPIRED.
  • Server-reported end: 7202 KeyNotFound / 7203 KeyExpired on a request signed with the session credential end the session (expiry notification once) and fail the operation with OMS_SESSION_EXPIRED, with the WaaS error as cause and no upstreamError, the same shape as a local expiry. A rejected Execute reports OMS_SESSION_EXPIRED (the middleware rejects it before execution); a status lookup after submission keeps its transaction error with txnId. Unauthenticated WaasPublic calls are excluded (InspectCredential returns 7202 for an unknown remote credential), and 7207 Unauthorized is not mapped.
  • Nonce ordering: WaaS needs strictly increasing nonces per credential, so a background refresh never overlaps another signed request: it starts only when none is in flight, and signed requests wait for an in-flight refresh before signing.
  • Lifetime cap: the maximum session lifetime is now 180 days (15_552_000 s); WaaS clamps rather than rejects, so this is safe on older servers.
  • Generated client: regenerated from waas origin/master @ 54d91262 (webrpc-gen v0.47.0). Besides GetCredential it adds ClaimWallet, claimable wallets, WalletStatus.Preallocated and error 7208; the SDK does not use them yet and none are public.
  • Docs (README, MIGRATION 0.4.0, error contracts, session-expiry-flow.md, docs/api.md) describe expiresAt as the current expiry, extended by use.
  • Live check: run on dev with the TypeScript SDK (restore sent GetCredential, saved the server's expiry, and the next signed request waited for it). This SDK's refresh, gate and fallback are covered by unit tests with mutation proofs; not yet exercised live from the demo app.

Release

POM_VERSION_NAME, the README dependency line and the generated module's snapshot fallback are set to 0.4.0 (chore(release): prepare 0.4.0).

Testing

  • ./gradlew ktlintCheck passes

  • ./gradlew :oms-wallet-kotlin-sdk:testDebugUnitTest passes (200 tests)

  • ./gradlew --build-cache verify passes (ktlint, unit tests, Android lint, both apps, API baseline, API docs check)

  • tools/check-expo-compatibility.sh minimum passes

  • tools/check-expo-compatibility.sh current passes (Expo 58.0.13, after merging the fixture bumps from master)

  • Wallet import on an emulator against dev: the CBOR 4.5.6 attestation path works end to end (a unit test also verifies a real Nitro document)

  • Instrumented tests (connectedDebugAndroidTest) pass on a Pixel 9 emulator (API 36): 3/3

  • Tested by hand on an Android emulator against the dev sandbox: Google sign-in, importWallet with an Ethereum private key (attestation verified, wallet listed as imported), a sponsored 1 TRX send on Nile and a 0.001 SOL send on Devnet (both submitted with a hash).

Related

Port Tron wallet support from the TypeScript SDK (0xPolygon/oms-wallet-typescript-sdk#104).

- Regenerate the WaaS client from 0xsequence/waas 8a2c7f6 (schema v1-26.9.22-f21ed9d2) with
  webrpc-gen v0.37.2 and gen-kotlin v0.3.2, adding PrepareTronTransaction,
  PrepareTronContractCall, the tron wallet type and network family, and networkFamily on
  IsValidTypedDataSignature.
- Add WalletType.Tron, TronNetwork (tron:mainnet, tron:nile), sendTronTransaction,
  callTronContract, signTronMessage, signTronTypedData, isValidTronMessageSignature,
  isValidTronTypedDataSignature, and Tron private-key import. Tron transactions always use
  native mode, and sendTronTransaction forwards data exactly (omitted for a plain TRX
  transfer, "0x" for the payable fallback).
- Add IndexerClient.getTronBalances through the OMS Tron indexer gateway, and use it to
  enrich Tron fee options so FeeOptionSelector.firstAvailable can pay unsponsored fees.
- Check wallet families against the stored wallet type instead of the address shape, and
  reject bare-name violations in callContract and callTronContract before any request.
- Validate Ethereum wallet addresses in wallet responses (hex shape only).

BREAKING CHANGE: WalletClient.walletAddress is replaced by activeWallet (Wallet?).
OMSWalletSessionState is renamed to OMSWalletSession; WalletClient.session is nullable with
non-null expiresAt and auth, and is non-null exactly when activeWallet is. walletAddress is
removed from WalletSelectionResult and CompleteAuthResult.WalletSelected (use
wallet.address). OMSWalletSessionExpiredEvent gains a nullable wallet. The persisted session
record now stores the full wallet (version 2); records saved by 0.3.x are discarded on load,
so users sign in once after upgrading. callContract rejects full function signatures such
as "transfer(address,uint256)"; pass the bare name.
Mirror the React example's TronExample: a wallet-type picker that uses or creates an Ethereum
or Tron wallet, and a Tron panel on Nile with TRX and Nile USDT balances from
getTronBalances, a faucet link, message signing with verification, and transfers of TRX
(sendTronTransaction) or USDT/custom TRC-20 tokens (callTronContract with method
"transfer"). Pending transfers with a hash are reported as submitted and link to Nile
Tronscan. The EVM signature and transaction cards are shown only for Ethereum wallets.
Upgrade com.upokecenter:cbor from 4.4.4 to 4.5.6, which fixes CVE-2024-23684: crafted CBOR
input could make decoding use excessive CPU. The SDK decodes CBOR only when verifying the
wallet-import attestation documents returned by WaaS, so a malicious or compromised
response could have stalled wallet import.

Release note (ships with the Tron release): Security: upgraded the CBOR dependency used for
wallet-import attestation verification to 4.5.6 to fix CVE-2024-23684 (excessive CPU when
decoding crafted CBOR). No API changes. CBOR 4.5.6 also brings
com.github.peteroupc:numbers 1.8.2 (from 1.8.0) and com.github.peteroupc:datautilities 1.1.0
as transitive runtime dependencies.
- Signature verification: every isValid*Signature method takes an optional
  walletAddress and no walletId. Requests always send networkFamily and
  walletAddress (never walletId). An omitted address uses the active wallet's
  address; no session throws OMSWalletSessionException and an active wallet of
  another family throws OMSWalletValidationException before any request.
- callContract and callTronContract name the contract parameter contractAddress.
- CompleteAuthResult exposes credential and wallet (null while selection is pending).
- Rename WalletSelectionResult to WalletActivationResult, TokenBalancesResult to
  BalancesResult, and OidcRedirectAuthMode to OidcAuthMode (wire values unchanged).
- TransactionStatusPollingOptions properties are timeoutMs, intervalMs,
  fastIntervalMs, and fastPollCount (same defaults and order).
- sendTransaction(network, to, value) accepts mode (default Relayer).
- Indexer page requests and responses support column/before/after/sort cursors
  (SortBy, SortOrder).
- Map WaaS AddressAlreadyImported (7313) to OMS_WALLET_ADDRESS_ALREADY_IMPORTED
  (status 409, not retryable).
- OMSWalletUpstreamService gains wireValue ("waas", "indexer").
- OIDC parameter order matches TS/Swift for signInWithOidcIdToken and the custom
  provider startOidcRedirectAuth.
- Docs: MIGRATION 0.4.0 entries, README, error contracts, regenerated API docs and
  public API baseline; trails-actions session label now says OMSWalletSession.
The wallet-type picker now offers Solana. A Solana (Devnet) panel mirrors the
Tron panel and the TypeScript React example: SOL and devnet USDC balances from
getSolanaBalances (with loading and error states), SOL/USDC faucet and wallet
explorer links, sign-and-verify via isValidSolanaMessageSignature with the
wallet address, and relayed SOL, USDC, or custom SPL transfers with fee-option
selection and a Solana Explorer link. Panel actions are disabled while one is
in flight. The session card title now reads OMSWalletSession.
Every isValid*Signature method now throws OMSWalletValidationException
("walletAddress must not be empty") before any request when walletAddress
is provided but empty or blank. Omitting it still verifies against the
active wallet.
…ess from Java

Callers use isEthereumHexAddress directly. The internal top-level helper is
marked @JvmSynthetic so Java source cannot call it through WalletClientKt.
… property

Code that creates or destructures the event positionally must account for it.
…xer errors

The Tron panel now uses the same busy-guarded launcher as the Solana panel,
generalised to launchWalletPanelAction, so a second tap cannot send a second
transfer while one is in flight. A failed Nile balance lookup shows
"Balances unavailable" instead of zero balances, and a new send clears the
previous transaction hash and explorer button.
executePreparedTransaction takes one fee-option enricher instead of three
mutually exclusive nullable networks, and the Solana and Tron enrichers share
the token-address and FeeOptionWithBalance mapping. Requests and results are
unchanged.
- Drop unused OMSWalletJson int/long/boolean/arrayOrEmpty helpers.
- Drop the uncalled clearPendingOidcRedirectAuth and the always-true
  clearSession flags and OIDC callback clearPendingAuth flag.
- Delete MonotonicNonceGenerator; OMSWalletTimestamps keeps nowMilliseconds.
- Remove the never-read OidcRedirectAuthStore.synchronizationKey and its
  javap release check.
- Drop the never-passed OMSWalletSessionStateMachine initialSnapshot.
- WalletClient.create takes one TransactionStatusPollingOptions default.
- Share writeTextAtomically, use APPLE_ISSUER, accessKeyHeaderName and
  OMSWalletHex.decode instead of local copies.

No behaviour or public API change; the baseline only loses internal symbols.
gradle.properties defines every POM_* key, so the orElse fallbacks (including
a stale 0.3.2-SNAPSHOT version) were never used.
Confirming a code calls completeEmailAuth once with the selected wallet
selection behaviour, and the session lifetime falls back to
DEFAULT_SESSION_LIFETIME_SECONDS instead of branching between overloads.
`javap -public` treats Kotlin `internal` declarations as public, so the baseline listed internal
classes (for example OMSWalletSessionStateMachine), private classes' companions and serializers,
name-mangled internal members and synthetic accessors. The dump now uses the
binary-compatibility-validator library, which reads Kotlin metadata: 122 classes instead of 188,
with no public API removed.

The dump also fails if it contains mangled internal members or synthetic accessors, or if its
top-level declarations differ from the source-based docs/api.md, so it cannot silently regress.
The validator keeps synthetic constructor bridges of non-public constructors, which name internal
types (OMSWalletEnvironment, OMSWalletSessionStateMachine, ...). Nothing outside the SDK can call
them, so they are dropped, and the dump now fails if any line references an SDK type that is not
itself public (for example a leaked generated WaaS type).
The sample app's Tron and Solana panels labelled the txnId fallback as a hash, and trails-actions opened an explorer link built from txnId when no on-chain hash was returned yet. The explorer link now uses txnHash only.
- MIGRATION: drop the impossible 0.3.x Tron typed-data case and document that a blank
  walletAddress fails locally with OMSWalletValidationException.
- README: use a placeholder Tron recipient instead of the mainnet USDT contract, scope the
  wallet-type rejection to the methods that check it, and list Solana/Tron in capabilities
  and the sample app.
- AGENTS: point at the session storage files that exist.
The Solana panel switches between Devnet and mainnet and the Tron panel between Nile and mainnet.
Each network has its own USDC mint or USDT contract, explorer links and faucet links (testnets
only), and mainnet shows that transfers move real funds. Switching clears the previous results,
and a balance response for a network the panel has left is ignored.
Pin the full PrepareSolanaTransfer, Solana and EVM SignMessage, AuthorizeRemoteAccess,
InspectCredential, GetSession, GetSessionUsage, and Solana balance request bodies instead of
substrings or values echoed from mocked responses. Spell the expected wallet-signature header
out literally so the signer vectors no longer compare the production builder with itself.
Observe that ID-token sign-in clears the previous session before CommitVerifier, record the
sponsored fee-selector input instead of asserting inside it, use distinct fast and slow poll
intervals so the switch-over is visible, and pin ABI args in the contract-call vector.
Drop exact duplicates, generated-constant checks, and payload vectors already pinned by the signer
vectors, after moving each test's unique assertions into its partner. Parameterize the
wallet-activation failure, ignored OIDC callback, and sponsored fee-selector cases, fold the
generated status-400 normalization into the central error contract test, and keep only local
state checks in focused invalid-lifetime tests.
Move the duplicated enqueueJson, RecordedRequest body readers, and restored-wallet-client setup
into WalletClientTestFixtures, and replace MockWebCryptoCredentialSigner with the equivalent
TrackingCredentialSigner configured for nonce 42. No test assertions change.
The wallet-import attestation verifier rejected a real Nitro document captured from WaaS, so
importWallet could not succeed against live WaaS:
- it required CBOR tag 18, while Nitro sends an untagged COSE_Sign1 (a wrong tag is still rejected);
- it built the certificate path from the root-first cabundle without reversing the intermediates;
- it checked CA path-length constraints against that root-first order.

The path now runs leaf -> intermediates -> pinned AWS Nitro root, matching the TypeScript and Swift
SDKs. A positive test verifies the real document (shared with the Swift SDK's fixture), and it also
checks that an untrusted PCR0 and a wrong COSE tag are still rejected.
Copy proto/clients/waas.gen.kt from waas origin/master (schema v1-26.10.19-5824b4d1), now
emitted by webrpc v0.47.0's built-in kotlin target, keeping the SDK package name. Adds
GetCredential, ClaimWallet, WalletStatus.Preallocated and SESSION_CAP_EXCEEDED.

Align the hand-built Webrpc header with the new generator versions and document the
refresh steps in AGENTS.md.
WaaS now slides a credential's expiry forward with use (waas #144, #152). The SDK reads the
current expiry with GetCredential through one single-flight, revision-guarded primitive: in
the background after restore and after signed calls once 6 hours have passed, and before
treating a session as locally expired (expiry timer and protected operations). Servers without
GetCredential (WebrpcBadRoute) keep exact local expiry; an unreachable WaaS keeps the session
and the timer rechecks with backoff.

A signed session request rejected with 7202 KeyNotFound or 7203 KeyExpired ends the session
like local expiry and fails with OMS_SESSION_EXPIRED; unsigned WaasPublic calls are excluded.
Refreshes never overlap other signed requests, so per-credential nonces stay ordered.

Raise MAX_SESSION_LIFETIME_SECONDS to 180 days and document the current-expiry semantics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant