UNPKG

@dolaned/wallet-sdk-ts

Version:

Wallet SDK for the Nexa blockchain

259 lines (209 loc) 9.98 kB
import { describe, test, expect, beforeEach, vi } from 'vitest' import { TransactionBuilder, Networks } from 'libnexa-ts' import WatchOnlyTransactionCreator from '../../../src/wallet/transactions/WatchOnlyTransactionCreator' import { WatchOnlyAddress } from '../../../src/models/wallet.entities' // Mock the WatchOnlyTXUtils functions vi.mock('../../../src/utils/WatchOnlyTXUtils', () => ({ watchOnlyPopulateTokenAuth: vi.fn().mockResolvedValue(['address1']), watchOnlyBuildCreateGroupTransaction: vi.fn().mockResolvedValue(['address2']), watchOnlyPopulateAndDuplicateTokenAuths: vi.fn().mockResolvedValue(['address3']), watchOnlyPrepareDeleteTransaction: vi.fn().mockResolvedValue(['address4']), watchOnlyPopulateTokenInputsAndChange: vi.fn().mockResolvedValue(['address5']), watchOnlyPopulateNexaInputsAndChange: vi.fn().mockResolvedValue(['address6']) })) describe('WatchOnlyTransactionCreator', () => { let creator: WatchOnlyTransactionCreator let mockAddresses: WatchOnlyAddress[] beforeEach(() => { mockAddresses = [ { address: 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' }, { address: 'nexatest:nqtsq5g5dsgh6mwjchqypn8hvdrjue0xpmz293fl7rm926xv' } ] creator = new WatchOnlyTransactionCreator() }) describe('constructor', () => { test('should create instance without transaction builder', () => { const creator = new WatchOnlyTransactionCreator() expect(creator).toBeInstanceOf(WatchOnlyTransactionCreator) }) test('should create instance with transaction builder', () => { const txBuilder = new TransactionBuilder() const creator = new WatchOnlyTransactionCreator(txBuilder) expect(creator).toBeInstanceOf(WatchOnlyTransactionCreator) }) }) describe('parseTxBuffer', () => { test('should not throw error and return this for chaining', () => { const buffer = Buffer.from('test') const result = creator.parseTxBuffer(buffer) expect(result).toBe(creator) expect(creator.builder).toHaveLength(1) }) }) describe('parseTxHex', () => { test('should not throw error and return this for chaining', () => { const hex = 'deadbeef' const result = creator.parseTxHex(hex) expect(result).toBe(creator) expect(creator.builder).toHaveLength(1) }) }) describe('from', () => { test('should accept single address string', () => { const address = 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const result = creator.onNetwork('testnet').from(address) expect(result).toBe(creator) // Should return this for chaining expect(creator['_availableAddresses']).toHaveLength(1) expect(creator['_availableAddresses'][0].address).toBe(address) }) test('should accept array of address strings', () => { const addresses = [ 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc', 'nexatest:nqtsq5g5dsgh6mwjchqypn8hvdrjue0xpmz293fl7rm926xv' ] const result = creator.onNetwork('testnet').from(addresses) expect(result).toBe(creator) expect(creator['_availableAddresses']).toHaveLength(2) expect(creator['_availableAddresses'][0].address).toBe(addresses[0]) expect(creator['_availableAddresses'][1].address).toBe(addresses[1]) }) test('should accept array of WatchOnlyAddress objects', () => { const result = creator.from(mockAddresses) expect(result).toBe(creator) expect(creator['_availableAddresses']).toHaveLength(2) expect(creator['_availableAddresses'][0]).toEqual(mockAddresses[0]) expect(creator['_availableAddresses'][1]).toEqual(mockAddresses[1]) }) test('should accept single WatchOnlyAddress object', () => { const address = mockAddresses[0] const result = creator.from(address) expect(result).toBe(creator) expect(creator['_availableAddresses']).toHaveLength(1) expect(creator['_availableAddresses'][0]).toEqual(address) }) }) describe('mint', () => { test('should add mint operation to builder', () => { const token = 'nexatest:tqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const amount = '1000' const toAddr = 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const result = creator.mint(token, amount, toAddr) expect(result).toBe(creator) expect(creator.builder).toHaveLength(1) }) test('should be chainable', () => { const token = 'nexatest:tqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const amount = '1000' const toAddr = 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const result = creator .mint(token, amount, toAddr) .mint(token, amount, toAddr) expect(result).toBe(creator) expect(creator.builder).toHaveLength(2) }) }) describe('melt', () => { test('should add melt operation to builder', () => { const token = 'nexatest:tqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const amount = '1000' const toAddr = 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const result = creator.melt(token, amount, toAddr) expect(result).toBe(creator) expect(creator.builder).toHaveLength(1) }) test('should be chainable', () => { const token = 'nexatest:tqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const amount = '1000' const toAddr = 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const result = creator .melt(token, amount, toAddr) .melt(token, amount, toAddr) expect(result).toBe(creator) expect(creator.builder).toHaveLength(2) }) }) describe('populate', () => { test('should add populate operation to builder', () => { const result = creator.populate() expect(result).toBe(creator) expect(creator.builder).toHaveLength(1) }) test('should be chainable', () => { const result = creator .from(mockAddresses) .populate() expect(result).toBe(creator) expect(creator.builder).toHaveLength(1) }) }) describe('integration tests', () => { test('should handle complete transaction flow', () => { const token = 'nexatest:tqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const amount = '1000' const toAddr = 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const result = creator .onNetwork('testnet') .from(mockAddresses) .mint(token, amount, toAddr) .melt(token, amount, toAddr) .populate() expect(result).toBe(creator) expect(creator.builder).toHaveLength(3) // mint, melt, populate expect(creator.network).toBe(Networks.testnet) }) test('should handle token operations and populate', () => { const token = 'nexatest:tqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const amount = '1000' const toAddr = 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const result = creator .from(mockAddresses) .sendTo(toAddr, amount) .sendToToken(toAddr, amount, token) .populate() expect(result).toBe(creator) expect(creator.builder).toHaveLength(3) // sendTo, sendToToken, populate }) test('should handle token creation', () => { const result = creator .from(mockAddresses) .token('Test Token', 'TEST', 2, 'https://test.com', 'hash') .populate() expect(result).toBe(creator) expect(creator.builder).toHaveLength(2) // token, populate }) test('should handle consolidate transaction', () => { const toAddr = 'nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc' const result = creator .from(mockAddresses) .consolidate(toAddr) .populate() expect(result).toBe(creator) expect(creator.builder).toHaveLength(2) // consolidate, populate }) }) describe('network handling', () => { test('should set network correctly', () => { const result = creator.onNetwork('testnet') expect(result).toBe(creator) expect(creator.network).toBe(Networks.testnet) }) test('should default to mainnet', () => { expect(creator.network).toBe(Networks.mainnet) }) }) describe('error handling', () => { test('should handle empty addresses array', () => { const result = creator.from([]) expect(result).toBe(creator) expect(creator['_availableAddresses']).toHaveLength(0) }) test('should handle null/undefined addresses', () => { // Test with addresses that don't have the address property const invalidAddress = {} as WatchOnlyAddress const result = creator.from(invalidAddress) expect(result).toBe(creator) // Should not add invalid addresses expect(creator['_availableAddresses']).toHaveLength(0) }) }) })