}\r
})\r
\r
-skip('Ledger device accounts', async () => {\r
+skip('fetch the first account from a Ledger device', async () => {\r
const wallet = await LedgerWallet.create()\r
+ const accounts = await wallet.accounts()\r
\r
- test('should fetch the first account from a Ledger device', async () => {\r
- const accounts = await wallet.accounts()\r
-\r
- assert.equals(accounts.length, 1)\r
- assert.exists(accounts[0].publicKey)\r
- assert.exists(accounts[0].address)\r
- })\r
+ assert.equals(accounts.length, 1)\r
+ assert.exists(accounts[0].publicKey)\r
+ assert.exists(accounts[0].address)\r
})\r
import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
import { Rolodex, Tools } from '#dist/main.js'
-test('rolodex valid contact management', async () => {
- test('should create a rolodex and add two contacts', async () => {
- const rolodex = new Rolodex()
- assert.equals(rolodex.constructor, Rolodex)
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
- await rolodex.add('JaneSmith', NANO_TEST_VECTORS.ADDRESS_1)
-
- assert.equals(rolodex.getAllNames().length, 2)
- assert.equals(rolodex.getAllNames()[0], 'JohnDoe')
- assert.equals(rolodex.getAllNames()[1], 'JaneSmith')
- assert.equals(rolodex.getAddresses('JohnDoe').length, 1)
- assert.equals(rolodex.getAddresses('JohnDoe')[0], NANO_TEST_VECTORS.ADDRESS_0)
- assert.equals(rolodex.getAddresses('JaneSmith').length, 1)
- assert.equals(rolodex.getAddresses('JaneSmith')[0], NANO_TEST_VECTORS.ADDRESS_1)
- })
-
- test('should get a name from an address', async () => {
- const rolodex = new Rolodex()
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
- assert.equals(rolodex.getName(NANO_TEST_VECTORS.ADDRESS_0), 'JohnDoe')
- })
-
- test('should add three addresses to the same contact', async () => {
- const rolodex = new Rolodex()
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_1)
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_2)
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
- assert.equals(rolodex.getAddresses('JohnDoe').length, 3)
- assert.equals(rolodex.getAddresses('JohnDoe')[0], NANO_TEST_VECTORS.ADDRESS_1)
- assert.equals(rolodex.getAddresses('JohnDoe')[1], NANO_TEST_VECTORS.ADDRESS_2)
- assert.equals(rolodex.getAddresses('JohnDoe')[2], NANO_TEST_VECTORS.ADDRESS_0)
- })
-
- test('should update the name on an existing entry', async () => {
- const rolodex = new Rolodex()
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
- await rolodex.add('JaneSmith', NANO_TEST_VECTORS.ADDRESS_0)
- assert.equals(rolodex.getAddresses('JohnDoe').length, 0)
- assert.equals(rolodex.getAddresses('JaneSmith').length, 1)
- assert.equals(rolodex.getAddresses('JaneSmith')[0], NANO_TEST_VECTORS.ADDRESS_0)
- })
-
- test('should return empty address array for an unknown contact', async () => {
- const rolodex = new Rolodex()
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
- assert.equals(Array.isArray(rolodex.getAddresses('JaneSmith')), true)
- assert.equals(rolodex.getAddresses('JaneSmith').length, 0)
- })
-
- test('should return empty address array for blank contact names', () => {
- const rolodex = new Rolodex()
- //@ts-expect-error
- assert.equals(Array.isArray(rolodex.getAddresses(undefined)), true)
- //@ts-expect-error
- assert.equals(rolodex.getAddresses(undefined).length, 0)
- //@ts-expect-error
- assert.equals(Array.isArray(rolodex.getAddresses(null)), true)
- //@ts-expect-error
- assert.equals(rolodex.getAddresses(null).length, 0)
- assert.equals(Array.isArray(rolodex.getAddresses('')), true)
- assert.equals(rolodex.getAddresses('').length, 0)
- })
-
- test('should return null for an unknown address', async () => {
- const rolodex = new Rolodex()
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
- assert.ok(rolodex.getName(NANO_TEST_VECTORS.ADDRESS_1) === null)
- assert.ok(rolodex.getName(NANO_TEST_VECTORS.ADDRESS_1) !== undefined)
- })
-
- test('should return null for a blank address', async () => {
- const rolodex = new Rolodex()
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
- //@ts-expect-error
- assert.ok(rolodex.getName(undefined) === null)
- //@ts-expect-error
- assert.ok(rolodex.getName(undefined) !== undefined)
- //@ts-expect-error
- assert.ok(rolodex.getName(null) === null)
- //@ts-expect-error
- assert.ok(rolodex.getName(null) !== undefined)
- assert.ok(rolodex.getName('') === null)
- assert.ok(rolodex.getName('') !== undefined)
- })
+console.log('> rolodex valid contact management <')
+
+test('should create a rolodex and add two contacts', async () => {
+ const rolodex = new Rolodex()
+ assert.equals(rolodex.constructor, Rolodex)
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
+ await rolodex.add('JaneSmith', NANO_TEST_VECTORS.ADDRESS_1)
+
+ assert.equals(rolodex.getAllNames().length, 2)
+ assert.equals(rolodex.getAllNames()[0], 'JohnDoe')
+ assert.equals(rolodex.getAllNames()[1], 'JaneSmith')
+ assert.equals(rolodex.getAddresses('JohnDoe').length, 1)
+ assert.equals(rolodex.getAddresses('JohnDoe')[0], NANO_TEST_VECTORS.ADDRESS_0)
+ assert.equals(rolodex.getAddresses('JaneSmith').length, 1)
+ assert.equals(rolodex.getAddresses('JaneSmith')[0], NANO_TEST_VECTORS.ADDRESS_1)
+})
+
+test('should get a name from an address', async () => {
+ const rolodex = new Rolodex()
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
+ assert.equals(rolodex.getName(NANO_TEST_VECTORS.ADDRESS_0), 'JohnDoe')
+})
+
+test('should add three addresses to the same contact', async () => {
+ const rolodex = new Rolodex()
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_1)
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_2)
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
+ assert.equals(rolodex.getAddresses('JohnDoe').length, 3)
+ assert.equals(rolodex.getAddresses('JohnDoe')[0], NANO_TEST_VECTORS.ADDRESS_1)
+ assert.equals(rolodex.getAddresses('JohnDoe')[1], NANO_TEST_VECTORS.ADDRESS_2)
+ assert.equals(rolodex.getAddresses('JohnDoe')[2], NANO_TEST_VECTORS.ADDRESS_0)
+})
+
+test('should update the name on an existing entry', async () => {
+ const rolodex = new Rolodex()
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
+ await rolodex.add('JaneSmith', NANO_TEST_VECTORS.ADDRESS_0)
+ assert.equals(rolodex.getAddresses('JohnDoe').length, 0)
+ assert.equals(rolodex.getAddresses('JaneSmith').length, 1)
+ assert.equals(rolodex.getAddresses('JaneSmith')[0], NANO_TEST_VECTORS.ADDRESS_0)
+})
+
+test('should return empty address array for an unknown contact', async () => {
+ const rolodex = new Rolodex()
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
+ assert.equals(Array.isArray(rolodex.getAddresses('JaneSmith')), true)
+ assert.equals(rolodex.getAddresses('JaneSmith').length, 0)
+})
+
+test('should return empty address array for blank contact names', () => {
+ const rolodex = new Rolodex()
+ //@ts-expect-error
+ assert.equals(Array.isArray(rolodex.getAddresses(undefined)), true)
+ //@ts-expect-error
+ assert.equals(rolodex.getAddresses(undefined).length, 0)
+ //@ts-expect-error
+ assert.equals(Array.isArray(rolodex.getAddresses(null)), true)
+ //@ts-expect-error
+ assert.equals(rolodex.getAddresses(null).length, 0)
+ assert.equals(Array.isArray(rolodex.getAddresses('')), true)
+ assert.equals(rolodex.getAddresses('').length, 0)
+})
+
+test('should return null for an unknown address', async () => {
+ const rolodex = new Rolodex()
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
+ assert.ok(rolodex.getName(NANO_TEST_VECTORS.ADDRESS_1) === null)
+ assert.ok(rolodex.getName(NANO_TEST_VECTORS.ADDRESS_1) !== undefined)
+})
+
+test('should return null for a blank address', async () => {
+ const rolodex = new Rolodex()
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
+ //@ts-expect-error
+ assert.ok(rolodex.getName(undefined) === null)
+ //@ts-expect-error
+ assert.ok(rolodex.getName(undefined) !== undefined)
+ //@ts-expect-error
+ assert.ok(rolodex.getName(null) === null)
+ //@ts-expect-error
+ assert.ok(rolodex.getName(null) !== undefined)
+ assert.ok(rolodex.getName('') === null)
+ assert.ok(rolodex.getName('') !== undefined)
+})
+
+console.log('> rolodex exceptions <')
+
+test('should throw if adding no data', async () => {
+ const rolodex = new Rolodex()
+ //@ts-expect-error
+ await assert.rejects(rolodex.add())
})
-test('rolodex exceptions', async () => {
- test('should throw if adding no data', async () => {
- const rolodex = new Rolodex()
- //@ts-expect-error
- await assert.rejects(rolodex.add())
- })
-
- test('should throw if passed no address', async () => {
- const rolodex = new Rolodex()
- //@ts-expect-error
- await assert.rejects(rolodex.add('JohnDoe'))
- //@ts-expect-error
- await assert.rejects(rolodex.add('JohnDoe', undefined))
- //@ts-expect-error
- await assert.rejects(rolodex.add('JohnDoe', null))
- await assert.rejects(rolodex.add('JohnDoe', ''))
- })
-
- test('should throw if name is blank', async () => {
- const rolodex = new Rolodex()
- //@ts-expect-error
- await assert.rejects(rolodex.add(undefined, NANO_TEST_VECTORS.ADDRESS_0))
- //@ts-expect-error
- await assert.rejects(rolodex.add(null, NANO_TEST_VECTORS.ADDRESS_0))
- await assert.rejects(rolodex.add('', NANO_TEST_VECTORS.ADDRESS_0))
- })
+test('should throw if passed no address', async () => {
+ const rolodex = new Rolodex()
+ //@ts-expect-error
+ await assert.rejects(rolodex.add('JohnDoe'))
+ //@ts-expect-error
+ await assert.rejects(rolodex.add('JohnDoe', undefined))
+ //@ts-expect-error
+ await assert.rejects(rolodex.add('JohnDoe', null))
+ await assert.rejects(rolodex.add('JohnDoe', ''))
})
-test('rolodex data signature verification', async () => {
- const data = 'Test data'
- const signature = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, data)
+test('should throw if name is blank', async () => {
const rolodex = new Rolodex()
+ //@ts-expect-error
+ await assert.rejects(rolodex.add(undefined, NANO_TEST_VECTORS.ADDRESS_0))
+ //@ts-expect-error
+ await assert.rejects(rolodex.add(null, NANO_TEST_VECTORS.ADDRESS_0))
+ await assert.rejects(rolodex.add('', NANO_TEST_VECTORS.ADDRESS_0))
+})
+
+console.log('> rolodex data signature verification <')
+const data = 'Test data'
+const signature = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, data)
+const rolodex = new Rolodex()
+
+test('should verify valid data and signature', async () => {
+ await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
+ const result = await rolodex.verify('JohnDoe', signature, data)
+ assert.equals(result, true)
+})
- test('should verify valid data and signature', async () => {
- await rolodex.add('JohnDoe', NANO_TEST_VECTORS.ADDRESS_0)
- const result = await rolodex.verify('JohnDoe', signature, data)
- assert.equals(result, true)
- })
-
- test('should reject incorrect contact for signature', async () => {
- await rolodex.add('JaneSmith', NANO_TEST_VECTORS.ADDRESS_1)
- const result = await rolodex.verify('JaneSmith', signature, data)
- assert.equals(result, false)
- })
+test('should reject incorrect contact for signature', async () => {
+ await rolodex.add('JaneSmith', NANO_TEST_VECTORS.ADDRESS_1)
+ const result = await rolodex.verify('JaneSmith', signature, data)
+ assert.equals(result, false)
})
const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
let rpc
-//@ts-expect-error
+//@ts-ignore
var process = process || null
if (process) {
//@ts-expect-error
rpc = new Rpc(process?.env?.NODE_URL ?? '', process?.env?.API_KEY_NAME)
}
-skip('refreshing account info', async () => {
- test('should fetch balance, frontier, and representative', async () => {
- const accounts = await wallet.accounts()
- const account = accounts[0]
- await account.refresh(rpc)
-
- assert.equals(typeof account.balance, 'bigint')
- assert.notEqual(account.balance, undefined)
- assert.notEqual(account.balance, null)
- assert.notEqual(account.balance, '')
- assert.notEqual(account.balance && account.balance < 0, true)
-
- assert.equals(typeof account.frontier, 'string')
- assert.notEqual(account.frontier, undefined)
- assert.notEqual(account.frontier, null)
- assert.notEqual(account.frontier, '')
- assert.match(account.frontier ?? '', /^[0-9A-F]{64}$/i)
-
- assert.equals(account.representative && account.representative.constructor, Account)
- assert.notEqual(account.representative, undefined)
- assert.notEqual(account.representative, null)
- assert.notEqual(account.representative, '')
- assert.notEqual(account.representative?.address, undefined)
- assert.notEqual(account.representative?.address, null)
- assert.notEqual(account.representative?.address, '')
- })
-
- test('should throw when refreshing unopened account', async () => {
- const accounts = await wallet.accounts(0x7fffffff)
- const account = accounts[0]
- await assert.rejects(account.refresh(rpc),
- { message: 'Account not found' })
- })
-
- test('should throw when referencing invalid account index', async () => {
- await assert.rejects(wallet.accounts(0x80000000),
- { message: 'Invalid child key index 0x80000000' })
- })
-
- test('should throw with invalid node', async () => {
- const invalidNode = new Rpc('http://invalid.com')
- const accounts = await wallet.accounts()
- const account = accounts[0]
- await assert.rejects(account.refresh(invalidNode),
- { message: 'Account not found' })
- })
+console.log('refreshing account info')
+
+test('fetch balance, frontier, and representative', async () => {
+ const accounts = await wallet.accounts()
+ const account = accounts[0]
+ await account.refresh(rpc)
+
+ assert.equals(typeof account.balance, 'bigint')
+ assert.notEqual(account.balance, undefined)
+ assert.notEqual(account.balance, null)
+ assert.notEqual(account.balance, '')
+ assert.notEqual(account.balance && account.balance < 0, true)
+
+ assert.equals(typeof account.frontier, 'string')
+ assert.notEqual(account.frontier, undefined)
+ assert.notEqual(account.frontier, null)
+ assert.notEqual(account.frontier, '')
+ assert.match(account.frontier ?? '', /^[0-9A-F]{64}$/i)
+
+ assert.equals(account.representative && account.representative.constructor, Account)
+ assert.notEqual(account.representative, undefined)
+ assert.notEqual(account.representative, null)
+ assert.notEqual(account.representative, '')
+ assert.notEqual(account.representative?.address, undefined)
+ assert.notEqual(account.representative?.address, null)
+ assert.notEqual(account.representative?.address, '')
})
-skip('finding next unopened account', async () => {
- test('should return correct account from test vector', async () => {
- const account = await wallet.getNextNewAccount(rpc)
- assert.ok(account)
- assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
- assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
- })
-
- test('should return successfully for small batch size', async () => {
- const account = await wallet.getNextNewAccount(rpc, 1)
- assert.ok(account)
- assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
- assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
- })
-
- test('should return successfully for large batch size', async () => {
- const account = await wallet.getNextNewAccount(rpc, 100)
- assert.ok(account)
- assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
- assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
- })
-
- test('should throw on invalid node URL', async () => {
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount())
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount(null))
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount(1))
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount(''))
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount('foo'))
- })
-
- test('should throw on invalid batch size', async () => {
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount(rpc, null))
- await assert.rejects(wallet.getNextNewAccount(rpc, -1))
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount(rpc, ''))
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount(rpc, 'foo'))
- //@ts-expect-error
- await assert.rejects(wallet.getNextNewAccount(rpc, { 'foo': 'bar' }))
- })
+test('throw when refreshing unopened account', async () => {
+ const accounts = await wallet.accounts(0x7fffffff)
+ const account = accounts[0]
+ await assert.rejects(account.refresh(rpc),
+ { message: 'Account not found' })
})
-skip('refreshing wallet accounts', async () => {
- test('should get balance, frontier, and representative for one account', async () => {
- const accounts = await wallet.refresh(rpc)
- const account = accounts[0]
- assert.ok(account instanceof Account)
- assert.equals(typeof account.balance, 'bigint')
- assert.notEqual(account.frontier, undefined)
- assert.notEqual(account.frontier, null)
- assert.equals(typeof account.frontier, 'string')
- })
-
- test('should get balance, frontier, and representative for multiple accounts', async () => {
- const accounts = await wallet.refresh(rpc, 0, 2)
- assert.equals(accounts.length, 1)
- assert.ok(accounts[0] instanceof Account)
- })
-
- test('should handle failure gracefully', async () => {
- await assert.doesNotReject(wallet.refresh(rpc, 0, 20))
- })
+test('throw when referencing invalid account index', async () => {
+ await assert.rejects(wallet.accounts(0x80000000),
+ { message: 'Invalid child key index 0x80000000' })
+})
+
+test('throw with invalid node', async () => {
+ const invalidNode = new Rpc('http://invalid.com')
+ const accounts = await wallet.accounts()
+ const account = accounts[0]
+ await assert.rejects(account.refresh(invalidNode),
+ { message: 'Account not found' })
+})
+
+console.log('finding next unopened account')
+
+test('return correct account from test vector', async () => {
+ const account = await wallet.getNextNewAccount(rpc)
+ assert.ok(account)
+ assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
+ assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
+})
+
+test('return successfully for small batch size', async () => {
+ const account = await wallet.getNextNewAccount(rpc, 1)
+ assert.ok(account)
+ assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
+ assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
+})
+
+test('return successfully for large batch size', async () => {
+ const account = await wallet.getNextNewAccount(rpc, 100)
+ assert.ok(account)
+ assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
+ assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
+})
+
+test('should throw on invalid node URL', async () => {
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount())
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount(null))
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount(1))
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount(''))
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount('foo'))
+})
+
+test('should throw on invalid batch size', async () => {
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount(rpc, null))
+ await assert.rejects(wallet.getNextNewAccount(rpc, -1))
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount(rpc, ''))
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount(rpc, 'foo'))
+ //@ts-expect-error
+ await assert.rejects(wallet.getNextNewAccount(rpc, { 'foo': 'bar' }))
+})
+
+console.log('> refreshing wallet accounts <')
+
+skip('should get balance, frontier, and representative for one account', async () => {
+ const accounts = await wallet.refresh(rpc)
+ const account = accounts[0]
+ assert.ok(account instanceof Account)
+ assert.equals(typeof account.balance, 'bigint')
+ assert.notEqual(account.frontier, undefined)
+ assert.notEqual(account.frontier, null)
+ assert.equals(typeof account.frontier, 'string')
+})
+
+skip('should get balance, frontier, and representative for multiple accounts', async () => {
+ const accounts = await wallet.refresh(rpc, 0, 2)
+ assert.equals(accounts.length, 1)
+ assert.ok(accounts[0] instanceof Account)
+})
+
+skip('should handle failure gracefully', async () => {
+ await assert.doesNotReject(wallet.refresh(rpc, 0, 20))
})
import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
import { SendBlock, ReceiveBlock, ChangeBlock } from '#dist/main.js'\r
\r
-test('valid blocks', async () => {\r
- test('should not allow negative balances', async () => {\r
- assert.throws(() => {\r
- const block = new SendBlock(\r
- NANO_TEST_VECTORS.ADDRESS_0,\r
- '7000000000000000000000000000000',\r
- NANO_TEST_VECTORS.ADDRESS_1,\r
- '12000000000000000000000000000000',\r
- NANO_TEST_VECTORS.ADDRESS_2,\r
- '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D'\r
- )\r
- }, { message: 'Negative balance' })\r
- })\r
+console.log('> valid blocks <')\r
\r
- test('should allow zero balances', async () => {\r
+test('should not allow negative balances', async () => {\r
+ assert.throws(() => {\r
const block = new SendBlock(\r
NANO_TEST_VECTORS.ADDRESS_0,\r
- '9007199254740991',\r
+ '7000000000000000000000000000000',\r
NANO_TEST_VECTORS.ADDRESS_1,\r
- '9007199254740991',\r
+ '12000000000000000000000000000000',\r
NANO_TEST_VECTORS.ADDRESS_2,\r
'92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D'\r
)\r
- assert.notEqual(block.balance, 0)\r
- assert.equals(block.balance, BigInt(0))\r
- })\r
+ }, { message: 'Negative balance' })\r
+})\r
\r
- test('should subtract balance from SendBlock correctly', async () => {\r
- const block = new SendBlock(\r
- NANO_TEST_VECTORS.ADDRESS_0,\r
- '3000000000000000000000000000000',\r
- NANO_TEST_VECTORS.ADDRESS_1,\r
- '2000000000000000000000000000000',\r
- NANO_TEST_VECTORS.ADDRESS_2,\r
- '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D'\r
- )\r
- assert.equals(block.balance, 1000000000000000000000000000000n)\r
- })\r
+test('should allow zero balances', async () => {\r
+ const block = new SendBlock(\r
+ NANO_TEST_VECTORS.ADDRESS_0,\r
+ '9007199254740991',\r
+ NANO_TEST_VECTORS.ADDRESS_1,\r
+ '9007199254740991',\r
+ NANO_TEST_VECTORS.ADDRESS_2,\r
+ '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D'\r
+ )\r
+ assert.notEqual(block.balance, 0)\r
+ assert.equals(block.balance, BigInt(0))\r
+})\r
\r
- test('should add balance from ReceiveBlock correctly', async () => {\r
- const block = new ReceiveBlock(\r
- NANO_TEST_VECTORS.ADDRESS_0,\r
- '2000000000000000000000000000000',\r
- NANO_TEST_VECTORS.ADDRESS_1,\r
- '1000000000000000000000000000000',\r
- NANO_TEST_VECTORS.ADDRESS_2,\r
- '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D'\r
- )\r
- assert.equals(block.balance, 3000000000000000000000000000000n)\r
- })\r
+test('should subtract balance from SendBlock correctly', async () => {\r
+ const block = new SendBlock(\r
+ NANO_TEST_VECTORS.ADDRESS_0,\r
+ '3000000000000000000000000000000',\r
+ NANO_TEST_VECTORS.ADDRESS_1,\r
+ '2000000000000000000000000000000',\r
+ NANO_TEST_VECTORS.ADDRESS_2,\r
+ '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D'\r
+ )\r
+ assert.equals(block.balance, 1000000000000000000000000000000n)\r
})\r
\r
-test('block signing tests using official test vectors', async () => {\r
- test('should create a valid signature for an open block', async () => {\r
- const block = new ReceiveBlock(\r
- NANO_TEST_VECTORS.OPEN_BLOCK.account,\r
- '0',\r
- NANO_TEST_VECTORS.OPEN_BLOCK.link,\r
- NANO_TEST_VECTORS.OPEN_BLOCK.balance,\r
- NANO_TEST_VECTORS.OPEN_BLOCK.representative,\r
- NANO_TEST_VECTORS.OPEN_BLOCK.previous,\r
- NANO_TEST_VECTORS.OPEN_BLOCK.work\r
- )\r
- await block.sign(NANO_TEST_VECTORS.OPEN_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.OPEN_BLOCK.hash)\r
- assert.equals(block.signature, NANO_TEST_VECTORS.OPEN_BLOCK.signature)\r
- })\r
+test('should add balance from ReceiveBlock correctly', async () => {\r
+ const block = new ReceiveBlock(\r
+ NANO_TEST_VECTORS.ADDRESS_0,\r
+ '2000000000000000000000000000000',\r
+ NANO_TEST_VECTORS.ADDRESS_1,\r
+ '1000000000000000000000000000000',\r
+ NANO_TEST_VECTORS.ADDRESS_2,\r
+ '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D'\r
+ )\r
+ assert.equals(block.balance, 3000000000000000000000000000000n)\r
+})\r
\r
- test('should create a valid signature for a receive block', async () => {\r
- const block = new ReceiveBlock(\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.account,\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.balance,\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.link,\r
- '0',\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.representative,\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.previous,\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.work\r
- )\r
- await block.sign(NANO_TEST_VECTORS.RECEIVE_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.RECEIVE_BLOCK.hash)\r
- assert.equals(block.signature, NANO_TEST_VECTORS.RECEIVE_BLOCK.signature)\r
- })\r
+console.log('> block signing tests using official test vectors <')\r
\r
- test('should create a valid signature for a receive block without work', async () => {\r
- const block = new ReceiveBlock(\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.account,\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.balance,\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.link,\r
- '0',\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.representative,\r
- NANO_TEST_VECTORS.RECEIVE_BLOCK.previous\r
- )\r
- await block.sign(NANO_TEST_VECTORS.RECEIVE_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.RECEIVE_BLOCK.hash)\r
- assert.equals(block.signature, NANO_TEST_VECTORS.RECEIVE_BLOCK.signature)\r
- assert.equals(block.work, '')\r
- })\r
+test('should create a valid signature for an open block', async () => {\r
+ const block = new ReceiveBlock(\r
+ NANO_TEST_VECTORS.OPEN_BLOCK.account,\r
+ '0',\r
+ NANO_TEST_VECTORS.OPEN_BLOCK.link,\r
+ NANO_TEST_VECTORS.OPEN_BLOCK.balance,\r
+ NANO_TEST_VECTORS.OPEN_BLOCK.representative,\r
+ NANO_TEST_VECTORS.OPEN_BLOCK.previous,\r
+ NANO_TEST_VECTORS.OPEN_BLOCK.work\r
+ )\r
+ await block.sign(NANO_TEST_VECTORS.OPEN_BLOCK.key)\r
+ assert.equals(await block.hash(), NANO_TEST_VECTORS.OPEN_BLOCK.hash)\r
+ assert.equals(block.signature, NANO_TEST_VECTORS.OPEN_BLOCK.signature)\r
+})\r
\r
- test('should create a valid signature for a send block', async () => {\r
- const block = new SendBlock(\r
- NANO_TEST_VECTORS.SEND_BLOCK.account,\r
- NANO_TEST_VECTORS.SEND_BLOCK.balance,\r
- NANO_TEST_VECTORS.SEND_BLOCK.link,\r
- '0',\r
- NANO_TEST_VECTORS.SEND_BLOCK.representative,\r
- NANO_TEST_VECTORS.SEND_BLOCK.previous,\r
- NANO_TEST_VECTORS.SEND_BLOCK.work\r
- )\r
- await block.sign(NANO_TEST_VECTORS.SEND_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.SEND_BLOCK.hash)\r
- assert.equals(block.signature, NANO_TEST_VECTORS.SEND_BLOCK.signature)\r
- })\r
+test('should create a valid signature for a receive block', async () => {\r
+ const block = new ReceiveBlock(\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.account,\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.balance,\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.link,\r
+ '0',\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.representative,\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.previous,\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.work\r
+ )\r
+ await block.sign(NANO_TEST_VECTORS.RECEIVE_BLOCK.key)\r
+ assert.equals(await block.hash(), NANO_TEST_VECTORS.RECEIVE_BLOCK.hash)\r
+ assert.equals(block.signature, NANO_TEST_VECTORS.RECEIVE_BLOCK.signature)\r
+})\r
\r
- test('should create a valid signature for a send block without work', async () => {\r
- const block = new SendBlock(\r
- NANO_TEST_VECTORS.SEND_BLOCK.account,\r
- NANO_TEST_VECTORS.SEND_BLOCK.balance,\r
- NANO_TEST_VECTORS.SEND_BLOCK.link,\r
- '0',\r
- NANO_TEST_VECTORS.SEND_BLOCK.representative,\r
- NANO_TEST_VECTORS.SEND_BLOCK.previous\r
- )\r
- await block.sign(NANO_TEST_VECTORS.SEND_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.SEND_BLOCK.hash)\r
- assert.equals(block.signature, NANO_TEST_VECTORS.SEND_BLOCK.signature)\r
- assert.equals(block.work, '')\r
- })\r
+test('should create a valid signature for a receive block without work', async () => {\r
+ const block = new ReceiveBlock(\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.account,\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.balance,\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.link,\r
+ '0',\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.representative,\r
+ NANO_TEST_VECTORS.RECEIVE_BLOCK.previous\r
+ )\r
+ await block.sign(NANO_TEST_VECTORS.RECEIVE_BLOCK.key)\r
+ assert.equals(await block.hash(), NANO_TEST_VECTORS.RECEIVE_BLOCK.hash)\r
+ assert.equals(block.signature, NANO_TEST_VECTORS.RECEIVE_BLOCK.signature)\r
+ assert.equals(block.work, '')\r
+})\r
\r
- test('should create a valid signature for a change rep block', async () => {\r
- const work = '0000000000000000'\r
- const block = new ChangeBlock(\r
- 'nano_3igf8hd4sjshoibbbkeitmgkp1o6ug4xads43j6e4gqkj5xk5o83j8ja9php',\r
- '3000000000000000000000000000000',\r
- 'nano_1anrzcuwe64rwxzcco8dkhpyxpi8kd7zsjc1oeimpc3ppca4mrjtwnqposrs',\r
- '128106287002E595F479ACD615C818117FCB3860EC112670557A2467386249D4',\r
- work,\r
- )\r
- await block.sign('781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3') // Did not find a private key at nano docs for this address\r
- assert.equals(block.signature?.toUpperCase(), 'A3C3C66D6519CBC0A198E56855942DEACC6EF741021A1B11279269ADC587DE1DA53CD478B8A47553231104CF24D742E1BB852B0546B87038C19BAE20F9082B0D')\r
- assert.equals(block.work, work)\r
- })\r
+test('should create a valid signature for a send block', async () => {\r
+ const block = new SendBlock(\r
+ NANO_TEST_VECTORS.SEND_BLOCK.account,\r
+ NANO_TEST_VECTORS.SEND_BLOCK.balance,\r
+ NANO_TEST_VECTORS.SEND_BLOCK.link,\r
+ '0',\r
+ NANO_TEST_VECTORS.SEND_BLOCK.representative,\r
+ NANO_TEST_VECTORS.SEND_BLOCK.previous,\r
+ NANO_TEST_VECTORS.SEND_BLOCK.work\r
+ )\r
+ await block.sign(NANO_TEST_VECTORS.SEND_BLOCK.key)\r
+ assert.equals(await block.hash(), NANO_TEST_VECTORS.SEND_BLOCK.hash)\r
+ assert.equals(block.signature, NANO_TEST_VECTORS.SEND_BLOCK.signature)\r
+})\r
\r
- test('should create a valid signature for a change rep block without work', async () => {\r
- const block = new ChangeBlock(\r
- NANO_TEST_VECTORS.ADDRESS_0,\r
- '0',\r
- 'nano_34amtofxstsfyqcgphp8piij9u33widykq9wbz6ysjpxhbgmqu8btu1eexer',\r
- 'F3C1D7B6EE97DA09D4C00538CEA93CBA5F74D78FD3FBE71347D2DFE7E53DF327'\r
- )\r
- await block.sign(NANO_TEST_VECTORS.PRIVATE_0)\r
- assert.equals(block.signature?.toUpperCase(), '2BD2F905E74B5BEE3E2277CED1D1E3F7535E5286B6E22F7B08A814AA9E5C4E1FEA69B61D60B435ADC2CE756E6EE5F5BE7EC691FE87E024A0B22A3D980CA5B305')\r
- assert.equals(block.work, '')\r
- })\r
+test('should create a valid signature for a send block without work', async () => {\r
+ const block = new SendBlock(\r
+ NANO_TEST_VECTORS.SEND_BLOCK.account,\r
+ NANO_TEST_VECTORS.SEND_BLOCK.balance,\r
+ NANO_TEST_VECTORS.SEND_BLOCK.link,\r
+ '0',\r
+ NANO_TEST_VECTORS.SEND_BLOCK.representative,\r
+ NANO_TEST_VECTORS.SEND_BLOCK.previous\r
+ )\r
+ await block.sign(NANO_TEST_VECTORS.SEND_BLOCK.key)\r
+ assert.equals(await block.hash(), NANO_TEST_VECTORS.SEND_BLOCK.hash)\r
+ assert.equals(block.signature, NANO_TEST_VECTORS.SEND_BLOCK.signature)\r
+ assert.equals(block.work, '')\r
+})\r
+\r
+test('should create a valid signature for a change rep block', async () => {\r
+ const work = '0000000000000000'\r
+ const block = new ChangeBlock(\r
+ 'nano_3igf8hd4sjshoibbbkeitmgkp1o6ug4xads43j6e4gqkj5xk5o83j8ja9php',\r
+ '3000000000000000000000000000000',\r
+ 'nano_1anrzcuwe64rwxzcco8dkhpyxpi8kd7zsjc1oeimpc3ppca4mrjtwnqposrs',\r
+ '128106287002E595F479ACD615C818117FCB3860EC112670557A2467386249D4',\r
+ work,\r
+ )\r
+ await block.sign('781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3') // Did not find a private key at nano docs for this address\r
+ assert.equals(block.signature?.toUpperCase(), 'A3C3C66D6519CBC0A198E56855942DEACC6EF741021A1B11279269ADC587DE1DA53CD478B8A47553231104CF24D742E1BB852B0546B87038C19BAE20F9082B0D')\r
+ assert.equals(block.work, work)\r
+})\r
+\r
+test('should create a valid signature for a change rep block without work', async () => {\r
+ const block = new ChangeBlock(\r
+ NANO_TEST_VECTORS.ADDRESS_0,\r
+ '0',\r
+ 'nano_34amtofxstsfyqcgphp8piij9u33widykq9wbz6ysjpxhbgmqu8btu1eexer',\r
+ 'F3C1D7B6EE97DA09D4C00538CEA93CBA5F74D78FD3FBE71347D2DFE7E53DF327'\r
+ )\r
+ await block.sign(NANO_TEST_VECTORS.PRIVATE_0)\r
+ assert.equals(block.signature?.toUpperCase(), '2BD2F905E74B5BEE3E2277CED1D1E3F7535E5286B6E22F7B08A814AA9E5C4E1FEA69B61D60B435ADC2CE756E6EE5F5BE7EC691FE87E024A0B22A3D980CA5B305')\r
+ assert.equals(block.work, '')\r
})\r
const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
let rpc\r
-//@ts-expect-error\r
+//@ts-ignore\r
var process = process || null\r
if (process) {\r
//@ts-expect-error\r
rpc = new Rpc(process?.env?.NODE_URL ?? '', process?.env?.API_KEY_NAME)\r
}\r
\r
-test('unit conversion tests', async () => {\r
- test('should convert nano to raw', async () => {\r
- const result = await Tools.convert('1', 'NANO', 'RAW')\r
- assert.equals(result, '1000000000000000000000000000000')\r
- })\r
-\r
- test('should convert raw to nano', async () => {\r
- const result = await Tools.convert('1000000000000000000000000000000', 'RAW', 'NANO')\r
- assert.equals(result, '1')\r
- })\r
-\r
- test('should convert 1 raw to 10^-29 nano', async () => {\r
- const result = await Tools.convert('1', 'RAW', 'NANO')\r
- assert.equals(result, '.000000000000000000000000000001')\r
- })\r
-\r
- test('should ignore leading and trailing zeros', async () => {\r
- const result = await Tools.convert('0011002200.0033004400', 'nano', 'nano')\r
- assert.equals(result, '11002200.00330044')\r
- })\r
-\r
- test('should convert raw to nyano', async () => {\r
- const result = await Tools.convert(RAW_MAX, 'RAW', 'NYANO')\r
- assert.equals(result, '340282366920938.463463374607431768211455')\r
- })\r
-\r
- test('should convert case-insensitive nyano to raw', async () => {\r
- const result = await Tools.convert('0.000000000000000123456789', 'nYaNo', 'rAw')\r
- assert.equals(result, '123456789')\r
- })\r
-\r
- test('should convert nano to pico', async () => {\r
- const result = await Tools.convert('123.456', 'nano', 'pico')\r
- assert.equals(result, '123456')\r
- })\r
-\r
- test('should convert knano to pico', async () => {\r
- const result = await Tools.convert('123.456', 'nano', 'pico')\r
- assert.equals(result, '123456')\r
- })\r
-\r
- test('should throw if amount exceeds raw max', async () => {\r
- await assert.rejects(Tools.convert(RAW_MAX, 'NANO', 'RAW'),\r
- { message: 'Amount exceeds Nano limits' })\r
- })\r
-\r
- test('should throw if amount exceeds raw min', async () => {\r
- await assert.rejects(Tools.convert('0.1', 'RAW', 'NANO'),\r
- { message: 'Amount must be at least 1 raw' })\r
- })\r
-\r
- test('should throw if amount is blank', async () => {\r
- await assert.rejects(Tools.convert('', 'RAW', 'NANO'),\r
- { message: 'Invalid amount' })\r
- })\r
-\r
- test('should throw if amount has non-digit characters', async () => {\r
- await assert.rejects(Tools.convert('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 'RAW', 'NANO'),\r
- { message: 'Invalid amount' })\r
- })\r
-})\r
-\r
-test('signature tests', async () => {\r
- test('should sign data with a single parameter', async () => {\r
- const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, 'miro@metsanheimo.fi')\r
- assert.equals(result, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C')\r
- })\r
-\r
- test('should sign data with multiple parameters', async () => {\r
- const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, 'miro@metsanheimo.fi', 'somePassword')\r
- assert.equals(result, 'BB534F9B469AF451B1941FFEF8EE461FC5D284B5D393140900C6E13A65EF08D0AE2BC77131EE182922F66C250C7237A83878160457D5C39A70E55F7FCE925804')\r
- })\r
-\r
- test('should verify a signature using the public key', async () => {\r
- const result = await Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'miro@metsanheimo.fi')\r
- assert.equals(result, true)\r
-\r
- const result2 = await Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'mir@metsanheimo.fi')\r
- assert.equals(result2, false)\r
-\r
- const result3 = await Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'AECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'miro@metsanheimo.fi')\r
- assert.equals(result3, false)\r
- })\r
-\r
- test('should verify a block using the public key', async () => {\r
- const accounts = await wallet.accounts()\r
- const account = accounts[0]\r
- const sendBlock = new SendBlock(\r
- account.address,\r
- '5618869000000000000000000000000',\r
- 'nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p',\r
- '2000000000000000000000000000000',\r
- 'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou',\r
- '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D',\r
- )\r
- await sendBlock.sign(account.privateKey ?? '')\r
- const valid = await sendBlock.verify(account.publicKey)\r
- assert.equals(valid, true)\r
- })\r
-\r
- test('should reject a block using the wrong public key', async () => {\r
- const accounts = await wallet.accounts()\r
- const account = accounts[0]\r
- const sendBlock = new SendBlock(\r
- account.address,\r
- '5618869000000000000000000000000',\r
- 'nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p',\r
- '2000000000000000000000000000000',\r
- 'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou',\r
- '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D',\r
- )\r
- await sendBlock.sign(account.privateKey ?? '')\r
-\r
- sendBlock.account = Account.fromAddress('nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p')\r
- const valid = await sendBlock.verify(account.publicKey)\r
- assert.equals(valid, false)\r
- })\r
-})\r
-\r
-test('sweeper', async () => {\r
- test('throws without required parameters', async () => {\r
- //@ts-expect-error\r
- await assert.rejects(Tools.sweep(),\r
- 'Missing required sweep arguments')\r
- })\r
-\r
- skip('fails gracefully for ineligible accounts', async () => {\r
- const results = await Tools.sweep(rpc, wallet, NANO_TEST_VECTORS.ADDRESS_1)\r
- assert.ok(results)\r
- assert.equals(results.length, 1)\r
- })\r
+console.log('> unit conversion tests <')\r
+\r
+test('should convert nano to raw', async () => {\r
+ const result = await Tools.convert('1', 'NANO', 'RAW')\r
+ assert.equals(result, '1000000000000000000000000000000')\r
+})\r
+\r
+test('should convert raw to nano', async () => {\r
+ const result = await Tools.convert('1000000000000000000000000000000', 'RAW', 'NANO')\r
+ assert.equals(result, '1')\r
+})\r
+\r
+test('should convert 1 raw to 10^-29 nano', async () => {\r
+ const result = await Tools.convert('1', 'RAW', 'NANO')\r
+ assert.equals(result, '.000000000000000000000000000001')\r
+})\r
+\r
+test('should ignore leading and trailing zeros', async () => {\r
+ const result = await Tools.convert('0011002200.0033004400', 'nano', 'nano')\r
+ assert.equals(result, '11002200.00330044')\r
+})\r
+\r
+test('should convert raw to nyano', async () => {\r
+ const result = await Tools.convert(RAW_MAX, 'RAW', 'NYANO')\r
+ assert.equals(result, '340282366920938.463463374607431768211455')\r
+})\r
+\r
+test('should convert case-insensitive nyano to raw', async () => {\r
+ const result = await Tools.convert('0.000000000000000123456789', 'nYaNo', 'rAw')\r
+ assert.equals(result, '123456789')\r
+})\r
+\r
+test('should convert nano to pico', async () => {\r
+ const result = await Tools.convert('123.456', 'nano', 'pico')\r
+ assert.equals(result, '123456')\r
+})\r
+\r
+test('should convert knano to pico', async () => {\r
+ const result = await Tools.convert('123.456', 'nano', 'pico')\r
+ assert.equals(result, '123456')\r
+})\r
+\r
+test('should throw if amount exceeds raw max', async () => {\r
+ await assert.rejects(Tools.convert(RAW_MAX, 'NANO', 'RAW'),\r
+ { message: 'Amount exceeds Nano limits' })\r
+})\r
+\r
+test('should throw if amount exceeds raw min', async () => {\r
+ await assert.rejects(Tools.convert('0.1', 'RAW', 'NANO'),\r
+ { message: 'Amount must be at least 1 raw' })\r
+})\r
+\r
+test('should throw if amount is blank', async () => {\r
+ await assert.rejects(Tools.convert('', 'RAW', 'NANO'),\r
+ { message: 'Invalid amount' })\r
+})\r
+\r
+test('should throw if amount has non-digit characters', async () => {\r
+ await assert.rejects(Tools.convert('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 'RAW', 'NANO'),\r
+ { message: 'Invalid amount' })\r
+})\r
+\r
+console.log('> signature tests <')\r
+\r
+test('should sign data with a single parameter', async () => {\r
+ const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, 'miro@metsanheimo.fi')\r
+ assert.equals(result, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C')\r
+})\r
+\r
+test('should sign data with multiple parameters', async () => {\r
+ const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, 'miro@metsanheimo.fi', 'somePassword')\r
+ assert.equals(result, 'BB534F9B469AF451B1941FFEF8EE461FC5D284B5D393140900C6E13A65EF08D0AE2BC77131EE182922F66C250C7237A83878160457D5C39A70E55F7FCE925804')\r
+})\r
+\r
+test('should verify a signature using the public key', async () => {\r
+ const result = await Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'miro@metsanheimo.fi')\r
+ assert.equals(result, true)\r
+\r
+ const result2 = await Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'mir@metsanheimo.fi')\r
+ assert.equals(result2, false)\r
+\r
+ const result3 = await Tools.verify(NANO_TEST_VECTORS.PUBLIC_0, 'AECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C', 'miro@metsanheimo.fi')\r
+ assert.equals(result3, false)\r
+})\r
+\r
+test('should verify a block using the public key', async () => {\r
+ const accounts = await wallet.accounts()\r
+ const account = accounts[0]\r
+ const sendBlock = new SendBlock(\r
+ account.address,\r
+ '5618869000000000000000000000000',\r
+ 'nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p',\r
+ '2000000000000000000000000000000',\r
+ 'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou',\r
+ '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D',\r
+ )\r
+ await sendBlock.sign(account.privateKey ?? '')\r
+ const valid = await sendBlock.verify(account.publicKey)\r
+ assert.equals(valid, true)\r
+})\r
+\r
+test('should reject a block using the wrong public key', async () => {\r
+ const accounts = await wallet.accounts()\r
+ const account = accounts[0]\r
+ const sendBlock = new SendBlock(\r
+ account.address,\r
+ '5618869000000000000000000000000',\r
+ 'nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p',\r
+ '2000000000000000000000000000000',\r
+ 'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou',\r
+ '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D',\r
+ )\r
+ await sendBlock.sign(account.privateKey ?? '')\r
+\r
+ sendBlock.account = Account.fromAddress('nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p')\r
+ const valid = await sendBlock.verify(account.publicKey)\r
+ assert.equals(valid, false)\r
+})\r
+\r
+test('sweeper throws without required parameters', async () => {\r
+ //@ts-expect-error\r
+ await assert.rejects(Tools.sweep(),\r
+ 'Missing required sweep arguments')\r
+})\r
+\r
+skip('sweeper fails gracefully for ineligible accounts', async () => {\r
+ const results = await Tools.sweep(rpc, wallet, NANO_TEST_VECTORS.ADDRESS_1)\r
+ assert.ok(results)\r
+ assert.equals(results.length, 1)\r
})\r