UNPKG

@bsv/wallet-toolbox

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

1,312 lines (1,111 loc) 52.2 kB
import * as bsv from '@bsv/sdk' import { sdk, StorageProvider } from '../../../src/index.client' import { _tu, expectToThrowWERR, MockData, TestWalletNoSetup } from '../../utils/TestUtilsWalletStorage' const env = _tu.getEnvFlags('test') const testName = () => expect.getState().currentTestName || 'test' describe('listActions2 single action tests', () => { jest.setTimeout(99999999) let ctxs: TestWalletNoSetup[] const mockData: MockData = { actions: [ { txid: 'tx', satoshis: 1, status: 'completed', isOutgoing: true, description: 'Transaction', version: 1, lockTime: 0, labels: ['label', 'label2'], inputs: [ { sourceOutpoint: 'tx.0', sourceSatoshis: 1, sourceLockingScript: '0123456789abcdef', unlockingScript: '0123456789abcdef', inputDescription: 'description', sequenceNumber: 0 } ], outputs: [ { satoshis: 1, spendable: false, tags: ['tag', 'tag2'], outputIndex: 2, outputDescription: 'description', basket: 'basket', lockingScript: '0123456789abcdef' } ] } ] } beforeEach(async () => { ctxs = [] const args = { chain: <sdk.Chain>'test', mockData, databaseName: testName(), rootKeyHex: '2'.repeat(64), dropAll: true } if (env.runMySQL) { ctxs.push(await _tu.createMySQLTestSetup2Wallet(args)) } ctxs.push(await _tu.createSQLiteTestSetup2Wallet(args)) }) afterEach(async () => { for (const { wallet } of ctxs) await wallet.destroy() }) test('12_no labels default any', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: [] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('13_no labels any', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: [], labelQueryMode: 'any' } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('14_no labels all', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: [], labelQueryMode: 'all' } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('15_empty label default any', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: [''] } await expectToThrowWERR(sdk.WERR_INVALID_PARAMETER, async () => await wallet.listActions(args)) } }) test('16_label is space character default any', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: [' '] } await expectToThrowWERR(sdk.WERR_INVALID_PARAMETER, async () => await wallet.listActions(args)) } }) test('17_label does not exist default any', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: ['nonexistantlabel'] // Testing with a non-existent label } const expectedResult = JSON.parse('{"totalActions":0,"actions":[]}') expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('18_label min 1 character default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const minLengthLabel = 'a' await storage.updateTxLabel(1, { label: minLengthLabel }) const args: bsv.ListActionsArgs = { labels: [minLengthLabel] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('19_label max 300 spaces default any', async () => { for (const { wallet } of ctxs) { const maxLengthSpacesLabel = ' '.repeat(300) const args: bsv.ListActionsArgs = { labels: [maxLengthSpacesLabel] } await expectToThrowWERR(sdk.WERR_INVALID_PARAMETER, async () => await wallet.listActions(args)) } }) test('20_label max 300 normal characters default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const maxLengthNormalLabel = 'a'.repeat(300) await storage.updateTxLabel(1, { label: maxLengthNormalLabel }) const args: bsv.ListActionsArgs = { labels: [maxLengthNormalLabel] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('21_label min 1 emoji default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const minimumEmojiLabel = generateRandomEmojiString(4) await storage.updateTxLabel(1, { label: minimumEmojiLabel }) const args: bsv.ListActionsArgs = { labels: [minimumEmojiLabel] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('22_label max length 75 emojis default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const maximumEmojisLabel = generateRandomEmojiString(300) await storage.updateTxLabel(1, { label: maximumEmojisLabel }) const args: bsv.ListActionsArgs = { labels: [maximumEmojisLabel] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('23_label exceeding max length 76 emojis default any', async () => { for (const { wallet } of ctxs) { const exceedingMaximumEmojisLabel = generateRandomEmojiString(304) const args: bsv.ListActionsArgs = { labels: [exceedingMaximumEmojisLabel] } await expectToThrowWERR(sdk.WERR_INVALID_PARAMETER, async () => await wallet.listActions(args)) } }) test('24_normal label default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const label = 'label' await storage.updateTxLabel(1, { label }) const args: bsv.ListActionsArgs = { labels: [label] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('25_normal label any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const label = 'label' await storage.updateTxLabel(1, { label }) const args: bsv.ListActionsArgs = { labels: [label], labelQueryMode: 'any' } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('26_normal label all', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const label = 'label' await storage.updateTxLabel(1, { label }) const args: bsv.ListActionsArgs = { labels: [label], labelQueryMode: 'all' } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) // Can't test mixed case at storage level // test('27_label mixed case default any', async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // const mixedCaseLabel = 'LAbEL' // await storage.updateTxLabel(1, { label: mixedCaseLabel }) // const args: bsv.ListActionsArgs = { // labels: [mixedCaseLabel] // } // const expectedResult = JSON.parse('{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}') // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) test('28_label special characters default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const specialCharsLabel = '@special#label!' await storage.updateTxLabel(1, { label: specialCharsLabel }) const args: bsv.ListActionsArgs = { labels: [specialCharsLabel] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) // Can't test external whitespace at storage level // test('29_label leading and trailing whitespace default any', async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // const leadTrailSpacesLabel = ' label ' // await storage.updateTxLabel(1, { label: leadTrailSpacesLabel }) // const args: bsv.ListActionsArgs = { // labels: [leadTrailSpacesLabel] // } // const expectedResult = JSON.parse('{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}') // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) test('30_label numeric default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const numericLabel = '12345' await storage.updateTxLabel(1, { label: numericLabel }) const args: bsv.ListActionsArgs = { labels: [numericLabel] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('31_label alphanumeric default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const alphaumericLabel = 'abcde12345' await storage.updateTxLabel(1, { label: alphaumericLabel }) const args: bsv.ListActionsArgs = { labels: [alphaumericLabel] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('32_label contains default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const containsLabel = 'label' await storage.updateTxLabel(1, { label: containsLabel }) const args: bsv.ListActionsArgs = { labels: ['labelone'] } const expectedResult = JSON.parse('{"totalActions":0,"actions":[]}') expect(await wallet.listActions(args)).toEqual(expectedResult) } }) // Can't test mixed case at storage level // test('33_label different case lower any', async () => { // for (const { wallet } of ctxs) { // const args: bsv.ListActionsArgs = { // labels: ['label'], // labelQueryMode: 'any' // } // const expectedResult = JSON.parse('{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}') // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test('34_label different case upper any', async () => { // for (const { wallet } of ctxs) { // const args: bsv.ListActionsArgs = { // labels: ['LABEL'], // labelQueryMode: 'any' // } // const expectedResult = JSON.parse('{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}') // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) test('35_label with whitespace default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const spacedLabel = 'lab el' await storage.updateTxLabel(1, { label: spacedLabel }) const args: bsv.ListActionsArgs = { labels: [spacedLabel] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) // Can't test mixed case at storage level // test('36_label different case lower all', async () => { // for (const { wallet } of ctxs) { // const args: bsv.ListActionsArgs = { // labels: ['label'], // labelQueryMode: 'all' // } // const expectedResult = JSON.parse('{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}') // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test('37_label different case upper all', async () => { // for (const { wallet } of ctxs) { // const args: bsv.ListActionsArgs = { // labels: ['LABEL'], // labelQueryMode: 'all' // } // const expectedResult = JSON.parse('{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}') // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test('38_label duplicated default any', async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // const pairSameLabels = ['label', 'label'] // await storage.updateTxLabel(1, { label: pairSameLabels[0] }) // await storage.updateTxLabel(2, { label: pairSameLabels[1] }) // const args: bsv.ListActionsArgs = { // labels: pairSameLabels // } // const expectedResult = JSON.parse('{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}') // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) test('39_label requested default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const label = 'label' await storage.updateTxLabel(1, { label }) await storage.updateTxLabel(2, { label: 'label2' }) const args: bsv.ListActionsArgs = { labels: [label], includeLabels: true } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"labels":["label","label2"],"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('40_label not requested default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const label = 'label' await storage.updateTxLabel(1, { label }) const args: bsv.ListActionsArgs = { labels: [label], includeLabels: false } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('41_label partial match default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'labels' }) await storage.updateTxLabel(2, { label: 'label2' }) const args: bsv.ListActionsArgs = { labels: ['label'], includeLabels: true } const expectedResult = JSON.parse('{"totalActions":0,"actions":[]}') expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('42_label only one match default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'labels' }) await storage.updateTxLabel(2, { label: 'label' }) const args: bsv.ListActionsArgs = { labels: ['label'] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test(`43_inputs requested`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) const args: bsv.ListActionsArgs = { labels: ['label2'], includeInputs: true } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test(`44_inputs not requested`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) const args: bsv.ListActionsArgs = { labels: ['label2'], includeInputs: false } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test(`45_inputs requested locking script`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) const args: bsv.ListActionsArgs = { labels: ['label2'], includeInputs: true, includeInputSourceLockingScripts: true } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"sourceLockingScript":"0123456789abcdef","sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test(`46_inputs no locking script`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) const args: bsv.ListActionsArgs = { labels: ['label2'], includeInputs: true, includeInputSourceLockingScripts: false } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test(`47_inputs empty locking script`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) await storage.updateOutput(1, { lockingScript: [] }) const args: bsv.ListActionsArgs = { labels: ['label2'], includeInputs: true, includeInputSourceLockingScripts: true } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"sourceLockingScript":"","sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) // This requires genuine rawTx // test(`48_inputs request unlocking script`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutput(1, { // lockingScript: hexStringToNumberArray( // '76a91489abcdefabbaabbaabbaabbaabbaabbaabbaabba88ac' // ) // }) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeInputs: true, // includeInputSourceLockingScripts: true, // includeInputUnlockingScripts: true // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","inputs":[{"inputDescription":"description","sequenceNumber":0,"unlockingScript":"47304402207f2e9a6a6d8a5cf3f9d54b4e5fdfbb7a9c75c7e7a22be59d202c4baf1681c6140220219b1c07338fdfc60e949d0b426ce7b8f95de7a9d2e78f587db13fa7a6eb582301 0411db93e1dcdb8a016b49840f8c53bc1eb68a382fd70c81b7c4eeb4c1aab0eedda7e4a3c88ad097448a687ea1f90337e62c23f8cbb4cd7a7b20c54d7e0ceda220","sourceOutpoint":"tx.0","sourceSatoshis":1}],"isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) test(`49_outputs requested`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) await storage.updateOutputBasket(1, { name: 'new basket' }) await storage.updateOutput(2, { satoshis: 1, spendable: false, vout: 2, outputDescription: 'new description', basketId: 1 }) await storage.updateOutputTag(2, { tag: 'new tag' }) await storage.updateOutputTagMap(1, 2, {}) const args: bsv.ListActionsArgs = { labels: ['label2'], includeOutputs: true } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test(`50_outputs requested`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) await storage.updateOutputBasket(1, { name: 'new basket' }) await storage.updateOutput(2, { satoshis: 1, spendable: false, vout: 2, outputDescription: 'new description', basketId: 1 }) await storage.updateOutputTag(2, { tag: 'new tag' }) await storage.updateOutputTagMap(1, 2, {}) const args: bsv.ListActionsArgs = { labels: ['label2'], includeOutputs: false } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) // Cannot empty outputs at storage level // test(`51_outputs empty requested`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, {}) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) test(`52_outputs locking script requested`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) await storage.updateOutputBasket(1, { name: 'new basket' }) await storage.updateOutput(2, { satoshis: 1, spendable: false, vout: 2, outputDescription: 'new description', basketId: 1, lockingScript: bsv.Utils.toArray('0123456789abcdef', 'hex') }) await storage.updateOutputTag(2, { tag: 'new tag' }) await storage.updateOutputTagMap(1, 2, {}) const args: bsv.ListActionsArgs = { labels: ['label2'], includeOutputs: true, includeOutputLockingScripts: true } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"lockingScript":"0123456789abcdef","tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test(`53_outputs locking script not requested`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) await storage.updateOutputBasket(1, { name: 'new basket' }) await storage.updateOutput(2, { satoshis: 1, spendable: false, vout: 2, outputDescription: 'new description', basketId: 1, lockingScript: bsv.Utils.toArray('0123456789abcdef', 'hex') }) await storage.updateOutputTag(2, { tag: 'new tag' }) await storage.updateOutputTagMap(1, 2, {}) const args: bsv.ListActionsArgs = { labels: ['label2'], includeOutputs: true, includeOutputLockingScripts: false } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test(`54_outputs locking script undefined`, async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label' }) await storage.updateTxLabel(2, { label: 'label2' }) await storage.updateOutputBasket(1, { name: 'new basket' }) await storage.updateOutput(2, { satoshis: 1, spendable: false, vout: 2, outputDescription: 'new description', basketId: 1, lockingScript: undefined }) await storage.updateOutputTag(2, { tag: 'new tag' }) await storage.updateOutputTagMap(1, 2, {}) const args: bsv.ListActionsArgs = { labels: ['label2'], includeOutputs: true, includeOutputLockingScripts: false } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) //TBD requires many mock actions to be performed // test(`55_limit is default`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test(`56_limit 1`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) test('57_limit 0', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: ['label'], limit: 0 } await expectToThrowWERR(sdk.WERR_INVALID_PARAMETER, async () => await wallet.listActions(args)) } }) test('58_limit 10001', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: ['label'], limit: 10001 } await expectToThrowWERR(sdk.WERR_INVALID_PARAMETER, async () => await wallet.listActions(args)) } }) // TBD requires many mock actions to be performed // test(`59_offset less than number of actions`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test(`60_offset equal to number of actions`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test(`61_offset above number of actions`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) test('62_offset is invalid', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: ['label'], offset: -1 } await expectToThrowWERR(sdk.WERR_INVALID_PARAMETER, async () => await wallet.listActions(args)) } }) //TBD requires many mock actions to be performed // test(`63_offset below limit with same number of actions`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test(`64_offset below limit greater than number of actions`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test(`65_offset skips all actions with limit set`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test(`66_limit exceeds remaining actions after offset`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) // test(`67_limit exceeds remaining actions after offset`, async () => { // for (const { activeStorage: storage, wallet } of ctxs) { // await storage.updateTxLabel(1, { label: 'label' }) // await storage.updateTxLabel(2, { label: 'label2' }) // await storage.updateOutputBasket(1, { name: 'new basket' }) // await storage.updateOutput(2, { // satoshis: 1, // spendable: false, // vout: 2, // outputDescription: 'new description', // basketId: 1, // lockingScript: undefined // }) // await storage.updateOutputTag(2, { tag: 'new tag' }) // await storage.updateOutputTagMap(1, 2, {}) // const args: bsv.ListActionsArgs = { // labels: ['label2'], // includeOutputs: true, // includeOutputLockingScripts: false // } // const expectedResult = JSON.parse( // '{"totalActions":1,"actions":[{"txid":"tx","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction","version":1,"lockTime":0,"outputs":[{"satoshis":1,"spendable":false,"tags":["tag","new tag"],"outputIndex":2,"outputDescription":"new description","basket":"new basket"}]}]}' // ) // expect(await wallet.listActions(args)).toEqual(expectedResult) // } // }) }) describe('listActions2 two action tests', () => { jest.setTimeout(99999999) let ctxs: TestWalletNoSetup[] const mockData: MockData = { actions: [ { txid: 'tx1', satoshis: 1, status: 'completed', isOutgoing: true, description: 'Transaction 1', version: 1, lockTime: 0, labels: ['label 1', 'label a'], inputs: [ { sourceOutpoint: 'tx1.1', sourceSatoshis: 1, //sourceLockingScript: '0123456789abcdef', //unlockingScript: '0123456789abcdef', inputDescription: 'description 1', sequenceNumber: 1 } ], outputs: [ { satoshis: 1, spendable: false, tags: ['tag1'], outputIndex: 1, outputDescription: 'description 1', basket: 'basket' //lockingScript: '0123456789abcdef' } ] }, { txid: 'tx2', satoshis: 2, status: 'completed', isOutgoing: true, description: 'Transaction 2', version: 1, lockTime: 0, labels: ['label2', 'label b'], inputs: [ { sourceOutpoint: 'tx2.2', sourceSatoshis: 2, //sourceLockingScript: '0123456789abcdef', //unlockingScript: '0123456789abcdef', inputDescription: 'description 2', sequenceNumber: 2 } ], outputs: [ { satoshis: 2, spendable: false, tags: ['tag2'], outputIndex: 2, outputDescription: 'description 2', basket: 'basket 2' //lockingScript: '0123456789abcdef' } ] } ] } beforeEach(async () => { ctxs = [] const args = { chain: <sdk.Chain>'test', mockData, databaseName: testName(), rootKeyHex: '2'.repeat(64), dropAll: true } if (env.runMySQL) { ctxs.push(await _tu.createMySQLTestSetup2Wallet(args)) } ctxs.push(await _tu.createSQLiteTestSetup2Wallet(args)) }) afterEach(async () => { for (const { wallet } of ctxs) await wallet.destroy() }) test('100_no labels (default) matched default any', async () => { for (const { wallet } of ctxs) { const args: bsv.ListActionsArgs = { labels: [] } const expectedResult = JSON.parse( '{"totalActions":2,"actions":[{"txid":"tx1","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction 1","version":1,"lockTime":0},{"txid":"tx2","satoshis":2,"status":"completed","isOutgoing":true,"description":"Transaction 2","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('101_label 1 matched default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const label = 'label 1' await storage.updateTxLabel(1, { label }) await storage.updateTxLabel(2, { label: 'label a' }) await storage.updateTxLabel(3, { label: 'label 2' }) await storage.updateTxLabel(4, { label: 'label b' }) const args: bsv.ListActionsArgs = { labels: [label] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx1","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction 1","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('102_label 2 matched default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { const label = 'label 2' await storage.updateTxLabel(1, { label: 'label 1' }) await storage.updateTxLabel(2, { label: 'label a' }) await storage.updateTxLabel(3, { label }) await storage.updateTxLabel(4, { label: 'label b' }) const args: bsv.ListActionsArgs = { labels: [label] } const expectedResult = JSON.parse( '{"totalActions":1,"actions":[{"txid":"tx2","satoshis":2,"status":"completed","isOutgoing":true,"description":"Transaction 2","version":1,"lockTime":0}]}' ) expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('103_no label matched default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label 1' }) await storage.updateTxLabel(2, { label: 'label a' }) await storage.updateTxLabel(3, { label: 'label 2' }) await storage.updateTxLabel(4, { label: 'label b' }) const args: bsv.ListActionsArgs = { labels: ['label'] } const expectedResult = JSON.parse('{"totalActions":0,"actions":[]}') expect(await wallet.listActions(args)).toEqual(expectedResult) } }) test('104_both labels matched default any', async () => { for (const { activeStorage: storage, wallet } of ctxs) { await storage.updateTxLabel(1, { label: 'label 1' }) await storage.updateTxLabel(2, { label: 'label a' }) await storage.updateTxLabel(3, { label: 'label 2' }) await storage.updateTxLabel(4, { label: 'label b' }) const args: bsv.ListActionsArgs = { labels: ['label 1', 'label 2'] } const expectedResult = JSON.parse( '{"totalActions":2,"actions":[{"txid":"tx1","satoshis":1,"status":"completed","isOutgoing":true,"description":"Transaction 1","version":1,"lockTime":0},{"txid":"tx2","satoshis":2,"status":"completed","isOutgoing":true,"descrip