mirror of
https://github.com/luxfi/bank.git
synced 2026-10-30 17:02:07 +00:00
Base v1.5.72 closed the door this depended on, and closed it deliberately: "IAM IS THE ONLY AUTH. There is no second way in... _superusers is not an exception: it reaches schema, settings, backups and logs, and one process serves many orgs' Bases, so two independently-keyed doors to it would be one more than can be reasoned about." The sandbox login was the second door. It kept a bcrypt hash in its own collection and minted a _superusers token, and until that release Base honoured such a token as a fallback. After it, the route still answered 200 with a token and the very next request answered 401 — a login that succeeds and authenticates nothing. Every authed route was refusing, and the suite could not see it: the test harness never registers the org plugin, so 141 tests passed green against a binary whose demo login was broken. It was also the custom auth this estate does not build. Gone: the route, the credentials collection, the token minting, the demo password that was a constant in a file every browser downloads, and the merged hook shape that let one path stand in for the other. The SPA already had the PKCE flow it needed. What this costs: [email protected] must exist in Lux IAM under org lux, app lux-bank. The demo cannot sign in until it does. That is an IAM seeding task, not a code one, and it is the same identity convention every other surface already follows. Co-authored-by: Hanzo Dev <[email protected]>
@luxfi/bank
Typed client for the Lux banking API (/v1/bank) — accounts, transfers,
payments, beneficiaries, cards, crypto, exchange, FX, and membership plans.
Sandbox and production serve the identical contract (LP-3040); point the
client at either.
import { Bank } from '@luxfi/bank'
const bank = new Bank({
baseUrl: 'https://api.sandbox.lux.financial',
token: () => sessionStorage.getItem('token'),
})
const plans = await bank.plans()
const { holdings } = await bank.wallet()
await bank.sendCrypto('ETH', 400_000, '0x1234…5678') // minor units, 6 dp
// Card issuance — branch only on the issuer's status/nextAction pair:
const { data } = await bank.cardAccount()
if (data.virtualAccount?.nextAction === 'complete_kyc') {
const { url } = await bank.cardKYCURL() // sensitive — straight to the browser
window.open(url)
}
Amounts are integers in minor units; every balance carries decimals
(2 for most fiat, 0 for JPY, 6 for crypto). Errors throw BankError
with status and the parsed body.
Docs: docs.lux.financial · Spec: LP-3040.