From 53f86b2086ca6cb704bd3b2b0c4f18ff188f7681 Mon Sep 17 00:00:00 2001 From: Pyper01 Date: Thu, 27 Aug 2026 16:33:40 +0100 Subject: [PATCH] fix: address multiple issues for Ajayi Closes #463 Closes #462 Closes #461 Closes #460 --- src/tests/batch-tx.test.ts | 26 +++++++++++ src/tests/soroban-rpc-helpers.test.ts | 64 +++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 src/tests/batch-tx.test.ts create mode 100644 src/tests/soroban-rpc-helpers.test.ts diff --git a/src/tests/batch-tx.test.ts b/src/tests/batch-tx.test.ts new file mode 100644 index 0000000..b5602b5 --- /dev/null +++ b/src/tests/batch-tx.test.ts @@ -0,0 +1,26 @@ +import { resolvePassphrase, BatchTransactionContext, BatchBuildError } from '../batch-tx.js'; +import { describe, it, expect } from 'vitest'; +import { Networks } from '@stellar/stellar-sdk'; + +describe('resolvePassphrase', () => { + it('should return networkPassphrase when provided', () => { + const ctx = { networkPassphrase: 'custom passphrase' } as BatchTransactionContext; + expect(resolvePassphrase(ctx)).toBe('custom passphrase'); + }); + + it('should resolve named networks', () => { + expect(resolvePassphrase({ network: 'mainnet' } as BatchTransactionContext)).toBe(Networks.PUBLIC); + expect(resolvePassphrase({ network: 'testnet' } as BatchTransactionContext)).toBe(Networks.TESTNET); + expect(resolvePassphrase({ network: 'local' } as BatchTransactionContext)).toBe(Networks.STANDALONE); + }); + + it('should throw BatchBuildError on unknown network', () => { + expect(() => resolvePassphrase({ network: 'unknown' as any } as BatchTransactionContext)) + .toThrowError(BatchBuildError); + }); + + it('should throw BatchBuildError when neither is provided', () => { + expect(() => resolvePassphrase({} as BatchTransactionContext)) + .toThrowError(BatchBuildError); + }); +}); diff --git a/src/tests/soroban-rpc-helpers.test.ts b/src/tests/soroban-rpc-helpers.test.ts new file mode 100644 index 0000000..51edef7 --- /dev/null +++ b/src/tests/soroban-rpc-helpers.test.ts @@ -0,0 +1,64 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; + +const { mockSimulateTransaction, mockGetAccount } = vi.hoisted(() => ({ + mockSimulateTransaction: vi.fn(), + mockGetAccount: vi.fn(), +})); + +vi.mock('@stellar/stellar-sdk', async () => { + const actual = await vi.importActual('@stellar/stellar-sdk'); + return { + ...actual, + SorobanRpc: { + ...(actual as any).SorobanRpc, + Server: vi.fn().mockImplementation(function MockServer() { + return { + simulateTransaction: mockSimulateTransaction, + getAccount: mockGetAccount, + }; + }), + Api: (actual as any).SorobanRpc.Api, + }, + }; +}); + +import { estimateRequiredFee, queryXlmBalance } from '../soroban.js'; +import { nativeToScVal, Account } from '@stellar/stellar-sdk'; + +beforeEach(() => { + mockSimulateTransaction.mockReset(); + mockGetAccount.mockReset(); +}); + +describe('estimateRequiredFee', () => { + it('should extract minResourceFee when available', () => { + const fee = estimateRequiredFee({ minResourceFee: '12345' }); + expect(fee).toBe(12345n); + }); + + it('should extract fee when available', () => { + const fee = estimateRequiredFee({ fee: 9999n }); + expect(fee).toBe(9999n); + }); + + it('should fallback to 1_000_000n when neither is available', () => { + const fee = estimateRequiredFee({}); + expect(fee).toBe(1_000_000n); + }); + + it('should use custom fallback', () => { + const fee = estimateRequiredFee({}, 100n); + expect(fee).toBe(100n); + }); +}); + +describe('queryXlmBalance', () => { + it('should return native balance', async () => { + mockGetAccount.mockResolvedValue(new Account('GAAQCAIBAEAQCAIBAEAQCAIBAEAQCAIBAEAQCAIBAEAQCAIBAEAQDZ7H', '100')); + const retval = nativeToScVal(1000n, { type: 'i128' }); + mockSimulateTransaction.mockResolvedValue({ result: { retval } }); + + const balance = await queryXlmBalance('http://localhost', 'Test SDF Network ; September 2015', 'GAAQCAIBAEAQCAIBAEAQCAIBAEAQCAIBAEAQCAIBAEAQCAIBAEAQDZ7H'); + expect(balance).toBe(1000n); + }); +});