@totemsdk/omnia-host 0.2.2 → 0.4.0
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 +7 -6
- package/dist/identity.js +16 -1
- package/dist/signing.d.ts +13 -10
- package/dist/signing.js +17 -16
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -38,12 +38,13 @@ The daemon configuration is read from environment variables:
|
|
|
38
38
|
|
|
39
39
|
### Signing model
|
|
40
40
|
|
|
41
|
-
`OMNIA_HOST_SEED` (or the keyfile) is the base seed. The host derives
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
channel participant's `publicKeyDigest` is
|
|
45
|
-
|
|
46
|
-
they survive restarts together
|
|
41
|
+
`OMNIA_HOST_SEED` (or the keyfile) is the base seed. The host derives the unified
|
|
42
|
+
child TreeKey (`createUnifiedChildTreeKey(baseSeed, localAddressIndex)`) and signs
|
|
43
|
+
every channel state (and the boot manifest) with serialized TreeSignatures; the
|
|
44
|
+
channel participant's `publicKeyDigest` is that TreeKey's root public key, and the
|
|
45
|
+
identity address is the matching Minima address. The WOTS lease journal and
|
|
46
|
+
watermark persist in `<OMNIA_HOST_DB>.lease/` so they survive restarts together
|
|
47
|
+
with the channel database.
|
|
47
48
|
|
|
48
49
|
### Read-only mode
|
|
49
50
|
|
package/dist/identity.js
CHANGED
|
@@ -92,7 +92,22 @@ async function createHostManifest(config, signing, identity) {
|
|
|
92
92
|
capabilities: ['omnia:open-channel', 'omnia:update-channel', 'omnia:route', 'omnia:settle'],
|
|
93
93
|
tags: ['omnia', 'payment-channel', 'daemon'],
|
|
94
94
|
};
|
|
95
|
-
|
|
95
|
+
// RFC-037: sign the manifest with the unified child TreeKey. Allocate a
|
|
96
|
+
// one-time leaf via the lease so restarts never reuse a WOTS leaf.
|
|
97
|
+
const reservation = await signing.leaseProvider.reserveKeyUse({
|
|
98
|
+
treeId: 'omnia-manifest',
|
|
99
|
+
purpose: 'manifest',
|
|
100
|
+
});
|
|
101
|
+
const useIndex = reservation.indices.l1 * 64 + reservation.indices.l2;
|
|
102
|
+
try {
|
|
103
|
+
const signed = await (0, manifest_1.signManifest)(manifest, signing.treeKey, useIndex);
|
|
104
|
+
await signing.leaseProvider.commitKeyUse(reservation.reservationId, 'manifest');
|
|
105
|
+
return signed;
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
await signing.leaseProvider.burnReservation(reservation.reservationId, 'manifest-sign-failed').catch(() => { });
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
96
111
|
}
|
|
97
112
|
/** Boot-time identity + manifest assembly. */
|
|
98
113
|
async function createHostIdentityAndManifest(config, signing) {
|
package/dist/signing.d.ts
CHANGED
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
* Host signing material — derives the channel signer, WOTS lease provider,
|
|
3
3
|
* and Minima address from env-provisioned key material.
|
|
4
4
|
*
|
|
5
|
-
* Key model (
|
|
5
|
+
* Key model (RFC-037 unified WOTS):
|
|
6
6
|
* - `baseSeed` comes from OMNIA_HOST_SEED (BIP39 mnemonic or 32-byte hex)
|
|
7
7
|
* or from an OMNIA_HOST_KEYFILE JSON.
|
|
8
|
-
* -
|
|
9
|
-
*
|
|
10
|
-
* `
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
8
|
+
* - The channel key is the unified child TreeKey
|
|
9
|
+
* `createUnifiedChildTreeKey(baseSeed, localAddressIndex)`; the participant's
|
|
10
|
+
* `publicKeyDigest` is its tree-root public key — the same key the on-chain
|
|
11
|
+
* `MULTISIG` eltoo script embeds.
|
|
12
|
+
* - Signatures are serialized hierarchical `TreeSignature`s (`serializeTreeSignature`)
|
|
13
|
+
* over the reserved leaf `(l1*64 + l2)`, verified by `verifyChannelSignature`.
|
|
14
|
+
* - The lease indices {addressIndex, l1, l2} select the one-time leaf.
|
|
15
15
|
*
|
|
16
16
|
* The lease journal/watermark persist in a directory next to the channel DB
|
|
17
17
|
* (`<dbPath>.lease/`) so they survive restarts together with the channel store.
|
|
18
18
|
*/
|
|
19
|
+
import { type TreeKey } from '@totemsdk/core';
|
|
19
20
|
import type { StorageAdapter } from '@totemsdk/core';
|
|
20
21
|
import type { ChannelSigner } from '@totemsdk/omnia';
|
|
21
22
|
import type { WotsLeaseProvider } from '@totemsdk/wots-lease';
|
|
@@ -23,12 +24,14 @@ import type { OmniaHostConfig } from './config.js';
|
|
|
23
24
|
export interface HostSigning {
|
|
24
25
|
signer: ChannelSigner;
|
|
25
26
|
leaseProvider: WotsLeaseProvider;
|
|
27
|
+
/** Minima address for the unified child TreeKey (identity + channels). */
|
|
26
28
|
address: string;
|
|
29
|
+
/** Channel participant key: the unified child TreeKey root pubkey (RFC-037). */
|
|
27
30
|
publicKeyDigest: string;
|
|
28
31
|
/** 32-byte base seed (used by the identity/manifest layer). */
|
|
29
32
|
baseSeed: Uint8Array;
|
|
30
|
-
/**
|
|
31
|
-
|
|
33
|
+
/** Unified child TreeKey used for channel + manifest signing (RFC-037). */
|
|
34
|
+
treeKey: TreeKey;
|
|
32
35
|
addressIndex: number;
|
|
33
36
|
deviceId: string;
|
|
34
37
|
}
|
package/dist/signing.js
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
* Host signing material — derives the channel signer, WOTS lease provider,
|
|
4
4
|
* and Minima address from env-provisioned key material.
|
|
5
5
|
*
|
|
6
|
-
* Key model (
|
|
6
|
+
* Key model (RFC-037 unified WOTS):
|
|
7
7
|
* - `baseSeed` comes from OMNIA_HOST_SEED (BIP39 mnemonic or 32-byte hex)
|
|
8
8
|
* or from an OMNIA_HOST_KEYFILE JSON.
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
* `
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
9
|
+
* - The channel key is the unified child TreeKey
|
|
10
|
+
* `createUnifiedChildTreeKey(baseSeed, localAddressIndex)`; the participant's
|
|
11
|
+
* `publicKeyDigest` is its tree-root public key — the same key the on-chain
|
|
12
|
+
* `MULTISIG` eltoo script embeds.
|
|
13
|
+
* - Signatures are serialized hierarchical `TreeSignature`s (`serializeTreeSignature`)
|
|
14
|
+
* over the reserved leaf `(l1*64 + l2)`, verified by `verifyChannelSignature`.
|
|
15
|
+
* - The lease indices {addressIndex, l1, l2} select the one-time leaf.
|
|
16
16
|
*
|
|
17
17
|
* The lease journal/watermark persist in a directory next to the channel DB
|
|
18
18
|
* (`<dbPath>.lease/`) so they survive restarts together with the channel store.
|
|
@@ -173,10 +173,10 @@ function createHostSigning(config) {
|
|
|
173
173
|
throw new Error(`localAddressIndex ${addressIndex} is outside device slot ${deviceSlot} range ` +
|
|
174
174
|
`${range.startAddressIndex}–${range.endAddressIndex}`);
|
|
175
175
|
}
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
const publicKeyDigest = `0x${(0, core_1.bytesToHex)(
|
|
179
|
-
const address = (0, core_1.
|
|
176
|
+
const treeKey = (0, core_1.createUnifiedChildTreeKey)(baseSeed, addressIndex);
|
|
177
|
+
const publicKey = treeKey.getPublicKey();
|
|
178
|
+
const publicKeyDigest = `0x${(0, core_1.bytesToHex)(publicKey)}`;
|
|
179
|
+
const address = (0, core_1.scriptToAddress)((0, core_1.scriptFromWotsPk)(publicKey));
|
|
180
180
|
const storage = new JsonFileStorageAdapter(leaseStorageDir(config.dbPath));
|
|
181
181
|
const leaseProvider = new wots_lease_1.LocalLeaseProvider(storage, undefined, deviceId);
|
|
182
182
|
const signer = {
|
|
@@ -184,13 +184,14 @@ function createHostSigning(config) {
|
|
|
184
184
|
async sign(payload, indices) {
|
|
185
185
|
// RFC-020 C1: honor the reserved leaf instead of hardcoding index 0. The
|
|
186
186
|
// reservation must belong to this signer's address; the leaf within the
|
|
187
|
-
// per-address
|
|
188
|
-
//
|
|
187
|
+
// per-address tree is (l1*64 + l2). Signatures are serialized TreeSignatures
|
|
188
|
+
// (RFC-037), verified by verifyChannelSignature against the tree-root pubkey.
|
|
189
189
|
if (indices.addressIndex !== addressIndex) {
|
|
190
190
|
throw new Error(`omnia-host signer address ${addressIndex} cannot sign reserved address ${indices.addressIndex}`);
|
|
191
191
|
}
|
|
192
192
|
const leafIndex = indices.l1 * 64 + indices.l2;
|
|
193
|
-
|
|
193
|
+
treeKey.setUses(leafIndex);
|
|
194
|
+
return (0, core_1.serializeTreeSignature)(treeKey.sign(payload));
|
|
194
195
|
},
|
|
195
196
|
};
|
|
196
197
|
return {
|
|
@@ -199,7 +200,7 @@ function createHostSigning(config) {
|
|
|
199
200
|
address,
|
|
200
201
|
publicKeyDigest,
|
|
201
202
|
baseSeed,
|
|
202
|
-
|
|
203
|
+
treeKey,
|
|
203
204
|
addressIndex,
|
|
204
205
|
deviceId,
|
|
205
206
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totemsdk/omnia-host",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Durable Omnia node daemon for channel lifecycle, routing, and control APIs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -24,16 +24,16 @@
|
|
|
24
24
|
"ws": "^8.21.1",
|
|
25
25
|
"@totemsdk/chain-provider": "^0.2.1",
|
|
26
26
|
"@totemsdk/core": "^1.2.11",
|
|
27
|
-
"@totemsdk/
|
|
27
|
+
"@totemsdk/omnia": "^2.0.1",
|
|
28
28
|
"@totemsdk/manifest": "^1.0.0",
|
|
29
|
-
"@totemsdk/
|
|
30
|
-
"@totemsdk/omnia-factory": "^0.
|
|
31
|
-
"@totemsdk/omnia-splice": "^0.
|
|
32
|
-
"@totemsdk/omnia-
|
|
33
|
-
"@totemsdk/
|
|
29
|
+
"@totemsdk/identity": "^1.0.1",
|
|
30
|
+
"@totemsdk/omnia-factory": "^0.4.0",
|
|
31
|
+
"@totemsdk/omnia-splice": "^0.3.0",
|
|
32
|
+
"@totemsdk/omnia-router": "^0.3.0",
|
|
33
|
+
"@totemsdk/omnia-vtxo": "^0.5.0",
|
|
34
34
|
"@totemsdk/storage": "^0.1.0",
|
|
35
|
-
"@totemsdk/
|
|
36
|
-
"@totemsdk/
|
|
35
|
+
"@totemsdk/minima-rpc": "^0.2.2",
|
|
36
|
+
"@totemsdk/wots-lease": "^1.0.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/jest": "^30.0.0",
|