await test('throw on negative balances', async () => {\r
assert.throws(() => {\r
new Block(ADDRESS_0, '7000000000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', ADDRESS_2)\r
- .send('12000000000000000000000000000000')\r
- .to(ADDRESS_1)\r
+ .send(ADDRESS_1, '12000000000000000000000000000000')\r
}, { message: 'Negative balance' })\r
})\r
\r
await test('allow zero balances', async () => {\r
const block = new Block(\r
ADDRESS_0, '9007199254740991', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', ADDRESS_2)\r
- .send('9007199254740991')\r
- .to(ADDRESS_1)\r
+ .send(ADDRESS_1, '9007199254740991')\r
assert.notEqual(block.balance, 0)\r
assert.equal(block.balance, BigInt(0))\r
})\r
await test('subtract balance from SendBlock correctly', async () => {\r
const block = new Block(\r
ADDRESS_0, '3000000000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', ADDRESS_2)\r
- .send('2000000000000000000000000000000')\r
- .to(ADDRESS_1)\r
+ .send(ADDRESS_1, '2000000000000000000000000000000')\r
assert.equal(block.balance, 1000000000000000000000000000000n)\r
})\r
\r
await test('add balance from ReceiveBlock correctly', async () => {\r
const block = new Block(ADDRESS_0, '2000000000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', ADDRESS_2)\r
- .receive('1000000000000000000000000000000')\r
- .from(RECEIVE_BLOCK.link)\r
+ .receive(RECEIVE_BLOCK.link, '1000000000000000000000000000000')\r
assert.equal(block.balance, 3000000000000000000000000000000n)\r
})\r
\r
await test('fail to receive from address, link must be block hash', async () => {\r
assert.throws(new Block(ADDRESS_0, '2000000000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', ADDRESS_2)\r
- .receive('1000000000000000000000000000000')\r
- .from(ADDRESS_1))\r
+ .receive(ADDRESS_1, '1000000000000000000000000000000'))\r
})\r
}),\r
\r
await assert.resolves(wallet.unlock(PASSWORD))\r
\r
const block = new Block(ADDRESS_0, '0', OPEN_BLOCK.previous, OPEN_BLOCK.representative)\r
- .receive(OPEN_BLOCK.balance)\r
- .from(OPEN_BLOCK.link)\r
+ .receive(OPEN_BLOCK.link, OPEN_BLOCK.balance)\r
const signature = await wallet.sign(0, block, 'hex')\r
assert.equal(block.signature, signature)\r
\r
await test('fail to sign open block with wallet when locked', async () => {\r
const wallet = await Wallet.import('BIP-44', PASSWORD, BIP39_SEED)\r
const block = new Block(OPEN_BLOCK.account, '0', OPEN_BLOCK.previous, OPEN_BLOCK.representative)\r
- .receive(OPEN_BLOCK.balance)\r
- .from(OPEN_BLOCK.link)\r
+ .receive(OPEN_BLOCK.link, OPEN_BLOCK.balance)\r
\r
await assert.rejects(wallet.sign(0, block))\r
assert.equal(block.hash, OPEN_BLOCK.hash)\r
})\r
\r
await test('sign open block with private key', async () => {\r
- const block = await (new Block(OPEN_BLOCK.account, '0', OPEN_BLOCK.previous, OPEN_BLOCK.representative)\r
- .receive(OPEN_BLOCK.balance)\r
- .from(OPEN_BLOCK.link))\r
+ const block = await new Block(OPEN_BLOCK.account, '0', OPEN_BLOCK.previous, OPEN_BLOCK.representative)\r
+ .receive(OPEN_BLOCK.link, OPEN_BLOCK.balance)\r
.pow(OPEN_BLOCK.work)\r
await block.sign(OPEN_BLOCK.key)\r
assert.equal(block.hash, OPEN_BLOCK.hash)\r
})\r
\r
await test('sign receive block', async () => {\r
- const block = await (new Block(RECEIVE_BLOCK.account, RECEIVE_BLOCK.balance, RECEIVE_BLOCK.previous, RECEIVE_BLOCK.representative)\r
- .receive(0)\r
- .from(RECEIVE_BLOCK.link))\r
+ const block = await new Block(RECEIVE_BLOCK.account, RECEIVE_BLOCK.balance, RECEIVE_BLOCK.previous, RECEIVE_BLOCK.representative)\r
+ .receive(RECEIVE_BLOCK.link, 0)\r
.pow(RECEIVE_BLOCK.work)\r
await block.sign(RECEIVE_BLOCK.key)\r
assert.equal(block.hash, RECEIVE_BLOCK.hash)\r
\r
await test('sign receive block without work', async () => {\r
const block = new Block(RECEIVE_BLOCK.account, RECEIVE_BLOCK.balance, RECEIVE_BLOCK.previous, RECEIVE_BLOCK.representative)\r
- .receive('0')\r
- .from(RECEIVE_BLOCK.link)\r
+ .receive(RECEIVE_BLOCK.link, '0')\r
await block.sign(RECEIVE_BLOCK.key)\r
assert.equal(block.hash, RECEIVE_BLOCK.hash)\r
assert.equal(block.signature, RECEIVE_BLOCK.signature)\r
})\r
\r
await test('sign send block', async () => {\r
- const block = await (new Block(SEND_BLOCK.account, SEND_BLOCK.balance, SEND_BLOCK.previous, SEND_BLOCK.representative)\r
- .send('0')\r
- .to(SEND_BLOCK.link))\r
+ const block = await new Block(SEND_BLOCK.account, SEND_BLOCK.balance, SEND_BLOCK.previous, SEND_BLOCK.representative)\r
+ .send(SEND_BLOCK.link, '0')\r
.pow(SEND_BLOCK.work)\r
await block.sign(SEND_BLOCK.key)\r
assert.equal(block.hash, SEND_BLOCK.hash)\r
})\r
\r
await test('sign send block without work', async () => {\r
- const block = new Block(SEND_BLOCK.account, SEND_BLOCK.balance, SEND_BLOCK.previous, SEND_BLOCK.representative)\r
- .send(0n)\r
- .to(SEND_BLOCK.link)\r
- await block.sign(SEND_BLOCK.key)\r
- //@ts-expect-error\r
- assert.equal(block.hash.map(b => b.toString(16).padStart(2, '0')).join(''), SEND_BLOCK.hash)\r
+ const block = await new Block(SEND_BLOCK.account, SEND_BLOCK.balance, SEND_BLOCK.previous, SEND_BLOCK.representative)\r
+ .send(SEND_BLOCK.link, 0n)\r
+ .sign(SEND_BLOCK.key)\r
+\r
+ assert.equal(block.hash, SEND_BLOCK.hash)\r
assert.equal(block.signature, SEND_BLOCK.signature)\r
assert.equal(block.work, '')\r
})\r
\r
await test('sign change rep block', async () => {\r
const work = '0000000000000000'\r
- const block = await (new Block('nano_3igf8hd4sjshoibbbkeitmgkp1o6ug4xads43j6e4gqkj5xk5o83j8ja9php', '3000000000000000000000000000000', '128106287002E595F479ACD615C818117FCB3860EC112670557A2467386249D4')\r
- .change()\r
- .to('nano_1anrzcuwe64rwxzcco8dkhpyxpi8kd7zsjc1oeimpc3ppca4mrjtwnqposrs'))\r
+ const block = await new Block('nano_3igf8hd4sjshoibbbkeitmgkp1o6ug4xads43j6e4gqkj5xk5o83j8ja9php', '3000000000000000000000000000000', '128106287002E595F479ACD615C818117FCB3860EC112670557A2467386249D4')\r
+ .change('nano_1anrzcuwe64rwxzcco8dkhpyxpi8kd7zsjc1oeimpc3ppca4mrjtwnqposrs')\r
.pow(work)\r
await block.sign('781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3') // Did not find a private key at nano docs for this address\r
assert.equal(block.signature?.toUpperCase(), 'A3C3C66D6519CBC0A198E56855942DEACC6EF741021A1B11279269ADC587DE1DA53CD478B8A47553231104CF24D742E1BB852B0546B87038C19BAE20F9082B0D')\r
})\r
\r
await test('sign change rep block without work', async () => {\r
- const block = new Block(ADDRESS_0, '0', 'F3C1D7B6EE97DA09D4C00538CEA93CBA5F74D78FD3FBE71347D2DFE7E53DF327')\r
- .change()\r
- .to('nano_34amtofxstsfyqcgphp8piij9u33widykq9wbz6ysjpxhbgmqu8btu1eexer')\r
- await block.sign(PRIVATE_0)\r
+ const block = await new Block(ADDRESS_0, '0', 'F3C1D7B6EE97DA09D4C00538CEA93CBA5F74D78FD3FBE71347D2DFE7E53DF327')\r
+ .change('nano_34amtofxstsfyqcgphp8piij9u33widykq9wbz6ysjpxhbgmqu8btu1eexer')\r
+ .sign(PRIVATE_0)\r
assert.equal(block.signature?.toUpperCase(), '2BD2F905E74B5BEE3E2277CED1D1E3F7535E5286B6E22F7B08A814AA9E5C4E1FEA69B61D60B435ADC2CE756E6EE5F5BE7EC691FE87E024A0B22A3D980CA5B305')\r
assert.equal(block.work, '')\r
})\r
\r
await test('fail to sign open block without key', async () => {\r
- const block = await (new Block(OPEN_BLOCK.account, '0', OPEN_BLOCK.previous, OPEN_BLOCK.representative)\r
- .receive(OPEN_BLOCK.balance)\r
- .from(OPEN_BLOCK.link))\r
+ const block = await new Block(OPEN_BLOCK.account, '0', OPEN_BLOCK.previous, OPEN_BLOCK.representative)\r
+ .receive(OPEN_BLOCK.link, OPEN_BLOCK.balance)\r
.pow(OPEN_BLOCK.work)\r
\r
//@ts-expect-error\r
*/
let Account
/**
-* @type {typeof import('../dist/types.d.ts').Ledger}
+* @type {typeof import('../dist/types.d.ts').Block}
*/
-let Ledger
+let Block
/**
-* @type {typeof import('../dist/types.d.ts').ReceiveBlock}
+* @type {typeof import('../dist/types.d.ts').Ledger}
*/
-let ReceiveBlock
+let Ledger
/**
* @type {typeof import('../dist/types.d.ts').Rpc}
*/
let Rpc
-/**
-* @type {typeof import('../dist/types.d.ts').SendBlock}
-*/
-let SendBlock
if (isNode) {
- ({ Account, Ledger, ReceiveBlock, Rpc, SendBlock } = await import('../dist/nodejs.min.js'))
+ ({ Account, Block, Ledger, Rpc } = await import('../dist/nodejs.min.js'))
} else {
- ({ Account, Ledger, ReceiveBlock, Rpc, SendBlock } = await import('../dist/browser.min.js'))
+ ({ Account, Block, Ledger, Rpc } = await import('../dist/browser.min.js'))
}
const rpc = new Rpc(env.NODE_URL ?? '', env.API_KEY_NAME)
/* node:coverage disable */
suite('Ledger hardware wallet', { skip: false || isNode || Ledger.isUnsupported }, async () => {
+ const { RECEIVE_BLOCK, SEND_BLOCK } = NANO_TEST_VECTORS
+
let wallet, account, openBlock, sendBlock, receiveBlock
await test('request permissions', async () => {
})
await test('sign open block from block', async () => {
- openBlock = new ReceiveBlock(
- account,
- '0',
- NANO_TEST_VECTORS.RECEIVE_BLOCK.link,
- NANO_TEST_VECTORS.RECEIVE_BLOCK.balance,
- NANO_TEST_VECTORS.RECEIVE_BLOCK.representative,
- '0'
- )
+ openBlock = new Block(account, '0', RECEIVE_BLOCK.representative, account.publicKey)
+ .receive(RECEIVE_BLOCK.link, RECEIVE_BLOCK.balance)
assert.ok(/^[A-Fa-f0-9]{64}$/.test(openBlock.hash))
assert.nullish(openBlock.signature)
})
await test('sign send block from wallet which requires cache to be up-to-date', async () => {
- sendBlock = new SendBlock(
- account,
- openBlock.balance,
- account.address,
- '0',
- NANO_TEST_VECTORS.SEND_BLOCK.representative,
- openBlock.hash
- )
+ sendBlock = new Block(account, openBlock.balance, SEND_BLOCK.representative, openBlock.hash)
+ .send(account.address, '0')
assert.ok(/^[A-Fa-f0-9]{64}$/.test(sendBlock.hash))
assert.nullish(sendBlock.signature)
})
await test('sign a receive block from block object which can accept previous block for cache', async () => {
- receiveBlock = new ReceiveBlock(
- account,
- sendBlock.balance,
- sendBlock.hash,
- '0',
- NANO_TEST_VECTORS.RECEIVE_BLOCK.representative,
- sendBlock.hash
- )
+ receiveBlock = new Block(account, sendBlock.balance, RECEIVE_BLOCK.representative, sendBlock.hash)
+ .receive(sendBlock.hash, '0')
assert.ok(/^[A-Fa-f0-9]{64}$/.test(sendBlock.hash))
assert.nullish(receiveBlock.signature)
assert.ok(/^[A-Fa-f0-9]{128}$/.test(receiveBlock.signature ?? ''))
})
+ await test('sign a send block from wallet without frontier block inheriting cache contents', async () => {
+ sendBlock = new Block(account, receiveBlock.balance, SEND_BLOCK.representative, receiveBlock.hash)
+ .send(account.address, '0')
+
+ assert.ok(/^[A-Fa-f0-9]{64}$/.test(sendBlock.hash))
+ assert.nullish(sendBlock.signature)
+ assert.equal(sendBlock.account.publicKey, account.publicKey)
+
+ const signature = await wallet.sign(0, sendBlock)
+
+ assert.exists(sendBlock.signature)
+ assert.ok(/^[A-Fa-f0-9]{128}$/.test(sendBlock.signature ?? ''))
+ assert.equal(signature, sendBlock.signature)
+ })
+
await test('sign a receive block from wallet including frontier block for cache', async () => {
- sendBlock = new ReceiveBlock(
- account,
- receiveBlock.balance,
- receiveBlock.hash,
- '0',
- NANO_TEST_VECTORS.RECEIVE_BLOCK.representative,
- receiveBlock.hash
- )
+ sendBlock = new Block(account, receiveBlock.balance, RECEIVE_BLOCK.representative, receiveBlock.hash)
+ .receive(receiveBlock.hash, '0')
assert.ok(/^[A-Fa-f0-9]{64}$/.test(receiveBlock.hash))
assert.nullish(sendBlock.signature)
})
await test('fail to sign a block without caching frontier', async () => {
- sendBlock = new SendBlock(
- account,
- receiveBlock.balance,
- account.address,
- '0',
- NANO_TEST_VECTORS.SEND_BLOCK.representative,
- receiveBlock.previous
- )
+ sendBlock = new Block(account, receiveBlock.balance, SEND_BLOCK.representative, receiveBlock.previous)
+ .send(account.address, '0')
await assert.rejects(sendBlock.sign(0))
})
})