// Checks for the Vest client's pure helpers (lib/vest-helpers.ts), the // relayed-session store (lib/vest-session.ts) and the order refusals it // throws (lib/platform-client.ts). // // npm run check // // Both files import only Node built-ins, so Node strips their types and loads // them directly; .mjs keeps this file out of Next's type check. The samples are // shaped like the gateway's real answers (captured 2026-10-26). import { test } from 'node:test'; import assert from 'node:assert/strict'; import { isVestWalletAddress, vestAccountId, num, toMs, formatDecimal, vestDayOf, lastVestResetMs, parseCapitalAccount, vestAccountName, parsePosition, awaitingLegs, parseOpenOrder, unrealizedPnl, parseTxn, bookTxns, txnKind, VEST_TXN, hourlyVolatility, marketOpen, MIN_HOURLY_RETURNS, nextVestResetMs, resetSafeStop, parseHistoryPosition, jwtClaimStrings, accountScopedToken, vestOrderEffect, } from '../lib/vest-helpers.ts'; import { putVestSession, vestSessionFor, dropVestSession, listVestSessions, refuseVestSession } from '../lib/vest-session.ts'; import { OrderNotPlacedError, NothingToCloseError, isOrderNotPlaced, isNothingToClose } from '../lib/platform-client.ts'; const iso = (s) => Date.parse(s); test('wallet addresses and account ids', () => { assert.equal(isVestWalletAddress('0x7ce10771819f80130e204ddb5ca1522e48a9b451'), true); assert.equal(isVestWalletAddress('0x7CE10771819F80130E204DDB5CA1522E48A9B451'), true); assert.equal(isVestWalletAddress('0x7ce1'), false); assert.equal(isVestWalletAddress(''), false); const id = vestAccountId('843f60e2-e013-5a0e-8b6c-face84bc5509'); assert.equal(id, vestAccountId('843F60E2-E013-5A0E-8B6C-FACE84BC5509')); assert.notEqual(id, vestAccountId('102566b2-515a-51c5-9ad7-4a7eae0a6a2a')); assert.ok(id >= 2 ** 50 && Number.isSafeInteger(id)); }); test('numbers, times and decimals as the gateway writes them', () => { assert.equal(num('49968.511115'), 49968.511115); assert.equal(num(''), undefined); assert.equal(num(null), undefined); assert.equal(toMs(1793035089), 1793035089000); assert.equal(toMs(1793035089277), 1793035089277); assert.equal(toMs('2026-10-26T18:41:02.886Z'), iso('2026-10-26T18:41:02.886Z')); assert.ok(Number.isNaN(toMs(undefined))); assert.equal(formatDecimal(29554.5, 2), '29554.5'); assert.equal(formatDecimal(50, 2), '50'); assert.equal(formatDecimal(3 * 0.0001, 4), '0.0003'); assert.equal(formatDecimal(42.65449999, 4), '42.6545'); assert.equal(formatDecimal(1e-7, 4), '0'); }); test("Vest's day turns at 20:00 New York, summer and winter", () => { // EDT (UTC−4): 20:00 ET is 00:00 UTC. assert.equal(vestDayOf(iso('2026-10-26T23:59:00Z')), '2026-10-26'); assert.equal(vestDayOf(iso('2026-10-27T00:00:00Z')), '2026-10-27'); assert.equal(vestDayOf(iso('2026-10-26T22:05:00Z')), '2026-10-26'); // the bots' 6:05 PM ET open // EST (UTC−5): 20:00 ET is 01:00 UTC. assert.equal(vestDayOf(iso('2026-12-01T00:30:00Z')), '2026-11-30'); assert.equal(vestDayOf(iso('2026-12-01T01:00:00Z')), '2026-12-01'); // Month and year ends. assert.equal(vestDayOf(iso('2026-12-31T23:00:00Z')), '2026-12-31'); assert.equal(vestDayOf(iso('2027-01-01T01:30:00Z')), '2027-01-01'); assert.equal(lastVestResetMs(iso('2026-10-26T18:00:00Z')), iso('2026-10-26T00:00:00Z')); assert.equal(lastVestResetMs(iso('2026-10-27T00:00:00Z')), iso('2026-10-27T00:00:00Z')); assert.equal(lastVestResetMs(iso('2026-12-01T00:30:00Z')), iso('2026-11-30T01:00:00Z')); assert.equal(lastVestResetMs(iso('2026-12-01T01:00:01Z')), iso('2026-12-01T01:00:00Z')); // Across the November switch back (Nov 1 2026, 2 AM ET). assert.equal(lastVestResetMs(iso('2026-11-01T12:00:00Z')), iso('2026-11-01T00:00:00Z')); assert.equal(lastVestResetMs(iso('2026-11-02T12:00:00Z')), iso('2026-11-02T01:00:00Z')); }); const evalAccount = { payment_id: 'tailoredpay:vest-markets:production:12727557177', id: 'e7f69717-bd18-5cb7-9466-673cb283d0b2', plan_id: '86bb03f9-7422-513c-8d5c-c546cb8d221d', account_type: 2, stage: 1, status: 2, initial_capital: '50000.00000000', max_drawdown_pct: '0.060000', max_leverage: '5.0000', max_profit_split_pct: '0.8000', target_equity: '55000.00000000', max_drawdown_limit: '47000.00000000', max_daily_loss_pct: '0.030000', daily_reset_balance: '50000.00000000000000', daily_reset_equity: '50000.00000000000000', daily_reset_base_limit: '1500.000000000000000', daily_loss_floor: '48500.00000000000000', daily_reset_at: 1793035043842, origin: 'eval_purchase', plan_name: 'Vest Capital Evaluation Fee | 10% Goal | 3% Daily Loss | 80/20 | Emerald', plan_product_type: 'eval', step: 1, steps_total: 1, root_account_id: 'e7f69717-bd18-5cb7-9466-673cb283d0b2', stages: [ { ordinal: 1, kind: 'eval', initial_capital: '50000.00000000', profit_target: '5000.00000000', max_drawdown_pct: '0.060000' }, { ordinal: 2, kind: 'funded', initial_capital: '50000.00000000', profit_target: '', max_drawdown_pct: '0.060000' }, ], attempt_index: 34, activated_at: 1793035043834, created_at: 1793035043756, updated_at: 1793035043843, }; test('capital accounts parse, and are named for their rules', () => { const a = parseCapitalAccount(evalAccount); assert.equal(a.id, evalAccount.id); assert.equal(a.kind, 'eval'); assert.equal(a.status, 2); assert.equal(a.initialCapital, 50000); assert.equal(a.profitTarget, 5000); assert.equal(a.maxDrawdownLimit, 47000); assert.equal(a.dailyLossFloor, 48500); assert.equal(a.maxDailyLossPct, 0.03); assert.equal(a.dailyResetAt, 1793035043842); assert.equal(vestAccountName(a), 'V50K-E-D3-T10-34'); assert.equal(vestAccountName(parseCapitalAccount({ ...evalAccount, stage: 2 })), 'V50K-F-D3-34'); assert.equal(vestAccountName(parseCapitalAccount({ ...evalAccount, max_daily_loss_pct: '0' })), 'V50K-E-D0-T10-34'); assert.equal(vestAccountName(parseCapitalAccount({ ...evalAccount, initial_capital: '5000.00000000', attempt_index: 12, stage: 2, steps_total: 2, stages: [ { ordinal: 1, kind: 'eval', profit_target: '500.00000000' }, { ordinal: 2, kind: 'eval', profit_target: '250.00000000' }, { ordinal: 3, kind: 'funded', profit_target: '' }, ], })), 'V5K-E-D3-T5-12'); assert.equal(vestAccountName(parseCapitalAccount({ ...evalAccount, plan_product_type: 'instant_funded', initial_capital: '25000.00000000', max_daily_loss_pct: '0', attempt_index: 7, stages: [{ ordinal: 1, kind: 'funded', profit_target: '' }], })), 'V25K-I-7'); assert.equal(vestAccountName(parseCapitalAccount({ ...evalAccount, plan_product_type: 'instant_funded', initial_capital: '500.00000000', attempt_index: 1, stages: [{ ordinal: 1, kind: 'funded', profit_target: '' }], })), 'V500-I-1'); assert.equal(parseCapitalAccount({ nope: true }), null); }); const openPosition = { positionId: 'afe96d7e-f5ac-4b8a-aae8-f5b63b74e508', accountId: '843f60e2-e013-5a0e-8b6c-face84bc5509', accountType: 2, symbol: 'NDX-USD-PERP', side: 'short', quantity: '42.6545', openPrice: '29529.250000000', closePrice: '290.250000000', openDate: 1793035089277, pnl: '0', fee: '31.488885', funding: '-5.423271000000000000', collateral: '24944.027426', leverage: '50', createdAt: 1793035089244, updatedAt: 1793037621104, stopLosses: [{ id: 'e22311d2-fbd9-4ab8-b65f-c2921f58fefc', triggerPrice: '29554.500000000', sizeMode: 'full_position', executionType: 'market', status: 'awaiting' }], takeProfits: [], }; test('positions, their legs and unrealized P&L', () => { const p = parsePosition(openPosition); assert.equal(p.side, 'short'); assert.equal(p.quantity, 42.6545); assert.equal(p.collateral, 24944.027426); assert.equal(p.openedAt, 1793035089277); assert.equal(awaitingLegs(p).length, 1); assert.equal(awaitingLegs({ ...p, stopLosses: [{ ...p.stopLosses[0], status: 'triggered' }] }).length, 0); // Short 42.6545 from 29529.25, marked at 29477.50: +51.75 points each. assert.ok(Math.abs(unrealizedPnl(p, 29477.5) - 42.6545 * 51.75) < 1e-6); assert.equal(unrealizedPnl(p, NaN), 0); assert.equal(parsePosition({ ...openPosition, quantity: '0' }), null); assert.equal(parseOpenOrder({ order_id: 'o1', account_id: 'a1', position_id: 'p1', symbol: 'GC-PERP', created_at: 1 }).positionId, 'p1'); assert.equal(parseOpenOrder({ symbol: 'x' }), null); }); test('an entry never closes a position, a flatten never opens one', () => { const effect = (held, side, intent) => vestOrderEffect({ symbol: 'NDX-USD-PERP', held, side, intent }); // No intent: the position decides, as before (the manual order route). assert.deepEqual(effect(null, 'long'), { effect: 'open' }); assert.deepEqual(effect('short', 'long'), { effect: 'close' }); assert.match(effect('long', 'long').refused, /adding to an open NDX-USD-PERP position/); // An entry on an account that already holds the symbol — a hand short the // engine's synced positions didn't show yet — is refused, not turned into // a close of that short. assert.deepEqual(effect(null, 'long', 'open'), { effect: 'open' }); const entry = effect('short', 'long', 'open'); assert.match(entry.refused, /short NDX-USD-PERP position is already open/); assert.equal(entry.nothingToClose, undefined); assert.match(effect('long', 'long', 'open').refused, /adding to an open/); // A flatten closes the leg it was sent for; on a flat account it opens // nothing and says there is nothing to close. assert.deepEqual(effect('long', 'short', 'close'), { effect: 'close' }); const flat = effect(null, 'short', 'close'); assert.match(flat.refused, /no NDX-USD-PERP position to close/); assert.equal(flat.nothingToClose, true); // Holding the flatten's own side is not the leg: refused, and not "flat". const wrong = effect('short', 'short', 'close'); assert.match(wrong.refused, /holds a short NDX-USD-PERP position, not one to close/); assert.equal(wrong.nothingToClose, undefined); // The refusal the client throws for it: still "never placed" (the leg is // un-counted), and told apart from every other refusal. const nothing = new NothingToCloseError('no NDX-USD-PERP position to close — nothing sent'); assert.equal(isOrderNotPlaced(nothing), true); assert.equal(isNothingToClose(nothing), true); assert.equal(isNothingToClose(new OrderNotPlacedError('Vest refused the order: 400')), false); assert.equal(isNothingToClose(new Error('outcome unknown')), false); assert.equal(isNothingToClose(undefined), false); }); test('transactions book into daily P&L and fund rows by Vest day', () => { assert.equal(txnKind(VEST_TXN.FEE), 'trade'); assert.equal(txnKind(VEST_TXN.REALIZED_PNL), 'trade'); assert.equal(txnKind(VEST_TXN.FUNDING), 'trade'); assert.equal(txnKind(VEST_TXN.WITHDRAW), 'fund'); assert.equal(txnKind(VEST_TXN.FILL_MARGIN), 'margin'); assert.equal(txnKind(VEST_TXN.ORDER_MARGIN_RELEASE), 'margin'); const w = parseTxn({ account_type: 3, action_id: 'a9', amount: '1200', created_at: iso('2026-10-26T15:00:00Z'), transaction_type: 2 }); assert.equal(w.amount, -1200); assert.equal(w.kind, 'fund'); assert.equal(parseTxn({ amount: 'x', transaction_type: 9, created_at: 1 }), null); const rows = [ { action_id: 'd', amount: '50000', created_at: iso('2026-10-20T14:00:00Z'), transaction_type: 1 }, { action_id: 'o', amount: '-24944.02', created_at: iso('2026-10-26T17:18:00Z'), transaction_type: 6 }, { action_id: 'f1', amount: '-31.49', created_at: iso('2026-10-26T17:18:00Z'), transaction_type: 8 }, // After 20:00 ET on the 26th: the 27th's day. { action_id: 'r1', amount: '812.5', created_at: iso('2026-10-27T00:30:00Z'), transaction_type: 9 }, { action_id: 'f2', amount: '-31.2', created_at: iso('2026-10-27T00:30:00Z'), transaction_type: 8 }, { action_id: 'u1', amount: '-5.42', created_at: iso('2026-10-27T01:00:00Z'), transaction_type: 10 }, ].map(parseTxn); const { daily, funds } = bookTxns(rows); assert.deepEqual([...funds.entries()], [['2026-10-20', 50000]]); assert.ok(Math.abs(daily.get('2026-10-26').pnl - -31.49) < 1e-9); assert.ok(Math.abs(daily.get('2026-10-27').pnl - (812.5 - 31.2 - 5.42)) < 1e-9); assert.ok(Math.abs(daily.get('2026-10-27').fees - 31.2) < 1e-9); }); test('hourly volatility leaves out the gaps', () => { const start = iso('2026-10-19T00:00:00Z'); const kl = []; let price = 29000; for (let h = 0; h < 60; h++) { price *= h % 2 === 0 ? 1.001 : 1 / 1.001; kl.push([start + h * 3_600_000, '0', '0', '0', String(price), '1']); } const base = hourlyVolatility(kl); assert.ok(base > 0.0009 && base < 0.0011, `σ ${base}`); // A weekend gap with a 3% jump: not an hour's move, so σ doesn't change. const gapped = [...kl, [start + 120 * 3_600_000, '0', '0', '0', String(price * 1.03), '1']]; assert.ok(Math.abs(hourlyVolatility(gapped) - base) < 1e-12); // Any order in, the same σ out. assert.equal(hourlyVolatility([...kl].reverse()), base); assert.equal(hourlyVolatility(kl.slice(0, MIN_HOURLY_RETURNS)), null); }); test('market hours: open stretches, closures and crypto', () => { const periods = [ { fromMs: 0, toMs: 100, state: { session: 'unspecified', closure: 'weekly', tradingStatus: 'CLOSE', price: { allow: false } } }, { fromMs: 100, toMs: 200, state: { session: 'overnight', closure: 'unspecified', tradingStatus: 'OPEN', price: { allow: true } } }, { fromMs: 200, toMs: 300, state: { session: 'regular', closure: 'unspecified', tradingStatus: 'OPEN', price: { allow: true } } }, { fromMs: 300, toMs: 400, state: { session: 'unspecified', closure: 'maintenance', tradingStatus: 'OPEN', price: { allow: true } } }, { fromMs: 400, toMs: 500, state: { session: 'overnight', closure: 'unspecified', tradingStatus: 'OPEN', price: { allow: true } } }, ]; assert.deepEqual(marketOpen(periods, 50), { open: false, closesAt: null }); assert.deepEqual(marketOpen(periods, 150), { open: true, closesAt: 300 }); assert.deepEqual(marketOpen(periods, 350), { open: false, closesAt: null }); assert.deepEqual(marketOpen(periods, 450), { open: true, closesAt: 500 }); assert.deepEqual(marketOpen(periods, 600), { open: false, closesAt: null }); assert.deepEqual(marketOpen([], 600), { open: true, closesAt: null }); }); test('relayed sessions: taken, kept fresher, dropped, never listed with tokens', () => { const now = iso('2026-10-26T18:40:00Z'); const jwt = (n) => `eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIke${n}In0.sig${n}`; const wallet = '0x7CE10771819F80130E204DDB5CA1522E48A9B451'; assert.equal(putVestSession({ accessToken: 'nope', expiresAt: now + 900_000, primaryAddr: wallet, userId: 'u' }, now), 'accessToken is not a JWT'); assert.equal(putVestSession({ accessToken: jwt(1), expiresAt: now + 10_000, primaryAddr: wallet, userId: 'u' }, now), 'token already expired'); assert.equal(putVestSession({ accessToken: jwt(1), expiresAt: now + 900_000, primaryAddr: '0x12', userId: 'u' }, now), 'primaryAddr is not a wallet address'); assert.equal(putVestSession({ accessToken: jwt(1), expiresAt: now + 900_000, primaryAddr: wallet, userId: 'u' }, now), null); // An older token relayed late doesn't replace the fresher one. assert.equal(putVestSession({ accessToken: jwt(0), expiresAt: now + 300_000, primaryAddr: wallet, userId: 'u' }, now), null); assert.equal(vestSessionFor(wallet.toLowerCase(), now).accessToken, jwt(1)); assert.equal(vestSessionFor(wallet, now + 890_000), null); // under 30s left const listed = listVestSessions(); assert.equal(listed.length, 1); assert.equal(listed[0].primaryAddr, wallet.toLowerCase()); assert.equal('accessToken' in listed[0], false); dropVestSession(wallet, jwt(0)); // not the held one: kept assert.ok(vestSessionFor(wallet, now)); dropVestSession(wallet, jwt(1)); assert.equal(vestSessionFor(wallet, now), null); }); test('the next 8 PM ET reset, across both time changes', () => { assert.equal(nextVestResetMs(iso('2026-10-26T18:00:00Z')), iso('2026-10-27T00:00:00Z')); assert.equal(nextVestResetMs(iso('2026-10-27T00:00:00Z')), iso('2026-10-28T00:00:00Z')); assert.equal(nextVestResetMs(iso('2026-10-31T23:59:00Z')), iso('2026-11-01T00:00:00Z')); // Nov 1 2026, the clocks go back: that evening's reset is 01:00 UTC. assert.equal(nextVestResetMs(iso('2026-11-01T12:00:00Z')), iso('2026-11-02T01:00:00Z')); assert.equal(nextVestResetMs(iso('2026-12-01T00:30:00Z')), iso('2026-12-01T01:00:00Z')); }); test('resetSafeStop: fit an open position into the room the reset will leave', () => { // A stage-2 leg after a claim: balance $50,000, 3% → the reset floor is // $48,500 (above the $47k drawdown floor). $150 reserve, a $3 fee: $1,347 to lose. const base = { side: 'long', quantity: 4, openPrice: 29500, mark: 29480, balance: 50000, dailyLossPct: 0.03, maxDrawdownFloor: 47000, reserve: 150, exitFeeRate: 0.000025, tick: 0.25, }; // No stop at all (a last stand): one comes in at open − 1347/4, rounded up to the tick. const fee = 0.000025 * 4 * 29480; const allowed = 50000 - 48500 - 150 - fee; const want = Math.ceil((29500 - allowed / 4) / 0.25) * 0.25; assert.deepEqual(resetSafeStop({ ...base, currentStop: null }), { action: 'stop', price: want }); // A wider stop is pulled in; one already tighter is left alone. assert.deepEqual(resetSafeStop({ ...base, currentStop: 29000 }), { action: 'stop', price: want }); assert.deepEqual(resetSafeStop({ ...base, currentStop: 29300 }), { action: 'none' }); // The mark already past where the stop must go: close. assert.deepEqual(resetSafeStop({ ...base, mark: 29100, currentStop: null }), { action: 'close' }); // Short: mirrored, rounded down. const short = resetSafeStop({ ...base, side: 'short', mark: 29510, currentStop: null }); assert.equal(short.action, 'stop'); assert.equal(short.price, Math.floor((29500 + (50000 - 48500 - 150 - 0.000025 * 4 * 29510) / 4) / 0.25) * 0.25); // No room past the reset at all: close. assert.deepEqual(resetSafeStop({ ...base, balance: 48600, maxDrawdownFloor: 48600 }), { action: 'close' }); // The drawdown floor binds when it's above the daily one. const dd = resetSafeStop({ ...base, maxDrawdownFloor: 49000, currentStop: null }); assert.equal(dd.action, 'stop'); assert.ok(dd.price > want); // A second position on the account gets what the first leaves: $500 // already committed at the first one's stop, from the same $48,500 floor. const second = resetSafeStop({ ...base, balance: 49500, floorBalance: 50000, currentStop: null }); assert.equal(second.action, 'stop'); assert.equal(second.price, Math.ceil((29500 - (allowed - 500) / 4) / 0.25) * 0.25); assert.ok(second.price > want); // ...and nothing when the first takes it all. assert.deepEqual(resetSafeStop({ ...base, balance: 48600, floorBalance: 50000, currentStop: null }), { action: 'close' }); // With no room left, a position already up keeps going on a stop that // locks in the shortfall: one already locking in more is left alone... const up = { ...base, mark: 29560, balance: 48600, floorBalance: 50000 }; assert.deepEqual(resetSafeStop({ ...up, currentStop: 29520 }), { action: 'none' }); // ...one with none gets it, on the profit side, still under the mark... const shortfall = 48600 - 48500 - 150 - 0.000025 * 4 * 29560; assert.deepEqual(resetSafeStop({ ...up, currentStop: null }), { action: 'stop', price: Math.ceil((29500 - shortfall / 4) / 0.25) * 0.25 }); assert.ok(resetSafeStop({ ...up, currentStop: null }).price > 29500); // ...and with no mark to tell, it closes. assert.deepEqual(resetSafeStop({ ...up, mark: NaN, currentStop: null }), { action: 'close' }); }); test('parseHistoryPosition: a closed position from GET /v3/positions', () => { // Shaped like the app's History tab reads it (camelCase, decimal strings). const t = parseHistoryPosition({ positionId: 'bdda9024-63a9-4abc-a5a8-f83df8ba030a', accountId: '843f60e2-e013-5a0e-8b6c-face84bc5509', symbol: 'NDX-USD-PERP', side: 'short', quantity: '4.2712', leverage: '50', openPrice: '29529.75', closePrice: '29556.50', pnl: '-114.25', fee: '6.31', funding: '-0.12', collateral: '2522.54', takeProfits: [], stopLosses: [], openDate: 1793065590123, closeDate: 1793066346456, createdAt: 1793065590123, updatedAt: 1793066346456, closeReason: 'user_requested', }); assert.deepEqual(t, { positionId: 'bdda9024-63a9-4abc-a5a8-f83df8ba030a', symbol: 'NDX-USD-PERP', side: 'short', quantity: 4.2712, leverage: 50, openPrice: 29529.75, closePrice: 29556.5, pnl: -114.25, fee: 6.31, funding: -0.12, openedAt: 1793065590123, closedAt: 1793066346456, closeReason: 'user_requested', }); }); test('parseHistoryPosition: open, snake_case, seconds, and junk', () => { const open = parseHistoryPosition({ position_id: 'p1', symbol: 'GC-PERP', side: 'LONG', quantity: '0', open_price: '4208.9', close_price: '', pnl: '', open_date: 1793065590, close_date: null, close_reason: '', }); assert.equal(open.side, 'long'); assert.equal(open.quantity, 0, 'a size Vest leaves out reads 0 — the store keeps the one it knows'); assert.equal(open.openPrice, 4208.9); assert.equal(open.closePrice, null); assert.equal(open.pnl, null); assert.equal(open.openedAt, 1793065590000); assert.equal(open.closedAt, null); assert.equal(open.closeReason, null); const held = parseHistoryPosition({ positionId: 'p3', symbol: 'NDX-USD-PERP', side: 'short', quantity: '85.7363', openPrice: '29538.96', closePrice: '290.25', pnl: '0.0', fee: '63.314059', funding: '0.0', openDate: 1793065422000, closeDate: null, }); assert.equal(held.closePrice, null, "an open position's placeholder close price is dropped"); assert.equal(held.pnl, null, 'and its $0 P&L'); assert.equal(held.fee, 63.314059, 'its entry fee is real'); assert.equal(parseHistoryPosition({ symbol: 'GC-PERP', openDate: 1 }), null, 'no id'); assert.equal(parseHistoryPosition({ positionId: 'p2', symbol: 'GC-PERP' }), null, 'no open time'); assert.equal(parseHistoryPosition(null), null); }); test('an account\'s own token is told from the login\'s', () => { const b64 = (o) => Buffer.from(JSON.stringify(o)).toString('base64url'); const acct = '275e765a-2d3d-5de3-8386-71aaa847c0e8'; const accountToken = `${b64({ alg: 'ES256' })}.${b64({ sub: '3cab1794-47bc-523b-91e6-64a9ad26dcbf', acc: { id: acct.toUpperCase() } })}.sig`; assert.ok(jwtClaimStrings(accountToken).includes(acct)); assert.deepEqual(jwtClaimStrings('not.a-jwt.at-all'), []); assert.deepEqual(jwtClaimStrings('nodots'), []); // The login sees every account and its primary one. assert.equal(accountScopedToken({ capitalIds: [acct, 'b', 'c'], hasPrimary: true, claims: [] }), false); // One account and no primary: an account's token, whatever its claims. assert.equal(accountScopedToken({ capitalIds: [acct], hasPrimary: false, claims: [] }), true); // One account with a primary: only when the token names that account. assert.equal(accountScopedToken({ capitalIds: [acct], hasPrimary: true, claims: jwtClaimStrings(accountToken) }), true); assert.equal(accountScopedToken({ capitalIds: [acct], hasPrimary: true, claims: ['3cab1794-47bc-523b-91e6-64a9ad26dcbf'] }), false); // A login with no capital accounts yet. assert.equal(accountScopedToken({ capitalIds: [], hasPrimary: true, claims: [] }), false); }); test('a refused account token falls back to the login\'s and stays refused', () => { const now = iso('2026-10-27T01:00:00Z'); const wallet = '0x00000000000000000000000000000000000000aa'; const login = 'eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJsb2dpbiJ9.loginsignature-loginsignature-loginsig'; const account = 'eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJhY2N0In0.accountsignature-accountsignature-acct'; assert.equal(putVestSession({ accessToken: login, expiresAt: now + 600_000, primaryAddr: wallet, userId: 'u' }, now), null); // The account's token lives longer, so it replaces the login's... assert.equal(putVestSession({ accessToken: account, expiresAt: now + 900_000, primaryAddr: wallet, userId: 'u' }, now), null); assert.equal(vestSessionFor(wallet, now).accessToken, account); // ...until the client finds it sees one account: back to the login's. refuseVestSession(wallet, account, now); assert.equal(vestSessionFor(wallet, now).accessToken, login); // Relayed again (the old extension posts it every minute): refused. assert.match(putVestSession({ accessToken: account, expiresAt: now + 900_000, primaryAddr: wallet, userId: 'u' }, now), /one Vest account's token/); assert.equal(vestSessionFor(wallet, now).accessToken, login); // The login's next renewal is taken as usual. const renewed = 'eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJsb2dpbiJ9.renewedsignature-renewedsignature-rene'; assert.equal(putVestSession({ accessToken: renewed, expiresAt: now + 1_200_000, primaryAddr: wallet, userId: 'u' }, now), null); assert.equal(vestSessionFor(wallet, now).accessToken, renewed); // Refusing a token that isn't held changes nothing held. refuseVestSession(wallet, 'x.y.zzz', now); assert.equal(vestSessionFor(wallet, now).accessToken, renewed); // No good token to fall back to: none at all. const wallet2 = '0x00000000000000000000000000000000000000bb'; assert.equal(putVestSession({ accessToken: account.replace('acct', 'accu'), expiresAt: now + 900_000, primaryAddr: wallet2, userId: 'u' }, now), null); refuseVestSession(wallet2, account.replace('acct', 'accu'), now); assert.equal(vestSessionFor(wallet2, now), null); });