@openrai/nano-core 2.3.1 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -18
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/signing/noms.d.ts +30 -0
- package/dist/signing/noms.d.ts.map +1 -0
- package/dist/signing/noms.js +53 -0
- package/dist/signing/noms.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -21,30 +21,36 @@ npm install @openrai/nano-core
|
|
|
21
21
|
## 🛠 Quick Start
|
|
22
22
|
|
|
23
23
|
### 1. Minimal Client
|
|
24
|
-
|
|
24
|
+
`nano-core` handles endpoint selection, auth redaction, and precision-safe math so you can focus on the task at hand:
|
|
25
25
|
|
|
26
26
|
```typescript
|
|
27
|
-
import { NanoClient } from '@openrai/nano-core';
|
|
27
|
+
import { NanoClient, NanoAddress, NanoAmount } from '@openrai/nano-core';
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
'https://work.primary.example.com?key=secret-work',
|
|
40
|
-
'https://rpc.nano.to',
|
|
41
|
-
], // [Optional] Defaults to `https://rpc.nano.to` as the current public work endpoint
|
|
42
|
-
warn: (message) => console.warn(message), // [Optional] Defaults to console.warn with nano-core prefix
|
|
43
|
-
});
|
|
29
|
+
// Start with built-in public endpoints — no config required
|
|
30
|
+
const client = NanoClient.initialize();
|
|
31
|
+
|
|
32
|
+
// Validate a destination address (checksum-verified, throws on bad input)
|
|
33
|
+
const destination = NanoAddress.parse(
|
|
34
|
+
'nano_3arg3asgtigae3xckabaaewkx3bzsh7nwz7jkmjos79ihyaxwphhm6qgjps4',
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Express value in human-readable NANO — stored as precision-safe raw internally
|
|
38
|
+
const amount = NanoAmount.fromNano('1.25');
|
|
44
39
|
|
|
45
|
-
|
|
40
|
+
// Hydrate a wallet from a seed (keep your seed in an env var, never hard-code it)
|
|
41
|
+
const wallet = await client.hydrateWallet(process.env.NANO_SEED!, { index: 0 });
|
|
42
|
+
const hash = await wallet.send(destination, amount);
|
|
43
|
+
|
|
44
|
+
console.log(`Sent ${amount} NANO → ${destination}`);
|
|
45
|
+
console.log(`Block hash: ${hash}`);
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
Under the hood, `nano-core` has already:
|
|
49
|
+
- Selected a live RPC from the built-in April 2026 public pool
|
|
50
|
+
- Validated the address checksum and derived the public key
|
|
51
|
+
- Stored `1.25 NANO` as `1250000000000000000000000000000` raw — no float drift
|
|
52
|
+
- Redacted any API keys from audit output
|
|
53
|
+
|
|
48
54
|
### 1.1 Observe Endpoint Selection
|
|
49
55
|
|
|
50
56
|
Long-running services can observe which upstream endpoint became active without
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { NanoAddress } from './primitives/NanoAddress.js';
|
|
2
2
|
export { NanoAmount } from './primitives/NanoAmount.js';
|
|
3
|
+
export { NOMS } from './signing/noms.js';
|
|
3
4
|
export { WorkProvider, RemoteWorkServer, LocalCompute, type WorkProviderOptions } from './work/WorkProvider.js';
|
|
4
5
|
export { NanoClient, TransportFallback, type NanoClientOptions, type NanoClientActiveEndpoints, type NanoClientAuditReport } from './client.js';
|
|
5
6
|
export { EndpointPool, HttpEndpointPool, NanoTransportConfigError, WsEndpointPool, normalizeEndpoints, } from './transport/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,KAAK,yBAAyB,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAChJ,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,EACd,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,KAAK,yBAAyB,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAChJ,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,EACd,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { NanoAddress } from './primitives/NanoAddress.js';
|
|
2
2
|
export { NanoAmount } from './primitives/NanoAmount.js';
|
|
3
|
+
export { NOMS } from './signing/noms.js';
|
|
3
4
|
export { WorkProvider, RemoteWorkServer, LocalCompute } from './work/WorkProvider.js';
|
|
4
5
|
export { NanoClient, TransportFallback } from './client.js';
|
|
5
6
|
export { EndpointPool, HttpEndpointPool, NanoTransportConfigError, WsEndpointPool, normalizeEndpoints, } from './transport/index.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAA4B,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAsF,MAAM,aAAa,CAAC;AAChJ,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,EACd,kBAAkB,GACnB,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAA4B,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAsF,MAAM,aAAa,CAAC;AAChJ,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,EACd,kBAAkB,GACnB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nano Off-chain Message Signing (NOMS) implementation (ORIS-001).
|
|
3
|
+
*/
|
|
4
|
+
export declare const NOMS: {
|
|
5
|
+
/**
|
|
6
|
+
* Constructs the binary payload for an off-chain message as per ORIS-001.
|
|
7
|
+
* Format: MAGIC_HEADER (25 bytes) || MESSAGE_LENGTH (4 bytes uint32be) || MESSAGE (UTF-8)
|
|
8
|
+
*/
|
|
9
|
+
createPayload(message: string): Uint8Array;
|
|
10
|
+
/**
|
|
11
|
+
* Computes the 32-byte Blake2b hash of the NOMS payload.
|
|
12
|
+
*/
|
|
13
|
+
hashMessage(message: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Signs an off-chain message using standard Nano Ed25519 behavior.
|
|
16
|
+
* @param message The UTF-8 string message to sign.
|
|
17
|
+
* @param secretKey The 32-byte private key in hexadecimal format.
|
|
18
|
+
* @returns The 64-byte signature in hexadecimal format (128 characters).
|
|
19
|
+
*/
|
|
20
|
+
signMessage(message: string, secretKey: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Verifies an off-chain message signature against a public key.
|
|
23
|
+
* @param message The UTF-8 string message that was signed.
|
|
24
|
+
* @param signature The 64-byte signature in hexadecimal format.
|
|
25
|
+
* @param publicKey The 32-byte public key in hexadecimal format.
|
|
26
|
+
* @returns True if the signature is valid for the given message and public key.
|
|
27
|
+
*/
|
|
28
|
+
verifyMessage(message: string, signature: string, publicKey: string): boolean;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=noms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noms.d.ts","sourceRoot":"","sources":["../../src/signing/noms.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,eAAO,MAAM,IAAI;IACf;;;OAGG;2BACoB,MAAM,GAAG,UAAU;IAa1C;;OAEG;yBACkB,MAAM,GAAG,MAAM;IAKpC;;;;;OAKG;yBACkB,MAAM,aAAa,MAAM,GAAG,MAAM;IAKvD;;;;;;OAMG;2BACoB,MAAM,aAAa,MAAM,aAAa,MAAM,GAAG,OAAO;CAI9E,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import blake from 'blakejs';
|
|
2
|
+
import * as nanocurrency from 'nanocurrency';
|
|
3
|
+
const { blake2bHex } = blake;
|
|
4
|
+
const MAGIC_HEADER_TEXT = '\x18Nano Off-chain Message:\n';
|
|
5
|
+
const MAGIC_HEADER_BYTES = new TextEncoder().encode(MAGIC_HEADER_TEXT);
|
|
6
|
+
/**
|
|
7
|
+
* Nano Off-chain Message Signing (NOMS) implementation (ORIS-001).
|
|
8
|
+
*/
|
|
9
|
+
export const NOMS = {
|
|
10
|
+
/**
|
|
11
|
+
* Constructs the binary payload for an off-chain message as per ORIS-001.
|
|
12
|
+
* Format: MAGIC_HEADER (25 bytes) || MESSAGE_LENGTH (4 bytes uint32be) || MESSAGE (UTF-8)
|
|
13
|
+
*/
|
|
14
|
+
createPayload(message) {
|
|
15
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
16
|
+
const lengthBytes = new Uint8Array(4);
|
|
17
|
+
new DataView(lengthBytes.buffer).setUint32(0, messageBytes.length, false);
|
|
18
|
+
const payload = new Uint8Array(MAGIC_HEADER_BYTES.length + lengthBytes.length + messageBytes.length);
|
|
19
|
+
payload.set(MAGIC_HEADER_BYTES, 0);
|
|
20
|
+
payload.set(lengthBytes, MAGIC_HEADER_BYTES.length);
|
|
21
|
+
payload.set(messageBytes, MAGIC_HEADER_BYTES.length + lengthBytes.length);
|
|
22
|
+
return payload;
|
|
23
|
+
},
|
|
24
|
+
/**
|
|
25
|
+
* Computes the 32-byte Blake2b hash of the NOMS payload.
|
|
26
|
+
*/
|
|
27
|
+
hashMessage(message) {
|
|
28
|
+
const payload = this.createPayload(message);
|
|
29
|
+
return blake2bHex(payload, undefined, 32);
|
|
30
|
+
},
|
|
31
|
+
/**
|
|
32
|
+
* Signs an off-chain message using standard Nano Ed25519 behavior.
|
|
33
|
+
* @param message The UTF-8 string message to sign.
|
|
34
|
+
* @param secretKey The 32-byte private key in hexadecimal format.
|
|
35
|
+
* @returns The 64-byte signature in hexadecimal format (128 characters).
|
|
36
|
+
*/
|
|
37
|
+
signMessage(message, secretKey) {
|
|
38
|
+
const hash = this.hashMessage(message);
|
|
39
|
+
return nanocurrency.signBlock({ hash, secretKey }).toLowerCase();
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* Verifies an off-chain message signature against a public key.
|
|
43
|
+
* @param message The UTF-8 string message that was signed.
|
|
44
|
+
* @param signature The 64-byte signature in hexadecimal format.
|
|
45
|
+
* @param publicKey The 32-byte public key in hexadecimal format.
|
|
46
|
+
* @returns True if the signature is valid for the given message and public key.
|
|
47
|
+
*/
|
|
48
|
+
verifyMessage(message, signature, publicKey) {
|
|
49
|
+
const hash = this.hashMessage(message);
|
|
50
|
+
return nanocurrency.verifyBlock({ hash, signature, publicKey });
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=noms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noms.js","sourceRoot":"","sources":["../../src/signing/noms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,KAAK,YAAY,MAAM,cAAc,CAAC;AAE7C,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;AAE7B,MAAM,iBAAiB,GAAG,+BAA+B,CAAC;AAC1D,MAAM,kBAAkB,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB;;;OAGG;IACH,aAAa,CAAC,OAAe;QAC3B,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAE1E,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,kBAAkB,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QACrG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,kBAAkB,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QAE1E,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,OAAe;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,OAAe,EAAE,SAAiB;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,YAAY,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACnE,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,OAAe,EAAE,SAAiB,EAAE,SAAiB;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,YAAY,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAClE,CAAC;CACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openrai/nano-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "Protocol engine for Nano integration ecosystem",
|
|
5
5
|
"repository": "https://github.com/OpenRai/nano-core",
|
|
6
6
|
"type": "module",
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
"dist"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"
|
|
46
|
+
"blakejs": "^1.2.1",
|
|
47
|
+
"nano-pow-with-fallback": "github:cbrunnkvist/nano-pow-with-fallback#v1.2.1",
|
|
47
48
|
"nanocurrency": "^2.5.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|