*
* @returns {Uint8Array<ArrayBuffer>} Block data hashed to a byte array
*/
- get #hash (): Uint8Array<ArrayBuffer> {
+ #hash (): Uint8Array<ArrayBuffer>
+ #hash (format: 'hex'): string
+ #hash (format?: unknown): string | Uint8Array<ArrayBuffer> {
try {
if (this.link == null) {
throw new Error('Link is required')
this.previous.padStart(64, '0'),
this.representative.publicKey,
dec.toHex(this.balance, 32),
- this.link
+ ...this.link
]
const hash = new Blake2b(32)
data.forEach(d => typeof d === 'string' ? hash.update(hex.toBytes(d)) : d)
- return hash.digest()
+ return format === 'hex' ? hash.digest(format) : hash.digest()
} catch (err) {
console.error(err)
throw new Error('Failed to hash block', { cause: err })
* @returns {string} Hexadecimal representation of 32-byte hash of block data
*/
get hash (): string {
- return bytes.toHex(this.#hash)
+ return this.#hash('hex').toUpperCase()
}
/**
if (typeof input !== 'number' && typeof input !== 'string' && !(input instanceof Wallet)) {
throw new TypeError('Invalid signing input')
} else if (typeof input === 'string' && /^[A-F0-9]{64}$/.test(input)) {
- const sig = await NanoNaCl.detached(this.#hash, hex.toBytes(input))
+ const sig = await NanoNaCl.detached(this.#hash(), hex.toBytes(input))
this.signature = bytes.toHex(sig)
} else if (input instanceof Wallet && typeof param === 'number') {
const wallet = input
if (typeof key !== 'string') {
throw new Error('Invalid key')
}
- return await NanoNaCl.verify(this.#hash, hex.toBytes(this.signature ?? ''), hex.toBytes(key))
+ return await NanoNaCl.verify(this.#hash(), hex.toBytes(this.signature ?? ''), hex.toBytes(key))
} catch (err) {
throw new Error('Failed to verify block signature', { cause: err })
}
assert.equal(block.balance, BigInt(0))\r
})\r
\r
- await test('subtract balance from SendBlock correctly', async () => {\r
+ await test('subtract balance from send block correctly', async () => {\r
const block = new Block(\r
ADDRESS_0, '3000000000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', ADDRESS_2)\r
.send(ADDRESS_1, '2000000000000000000000000000000')\r
assert.equal(block.balance, 1000000000000000000000000000000n)\r
})\r
\r
- await test('add balance from ReceiveBlock correctly', async () => {\r
+ await test('add balance from receive block correctly', async () => {\r
const block = new Block(ADDRESS_0, '2000000000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', ADDRESS_2)\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(ADDRESS_1, '1000000000000000000000000000000'))\r
+ assert.throws(() => {\r
+ new Block(ADDRESS_0, '2000000000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', ADDRESS_2)\r
+ .receive(ADDRESS_1, '1000000000000000000000000000000')\r
+ })\r
})\r
}),\r
\r
*/\r
let Account\r
/**\r
-* @type {typeof import('../dist/types.d.ts').Rpc}\r
+* @type {typeof import('../dist/types.d.ts').Block}\r
*/\r
-let Rpc\r
+let Block\r
/**\r
-* @type {typeof import('../dist/types.d.ts').SendBlock}\r
+* @type {typeof import('../dist/types.d.ts').Rpc}\r
*/\r
-let SendBlock\r
+let Rpc\r
/**\r
* @type {typeof import('../dist/types.d.ts').Tools}\r
*/\r
*/\r
let Wallet\r
if (isNode) {\r
- ({ Account, Rpc, SendBlock, Tools, Wallet } = await import('../dist/nodejs.min.js'))\r
+ ({ Account, Block, Rpc, Tools, Wallet } = await import('../dist/nodejs.min.js'))\r
} else {\r
- ({ Account, Rpc, SendBlock, Tools, Wallet } = await import('../dist/browser.min.js'))\r
+ ({ Account, Block, Rpc, Tools, Wallet } = await import('../dist/browser.min.js'))\r
}\r
\r
const rpc = new Rpc(env?.NODE_URL ?? '', env?.API_KEY_NAME)\r
if (account.index == null) {\r
throw new Error('Account index missing')\r
}\r
- const sendBlock = new SendBlock(\r
- account.address,\r
- '5618869000000000000000000000000',\r
- 'nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p',\r
- '2000000000000000000000000000000',\r
- 'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou',\r
- '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D',\r
- )\r
-\r
- const signature = await wallet.sign(account.index, sendBlock)\r
- const valid = await sendBlock.verify(account.publicKey)\r
-\r
- assert.equal(signature, sendBlock.signature)\r
- assert.equal(valid, true)\r
+ const sendBlock = await new Block(account.address, '5618869000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', 'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou')\r
+ .send('nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p', '2000000000000000000000000000000')\r
+ .sign(wallet, account.index)\r
\r
+ assert.ok(await sendBlock.verify(account.publicKey))\r
await assert.resolves(wallet.destroy())\r
})\r
\r
if (account.index == null) {\r
throw new Error('Account index missing')\r
}\r
- const sendBlock = new SendBlock(\r
- account.address,\r
- '5618869000000000000000000000000',\r
- 'nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p',\r
- '2000000000000000000000000000000',\r
- 'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou',\r
- '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D',\r
- )\r
assert.equal(account.index, 0)\r
- const signature = await wallet.sign(account.index, sendBlock)\r
\r
- assert.equal(signature, sendBlock.signature)\r
+ const sendBlock = await new Block(account.address, '5618869000000000000000000000000', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', 'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou')\r
+ .send('nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p', '2000000000000000000000000000000')\r
+ .sign(wallet, account.index)\r
\r
sendBlock.account = Account.import('nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p')\r
- const valid = await sendBlock.verify(account.publicKey)\r
- assert.equal(valid, false)\r
+ assert.ok(await sendBlock.verify(account.publicKey))\r
\r
await assert.resolves(sendBlock.account.destroy())\r
await assert.resolves(wallet.destroy())\r