Skip to content

chore(release): v3.20.0 - #859

Closed
fraseragain wants to merge 7 commits into
mainfrom
develop
Closed

fraseragain wants to merge 7 commits into
mainfrom
develop

Conversation

@fraseragain

Copy link
Copy Markdown
Contributor

Release

Release of develop to main. Expected version: 3.20.0 (minor, from the feat commit).

PR Change
#858 Removes the automatic testnet top-up on sign-up. It never fired in practice (the default testnet payment account was created first, so the "new account" check was always false) and new users now request testnet CHEQ from the dashboard instead. Also removes the unused ENABLE_ACCOUNT_TOPUP, TESTNET_INITIAL_TOPUP_CHEQ and TESTNET_MINIMUM_BALANCE settings.

Behaviour in production does not change for new sign-ups (they already received no top-up). The release deletes dead code.

Before merging

Merging

  • Use a merge commit, not squash.
  • After merging, confirm the Semantic Release and deploy workflows actually started on main. If none started, push an empty commit as in chore(release): re-trigger the v3.18.0 release #846.
  • Then open the back-merge PR main to develop.

After release

  • Delete ENABLE_ACCOUNT_TOPUP, TESTNET_INITIAL_TOPUP_CHEQ and TESTNET_MINIMUM_BALANCE from the DigitalOcean app specs.

🤖 Generated with Claude Code

dubiouspip and others added 7 commits October 26, 2026 09:39
APIKeyService.get now throws InvalidAPIKeyError for an unknown,
mismatched or revoked key, and the API key fetcher maps it to 401.
Other failures stay 500, without internal details in the body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DID create, update and deactivate and resource create returned 500
with a raw CosmJS message when the payer account had no CHEQ. They now
return 402 naming the account and how to fund it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New accounts are not topped up: people may want to fund an external
address instead, and the portal now tells new users to request testnet
CHEQ. The top-up never ran for new sign-ups since 3.18.0 anyway, because
the testnet account already exists when it is checked.

Removes the top-up code, ENABLE_ACCOUNT_TOPUP, TESTNET_INITIAL_TOPUP_CHEQ,
TESTNET_MINIMUM_BALANCE and the BootStrapAccountResponse
testnetMinimumBalance field.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
## What changed

New accounts are **not** topped up with testnet CHEQ. People may want to
fund an external address instead, and the portal now tells new users, on
the dashboard, to request tokens from Balances & Faucet (studio-portal
PR to follow).

Removed:
- The top-up in `bootstrap` and in `POST /account/create`, and the
`topupTestnet` and `delegateWithinQuota` helpers.
- Settings `ENABLE_ACCOUNT_TOPUP`, `TESTNET_INITIAL_TOPUP_CHEQ` and
`TESTNET_MINIMUM_BALANCE`, from the constants, env types, `example.env`,
the Dockerfile and the README.
- The `testnetMinimumBalance` field of the bootstrap status object,
which only the top-up set.
- The integration tests for the initial top-up.

Unchanged: `POST /account/faucet` and its limits.

## Why

- **Product decision:** no automatic top-up.
- **It was already not happening.** Since 3.18.0 the top-up ran only
when the call had created the testnet account, but
`CustomerService.create` already creates it, so the check was always
false for new sign-ups. A fresh production account had a balance of 0.
Removing the code makes today's behaviour deliberate, so nobody later
"fixes" the check and turns auto top-ups on, as production sets
`ENABLE_ACCOUNT_TOPUP=true`.

## Deploy note

Production and staging may still set `ENABLE_ACCOUNT_TOPUP`,
`TESTNET_INITIAL_TOPUP_CHEQ` or `TESTNET_MINIMUM_BALANCE` in the
DigitalOcean app spec. They are ignored now and can be deleted.

## How to test

- `npm run test:unit`: 23 suites and 213 tests pass. `tsc --noEmit`
exits 0.
- ESLint over the touched files and `src/types` reports only existing
`no-explicit-any` errors: 55 on `develop`, 47 with this change (the
removed code accounts for the difference). None are new.
- On staging: sign up a new account. `GET /account/balances` shows
testnet balance 0, and `POST /account/faucet` with no body funds the
account.

## Risks

