- Finance API: baskets, holdings, rebalances, deposits, bridge withdrawals, vault checks. - Schemas: btc-basket; api-client finance types; workspace lockfile update. - Vitest config for finance service; expanded tests. Made-with: Cursor
57 lines
1.9 KiB
TypeScript
57 lines
1.9 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { JewelryBoxStore } from '../src/jewelry-box-store';
|
|
|
|
describe('JewelryBoxStore', () => {
|
|
it('creates queued rebalance work only for non-cBTC allocations', () => {
|
|
const store = new JewelryBoxStore();
|
|
const basket = store.createBasket({
|
|
clientId: 'client-1',
|
|
mandateName: 'Multi-asset jewelry box',
|
|
chain138VaultAddress: '0x4444444444444444444444444444444444444444',
|
|
allocations: [
|
|
{ symbol: 'cBTC', targetWeightBps: 2500 },
|
|
{ symbol: 'cUSDC', targetWeightBps: 5000 },
|
|
{ symbol: 'cXAUC', targetWeightBps: 2500 },
|
|
],
|
|
baseAssetSymbol: 'cBTC',
|
|
});
|
|
|
|
const rebalances = store.listRebalances({ basketId: basket.id });
|
|
expect(rebalances).toHaveLength(1);
|
|
expect(rebalances[0]).toMatchObject({
|
|
sourceSymbol: 'cBTC',
|
|
targetSymbols: ['cUSDC', 'cXAUC'],
|
|
status: 'planned',
|
|
});
|
|
});
|
|
|
|
it('promotes rebalance plans once a deposit is marked minted', () => {
|
|
const store = new JewelryBoxStore();
|
|
const { basket, deposit } = store.createDeposit({
|
|
clientId: 'client-2',
|
|
chain138VaultAddress: '0x5555555555555555555555555555555555555555',
|
|
allocations: [
|
|
{ symbol: 'cBTC', targetWeightBps: 3000 },
|
|
{ symbol: 'cUSDT', targetWeightBps: 7000 },
|
|
],
|
|
expectedAmountSats: 300000000,
|
|
});
|
|
|
|
store.markDepositObserved(deposit.id, 'btc-tx-1', 6, 300000000);
|
|
store.markDepositMinted(deposit.id);
|
|
|
|
const updatedDeposit = store.getDeposit(deposit.id);
|
|
expect(updatedDeposit?.status).toBe('minted');
|
|
|
|
const holdings = store.listHoldings({ basketId: basket.id });
|
|
expect(holdings[1]).toMatchObject({
|
|
symbol: 'cUSDT',
|
|
bookValueSats: 210000000,
|
|
status: 'funded',
|
|
});
|
|
|
|
const rebalances = store.listRebalances({ basketId: basket.id });
|
|
expect(rebalances[0]?.status).toBe('queued');
|
|
});
|
|
});
|