@toon-protocol/townhouse 0.8.0 → 0.9.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/dist/chunk-BLNEL3QS.js +39 -0
- package/dist/chunk-BLNEL3QS.js.map +1 -0
- package/dist/{chunk-BDT2FIQL.js → chunk-UBFITLPQ.js} +116 -17
- package/dist/chunk-UBFITLPQ.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/compose/townhouse-dev.yml +1 -1
- package/dist/compose/townhouse-hs.yml +10 -10
- package/dist/{demo-CKC6HA7X.js → demo-COZ7SB5F.js} +2 -2
- package/dist/image-manifest.json +12 -12
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{manager-CKTAGzVH.d.ts → manager-BzalncRW.d.ts} +16 -4
- package/package.json +5 -5
- package/dist/chunk-BDT2FIQL.js.map +0 -1
- package/dist/chunk-RCHQDZBZ.js +0 -46
- package/dist/chunk-RCHQDZBZ.js.map +0 -1
- /package/dist/{demo-CKC6HA7X.js.map → demo-COZ7SB5F.js.map} +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/constants.ts
|
|
4
|
+
var CONTAINER_PREFIX = "townhouse-";
|
|
5
|
+
var NODE_BTP_PORT = 3e3;
|
|
6
|
+
var DEFAULT_CONNECTOR_IMAGE = (
|
|
7
|
+
// v3.9.0 — wires Solana + Mina settlement end-to-end (toon-protocol/connector#86).
|
|
8
|
+
// Adds non-EVM key resolution (chainProviders[].keyId as a raw base58 private
|
|
9
|
+
// key, or SOLANA_PRIVATE_KEY / MINA_PRIVATE_KEY env), bootstrap registration of
|
|
10
|
+
// Solana/Mina payment-channel providers, and the non-EVM branch in the
|
|
11
|
+
// settlement executor. EVM settlement is unchanged. Builds on 3.8.1's dual-party
|
|
12
|
+
// Mina claim path (#84) and 3.8.0's libsql migration (#79) + relation-aware
|
|
13
|
+
// inbound claim validation (#78). No breaking changes to the SDK/admin contract
|
|
14
|
+
// within 3.x (verified >=3.3.2 through 3.9.0 — see packages/sdk/CONNECTOR_MIGRATION.md).
|
|
15
|
+
// Digest resolved via `docker buildx imagetools inspect` for tag 3.9.0. To bump:
|
|
16
|
+
// see CONNECTOR_RELEASE_CONTRACT.md.
|
|
17
|
+
"ghcr.io/toon-protocol/connector@sha256:673a49e30a5b9ae3968fe7ef5ca99b6ceca21bb69996bda68cd18ec335b874fe"
|
|
18
|
+
);
|
|
19
|
+
var ACCOUNT_INDEX_TOWN = 0;
|
|
20
|
+
var ACCOUNT_INDEX_MILL = 1;
|
|
21
|
+
var ACCOUNT_INDEX_DVM = 2;
|
|
22
|
+
var ACCOUNT_INDEX_APEX = 3;
|
|
23
|
+
var TOWN_HEALTH_PORT = 3100;
|
|
24
|
+
var MILL_HEALTH_PORT = 3200;
|
|
25
|
+
var DVM_HEALTH_PORT = 3400;
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
CONTAINER_PREFIX,
|
|
29
|
+
NODE_BTP_PORT,
|
|
30
|
+
DEFAULT_CONNECTOR_IMAGE,
|
|
31
|
+
ACCOUNT_INDEX_TOWN,
|
|
32
|
+
ACCOUNT_INDEX_MILL,
|
|
33
|
+
ACCOUNT_INDEX_DVM,
|
|
34
|
+
ACCOUNT_INDEX_APEX,
|
|
35
|
+
TOWN_HEALTH_PORT,
|
|
36
|
+
MILL_HEALTH_PORT,
|
|
37
|
+
DVM_HEALTH_PORT
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=chunk-BLNEL3QS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Shared constants for Townhouse package.\n *\n * Single source of truth for values used across multiple modules\n * (orchestrator, config-generator, CLI).\n */\n\n/** Container name prefix for all Townhouse-managed Docker containers */\nexport const CONTAINER_PREFIX = 'townhouse-';\n\n/** Internal BTP port exposed by node containers (Docker-internal only) */\nexport const NODE_BTP_PORT = 3000;\n\n/**\n * Default connector Docker image — digest-pinned per CONNECTOR_RELEASE_CONTRACT.md.\n *\n * To bump: capture a new digest by running the Story 45.1 publish workflow\n * against the desired connector tag, copy the resulting image-manifest.json\n * connector entry's digest, and update this constant + the contract canary\n * fixture. See packages/sdk/CONNECTOR_RELEASE_CONTRACT.md for the full bump\n * checklist + breaking-changes history.\n *\n * To read the human-readable tag for log output, consult dist/image-manifest.json:\n * manifest.images.connector.tag\n */\nexport const DEFAULT_CONNECTOR_IMAGE =\n // v3.9.0 — wires Solana + Mina settlement end-to-end (toon-protocol/connector#86).\n // Adds non-EVM key resolution (chainProviders[].keyId as a raw base58 private\n // key, or SOLANA_PRIVATE_KEY / MINA_PRIVATE_KEY env), bootstrap registration of\n // Solana/Mina payment-channel providers, and the non-EVM branch in the\n // settlement executor. EVM settlement is unchanged. Builds on 3.8.1's dual-party\n // Mina claim path (#84) and 3.8.0's libsql migration (#79) + relation-aware\n // inbound claim validation (#78). No breaking changes to the SDK/admin contract\n // within 3.x (verified >=3.3.2 through 3.9.0 — see packages/sdk/CONNECTOR_MIGRATION.md).\n // Digest resolved via `docker buildx imagetools inspect` for tag 3.9.0. To bump:\n // see CONNECTOR_RELEASE_CONTRACT.md.\n 'ghcr.io/toon-protocol/connector@sha256:673a49e30a5b9ae3968fe7ef5ca99b6ceca21bb69996bda68cd18ec335b874fe';\n\n/**\n * HD wallet account indices per node type (Story 21.4, D21-008).\n * BIP-44 paths: m/44'/{coin}'/ACCOUNT'/0/0\n */\nexport const ACCOUNT_INDEX_TOWN = 0;\nexport const ACCOUNT_INDEX_MILL = 1;\nexport const ACCOUNT_INDEX_DVM = 2;\n/**\n * Apex (connector) settlement account. The apex is the parent connector\n * (`g.townhouse`) that signs settlement claims; its key is derived from the\n * operator mnemonic at this index so the operator never has to supply a raw\n * settlement key. Index 3 continues the town/mill/dvm sequence (and matches the\n * dev convention where the apex is Anvil account[3], 0x90F79bf6…).\n */\nexport const ACCOUNT_INDEX_APEX = 3;\n\n/** BLS health port exposed by each node container type (internal Docker port). */\nexport const TOWN_HEALTH_PORT = 3100;\nexport const MILL_HEALTH_PORT = 3200;\nexport const DVM_HEALTH_PORT = 3400;\n"],"mappings":";;;AAQO,IAAM,mBAAmB;AAGzB,IAAM,gBAAgB;AActB,IAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWX;AAAA;AAMK,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAQ1B,IAAM,qBAAqB;AAG3B,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;","names":[]}
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
MILL_HEALTH_PORT,
|
|
36
36
|
NODE_BTP_PORT,
|
|
37
37
|
TOWN_HEALTH_PORT
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-BLNEL3QS.js";
|
|
39
39
|
import {
|
|
40
40
|
__commonJS,
|
|
41
41
|
__require,
|
|
@@ -14187,6 +14187,56 @@ var HDKey = class _HDKey {
|
|
|
14187
14187
|
|
|
14188
14188
|
// ../core/dist/index.js
|
|
14189
14189
|
import { getPublicKey as getPublicKey5 } from "nostr-tools/pure";
|
|
14190
|
+
function hexToBytes3(hex) {
|
|
14191
|
+
const clean3 = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
14192
|
+
if (clean3.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(clean3)) {
|
|
14193
|
+
throw new Error(`Invalid hex string: ${hex}`);
|
|
14194
|
+
}
|
|
14195
|
+
return hexToBytes2(clean3);
|
|
14196
|
+
}
|
|
14197
|
+
function concatBytes3(...parts) {
|
|
14198
|
+
let len = 0;
|
|
14199
|
+
for (const p of parts) len += p.length;
|
|
14200
|
+
const out = new Uint8Array(len);
|
|
14201
|
+
let o = 0;
|
|
14202
|
+
for (const p of parts) {
|
|
14203
|
+
out.set(p, o);
|
|
14204
|
+
o += p.length;
|
|
14205
|
+
}
|
|
14206
|
+
return out;
|
|
14207
|
+
}
|
|
14208
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
14209
|
+
function base58Encode(bytes) {
|
|
14210
|
+
let zeros = 0;
|
|
14211
|
+
for (let i = 0; i < bytes.length && bytes[i] === 0; i++) zeros++;
|
|
14212
|
+
let value = 0n;
|
|
14213
|
+
for (const byte of bytes) {
|
|
14214
|
+
value = value * 256n + BigInt(byte);
|
|
14215
|
+
}
|
|
14216
|
+
let result = "";
|
|
14217
|
+
while (value > 0n) {
|
|
14218
|
+
result = BASE58_ALPHABET[Number(value % 58n)] + result;
|
|
14219
|
+
value = value / 58n;
|
|
14220
|
+
}
|
|
14221
|
+
for (let i = 0; i < zeros; i++) {
|
|
14222
|
+
result = "1" + result;
|
|
14223
|
+
}
|
|
14224
|
+
return result || "1";
|
|
14225
|
+
}
|
|
14226
|
+
var MINA_PRIVATE_KEY_VERSION = 90;
|
|
14227
|
+
function hexToMinaBase58PrivateKey(privateKey) {
|
|
14228
|
+
if (!/^(0x)?[0-9a-fA-F]{64}$/.test(privateKey)) {
|
|
14229
|
+
return privateKey;
|
|
14230
|
+
}
|
|
14231
|
+
const beScalar = hexToBytes3(privateKey);
|
|
14232
|
+
const leScalar = Uint8Array.from(beScalar).reverse();
|
|
14233
|
+
const payload = concatBytes3(
|
|
14234
|
+
Uint8Array.from([MINA_PRIVATE_KEY_VERSION, 1]),
|
|
14235
|
+
leScalar
|
|
14236
|
+
);
|
|
14237
|
+
const checksum2 = sha2562(sha2562(payload)).slice(0, 4);
|
|
14238
|
+
return base58Encode(concatBytes3(payload, checksum2));
|
|
14239
|
+
}
|
|
14190
14240
|
var ILP_TO_SEMANTIC = Object.freeze({
|
|
14191
14241
|
T00: "internal_error",
|
|
14192
14242
|
T04: "insufficient_funds",
|
|
@@ -14505,13 +14555,25 @@ function writeHsConnectorConfig(configDir, config, options = {}) {
|
|
|
14505
14555
|
}
|
|
14506
14556
|
}
|
|
14507
14557
|
const apexEvmKey = options.apexSettlementKeys?.evmPrivateKeyHex;
|
|
14558
|
+
const apexSolanaKey = options.apexSettlementKeys?.solanaPrivateKeyBase58;
|
|
14559
|
+
const apexMinaKey = options.apexSettlementKeys?.minaPrivateKeyBase58;
|
|
14508
14560
|
const derived = resolveConfigNetworkProfile(
|
|
14509
14561
|
config,
|
|
14510
14562
|
apexEvmKey ?? DEFAULT_HS_CHAIN_PROVIDERS[0]?.keyId
|
|
14511
14563
|
).chainProviders;
|
|
14512
|
-
const fillApexKey = (providers) => providers.map(
|
|
14513
|
-
(p
|
|
14514
|
-
|
|
14564
|
+
const fillApexKey = (providers) => providers.map((p) => {
|
|
14565
|
+
if (p.keyId) return p;
|
|
14566
|
+
if (p.chainType === "evm" && apexEvmKey) {
|
|
14567
|
+
return { ...p, keyId: apexEvmKey };
|
|
14568
|
+
}
|
|
14569
|
+
if (p.chainType === "solana" && apexSolanaKey) {
|
|
14570
|
+
return { ...p, keyId: apexSolanaKey };
|
|
14571
|
+
}
|
|
14572
|
+
if (p.chainType === "mina" && apexMinaKey) {
|
|
14573
|
+
return { ...p, keyId: apexMinaKey };
|
|
14574
|
+
}
|
|
14575
|
+
return p;
|
|
14576
|
+
});
|
|
14515
14577
|
const hsConfig = derived.length > 0 ? { ...config, chainProviders: fillApexKey(derived) } : { ...config, chainProviders: [...DEFAULT_HS_CHAIN_PROVIDERS] };
|
|
14516
14578
|
const generator = new ConnectorConfigGenerator(hsConfig);
|
|
14517
14579
|
const baseConfig = generator.generate([]);
|
|
@@ -18076,15 +18138,15 @@ function deriveSolana(seed, accountIndex) {
|
|
|
18076
18138
|
}
|
|
18077
18139
|
|
|
18078
18140
|
// src/wallet/manager.ts
|
|
18079
|
-
var
|
|
18080
|
-
function
|
|
18141
|
+
var BASE58_ALPHABET2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
18142
|
+
function base58Encode2(bytes) {
|
|
18081
18143
|
let zeros = 0;
|
|
18082
18144
|
for (let i = 0; i < bytes.length && bytes[i] === 0; i++) zeros++;
|
|
18083
18145
|
let value = 0n;
|
|
18084
18146
|
for (const byte of bytes) value = value * 256n + BigInt(byte);
|
|
18085
18147
|
let result = "";
|
|
18086
18148
|
while (value > 0n) {
|
|
18087
|
-
result =
|
|
18149
|
+
result = BASE58_ALPHABET2[Number(value % 58n)] + result;
|
|
18088
18150
|
value = value / 58n;
|
|
18089
18151
|
}
|
|
18090
18152
|
for (let i = 0; i < zeros; i++) result = "1" + result;
|
|
@@ -18237,7 +18299,7 @@ var WalletManager = class {
|
|
|
18237
18299
|
accountIndex: derivationIndex
|
|
18238
18300
|
});
|
|
18239
18301
|
if (chainKeys.solana) {
|
|
18240
|
-
solanaAddress =
|
|
18302
|
+
solanaAddress = base58Encode2(chainKeys.solana.publicKey);
|
|
18241
18303
|
solanaPrivateKey = chainKeys.solana.privateKey;
|
|
18242
18304
|
solanaDerivationPath = chainKeys.solana.path;
|
|
18243
18305
|
}
|
|
@@ -18279,29 +18341,66 @@ var WalletManager = class {
|
|
|
18279
18341
|
*
|
|
18280
18342
|
* Returns the EVM private key as a `0x`-prefixed 64-char hex string — the
|
|
18281
18343
|
* form the connector config's `keyId` expects (matches the dev placeholder
|
|
18282
|
-
* `0x7c85…`).
|
|
18283
|
-
*
|
|
18344
|
+
* `0x7c85…`). Also returns Solana + Mina settlement keys (connector 3.9.0)
|
|
18345
|
+
* derived at the same `ACCOUNT_INDEX_APEX`, in the RAW base58 form the
|
|
18346
|
+
* connector resolves a non-EVM `keyId` as:
|
|
18347
|
+
* - Solana: base58 of the 32-byte Ed25519 seed,
|
|
18348
|
+
* - Mina: `EK…` base58check (via `hexToMinaBase58PrivateKey`).
|
|
18349
|
+
*
|
|
18350
|
+
* EVM derivation must always succeed (it throws on failure). Solana/Mina
|
|
18351
|
+
* derivation is best-effort: if `deriveMillKeys` throws (unsupported
|
|
18352
|
+
* platform, library load error) the corresponding key is OMITTED rather than
|
|
18353
|
+
* failing the whole method, so the EVM keyId path is never blocked.
|
|
18354
|
+
*
|
|
18355
|
+
* Async because `deriveMillKeys` is async. Throws when the wallet is locked.
|
|
18284
18356
|
*/
|
|
18285
|
-
getApexSettlementKeys() {
|
|
18357
|
+
async getApexSettlementKeys() {
|
|
18286
18358
|
if (!this.state) {
|
|
18287
18359
|
throw new Error(
|
|
18288
18360
|
"Wallet not initialized. Call generate() or fromMnemonic() first."
|
|
18289
18361
|
);
|
|
18290
18362
|
}
|
|
18363
|
+
const mnemonic = this.state.mnemonic;
|
|
18291
18364
|
let seed;
|
|
18365
|
+
let evmPrivateKeyHex;
|
|
18292
18366
|
try {
|
|
18293
|
-
seed = mnemonicToSeedSync(
|
|
18367
|
+
seed = mnemonicToSeedSync(mnemonic);
|
|
18294
18368
|
const path = `m/44'/60'/${ACCOUNT_INDEX_APEX}'/0/0`;
|
|
18295
18369
|
const hd = HDKey.fromMasterSeed(seed).derive(path);
|
|
18296
18370
|
if (!hd.privateKey) {
|
|
18297
18371
|
throw new Error(`Apex EVM private key missing at ${path}`);
|
|
18298
18372
|
}
|
|
18299
|
-
|
|
18300
|
-
evmPrivateKeyHex: `0x${bytesToHex(new Uint8Array(hd.privateKey))}`
|
|
18301
|
-
};
|
|
18373
|
+
evmPrivateKeyHex = `0x${bytesToHex(new Uint8Array(hd.privateKey))}`;
|
|
18302
18374
|
} finally {
|
|
18303
18375
|
if (seed) seed.fill(0);
|
|
18304
18376
|
}
|
|
18377
|
+
let solanaPrivateKeyBase58;
|
|
18378
|
+
let minaPrivateKeyBase58;
|
|
18379
|
+
try {
|
|
18380
|
+
const chainKeys = await deriveMillKeys({
|
|
18381
|
+
mnemonic,
|
|
18382
|
+
chains: ["solana", "mina"],
|
|
18383
|
+
accountIndex: ACCOUNT_INDEX_APEX
|
|
18384
|
+
});
|
|
18385
|
+
if (chainKeys.solana) {
|
|
18386
|
+
solanaPrivateKeyBase58 = base58Encode(chainKeys.solana.privateKey);
|
|
18387
|
+
}
|
|
18388
|
+
if (chainKeys.mina) {
|
|
18389
|
+
minaPrivateKeyBase58 = hexToMinaBase58PrivateKey(
|
|
18390
|
+
chainKeys.mina.privateKey
|
|
18391
|
+
);
|
|
18392
|
+
}
|
|
18393
|
+
} catch (err) {
|
|
18394
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
18395
|
+
console.warn(
|
|
18396
|
+
`[WalletManager] deriveMillKeys failed for apex (accountIndex=${ACCOUNT_INDEX_APEX}): ${errMsg} \u2014 Solana/Mina apex keys omitted`
|
|
18397
|
+
);
|
|
18398
|
+
}
|
|
18399
|
+
return {
|
|
18400
|
+
evmPrivateKeyHex,
|
|
18401
|
+
...solanaPrivateKeyBase58 ? { solanaPrivateKeyBase58 } : {},
|
|
18402
|
+
...minaPrivateKeyBase58 ? { minaPrivateKeyBase58 } : {}
|
|
18403
|
+
};
|
|
18305
18404
|
}
|
|
18306
18405
|
/**
|
|
18307
18406
|
* Returns the Solana Ed25519 private key seed for a node as a 64-char
|
|
@@ -18447,7 +18546,7 @@ var WalletManager = class {
|
|
|
18447
18546
|
accountIndex
|
|
18448
18547
|
});
|
|
18449
18548
|
if (chainKeys.solana) {
|
|
18450
|
-
chainExtras[nodeType].solanaAddress =
|
|
18549
|
+
chainExtras[nodeType].solanaAddress = base58Encode2(
|
|
18451
18550
|
chainKeys.solana.publicKey
|
|
18452
18551
|
);
|
|
18453
18552
|
chainExtras[nodeType].solanaPrivateKey = chainKeys.solana.privateKey;
|
|
@@ -22904,4 +23003,4 @@ export {
|
|
|
22904
23003
|
@scure/bip32/index.js:
|
|
22905
23004
|
(*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
22906
23005
|
*/
|
|
22907
|
-
//# sourceMappingURL=chunk-
|
|
23006
|
+
//# sourceMappingURL=chunk-UBFITLPQ.js.map
|