},
"scripts": {
"build": "rm -rf dist && tsc && esbuild main.min=dist/main.js global.min=dist/global.js --outdir=dist --target=esnext --format=esm --platform=browser --bundle --sourcemap",
- "test": "npm run build && esbuild test.min=test/main.mjs --outdir=dist --target=esnext --format=esm --platform=browser --bundle --sourcemap",
+ "test": "npm run build && esbuild test.min=test/test.main.mjs --outdir=dist --target=esnext --format=esm --platform=browser --bundle --sourcemap",
"test:node": "npm run build -- --platform=node && node --test --test-force-exit --env-file .env",
"test:coverage": "npm run test:node -- --experimental-test-coverage",
"test:coverage:report": "npm run test:coverage -- --test-reporter=lcov --test-reporter-destination=coverage.info && genhtml coverage.info --output-directory test/coverage && rm coverage.info && xdg-open test/coverage/index.html",
- "test:performance": "npm run build && esbuild perf.min=perf/main.mjs --outdir=dist --target=esnext --format=esm --platform=browser --bundle --sourcemap"
+ "test:performance": "npm run build && esbuild perf.min=test/perf.main.mjs --outdir=dist --target=esnext --format=esm --platform=browser --bundle --sourcemap"
},
"imports": {
- "#*": "./*"
+ "#~/*": "./src/lib/*",
+ "#dist/*": "./dist/*",
+ "#test/*": "./test/*",
+ "#nano-pow/*": "./src/lib/nano-pow/*"
},
"optionalDependencies": {
"@ledgerhq/hw-transport-web-ble": "^6.29.4",
import { NanoNaCl } from './workers/nano-nacl.js'
import { Pool } from './pool.js'
import { Rpc } from './rpc.js'
-import { PowGl, NanoPowGpu } from './workers.js'
+import { NanoPow } from './workers.js'
/**
* Represents a block as defined by the Nano cryptocurrency protocol. The Block
* of three derived classes: SendBlock, ReceiveBlock, ChangeBlock.
*/
abstract class Block {
- static #pool: Pool = new Pool(NanoPowGpu)
+ static #pool: Pool = new Pool(NanoPow)
account: Account
type: string = 'state'
abstract subtype: 'send' | 'receive' | 'change'
// SPDX-License-Identifier: GPL-3.0-or-later
// Based on nano-webgl-pow by Ben Green (numtel) <ben@latenightsketches.com>
// https://github.com/numtel/nano-webgl-pow
-import { WorkerInterface } from '../pool.js'
-import { NanoPowGlFragmentShader, NanoPowGlVertexShader } from './shaders'
-
-export class PowGl extends WorkerInterface {
- static {
- PowGl.listen()
- }
- /**
- * Calculates proof-of-work as described by the Nano cryptocurrency protocol.
- *
- * @param {any[]} data - Array of hashes and minimum thresholds
- * @returns Promise for proof-of-work attached to original array objects
- */
- static async work (data: any[]): Promise<any[]> {
- return new Promise(async (resolve, reject): Promise<void> => {
- for (const d of data) {
- try {
- d.work = await this.search(d.hash, d.threshold)
- } catch (err) {
- reject(err)
- }
- }
- resolve(data)
- })
- }
+// import { WorkerInterface } from '#~/pool.js'
+import { NanoPowGlFragmentShader, NanoPowGlVertexShader } from '#nano-pow/shaders/index.js'
+
+// export class NanoPowGl extends WorkerInterface {
+// static {
+// NanoPowGl.listen()
+// }
+// /**
+// * Calculates proof-of-work as described by the Nano cryptocurrency protocol.
+// *
+// * @param {any[]} data - Array of hashes and minimum thresholds
+// * @returns Promise for proof-of-work attached to original array objects
+// */
+// static async work (data: any[]): Promise<any[]> {
+// return new Promise(async (resolve, reject): Promise<void> => {
+// for (const d of data) {
+// try {
+// d.work = await this.search(d.hash, d.threshold)
+// } catch (err) {
+// reject(err)
+// }
+// }
+// resolve(data)
+// })
+// }
+export class NanoPowGl {
/** Used to set canvas size. Must be a multiple of 256. */
static #WORKLOAD: number = 256 * Math.max(1, Math.floor(navigator.hardwareConcurrency))
* @param {number} [threshold=0xfffffff8] - Difficulty of proof-of-work calculation
*/
static async search (hash: string, threshold: number = 0xfffffff8): Promise<string> {
- if (PowGl.#gl == null) throw new Error('WebGL 2 is required')
+ if (NanoPowGl.#gl == null) throw new Error('WebGL 2 is required')
if (!/^[A-F-a-f0-9]{64}$/.test(hash)) throw new Error(`invalid_hash ${hash}`)
if (typeof threshold !== 'number') throw new TypeError(`Invalid threshold ${threshold}`)
if (this.#gl == null) throw new Error('WebGL 2 is required')
uboView.setUint32(i * 2, parseInt(uint32, 16))
}
uboView.setUint32(128, threshold, true)
- uboView.setFloat32(132, PowGl.#WORKLOAD - 1, true)
- PowGl.#gl.bindBuffer(PowGl.#gl.UNIFORM_BUFFER, PowGl.#uboBuffer)
- PowGl.#gl.bufferSubData(PowGl.#gl.UNIFORM_BUFFER, 0, uboView)
- PowGl.#gl.bindBuffer(PowGl.#gl.UNIFORM_BUFFER, null)
+ uboView.setFloat32(132, NanoPowGl.#WORKLOAD - 1, true)
+ NanoPowGl.#gl.bindBuffer(NanoPowGl.#gl.UNIFORM_BUFFER, NanoPowGl.#uboBuffer)
+ NanoPowGl.#gl.bufferSubData(NanoPowGl.#gl.UNIFORM_BUFFER, 0, uboView)
+ NanoPowGl.#gl.bindBuffer(NanoPowGl.#gl.UNIFORM_BUFFER, null)
// Start drawing to calculate one nonce per pixel
let nonce = null
return new Promise((resolve, reject): void => {
try {
requestAnimationFrame(async (): Promise<void> => {
- const result = await PowGl.checkQueryResult()
+ const result = await NanoPowGl.checkQueryResult()
resolve(result)
})
} catch (err) {
}
}
+// export default `
+// const NanoPowGlFragmentShader = ${NanoPowGlFragmentShader}
+// const NanoPowGlVertexShader = ${NanoPowGlVertexShader}
+// // const WorkerInterface = ${WorkerInterface}
+// const PowGl = ${NanoPowGl}
+// `
+
export default `
- const NanoPowGlFragmentShader = ${NanoPowGlFragmentShader}
- const NanoPowGlVertexShader = ${NanoPowGlVertexShader}
- const WorkerInterface = ${WorkerInterface}
- const PowGl = ${PowGl}
+ const NanoPowGlFragmentShader = \`${NanoPowGlFragmentShader}\`
+ const NanoPowGlVertexShader = \`${NanoPowGlVertexShader}\`
+ const PowGl = ${NanoPowGl}
`
// SPDX-License-Identifier: GPL-3.0-or-later
// BLAKE2b hashing implementation derived from nano-webgl-pow by Ben Green <ben@latenightsketches.com> (https://github.com/numtel/nano-webgl-pow)
/// <reference types="@webgpu/types" />
-import { WorkerInterface } from '../pool.js'
-import { NanoPowGpuComputeShader } from './shaders'
+// import { WorkerInterface } from '#~/pool.js'
+import { NanoPowGpuComputeShader } from '#nano-pow/shaders/index.js'
/**
* Nano proof-of-work using WebGPU.
*/
-export class NanoPowGpu extends WorkerInterface {
- static {
- NanoPowGpu.listen()
- }
-
- /**
- * Calculates proof-of-work as described by the Nano cryptocurrency protocol.
- *
- * @param {any[]} data - Array of hashes and minimum thresholds
- * @returns Promise for proof-of-work attached to original array objects
- */
- static async work (data: any[]): Promise<any[]> {
- return new Promise(async (resolve, reject): Promise<void> => {
- for (const d of data) {
- try {
- d.work = await this.search(d.hash, d.threshold)
- } catch (err) {
- reject(err)
- }
- }
- resolve(data)
- })
- }
+// export class NanoPowGpu extends WorkerInterface {
+// static {
+// NanoPowGpu.listen()
+// }
+
+// /**
+// * Calculates proof-of-work as described by the Nano cryptocurrency protocol.
+// *
+// * @param {any[]} data - Array of hashes and minimum thresholds
+// * @returns Promise for proof-of-work attached to original array objects
+// */
+// static async work (data: any[]): Promise<any[]> {
+// return new Promise(async (resolve, reject): Promise<void> => {
+// for (const d of data) {
+// try {
+// d.work = await this.search(d.hash, d.threshold)
+// } catch (err) {
+// reject(err)
+// }
+// }
+// resolve(data)
+// })
+// }
+// */
+export class NanoPowGpu {
// Initialize WebGPU
static #device: GPUDevice | null = null
}
}
+// export default `
+// const NanoPowGpuComputeShader = \`${NanoPowGpuComputeShader}\`
+// const WorkerInterface = ${WorkerInterface}
+// const NanoPowGpu = ${NanoPowGpu}
+// `
+
export default `
const NanoPowGpuComputeShader = \`${NanoPowGpuComputeShader}\`
- const WorkerInterface = ${WorkerInterface}
const NanoPowGpu = ${NanoPowGpu}
`
--- /dev/null
+import { NanoPowGl } from "./classes/gl"
+import { NanoPowGpu } from "./classes/gpu"
+
+export { NanoPowGl, NanoPowGpu }
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { default as Bip44Ckd } from './workers/bip44-ckd.js'
-import { default as NanoNaCl } from './workers/nano-nacl.js'
-import { default as PowGl } from './nano-pow/nanopow-gl.js'
-import { default as NanoPowGpu } from './nano-pow/nanopow-gpu.js'
-
-export { Bip44Ckd, NanoNaCl, PowGl, NanoPowGpu }
+import { default as Bip44Ckd } from '#~/workers/bip44-ckd.js'
+import { default as NanoNaCl } from '#~/workers/nano-nacl.js'
+import { default as NanoPow } from '#~/workers/nano-pow.js'
+console.log(NanoPow)
+export { Bip44Ckd, NanoNaCl, NanoPow }
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { WorkerInterface } from '../pool.js'
+import { WorkerInterface } from '#~/pool.js'
type ExtendedKey = {
privateKey: DataView
'use strict'\r
\r
import { Blake2b } from '../blake2b.js'\r
-import { WorkerInterface } from '../pool.js'\r
+import { WorkerInterface } from '#~/pool.js'\r
\r
// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.\r
// Public domain.\r
--- /dev/null
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+import { WorkerInterface } from '#~/pool.js'
+import { NanoPowGpuComputeShader, NanoPowGlFragmentShader, NanoPowGlVertexShader } from '#nano-pow/shaders/index.js'
+import { NanoPowGl, NanoPowGpu } from '#nano-pow/index.js'
+
+/**
+* Nano proof-of-work using WebGPU.
+*/
+export class NanoPow extends WorkerInterface {
+ static {
+ NanoPow.listen()
+ }
+
+ /**
+ * Calculates proof-of-work as described by the Nano cryptocurrency protocol.
+ *
+ * @param {any[]} data - Array of hashes and minimum thresholds
+ * @returns Promise for proof-of-work attached to original array objects
+ */
+ static async work (data: any[]): Promise<any[]> {
+ return new Promise(async (resolve, reject): Promise<void> => {
+ for (const d of data) {
+ try {
+ d.work = await NanoPowGpu.search(d.hash, d.threshold)
+ } catch (err) {
+ reject(err)
+ }
+ }
+ resolve(data)
+ })
+ }
+}
+
+export default `
+ const NanoPowGpuComputeShader = \`${NanoPowGpuComputeShader}\`
+ const NanoPowGlFragmentShader = \`${NanoPowGlFragmentShader}\`
+ const NanoPowGlVertexShader = \`${NanoPowGlVertexShader}\`
+ const NanoPowGl = ${NanoPowGl}
+ const NanoPowGpu = ${NanoPowGpu}
+ const WorkerInterface = ${WorkerInterface}
+ const NanoPow = ${NanoPow}
+`
import { Account } from './lib/account.js'
import { Blake2b } from './lib/blake2b.js'
import { SendBlock, ReceiveBlock, ChangeBlock } from './lib/block.js'
-import { PowGl } from './lib/nano-pow/nanopow-gl.js'
-import { NanoPowGpu } from './lib/nano-pow/nanopow-gpu.js'
+import { NanoPowGl, NanoPowGpu } from '#nano-pow/index.js'
import { Rpc } from './lib/rpc.js'
import { Rolodex } from './lib/rolodex.js'
import { Safe } from './lib/safe.js'
import { Tools } from './lib/tools.js'
import { Bip44Wallet, Blake2bWallet, LedgerWallet } from './lib/wallet.js'
-export { Account, Blake2b, SendBlock, ReceiveBlock, ChangeBlock, PowGl, NanoPowGpu, Rpc, Rolodex, Safe, Tools, Bip44Wallet, Blake2bWallet, LedgerWallet }
+export { Account, Blake2b, SendBlock, ReceiveBlock, ChangeBlock, NanoPowGl as PowGl, NanoPowGpu, Rpc, Rolodex, Safe, Tools, Bip44Wallet, Blake2bWallet, LedgerWallet }
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-import './calculate-pow.test.mjs'
-import './create-wallet.test.mjs'
-import './derive-accounts.test.mjs'
-import './import-wallet.test.mjs'
-import './lock-unlock-wallet.mjs'
-import './manage-rolodex.mjs'
-import './refresh-accounts.test.mjs'
-import './sign-blocks.test.mjs'
-import './tools.test.mjs'
-
-console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
'use strict'
-import { assert, average, skip, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
+import { assert, average, skip, suite, test } from '#test/GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'
import { Bip44Wallet, Blake2bWallet } from '#dist/main.js'
await suite('Account performance', async () => {
'use strict'
-import { assert, average, skip, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
+import { assert, average, skip, suite, test } from '#test/GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'
import { PowGl, NanoPowGpu, SendBlock } from '#dist/main.js'
import 'nano-webgl-pow'
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-// import './wallet.perf.js'
-// import './account.perf.js'
-import './block.perf.js'
+// import './perf.wallet.js'
+// import './perf.account.js'
+import './perf.block.js'
console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
'use strict'
-import { assert, average, skip, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
+import { assert, average, skip, suite, test } from '#test/GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'
import { Bip44Wallet, Blake2bWallet } from '#dist/main.js'
await suite(`Wallet performance`, async () => {
\r
'use strict'\r
\r
-import { assert, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
+import { assert, suite, test } from '#test/GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'\r
import { SendBlock, Blake2b } from '#dist/main.js'\r
\r
await suite('Calculate proof-of-work', async () => {\r
\r
'use strict'\r
\r
-import { assert, skip, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
+import { assert, skip, suite, test } from '#test/GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'\r
import { Bip44Wallet, Blake2bWallet, LedgerWallet } from '#dist/main.js'\r
\r
await suite('Create wallets', async () => {\r
\r
'use strict'\r
\r
-import { assert, skip, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
+import { assert, skip, suite, test } from '#test/GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'\r
import { Bip44Wallet, Blake2bWallet, LedgerWallet } from '#dist/main.js'\r
\r
await suite('Account derivation', async () => {\r
\r
'use strict'\r
\r
-import { assert, suite, test } from '#GLOBALS.mjs'\r
-import { BIP32_TEST_VECTORS, CUSTOM_TEST_VECTORS, NANO_TEST_VECTORS, TREZOR_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
+import { assert, suite, test } from '#test/GLOBALS.mjs'\r
+import { BIP32_TEST_VECTORS, CUSTOM_TEST_VECTORS, NANO_TEST_VECTORS, TREZOR_TEST_VECTORS } from '#test/VECTORS.js'\r
import { Account, Bip44Wallet, Blake2bWallet } from '#dist/main.js'\r
\r
await suite('Import wallets', async () => {\r
\r
'use strict'\r
\r
-import { assert, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS, TREZOR_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
+import { assert, suite, test } from '#test/GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS, TREZOR_TEST_VECTORS } from '#test/VECTORS.js'\r
import { Bip44Wallet, Blake2bWallet } from '#dist/main.js'\r
\r
await suite('Lock and unlock wallets', async () => {\r
--- /dev/null
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import './test.calculate-pow.mjs'
+import './test.create-wallet.mjs'
+import './test.derive-accounts.mjs'
+import './test.import-wallet.mjs'
+import './test.lock-unlock-wallet.mjs'
+import './test.manage-rolodex.mjs'
+import './test.refresh-accounts.mjs'
+import './test.sign-blocks.mjs'
+import './test.tools.mjs'
+
+console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
'use strict'
-import { assert, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
+import { assert, suite, test } from '#test/GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'
import { Rolodex, Tools } from '#dist/main.js'
await suite('Rolodex valid contact management', async () => {
'use strict'
-import { assert, skip, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
+import { assert, skip, suite, test } from '#test/GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'
import { Account, Bip44Wallet, Rpc } from '#dist/main.js'
let rpc
\r
'use strict'\r
\r
-import { assert, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
+import { assert, suite, test } from '#test/GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS } from '#test/VECTORS.js'\r
import { SendBlock, ReceiveBlock, ChangeBlock } from '#dist/main.js'\r
\r
await suite('Valid blocks', async () => {\r
\r
'use strict'\r
\r
-import { assert, skip, suite, test } from '#GLOBALS.mjs'\r
-import { RAW_MAX, NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
+import { assert, skip, suite, test } from '#test/GLOBALS.mjs'\r
+import { RAW_MAX, NANO_TEST_VECTORS } from '#test/VECTORS.js'\r
import { Bip44Wallet, Account, SendBlock, Rpc, Tools } from '#dist/main.js'\r
\r
let rpc\r
"forceConsistentCasingInFileNames": true,
"noErrorTruncation": true,
"noFallthroughCasesInSwitch": true,
- "strict": true
+ "strict": true,
+ "rootDir": "src"
},
"include": [
"src/main.ts",