Refactor host code to compile synchronously, return both sync and async functions, merge trace logging function into wasm env, refactor worker listening process, add type checks to worker message parsing, and emit type definitions.
Update testing page to add NanoNaCl to global context in test page to enable testing ad hoc commands, add tests for sync functions using byte arrays, add pause when starting each test run to allow DOM to repaint status text, and always run self-check.
Rename main assembly file.
Improve documentation and reorganize functions.
Update dependencies.
}
}
}
+ window.NanoNaCl = NanoNaCl
try {
({ TEST_VECTORS } = await import('./env.mjs'))
} catch (err) {
return [...bytes].map(b => b.toString(16).padStart(2, '0')).join('')
}
- export async function test (api, size, runs, isDebug, isSelfCheck) {
+ const derive = (sk, api) => {
+ const sk8 = new Uint8Array(sk.match(/.{2}/g).map(b => parseInt(b, 16)))
+ switch (api) {
+ case 'NanoNaCl': {
+ const pk8 = NanoNaCl.derive(sk8)
+ return [...pk8].map(b => b.toString(16).padStart(2, '0')).join('')
+ }
+ case 'NanoNaCl (async)': {
+ return NanoNaCl.deriveAsync(sk)
+ }
+ case 'NanocurrencyWeb': {
+ return NanocurrencyWeb.wallet.legacyAccounts(sk)[0].publicKey
+ }
+ case 'Sodium': {
+ return sodium.crypto_sign_seed_keypair(sk8, 'hex').publicKey
+ }
+ case 'TweetNaCl.js': {
+ const sk8 = sk.match(/.{2}/g).map(b => parseInt(b, 16))
+ const pk8 = nacl.sign.keyPair.fromSeed(sk8).publicKey
+ return [...pk8].map(b => b.toString(16).padStart(2, '0')).join('')
+ }
+ default: {
+ return null
+ }
+ }
+ }
+
+ const sign = (h, sk, pk, api) => {
+ const h8 = new Uint8Array(h.match(/.{2}/g).map(b => parseInt(b, 16)))
+ const sk8 = new Uint8Array((sk + pk).match(/.{2}/g).map(b => parseInt(b, 16)))
+ switch (api) {
+ case 'NanoNaCl': {
+ const s8 = NanoNaCl.sign(h8, sk8)
+ return [...s8].map(b => b.toString(16).padStart(2, '0')).join('')
+ }
+ case 'NanoNaCl (async)': {
+ return NanoNaCl.signAsync(h, sk + pk)
+ }
+ case 'NanocurrencyWeb': {
+ const { privateKey } = NanocurrencyWeb.wallet.legacyAccounts(sk)[0]
+ return NanocurrencyWeb.tools.sign(privateKey, h)
+ }
+ case 'Sodium': {
+ return sodium.crypto_sign_detached(new Uint8Array(h8), new Uint8Array(sk8), 'hex')
+ }
+ case 'TweetNaCl.js': {
+ const s8 = nacl.sign.detached(new Uint8Array(h8), new Uint8Array(sk8))
+ return [...s8].map(b => b.toString(16).padStart(2, '0')).join('')
+ }
+ default: {
+ return null
+ }
+ }
+ }
+
+ const verify = (s, h, pk, api) => {
+ const h8 = new Uint8Array(h.match(/.{2}/g).map(b => parseInt(b, 16)))
+ const s8 = new Uint8Array(s.match(/.{2}/g).map(b => parseInt(b, 16)))
+ const pk8 = new Uint8Array(pk.match(/.{2}/g).map(b => parseInt(b, 16)))
+ switch (api) {
+ case 'NanoNaCl': {
+ return NanoNaCl.verify(s8, h8, pk8)
+ }
+ case 'NanoNaCl (async)': {
+ return NanoNaCl.verifyAsync(s, h, pk)
+ }
+ case 'NanocurrencyWeb': {
+ return NanocurrencyWeb.tools.verify(pk, s, h)
+ }
+ case 'Sodium': {
+ return sodium.crypto_sign_verify_detached(s8, h8, pk8)
+ }
+ case 'TweetNaCl.js': {
+ return nacl.sign.detached.verify(h8, s8, pk8)
+ }
+ default: {
+ return null
+ }
+ }
+ }
+
+ export async function test (api, size, runs, isDebug) {
if (typeof size !== 'number' || size < 1) {
size = 1
}
if (typeof runs !== 'number' || runs < 1) {
runs = 1
}
- const selectedApi = api
- // Execute once on load to initialize worker and WASM
- const h = random(), k = random(64)
- await NanoNaCl.sign(h, k)
- const derive = sk => {
- const sk8 = new Uint8Array(sk.match(/.{2}/g).map(b => parseInt(b, 16)))
- switch (api) {
- case 'NanoNaCl': {
- const pk8 = NanoNaCl.deriveSync(sk8)
- return [...pk8].map(b => b.toString(16).padStart(2, '0')).join('')
- }
- case 'NanocurrencyWeb': {
- return NanocurrencyWeb.wallet.legacyAccounts(sk)[0].publicKey
- }
- case 'Sodium': {
- return sodium.crypto_sign_seed_keypair(sk8, 'hex').publicKey
- }
- case 'TweetNaCl.js': {
- const sk8 = sk.match(/.{2}/g).map(b => parseInt(b, 16))
- const pk8 = nacl.sign.keyPair.fromSeed(sk8).publicKey
- return [...pk8].map(b => b.toString(16).padStart(2, '0')).join('')
- }
- default: {
- return null
- }
- }
- }
- const sign = (h, sk, pk) => {
- const h8 = new Uint8Array(h.match(/.{2}/g).map(b => parseInt(b, 16)))
- const sk8 = new Uint8Array((sk + pk).match(/.{2}/g).map(b => parseInt(b, 16)))
- switch (api) {
- case 'NanoNaCl': {
- const s8 = NanoNaCl.signSync(h8, sk8)
- return [...s8].map(b => b.toString(16).padStart(2, '0')).join('')
- }
- case 'NanocurrencyWeb': {
- const { privateKey } = NanocurrencyWeb.wallet.legacyAccounts(sk)[0]
- return NanocurrencyWeb.tools.sign(privateKey, h)
- }
- case 'Sodium': {
- return sodium.crypto_sign_detached(new Uint8Array(h8), new Uint8Array(sk8), 'hex')
- }
- case 'TweetNaCl.js': {
- const s8 = nacl.sign.detached(new Uint8Array(h8), new Uint8Array(sk8))
- return [...s8].map(b => b.toString(16).padStart(2, '0')).join('')
- }
- default: {
- return null
- }
- }
- }
- const verify = (s, h, pk) => {
- const h8 = new Uint8Array(h.match(/.{2}/g).map(b => parseInt(b, 16)))
- const s8 = new Uint8Array(s.match(/.{2}/g).map(b => parseInt(b, 16)))
- const pk8 = new Uint8Array(pk.match(/.{2}/g).map(b => parseInt(b, 16)))
- switch (api) {
- case 'NanoNaCl': {
- const v = NanoNaCl.verifySync(s8, h8, pk8)
- return v[0] === 0
- }
- case 'NanocurrencyWeb': {
- return NanocurrencyWeb.tools.verify(pk, s, h)
- }
- case 'Sodium': {
- return sodium.crypto_sign_verify_detached(s8, h8, pk8)
- }
- case 'TweetNaCl.js': {
- return nacl.sign.detached.verify(h8, s8, pk8)
- }
- default: {
- return null
- }
- }
+ // self-check
+ document.getElementById('status').innerHTML = `RUNNING SELF-CHECK`
+ console.log(`%cNanoNaCl`, 'color:green', 'Checking validation against known values')
+ // https://docs.nano.org/integration-guides/key-management/#success-response_2
+ TEST_VECTORS ??= {
+ blockHash: 'BB569136FA05F8CBF65CEF2EDE368475B289C4477342976556BA4C0DDF216E45',
+ blockHashBytes: new Uint8Array([0xBB, 0x56, 0x91, 0x36, 0xFA, 0x05, 0xF8, 0xCB, 0xF6, 0x5C, 0xEF, 0x2E, 0xDE, 0x36, 0x84, 0x75, 0xB2, 0x89, 0xC4, 0x47, 0x73, 0x42, 0x97, 0x65, 0x56, 0xBA, 0x4C, 0x0D, 0xDF, 0x21, 0x6E, 0x45]),
+ privateKey: '781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3',
+ privateKeyBytes: new Uint8Array([0x78, 0x11, 0x86, 0xFB, 0x9E, 0xF1, 0x7D, 0xB6, 0xE3, 0xD1, 0x05, 0x65, 0x50, 0xD9, 0xFA, 0xE5, 0xD5, 0xBB, 0xAD, 0xA6, 0xA6, 0xBC, 0x37, 0x0E, 0x4C, 0xBB, 0x93, 0x8B, 0x1D, 0xC7, 0x1D, 0xA3]),
+ publicKey: '3068BB1CA04525BB0E416C485FE6A67FD52540227D267CC8B6E8DA958A7FA039',
+ publicKeyBytes: new Uint8Array([0x30, 0x68, 0xBB, 0x1C, 0xA0, 0x45, 0x25, 0xBB, 0x0E, 0x41, 0x6C, 0x48, 0x5F, 0xE6, 0xA6, 0x7F, 0xD5, 0x25, 0x40, 0x22, 0x7D, 0x26, 0x7C, 0xC8, 0xB6, 0xE8, 0xDA, 0x95, 0x8A, 0x7F, 0xA0, 0x39]),
+ secretKey: '781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA33068BB1CA04525BB0E416C485FE6A67FD52540227D267CC8B6E8DA958A7FA039',
+ secretKeyBytes: new Uint8Array([0x78, 0x11, 0x86, 0xFB, 0x9E, 0xF1, 0x7D, 0xB6, 0xE3, 0xD1, 0x05, 0x65, 0x50, 0xD9, 0xFA, 0xE5, 0xD5, 0xBB, 0xAD, 0xA6, 0xA6, 0xBC, 0x37, 0x0E, 0x4C, 0xBB, 0x93, 0x8B, 0x1D, 0xC7, 0x1D, 0xA3, 0x30, 0x68, 0xBB, 0x1C, 0xA0, 0x45, 0x25, 0xBB, 0x0E, 0x41, 0x6C, 0x48, 0x5F, 0xE6, 0xA6, 0x7F, 0xD5, 0x25, 0x40, 0x22, 0x7D, 0x26, 0x7C, 0xC8, 0xB6, 0xE8, 0xDA, 0x95, 0x8A, 0x7F, 0xA0, 0x39]),
+ signature: '74BCC59DBA39A1E34A5F75F96D6DE9154E3477AAD7DE30EA563DFCFE501A804228008F98DDF4A15FD35705102785C50EF76732C3A74B0FEC5B0DD67B574A5900',
+ signatureBytes: new Uint8Array([0x74, 0xBC, 0xC5, 0x9D, 0xBA, 0x39, 0xA1, 0xE3, 0x4A, 0x5F, 0x75, 0xF9, 0x6D, 0x6D, 0xE9, 0x15, 0x4E, 0x34, 0x77, 0xAA, 0xD7, 0xDE, 0x30, 0xEA, 0x56, 0x3D, 0xFC, 0xFE, 0x50, 0x1A, 0x80, 0x42, 0x28, 0x00, 0x8F, 0x98, 0xDD, 0xF4, 0xA1, 0x5F, 0xD3, 0x57, 0x05, 0x10, 0x27, 0x85, 0xC5, 0x0E, 0xF7, 0x67, 0x32, 0xC3, 0xA7, 0x4B, 0x0F, 0xEC, 0x5B, 0x0D, 0xD6, 0x7B, 0x57, 0x4A, 0x59, 0x00]),
+ badSignature: '74BCC59DBA39A1E34A5F75F96D6DE9154E3477AAD7DE30EA563DFCFE501A804215d484f5f757b4b7a9f4fcb2057fa423f76732c3a74b0fec5b0dd67b574a5910'
}
+ const zeroes = '0000000000000000000000000000000000000000000000000000000000000000'
+ const expect = []
+ let result
- if (isSelfCheck) {
- api = 'NanoNaCl'
- document.getElementById('status').innerHTML = `RUNNING SELF-CHECK`
- console.log(`%cNanoNaCl`, 'color:green', 'Checking validation against known values')
- // https://docs.nano.org/integration-guides/key-management/#success-response_2
- TEST_VECTORS ??= {
- blockHash: 'BB569136FA05F8CBF65CEF2EDE368475B289C4477342976556BA4C0DDF216E45',
- privateKey: '781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3',
- publicKey: '3068BB1CA04525BB0E416C485FE6A67FD52540227D267CC8B6E8DA958A7FA039',
- signature: '74BCC59DBA39A1E34A5F75F96D6DE9154E3477AAD7DE30EA563DFCFE501A804228008F98DDF4A15FD35705102785C50EF76732C3A74B0FEC5B0DD67B574A5900',
- badSignature: '74BCC59DBA39A1E34A5F75F96D6DE9154E3477AAD7DE30EA563DFCFE501A804215d484f5f757b4b7a9f4fcb2057fa423f76732c3a74b0fec5b0dd67b574a5910'
- }
- const zeroes = '0000000000000000000000000000000000000000000000000000000000000000'
- const expect = []
- let result
+ // PASS
+ result = NanoNaCl.derive(TEST_VECTORS.privateKeyBytes)
+ console.log('expected: ', TEST_VECTORS.publicKeyBytes)
+ console.log('actual:', result)
+ result = [...result].map(b => b.toString(16).padStart(2, '0')).join('').toUpperCase() === TEST_VECTORS.publicKey.toUpperCase()
+ console.log(`derive() output for good private key is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- // PASS
- result = await derive(TEST_VECTORS.privateKey)
- console.log('expected: ', TEST_VECTORS.publicKey.toUpperCase())
- console.log('actual', result?.toUpperCase?.())
- result = result.toUpperCase() === TEST_VECTORS.publicKey.toUpperCase()
- console.log(`derive() output for good private key is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = NanoNaCl.sign(TEST_VECTORS.blockHashBytes, TEST_VECTORS.secretKeyBytes)
+ console.log('expected: ', TEST_VECTORS.signatureBytes)
+ console.log('actual:', result)
+ result = [...result].map(b => b.toString(16).padStart(2, '0')).join('').toUpperCase() === TEST_VECTORS.signature.toUpperCase()
+ console.log(`sign() output for good block hash and secret key is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await sign(TEST_VECTORS.blockHash, TEST_VECTORS.privateKey, TEST_VECTORS.publicKey)
- console.log('expected: ', TEST_VECTORS.signature.toUpperCase())
- console.log('actual', result?.toUpperCase?.())
- result = result.toUpperCase() === TEST_VECTORS.signature.toUpperCase()
- console.log(`sign() output for good block hash and secret key is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = NanoNaCl.verify(TEST_VECTORS.signatureBytes, TEST_VECTORS.blockHashBytes, TEST_VECTORS.publicKeyBytes)
+ console.log('expected:', true)
+ console.log('actual:', result)
+ result = result === true
+ console.log(`verify() output for good block hash, signature, and private key is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await verify(TEST_VECTORS.signature, TEST_VECTORS.blockHash, TEST_VECTORS.publicKey)
- console.log(result)
- result = result === true
- console.log(`verify() output for good block hash, signature, and private key is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoNaCl.deriveAsync(TEST_VECTORS.privateKey)
+ console.log('expected: ', TEST_VECTORS.publicKey.toUpperCase())
+ console.log('actual:', result?.toUpperCase?.())
+ result = result.toUpperCase() === TEST_VECTORS.publicKey.toUpperCase()
+ console.log(`deriveAsync() output for good private key is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- // XFAIL
- result = await verify(TEST_VECTORS.badSignature, TEST_VECTORS.blockHash, TEST_VECTORS.publicKey)
- console.log(result)
- result = result === false
- console.log(`verify() output for non-canonical signature is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoNaCl.signAsync(TEST_VECTORS.blockHash, TEST_VECTORS.secretKey)
+ console.log('expected: ', TEST_VECTORS.signature.toUpperCase())
+ console.log('actual:', result?.toUpperCase?.())
+ result = result.toUpperCase() === TEST_VECTORS.signature.toUpperCase()
+ console.log(`signAsync() output for good block hash and secret key is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await verify(TEST_VECTORS.signature, random(), TEST_VECTORS.publicKey)
- console.log(result)
- result = result === false
- console.log(`verify() output for random block hash is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoNaCl.verifyAsync(TEST_VECTORS.signature, TEST_VECTORS.blockHash, TEST_VECTORS.publicKey)
+ console.log('expected:', true)
+ console.log('actual:', result)
+ result = result === true
+ console.log(`verifyAsync() output for good block hash, signature, and private key is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await verify(TEST_VECTORS.signature, zeroes, TEST_VECTORS.publicKey)
- console.log(result)
- result = result === false
- console.log(`verify() output for bad block hash is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ // XFAIL
+ result = await NanoNaCl.verifyAsync(TEST_VECTORS.badSignature, TEST_VECTORS.blockHash, TEST_VECTORS.publicKey)
+ console.log(result)
+ result = result === false
+ console.log(`verify() output for non-canonical signature is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await verify(`${zeroes}${zeroes}`, TEST_VECTORS.blockHash, TEST_VECTORS.publicKey)
- console.log(result)
- result = result === false
- console.log(`verify() output for bad signature is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoNaCl.verifyAsync(TEST_VECTORS.signature, random(), TEST_VECTORS.publicKey)
+ console.log(result)
+ result = result === false
+ console.log(`verify() output for random block hash is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await verify(TEST_VECTORS.signature, TEST_VECTORS.blockHash, zeroes)
- console.log(result)
- result = result === false
- console.log(`verify() output for bad public key is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoNaCl.verifyAsync(TEST_VECTORS.signature, zeroes, TEST_VECTORS.publicKey)
+ console.log(result)
+ result = result === false
+ console.log(`verify() output for bad block hash is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- try {
- if (!expect.every(result => result)) throw new Error(`Validation is not working`)
- } catch (err) {
- document.getElementById('status').innerHTML = `FAILED TO VALIDATE KNOWN VALUES`
- document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
- console.error(err)
- return
- } finally {
- api = selectedApi
- }
+ result = await NanoNaCl.verifyAsync(`${zeroes}${zeroes}`, TEST_VECTORS.blockHash, TEST_VECTORS.publicKey)
+ console.log(result)
+ result = result === false
+ console.log(`verify() output for bad signature is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
+
+ result = await NanoNaCl.verifyAsync(TEST_VECTORS.signature, TEST_VECTORS.blockHash, zeroes)
+ console.log(result)
+ result = result === false
+ console.log(`verify() output for bad public key is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
+
+ try {
+ if (!expect.every(result => result)) throw new Error(`Validation is not working`)
+ } catch (err) {
+ document.getElementById('status').innerHTML = `FAILED TO VALIDATE KNOWN VALUES`
+ document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
+ console.error(err)
+ return
}
+ // run tests
console.log(`%c${api}`, 'color:green', `Calculate truncated harmonic mean of the truncated arithmetic rate of signing random block hashes across ${runs} runs of ${size} samples.`)
const rates = []
let start = 0, end = 0, publicKey = null, signature = null, isValid = false
for (let i = 0; i < runs; i++) {
+ await new Promise(r => setTimeout(r))
const times = []
for (let j = 0; j < size; j++) {
document.getElementById('status').innerHTML = `TESTING IN PROGRESS. THIS MAY TAKE A LONG TIME. ${i}/${runs} ${j}/${size}<br/>`
const privateKey = blockHash
try {
start = performance.now()
- publicKey = await derive(privateKey)
- signature = await sign(blockHash, privateKey, publicKey)
- isValid = await verify(signature, blockHash, publicKey)
+ publicKey = await derive(privateKey, api)
+ signature = await sign(blockHash, privateKey, publicKey, api)
+ isValid = await verify(signature, blockHash, publicKey, api)
end = performance.now()
} catch (err) {
document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
const size = document.getElementById('size')
const runs = document.getElementById('runs')
const isDebug = document.getElementById('isDebug')
- const isSelfCheck = document.getElementById('isSelfCheck')
- test(api.value, +size.value, +runs.value, isDebug.checked, isSelfCheck.checked)
+ test(api.value, +size.value, +runs.value, isDebug.checked)
.then(() => {
event.target.disabled = false
- isSelfCheck.checked = false
})
}
<label for="api">API</label>
<select id="api">
<option>NanoNaCl</option>
+ <option>NanoNaCl (async)</option>
<option>NanocurrencyWeb</option>
<option>Sodium</option>
<option>TweetNaCl.js</option>
<label for="isDebug">Debug?</label>
<input id="isDebug" type="checkbox" />
</span>
- <span>
- <label for="isSelfCheck">Run self-check?</label>
- <input id="isSelfCheck" type="checkbox" checked />
- </span>
<button id="btnStartTest">Go</button>
<hr />
<h3 id="status">WAITING</h3>
//! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
+//@ts-expect-error
import nacl from './build/nano-nacl.wasm'
-type Derive = () => void
-type Sign = () => void
-type Verify = () => number
-type GetInputPointer = () => number
-type GetOutputPointer = () => number
+
type Data = {
action: string
blockHash?: string
secretKey?: string
signature?: string
}
+type Exports = {
+ exports: {
+ derive: () => void,
+ sign: () => void,
+ verify: () => void,
+ getInputPointer: () => number,
+ getOutputPointer: () => number,
+ memory: WebAssembly.Memory
+ }
+}
-export const NanoNaCl = async (bytes: number[]): Promise<any> => {
- let isReady = false
- let wasm
- let module
- let instance
- let memory: WebAssembly.Memory
- let derive: (k: Uint8Array) => Uint8Array<ArrayBuffer>
- let sign: (h: Uint8Array, k: Uint8Array) => Uint8Array<ArrayBuffer>
- let verify: (s: Uint8Array, h: Uint8Array, k: Uint8Array) => Uint8Array<ArrayBuffer>
-
- async function setup (): Promise<void> {
- try {
- wasm = Uint8Array.from(bytes)
- module = await WebAssembly.compile(wasm)
- instance = await WebAssembly.instantiate(module, {
- env: {
- abort: (msg: any, file: any, row: any, col: any) => {
- // ~lib/builtins/abort(~lib/string/String | null?, ~lib/string/String | null?, u32?, u32?) => void
- // msg = __liftString(msg >>> 0)
- // file = __liftString(file >>> 0)
- row = row >>> 0
- col = col >>> 0
- console.error('wasm abort:', `msg ${msg}`, `file ${file}`, `row ${row}`, `col ${col}`)
- throw new Error(msg, { cause: { file, row, col } })
- },
- "performance.now" () {
- // ~lib/bindings/dom/performance.now() => f64
- return performance.now()
- },
- trace: (message: any, n?: number, a0?: number, a1?: number, a2?: number, a3?: number, a4?: number) => {
- // ~lib/builtins/trace(~lib/string/String, i32?, f64?, f64?, f64?, f64?, f64?) => void
- message = __liftString(message >>> 0);
- (() => {
- // @external.js
- console.log(message, ...[a0, a1, a2, a3, a4].slice(0, n))
- })()
- },
- memory: new WebAssembly.Memory({ initial: 4, maximum: 4 })
- }
- })
- const { exports } = instance as { exports: { derive: Derive, sign: Sign, verify: Verify, getInputPointer: GetInputPointer, getOutputPointer: GetOutputPointer, memory: WebAssembly.Memory } }
- memory = exports.memory
-
- function __liftString (pointer: number) {
- if (!pointer) return null
- const
- //@ts-ignore
- end = pointer + new Uint32Array(memory.buffer)[pointer - 4 >>> 2] >>> 1,
- //@ts-ignore
- memoryU16 = new Uint16Array(memory.buffer)
- let
- start = pointer >>> 1,
- string = ""
- while (end - start > 1024) string += String.fromCharCode(...memoryU16.subarray(start, start += 1024))
- return string + String.fromCharCode(...memoryU16.subarray(start, end))
- }
-
- derive = function (k: Uint8Array): Uint8Array<ArrayBuffer> {
- // assembly/nano-nacl/derive() => void
- let buffer: DataView | undefined = new DataView(memory.buffer)
- let inPtr = exports.getInputPointer()
- for (let i = 0; i < 32; i++) {
- buffer.setUint8(inPtr + i, k[i])
- }
- exports.derive()
- const outPtr = exports.getOutputPointer()
- const pk = new Uint8Array(32)
- buffer = new DataView(memory.buffer)
- for (let i = 0; i < 32; i++) {
- pk[i] = buffer.getUint8(outPtr + i)
+const startNanoNaCl = (bytes: number[]): { derive: typeof derive, sign: typeof sign, verify: typeof verify } => {
+ const wasm: Uint8Array<ArrayBuffer> = Uint8Array.from(bytes)
+ const module = new WebAssembly.Module(wasm)
+ const { exports } = new WebAssembly.Instance(module, {
+ env: {
+ abort: (msg: any, file: any, row: any, col: any) => {
+ // ~lib/builtins/abort(~lib/string/String | null?, ~lib/string/String | null?, u32?, u32?) => void
+ // msg = __liftString(msg >>> 0)
+ // file = __liftString(file >>> 0)
+ row = row >>> 0
+ col = col >>> 0
+ console.error('wasm abort:', `msg ${msg}`, `file ${file}`, `row ${row}`, `col ${col}`)
+ throw new Error(msg, { cause: { file, row, col } })
+ },
+ "performance.now" () {
+ // ~lib/bindings/dom/performance.now() => f64
+ return performance.now()
+ },
+ // ~lib/builtins/trace(~lib/string/String, i32?, f64?, f64?, f64?, f64?, f64?) => void
+ trace: (message: any, n?: number, a0?: number, a1?: number, a2?: number, a3?: number, a4?: number): void => {
+ let string = ''
+ const pointer: number = message >>> 0
+ if (pointer) {
+ const end = pointer + new Uint32Array(exports.memory.buffer)[pointer - 4 >>> 2] >>> 1
+ const memU16 = new Uint16Array(exports.memory.buffer)
+ let start = pointer >>> 1
+ while (end - start > 1024) {
+ string += String.fromCharCode(...memU16.subarray(start, start += 1024))
+ }
+ message = string + String.fromCharCode(...memU16.subarray(start, end))
}
- buffer = undefined
- return pk
- }
+ (() => {
+ // @external.js
+ console.log(message, ...[a0, a1, a2, a3, a4].slice(0, n))
+ })()
+ },
+ memory: new WebAssembly.Memory({ initial: 4, maximum: 4 })
+ }
+ }) as Exports
- sign = function (h: Uint8Array, k: Uint8Array): Uint8Array<ArrayBuffer> {
- // assembly/nano-nacl/sign() => void
- let buffer: DataView | undefined = new DataView(memory.buffer)
- let inPtr = exports.getInputPointer()
- for (let i = 0; i < 32; i++) {
- buffer.setUint8(inPtr + i, h[i])
- }
- inPtr += 32
- for (let i = 0; i < 64; i++) {
- buffer.setUint8(inPtr + i, k[i])
- }
- exports.sign()
- const outPtr = exports.getOutputPointer()
- const s = new Uint8Array(64)
- buffer = new DataView(memory.buffer)
- for (let i = 0; i < 64; i++) {
- s[i] = buffer.getUint8(outPtr + i)
- }
- buffer = undefined
- return s
- }
+ function derive (k: unknown): Uint8Array<ArrayBuffer> {
+ validate('private key', 32, k)
+ let buffer: DataView | undefined = new DataView(exports.memory.buffer)
+ let inPtr = exports.getInputPointer()
+ for (let i = 0; i < 32; i++) {
+ buffer.setUint8(inPtr + i, k[i])
+ }
+ exports.derive()
+ const outPtr = exports.getOutputPointer()
+ const pk = new Uint8Array(32)
+ buffer = new DataView(exports.memory.buffer)
+ for (let i = 0; i < 32; i++) {
+ pk[i] = buffer.getUint8(outPtr + i)
+ }
+ buffer = undefined
+ return pk
+ }
- verify = function (s: Uint8Array, h: Uint8Array, k: Uint8Array): Uint8Array<ArrayBuffer> {
- // assembly/nano-nacl/verify() => void
- let buffer: DataView | undefined = new DataView(memory.buffer)
- let inPtr = exports.getInputPointer()
- for (let i = 0; i < 64; i++) {
- buffer.setUint8(inPtr + i, s[i])
- }
- inPtr += 64
- for (let i = 0; i < 32; i++) {
- buffer.setUint8(inPtr + i, h[i])
- }
- inPtr += 32
- for (let i = 0; i < 32; i++) {
- buffer.setUint8(inPtr + i, k[i])
- }
- exports.verify()
- const outPtr = exports.getOutputPointer()
- const v = new Uint8Array(1)
- buffer = new DataView(memory.buffer)
- v[0] = buffer.getUint8(outPtr)
- buffer = undefined
- return v
- }
+ function sign (h: unknown, k: unknown): Uint8Array<ArrayBuffer> {
+ validate('block hash', 32, h)
+ validate('secret key', 64, k)
+ let buffer: DataView | undefined = new DataView(exports.memory.buffer)
+ let inPtr = exports.getInputPointer()
+ for (let i = 0; i < 32; i++) {
+ buffer.setUint8(inPtr + i, h[i])
+ }
+ inPtr += 32
+ for (let i = 0; i < 64; i++) {
+ buffer.setUint8(inPtr + i, k[i])
+ }
+ exports.sign()
+ const outPtr = exports.getOutputPointer()
+ const s = new Uint8Array(64)
+ buffer = new DataView(exports.memory.buffer)
+ for (let i = 0; i < 64; i++) {
+ s[i] = buffer.getUint8(outPtr + i)
+ }
+ buffer = undefined
+ return s
+ }
- isReady = true
- } catch (err) {
- throw new Error('Error instantiating WebAssembly', { cause: err })
+ function verify (s: unknown, h: unknown, k: unknown): Uint8Array<ArrayBuffer> {
+ validate('signature', 64, s)
+ validate('block hash', 32, h)
+ validate('public key', 32, k)
+ let buffer: DataView | undefined = new DataView(exports.memory.buffer)
+ let inPtr = exports.getInputPointer()
+ for (let i = 0; i < 64; i++) {
+ buffer.setUint8(inPtr + i, s[i])
+ }
+ inPtr += 64
+ for (let i = 0; i < 32; i++) {
+ buffer.setUint8(inPtr + i, h[i])
}
+ inPtr += 32
+ for (let i = 0; i < 32; i++) {
+ buffer.setUint8(inPtr + i, k[i])
+ }
+ exports.verify()
+ const outPtr = exports.getOutputPointer()
+ const v = new Uint8Array(1)
+ buffer = new DataView(exports.memory.buffer)
+ v[0] = buffer.getUint8(outPtr)
+ buffer = undefined
+ return v
}
function hex2bytes (type: string, byteLength: number, hex?: unknown): Uint8Array<ArrayBuffer> {
return bytes
}
- async function handleMessage (msg: any): Promise<void> {
+ function validate (type: string, byteLength: number, bytes: unknown): asserts bytes is Uint8Array<ArrayBuffer> {
+ if (!(bytes instanceof Uint8Array)) {
+ throw new TypeError(`${type} must be Uint8Array`)
+ }
+ if (!('buffer' in bytes)) {
+ throw new TypeError(`${type} must be backed by an ArrayBuffer`)
+ }
+ if (bytes.buffer.byteLength !== byteLength) {
+ throw new TypeError(`${type} must be ${byteLength} bytes`)
+ }
+ }
+
+ let isListening = false
+
+ /**
+ * Parses inbound data when NanoNaCl is started as a Web Worker.
+ * @param {object} message.data - String of worker commands and related data
+ */
+ async function handleMessage (message: unknown): Promise<void> {
let result: any = null
try {
- if (!isReady) await setup()
-
+ if (message == null
+ || typeof message !== 'object'
+ || !('data' in message)
+ || typeof message.data !== 'string'
+ ) {
+ throw new TypeError('Invalid NanoNaClWorker request')
+ }
+ const msg = message as { [key: string]: string }
if (msg.data === 'start') {
- result = 'started'
+ isListening = true
+ postMessage('started')
} else if (msg.data === 'stop') {
- removeEventListener('message', handleMessage)
- result = 'stopped'
- } else {
+ isListening = false
+ postMessage('stopped')
+ } else if (isListening) {
const data: Data = JSON.parse(msg.data)
const { action } = data
if (action === 'derive') {
}
result = verification
}
+ postMessage(result)
}
} catch (err: unknown) {
if (typeof err === 'object' && err != null) {
} else {
result = JSON.stringify(err)
}
- } finally {
postMessage(result)
- addEventListener('message', handleMessage)
}
}
addEventListener('message', handleMessage)
-}
-const NanoNaClWorker = `;await (${NanoNaCl})([${nacl}])`
+ return { derive, sign, verify }
+}
/**
- * HOST CODE
+ * Host code for asynchronous Web Worker
*/
-// Initialize CPU
let isWorkerReady: boolean = false
+let isWorkerListening: boolean = false
let worker: Worker
let url: string
+// Create worker module
function init (): void {
try {
url = URL.createObjectURL(new Blob([NanoNaClWorker], { type: 'text/javascript' }))
}
}
+// Reconstruct worker when errors occur
function reset (): void {
console.warn(`NanoNaCl encountered an error. Reinitializing...`)
isWorkerReady = false
init()
}
+// Check that the worker is running and listening before sending messages
async function start (): Promise<void> {
if (!isWorkerReady) init()
- return new Promise(async (ready, fail): Promise<void> => {
- worker.onmessage = msg => msg.data === 'started' ? ready(msg.data) : fail(msg.data)
- worker.onerror = err => fail(err.message)
- worker.postMessage('start')
- })
+ if (!isWorkerListening) {
+ return new Promise(async (resolve, reject): Promise<void> => {
+ worker.onerror = err => reject(err.message)
+ worker.onmessage = (msg): void => {
+ const result = msg.data
+ if (result === 'started') {
+ console.log('worker started successfully')
+ isWorkerListening = true
+ resolve(result)
+ } else {
+ reject(result)
+ }
+ }
+ worker.postMessage('start')
+ })
+ }
}
+// Send command and relevant data to NanoNaCl worker
async function dispatch (data: { [key: string]: string }): Promise<Uint8Array<ArrayBuffer>> {
return new Promise((resolve, reject) => {
worker.onerror = reject
})
}
+// Request that the worker stop listening without terminating
async function stop (): Promise<void> {
return new Promise((resolve, reject): void => {
worker.onerror = reject
const result = msg.data
if (result === 'stopped') {
console.log('worker stopped successfully')
+ isWorkerListening = false
resolve()
} else {
reject(result)
console.error(err)
throw new Error('Error initializing worker')
}
-
try {
const result = await dispatch(data)
if (!(result instanceof Uint8Array)) {
}
}
-let isReady = false
-let wasm
-let module
-let instance
-let memory: WebAssembly.Memory
-let deriveSync: (k: Uint8Array) => Uint8Array<ArrayBuffer>
-let signSync: (h: Uint8Array, k: Uint8Array) => Uint8Array<ArrayBuffer>
-let verifySync: (s: Uint8Array, h: Uint8Array, k: Uint8Array) => Uint8Array<ArrayBuffer>
-try {
- wasm = Uint8Array.from(nacl)
- module = await WebAssembly.compile(wasm)
- instance = await WebAssembly.instantiate(module, {
- env: {
- abort: (msg: any, file: any, row: any, col: any) => {
- // ~lib/builtins/abort(~lib/string/String | null?, ~lib/string/String | null?, u32?, u32?) => void
- // msg = __liftString(msg >>> 0)
- // file = __liftString(file >>> 0)
- row = row >>> 0
- col = col >>> 0
- console.error('wasm abort:', `msg ${msg}`, `file ${file}`, `row ${row}`, `col ${col}`)
- throw new Error(msg, { cause: { file, row, col } })
- },
- "performance.now" () {
- // ~lib/bindings/dom/performance.now() => f64
- return performance.now()
- },
- trace: (message: any, n?: number, a0?: number, a1?: number, a2?: number, a3?: number, a4?: number) => {
- // ~lib/builtins/trace(~lib/string/String, i32?, f64?, f64?, f64?, f64?, f64?) => void
- message = __liftString(message >>> 0);
- (() => {
- // @external.js
- console.log(message, ...[a0, a1, a2, a3, a4].slice(0, n))
- })()
- },
- memory: new WebAssembly.Memory({ initial: 4, maximum: 4 })
- }
- })
- const { exports } = instance as { exports: { derive: Derive, sign: Sign, verify: Verify, getInputPointer: GetInputPointer, getOutputPointer: GetOutputPointer, memory: WebAssembly.Memory } }
- memory = exports.memory
-
- function __liftString (pointer: number) {
- if (!pointer) return null
- const
- //@ts-ignore
- end = pointer + new Uint32Array(memory.buffer)[pointer - 4 >>> 2] >>> 1,
- //@ts-ignore
- memoryU16 = new Uint16Array(memory.buffer)
- let
- start = pointer >>> 1,
- string = ""
- while (end - start > 1024) string += String.fromCharCode(...memoryU16.subarray(start, start += 1024))
- return string + String.fromCharCode(...memoryU16.subarray(start, end))
- }
+const NanoNaCl = startNanoNaCl(nacl)
+const NanoNaClWorker = `;(${startNanoNaCl})([${nacl}]);`
- deriveSync = function (k: Uint8Array): Uint8Array<ArrayBuffer> {
- // assembly/nano-nacl/derive() => void
- let buffer: DataView | undefined = new DataView(memory.buffer)
- let inPtr = exports.getInputPointer()
- for (let i = 0; i < 32; i++) {
- buffer.setUint8(inPtr + i, k[i])
- }
- exports.derive()
- const outPtr = exports.getOutputPointer()
- const pk = new Uint8Array(32)
- buffer = new DataView(memory.buffer)
- for (let i = 0; i < 32; i++) {
- pk[i] = buffer.getUint8(outPtr + i)
- }
- buffer = undefined
- return pk
- }
+/**
+ * Nano public key derivation using WebAssembly.
+ * @param {Uint8Array<ArrayBuffer>} k - 32-byte private key
+ * @returns 32-byte public key
+ */
+export function derive (k: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer> {
+ return NanoNaCl.derive(k)
+}
- signSync = function (h: Uint8Array, k: Uint8Array): Uint8Array<ArrayBuffer> {
- // assembly/nano-nacl/sign() => void
- let buffer: DataView | undefined = new DataView(memory.buffer)
- let inPtr = exports.getInputPointer()
- for (let i = 0; i < 32; i++) {
- buffer.setUint8(inPtr + i, h[i])
- }
- inPtr += 32
- for (let i = 0; i < 64; i++) {
- buffer.setUint8(inPtr + i, k[i])
- }
- exports.sign()
- const outPtr = exports.getOutputPointer()
- const s = new Uint8Array(64)
- buffer = new DataView(memory.buffer)
- for (let i = 0; i < 64; i++) {
- s[i] = buffer.getUint8(outPtr + i)
- }
- buffer = undefined
- return s
- }
+/**
+ * Nano block signing using WebAssembly.
+ * @param {Uint8Array<ArrayBuffer>} h - 32-byte block hash
+ * @param {Uint8Array<ArrayBuffer>} k - 64-byte secret key (prv + pub)
+ * @returns 64-byte detached signature
+ */
+export function sign (h: Uint8Array<ArrayBuffer>, k: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer> {
+ return NanoNaCl.sign(h, k)
+}
- verifySync = function (s: Uint8Array, h: Uint8Array, k: Uint8Array): Uint8Array<ArrayBuffer> {
- // assembly/nano-nacl/verify() => void
- let buffer: DataView | undefined = new DataView(memory.buffer)
- let inPtr = exports.getInputPointer()
- for (let i = 0; i < 64; i++) {
- buffer.setUint8(inPtr + i, s[i])
- }
- inPtr += 64
- for (let i = 0; i < 32; i++) {
- buffer.setUint8(inPtr + i, h[i])
- }
- inPtr += 32
- for (let i = 0; i < 32; i++) {
- buffer.setUint8(inPtr + i, k[i])
- }
- exports.verify()
- const outPtr = exports.getOutputPointer()
- const v = new Uint8Array(1)
- buffer = new DataView(memory.buffer)
- v[0] = buffer.getUint8(outPtr)
- buffer = undefined
- return v
- }
- isReady = true
-} catch (err) {
- throw new Error('Error instantiating WebAssembly', { cause: err })
+/**
+ * Nano block signature verification using WebAssembly.
+ * @param {Uint8Array<ArrayBuffer>} s - 64-byte detached signature
+ * @param {Uint8Array<ArrayBuffer>} h - 32-byte block hash
+ * @param {Uint8Array<ArrayBuffer>} k - 32-byte public key
+ * @returns true if signature matches block hash and public key, else false
+ */
+export function verify (s: Uint8Array<ArrayBuffer>, h: Uint8Array<ArrayBuffer>, k: Uint8Array<ArrayBuffer>): boolean {
+ return NanoNaCl.verify(s, h, k)[0] === 0
}
-export { deriveSync, signSync, verifySync }
/**
-* Nano public key derivation using WebAssembly.
-*/
-export async function derive (privateKey: string): Promise<string> {
+ * Asynchronous Nano public key derivation using WebAssembly.
+ * @param {Uint8Array<ArrayBuffer>} k - 64-character private key hex string
+ * @returns Promise for 64-character public key hex string
+ */
+export async function deriveAsync (privateKey: string): Promise<string> {
return await run({ action: 'derive', privateKey })
}
/**
-* Nano block signature using WebAssembly.
-*/
-export async function sign (blockHash: string, secretKey: string): Promise<string> {
+ * Asynchronous Nano block signing using WebAssembly.
+ * @param {Uint8Array<ArrayBuffer>} h - 64-character block hash hex string
+ * @param {Uint8Array<ArrayBuffer>} k - 128-character secret key (prv + pub) hex string
+ * @returns Promise for 128-character detached signature hex string
+ */
+export const signAsync = async function (blockHash: string, secretKey: string): Promise<string> {
return await run({ action: 'sign', blockHash, secretKey })
}
/**
-* Nano block signature verification using WebAssembly.
-*/
-export async function verify (signature: string, blockHash: string, publicKey: string): Promise<boolean> {
- const result = await run({ action: 'verify', signature, blockHash, publicKey })
- return result === '00'
+ * Asynchronous Nano block signature verification using WebAssembly.
+ * @param {Uint8Array<ArrayBuffer>} s - 128-character detached signature hex string
+ * @param {Uint8Array<ArrayBuffer>} h - 64-character block hash hex string
+ * @param {Uint8Array<ArrayBuffer>} k - 64-character public key hex string
+ * @returns Promise resolving to true if signature matches block hash and public key, else false
+ */
+export const verifyAsync = async function (signature: string, blockHash: string, publicKey: string): Promise<boolean> {
+ return await run({ action: 'verify', signature, blockHash, publicKey }) === '00'
}
"version": "0.0.1",
"license": "(GPL-3.0-or-later AND MIT)",
"devDependencies": {
- "@types/node": "^25.2.3",
- "assemblyscript": "^0.28.9",
- "esbuild": "^0.27.3",
+ "@types/node": "^25.5.0",
+ "assemblyscript": "^0.28.10",
+ "esbuild": "^0.27.4",
"typescript": "^5.9.3"
},
"funding": {
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
- "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz",
+ "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==",
"cpu": [
"ppc64"
],
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
- "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz",
+ "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==",
"cpu": [
"arm"
],
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
- "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz",
+ "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
- "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz",
+ "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
- "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz",
+ "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
- "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz",
+ "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
- "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz",
+ "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
- "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz",
+ "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
- "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz",
+ "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==",
"cpu": [
"arm"
],
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
- "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz",
+ "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
- "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz",
+ "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==",
"cpu": [
"ia32"
],
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
- "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz",
+ "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==",
"cpu": [
"loong64"
],
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
- "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz",
+ "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==",
"cpu": [
"mips64el"
],
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
- "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz",
+ "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==",
"cpu": [
"ppc64"
],
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
- "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz",
+ "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==",
"cpu": [
"riscv64"
],
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
- "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz",
+ "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==",
"cpu": [
"s390x"
],
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
- "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz",
+ "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz",
+ "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
- "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz",
+ "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz",
+ "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
- "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz",
+ "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
- "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz",
+ "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
- "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz",
+ "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==",
"cpu": [
"x64"
],
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
- "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz",
+ "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==",
"cpu": [
"arm64"
],
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
- "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz",
+ "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==",
"cpu": [
"ia32"
],
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
- "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz",
+ "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==",
"cpu": [
"x64"
],
}
},
"node_modules/@types/node": {
- "version": "25.2.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz",
- "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==",
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz",
+ "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "undici-types": "~7.16.0"
+ "undici-types": "~7.18.0"
}
},
"node_modules/assemblyscript": {
- "version": "0.28.9",
- "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.28.9.tgz",
- "integrity": "sha512-UQqIYSUuJzqQP6fKTs1CtanyxmnDk7K+Kmj/J67agimxDqxjdMnTF/y9rEHUBL+K/VIEV4QYu57RMrL5LwbAvw==",
+ "version": "0.28.10",
+ "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.28.10.tgz",
+ "integrity": "sha512-MGqjjNlPMmcWjfnme3cGFKmbBY/rj0bmE4M1Wg8tNqmHusA1PAjOMgWK67KWBK63lmvotFDoP8e5N0URxKlR/Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
}
},
"node_modules/esbuild": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
- "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz",
+ "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.3",
- "@esbuild/android-arm": "0.27.3",
- "@esbuild/android-arm64": "0.27.3",
- "@esbuild/android-x64": "0.27.3",
- "@esbuild/darwin-arm64": "0.27.3",
- "@esbuild/darwin-x64": "0.27.3",
- "@esbuild/freebsd-arm64": "0.27.3",
- "@esbuild/freebsd-x64": "0.27.3",
- "@esbuild/linux-arm": "0.27.3",
- "@esbuild/linux-arm64": "0.27.3",
- "@esbuild/linux-ia32": "0.27.3",
- "@esbuild/linux-loong64": "0.27.3",
- "@esbuild/linux-mips64el": "0.27.3",
- "@esbuild/linux-ppc64": "0.27.3",
- "@esbuild/linux-riscv64": "0.27.3",
- "@esbuild/linux-s390x": "0.27.3",
- "@esbuild/linux-x64": "0.27.3",
- "@esbuild/netbsd-arm64": "0.27.3",
- "@esbuild/netbsd-x64": "0.27.3",
- "@esbuild/openbsd-arm64": "0.27.3",
- "@esbuild/openbsd-x64": "0.27.3",
- "@esbuild/openharmony-arm64": "0.27.3",
- "@esbuild/sunos-x64": "0.27.3",
- "@esbuild/win32-arm64": "0.27.3",
- "@esbuild/win32-ia32": "0.27.3",
- "@esbuild/win32-x64": "0.27.3"
+ "@esbuild/aix-ppc64": "0.27.4",
+ "@esbuild/android-arm": "0.27.4",
+ "@esbuild/android-arm64": "0.27.4",
+ "@esbuild/android-x64": "0.27.4",
+ "@esbuild/darwin-arm64": "0.27.4",
+ "@esbuild/darwin-x64": "0.27.4",
+ "@esbuild/freebsd-arm64": "0.27.4",
+ "@esbuild/freebsd-x64": "0.27.4",
+ "@esbuild/linux-arm": "0.27.4",
+ "@esbuild/linux-arm64": "0.27.4",
+ "@esbuild/linux-ia32": "0.27.4",
+ "@esbuild/linux-loong64": "0.27.4",
+ "@esbuild/linux-mips64el": "0.27.4",
+ "@esbuild/linux-ppc64": "0.27.4",
+ "@esbuild/linux-riscv64": "0.27.4",
+ "@esbuild/linux-s390x": "0.27.4",
+ "@esbuild/linux-x64": "0.27.4",
+ "@esbuild/netbsd-arm64": "0.27.4",
+ "@esbuild/netbsd-x64": "0.27.4",
+ "@esbuild/openbsd-arm64": "0.27.4",
+ "@esbuild/openbsd-x64": "0.27.4",
+ "@esbuild/openharmony-arm64": "0.27.4",
+ "@esbuild/sunos-x64": "0.27.4",
+ "@esbuild/win32-arm64": "0.27.4",
+ "@esbuild/win32-ia32": "0.27.4",
+ "@esbuild/win32-x64": "0.27.4"
}
},
"node_modules/long": {
}
},
"node_modules/undici-types": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
- "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
+ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"dev": true,
"license": "MIT"
}
"scripts": {
"build": "npm run clean && npm run compile && node ./esbuild.mjs",
"clean": "rm -rf {build,dist}",
- "compile": "asc ./assembly/nano-nacl.ts",
+ "compile": "asc ./assembly/index.ts && tsc",
"prepublishOnly": "npm run build",
"test": "npm run build && node ./test.mjs"
},
"devDependencies": {
- "@types/node": "^25.2.3",
- "assemblyscript": "^0.28.9",
- "esbuild": "^0.27.3",
+ "@types/node": "^25.5.0",
+ "assemblyscript": "^0.28.10",
+ "esbuild": "^0.27.4",
"typescript": "^5.9.3"
},
"type": "module",
"exports": {
".": {
- "types": "./dist/types.d.ts",
+ "types": "./dist/index.d.ts",
"default": "./dist/browser.js"
}
},
- "types": "./dist/types.d.ts",
+ "types": "./dist/index.d.ts",
"unpkg": "./dist/browser.js"
}
"noErrorTruncation": true,
"noFallthroughCasesInSwitch": true,
"strict": true,
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "outDir": "dist",
"lib": [
"DOM",
"ESNext"
]
},
"exclude": [
- "assembly"
+ "assembly",
+ "dist"
]
}