Anything that reads `testnetMinimumBalance` from the bootstrap response
would now see it missing. I found no consumer in this repo.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## [3.19.0-develop.2](3.19.0-develop.1...3.19.0-develop.2) (2026-10-27)

### Features

* **account:** remove the automatic testnet top-up on sign-up ([2c34509](2c34509))
* **account:** remove the automatic testnet top-up on sign-up ([#858](#858)) ([a2023a0](a2023a0))
Closes #843.

## What changed

- **`APIKeyService.get`** now throws a new `InvalidAPIKeyError` for an
unknown key, a hash mismatch or a revoked key. Before, it threw a plain
`Error`.
- **The API key fetcher** (`api-token.ts`) uses
`apiKeyVerificationFailure` to choose the response:
- `InvalidAPIKeyError` returns **401**: `Unauthorized error: Invalid API
key.` or `Unauthorized error: API key is revoked.`
- Any other error still returns **500**. The body is now `Internal
error: Could not verify the API key.`, and the details go to the server
log instead of the response.

## Why

A mistyped key returned 500 with `Unexpected error: While verifying API
key: Error: Invalid API key`. Clients and monitoring treat that as an
outage, and the body leaked internal wording.

## Edge cases

- Revoked keys keep their own message. It said "expired" before, which
was wrong.
- A database failure while looking up the key is still a 500.

## How to test

- `npm run test:unit`: new `tests/unit/auth/api-key-errors.test.ts` (3
tests). Locally: 24 suites passed, 216 tests passed.
- `npx tsc -p tsconfig.build.json --noEmit` exits 0.
- On staging after deploy: `curl -i -X POST
https://studio-api-staging.cheqd.net/account/faucet -H 'x-api-key:
not-a-real-key' -H 'content-type: application/json' -d '{}'` should
return `401`.

## Risks

Clients that treated a 500 as "bad key" now get a 401 instead.

The `swagger-ui.ts` fetcher still uses the "While verifying API key"
wording for LogTo session failures. That path isn't API-key auth, so I
left it out of scope.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Closes #844.

## What changed

- New helper `src/helpers/ledger-errors.ts`. `unfundedPayerFailure`
recognises two errors:
  - CosmJS's `Account '<address>' does not exist on chain`
  - the chain's `insufficient funds`

For either, it returns **402** with a message naming the account and how
to fund it: `POST /account/faucet` or Account > Balances & Faucet on
testnet, or sending CHEQ on mainnet. For any other error it returns
nothing, so existing handling is unchanged.
- It is used in the `catch` of `POST /did/create`, `/did/update`,
`/did/deactivate/{did}` and `/resource/create/{did}`.
- Swagger: those four routes now document `402`, and `swagger-api.json`
is regenerated (only the 4 new entries change).

## Why

A new developer's first DID create on an unfunded account returned:

`500 Internal error: Error: Error: Account 'cheqd1…' does not exist on
chain. Send some tokens there before trying to query sequence.`

That looks like an outage, and it doesn't say what to do.

## Edge cases

- The issue's second point, the automatic top-up not running, was the
monthly quota being used up (#841). That was fixed in 3.18.0 by #839 and
#842: new accounts get a one-time 10,000 CHEQ top-up, which is skipped
(and logged) if the quota is used up. This PR handles the remaining
case, an account that is still unfunded.
- Credential-status and other ledger writes still return 500 for this
error. They can adopt the helper later if needed.

## How to test

- `npx jest tests/unit/account/ledger-errors.test.ts`: 3 tests pass. The
full unit suite passes (24 suites, 216 tests), and `tsc --noEmit` exits
0.
- On staging, with a customer whose testnet account has a balance of 0:
`POST /did/create` with `{"network":"testnet"}` should return 402, and
the message should name the account.

## Risks

Clients that retried on 500 now get a 402, which shouldn't be retried
without funding the account first. ESLint reports two existing errors on
`develop` in these files (`did.ts` `no-case-declarations`, `resource.ts`
`prefer-const`). Neither is in changed lines.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@fraseragain

Copy link
Copy Markdown
Contributor Author

Superseded: conflicted with main in CHANGELOG.md and package.json. The replacement carries the same develop commits with main merged in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants