Refactor: Host shared transfer status and amount vocabulary - #432
Refactor: Host shared transfer status and amount vocabulary#432sephynox wants to merge 2 commits into
Conversation
|
| export class KeetaAnchorAmount { | ||
| readonly #value: bigint; | ||
| readonly #decimals: number; | ||
| readonly #asset: Asset['id']; |
There was a problem hiding this comment.
Why just the asset id and not the full asset with id/location? The decimals can be different on different locations.
| /** | ||
| * An amount of an on-chain token, at the token's precision. | ||
| */ | ||
| static fromToken(value: bigint, token: AmountToken): KeetaAnchorAmount { |
There was a problem hiding this comment.
Should this be generalized more to an asset instead of a keeta token?
| * An immutable amount value object: smallest-unit integer `value` at | ||
| * `decimals` precision, denominated in `asset`. | ||
| */ | ||
| export class KeetaAnchorAmount { |
There was a problem hiding this comment.
We've talked about having an asset amount class that includes many of these attributes, should it be generalized more to support any asset/location/id etc?
| export interface LocationAssetPrecision { | ||
| readonly id: Asset['id']; | ||
| readonly decimals: number; | ||
| } | ||
|
|
||
| /** | ||
| * The per-asset precision table of a location, for | ||
| * {@link KeetaAnchorAmount.toLocationDecimals}. | ||
| */ | ||
| export interface AmountLocation { | ||
| readonly assets: readonly LocationAssetPrecision[]; | ||
| } | ||
|
|
||
| /** | ||
| * The token shape {@link KeetaAnchorAmount.fromToken} accepts. | ||
| */ | ||
| export interface AmountToken { | ||
| readonly tokenPublicKey: TokenPublicKeyString; | ||
| readonly decimals: number; | ||
| } |
There was a problem hiding this comment.
Bit confused by these types, are they necessary when we could just have a KeetaAssetAmount (or the new KeetaAnchorAmount class that handles these types within it?



Summary
Downstream consumers (asset-movement-anchor-sdk, sentinel, and the planned sentinel-client) need one shared transfer vocabulary, and anchor is the only common lower layer that keeps the package graph acyclic. This change hosts the ISO 20022 transfer state machine and the self-describing amount value object.
Note
Medium Risk
New fund-precision and state-transition rules will govern future transfer flows; incorrect adoption could affect money handling, but this PR only adds library code and tests without wiring production paths yet.
Overview
Adds shared asset-movement transfer primitives in anchor (
src/services/asset-movement/lib/) so downstream packages can share one vocabulary without circular deps. Package version bumps 0.0.96 → 0.0.97.Introduces an ISO 20022–style transfer state machine (
transfer-status.ts): status constants, per-status metadata (category, phase, cancelable/terminal), a transition graph, and helpers (canTransition,assertTransition,isTransferStatus).Adds
KeetaAssetMovementTransferError(transfer-error.ts) with stableMovementErrorCodevalues, HTTP status mapping, and JSON serialization—used by amount rescaling and illegal transitions.Adds
KeetaAnchorAmount(amount.ts) as an immutable smallest-unit + decimals + asset type, with loss-checkedtoDecimals, location-based precision viaAmountLocation,minorToMajor/majorToMinor, and cross-precisionequals. Vitest coverage exercises transitions and amount behavior.Reviewed by Cursor Bugbot for commit 5ee953b. Bugbot is set up for automated code reviews on this repo. Configure here.