@winbit32/wallet-kit 0.1.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/LICENSE +21 -0
- package/README.md +117 -0
- package/dist/cosign/bytes.d.ts +10 -0
- package/dist/cosign/bytes.d.ts.map +1 -0
- package/dist/cosign/bytes.js +37 -0
- package/dist/cosign/bytes.js.map +1 -0
- package/dist/cosign/config.d.ts +58 -0
- package/dist/cosign/config.d.ts.map +1 -0
- package/dist/cosign/config.js +54 -0
- package/dist/cosign/config.js.map +1 -0
- package/dist/cosign/cosignSend.d.ts +104 -0
- package/dist/cosign/cosignSend.d.ts.map +1 -0
- package/dist/cosign/cosignSend.js +157 -0
- package/dist/cosign/cosignSend.js.map +1 -0
- package/dist/cosign/index.d.ts +33 -0
- package/dist/cosign/index.d.ts.map +1 -0
- package/dist/cosign/index.js +49 -0
- package/dist/cosign/index.js.map +1 -0
- package/dist/cosign/initiator.d.ts +121 -0
- package/dist/cosign/initiator.d.ts.map +1 -0
- package/dist/cosign/initiator.js +270 -0
- package/dist/cosign/initiator.js.map +1 -0
- package/dist/cosign/orchardFrost.d.ts +140 -0
- package/dist/cosign/orchardFrost.d.ts.map +1 -0
- package/dist/cosign/orchardFrost.js +227 -0
- package/dist/cosign/orchardFrost.js.map +1 -0
- package/dist/cosign/relay.d.ts +100 -0
- package/dist/cosign/relay.d.ts.map +1 -0
- package/dist/cosign/relay.js +359 -0
- package/dist/cosign/relay.js.map +1 -0
- package/dist/cosign/seed.d.ts +32 -0
- package/dist/cosign/seed.d.ts.map +1 -0
- package/dist/cosign/seed.js +69 -0
- package/dist/cosign/seed.js.map +1 -0
- package/dist/cosign/transports.d.ts +127 -0
- package/dist/cosign/transports.d.ts.map +1 -0
- package/dist/cosign/transports.js +426 -0
- package/dist/cosign/transports.js.map +1 -0
- package/dist/cosign/vaultShare.d.ts +65 -0
- package/dist/cosign/vaultShare.d.ts.map +1 -0
- package/dist/cosign/vaultShare.js +157 -0
- package/dist/cosign/vaultShare.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/monero/types.d.ts +75 -0
- package/dist/monero/types.d.ts.map +1 -0
- package/dist/monero/types.js +9 -0
- package/dist/monero/types.js.map +1 -0
- package/dist/scanner/baseUrl.d.ts +24 -0
- package/dist/scanner/baseUrl.d.ts.map +1 -0
- package/dist/scanner/baseUrl.js +35 -0
- package/dist/scanner/baseUrl.js.map +1 -0
- package/dist/scanner/moneroScannerClient.d.ts +97 -0
- package/dist/scanner/moneroScannerClient.d.ts.map +1 -0
- package/dist/scanner/moneroScannerClient.js +125 -0
- package/dist/scanner/moneroScannerClient.js.map +1 -0
- package/dist/scanner/zcashScannerClient.d.ts +116 -0
- package/dist/scanner/zcashScannerClient.d.ts.map +1 -0
- package/dist/scanner/zcashScannerClient.js +150 -0
- package/dist/scanner/zcashScannerClient.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Orchard (RedPallas) FROST engine bridge.
|
|
4
|
+
*
|
|
5
|
+
* A framework-agnostic port of WINBIT32's `orchardFrostBridge` trimmed to
|
|
6
|
+
* the pieces an initiator needs: load the WASM, derive a UFVK / unified
|
|
7
|
+
* address from a FROST share, and (for tests / local 2-of-2) split a key
|
|
8
|
+
* with a trusted dealer. The two-round signing ceremony wrappers live here
|
|
9
|
+
* so their wire shapes stay matched to the relay protocol.
|
|
10
|
+
*
|
|
11
|
+
* Design for reuse: there is no module-global "current WASM" the way the
|
|
12
|
+
* original bridge keeps one. The loaded module is returned and passed
|
|
13
|
+
* explicitly into each function (dependency injection), so a host can run
|
|
14
|
+
* more than one engine instance and nothing leaks across React renders.
|
|
15
|
+
* The only internal state is a load cache keyed by asset URL.
|
|
16
|
+
*
|
|
17
|
+
* The underlying WASM is `orchard-frost-wasm` (built from frosty-lib /
|
|
18
|
+
* orchard-frost-wasm), served as static assets. See {@link CosignConfig}.
|
|
19
|
+
*/
|
|
20
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
+
}
|
|
26
|
+
Object.defineProperty(o, k2, desc);
|
|
27
|
+
}) : (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
o[k2] = m[k];
|
|
30
|
+
}));
|
|
31
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
+
}) : function(o, v) {
|
|
34
|
+
o["default"] = v;
|
|
35
|
+
});
|
|
36
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.orchardGroupVerifyingKey = exports.orchardGenerateRandomizer = exports.orchardAggregate = exports.orchardSignWithNonces = exports.orchardCommitNonces = exports.deriveOrchardAddressFromBundle = exports.orchardKeygenWithCompatibleExtras = exports.isOrchardCompatibleGroupPublicHex = exports.generateOrchardExtras = exports.orchardKeygenWithDealer = exports.loadOrchardFrostWasm = exports.DEFAULT_KEYGEN_RETRY_LIMIT = void 0;
|
|
45
|
+
/** Attempts before giving up on producing an Orchard-compatible `ak`. */
|
|
46
|
+
exports.DEFAULT_KEYGEN_RETRY_LIMIT = 32;
|
|
47
|
+
// ─── WASM loader (config-injected, cached per asset URL) ────────────
|
|
48
|
+
const wasmCache = new Map();
|
|
49
|
+
const cacheBustSuffix = (config) => config.assetCacheBustToken ? `?v=${encodeURIComponent(config.assetCacheBustToken)}` : '';
|
|
50
|
+
/**
|
|
51
|
+
* Load + initialise the Orchard FROST WASM.
|
|
52
|
+
*
|
|
53
|
+
* Uses `config.loadOrchardFrostWasm` when provided (hosts that bundle the WASM
|
|
54
|
+
* themselves). Otherwise lazily fetches the artefacts from `config.wasmBaseUrl`
|
|
55
|
+
* — the dynamic `import()` is deliberate: it keeps the ~500 KB engine off the
|
|
56
|
+
* critical path until a co-signing flow actually needs it.
|
|
57
|
+
*/
|
|
58
|
+
const loadOrchardFrostWasm = (config) => {
|
|
59
|
+
if (config.loadOrchardFrostWasm) {
|
|
60
|
+
return config.loadOrchardFrostWasm();
|
|
61
|
+
}
|
|
62
|
+
const jsUrl = `${config.wasmBaseUrl}/orchard_frost_wasm.js${cacheBustSuffix(config)}`;
|
|
63
|
+
const wasmUrl = `${config.wasmBaseUrl}/orchard_frost_wasm_bg.wasm${cacheBustSuffix(config)}`;
|
|
64
|
+
const cached = wasmCache.get(jsUrl);
|
|
65
|
+
if (cached)
|
|
66
|
+
return cached;
|
|
67
|
+
const loading = (async () => {
|
|
68
|
+
var _a;
|
|
69
|
+
try {
|
|
70
|
+
const glue = (await (_a = jsUrl, Promise.resolve().then(() => __importStar(require(_a)))));
|
|
71
|
+
const bytes = await config.fetchImpl(wasmUrl).then((r) => r.arrayBuffer());
|
|
72
|
+
await glue.default(bytes);
|
|
73
|
+
return glue;
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
wasmCache.delete(jsUrl);
|
|
77
|
+
throw new Error(`Failed to initialise orchard-frost WASM from ${config.wasmBaseUrl}: ${err.message}`);
|
|
78
|
+
}
|
|
79
|
+
})();
|
|
80
|
+
wasmCache.set(jsUrl, loading);
|
|
81
|
+
return loading;
|
|
82
|
+
};
|
|
83
|
+
exports.loadOrchardFrostWasm = loadOrchardFrostWasm;
|
|
84
|
+
// ─── Engine operations (WASM module injected) ───────────────────────
|
|
85
|
+
/** Trusted-dealer t-of-n split (used by tests and local 2-of-2 setups). */
|
|
86
|
+
const orchardKeygenWithDealer = (wasm, maxSigners, minSigners) => {
|
|
87
|
+
const result = JSON.parse(wasm.keygen_with_dealer(maxSigners, minSigners));
|
|
88
|
+
const shares = {};
|
|
89
|
+
for (const [idHex, share] of Object.entries(result.shares)) {
|
|
90
|
+
shares[idHex] = {
|
|
91
|
+
id: share.id,
|
|
92
|
+
secretShare: share.secret_share,
|
|
93
|
+
publicKey: share.public,
|
|
94
|
+
groupPublic: share.group_public,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
shares,
|
|
99
|
+
publicKeyPackage: {
|
|
100
|
+
signerPubkeys: result.public_key_package.signer_pubkeys,
|
|
101
|
+
groupPublic: result.public_key_package.group_public,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
exports.orchardKeygenWithDealer = orchardKeygenWithDealer;
|
|
106
|
+
/** Generate random 64-byte nk‖rivk extras compatible with `groupPublicHex`. */
|
|
107
|
+
const generateOrchardExtras = (wasm, groupPublicHex) => {
|
|
108
|
+
if (!wasm.orchard_random_extras) {
|
|
109
|
+
throw new Error('orchard-frost WASM lacks orchard_random_extras — rebuild/redeploy the WASM bundle.');
|
|
110
|
+
}
|
|
111
|
+
return wasm.orchard_random_extras(groupPublicHex);
|
|
112
|
+
};
|
|
113
|
+
exports.generateOrchardExtras = generateOrchardExtras;
|
|
114
|
+
/**
|
|
115
|
+
* Whether a 32-byte serialised group_public is a usable Orchard `ak`.
|
|
116
|
+
*
|
|
117
|
+
* Orchard's `SpendValidatingKey::from_bytes` rejects points whose y-sign bit
|
|
118
|
+
* (top bit of byte 31) is set, and the identity (all-zero) point. RedPallas
|
|
119
|
+
* keygen produces a random y-sign, so ~half of keygens are unusable as-is.
|
|
120
|
+
*/
|
|
121
|
+
const isOrchardCompatibleGroupPublicHex = (groupPublicHex) => {
|
|
122
|
+
if (typeof groupPublicHex !== 'string' || groupPublicHex.length !== 64)
|
|
123
|
+
return false;
|
|
124
|
+
const lastByte = parseInt(groupPublicHex.slice(62, 64), 16);
|
|
125
|
+
if (Number.isNaN(lastByte))
|
|
126
|
+
return false;
|
|
127
|
+
if ((lastByte & 0x80) !== 0)
|
|
128
|
+
return false;
|
|
129
|
+
if (/^0+$/.test(groupPublicHex))
|
|
130
|
+
return false;
|
|
131
|
+
return true;
|
|
132
|
+
};
|
|
133
|
+
exports.isOrchardCompatibleGroupPublicHex = isOrchardCompatibleGroupPublicHex;
|
|
134
|
+
/**
|
|
135
|
+
* Trusted-dealer keygen that re-rolls until the group_public is an
|
|
136
|
+
* Orchard-compatible `ak`, then derives matching nk‖rivk extras. With
|
|
137
|
+
* p ≈ 0.5 per attempt, the default 32-attempt cap fails with probability
|
|
138
|
+
* ≈ 2^-32. Returns the keygen, the extras, and how many attempts it took.
|
|
139
|
+
*/
|
|
140
|
+
const orchardKeygenWithCompatibleExtras = (wasm, maxSigners, minSigners, options = {}) => {
|
|
141
|
+
if (!wasm.orchard_random_extras) {
|
|
142
|
+
throw new Error('orchard-frost WASM lacks orchard_random_extras — rebuild/redeploy the WASM bundle.');
|
|
143
|
+
}
|
|
144
|
+
const maxAttempts = Math.max(1, options.maxAttempts ?? exports.DEFAULT_KEYGEN_RETRY_LIMIT);
|
|
145
|
+
let lastError = null;
|
|
146
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
147
|
+
const keygen = (0, exports.orchardKeygenWithDealer)(wasm, maxSigners, minSigners);
|
|
148
|
+
const groupPublic = keygen.publicKeyPackage.groupPublic;
|
|
149
|
+
if (!(0, exports.isOrchardCompatibleGroupPublicHex)(groupPublic)) {
|
|
150
|
+
lastError = new Error(`group_public has wrong y-sign (attempt ${attempt})`);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
return { keygen, orchardExtras: wasm.orchard_random_extras(groupPublic), keygenAttempts: attempt };
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
lastError = err;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const detail = lastError instanceof Error ? lastError.message : String(lastError ?? 'unknown error');
|
|
161
|
+
throw new Error(`orchard-frost keygen could not produce an Orchard-compatible ak after ${maxAttempts} attempts: ${detail}`);
|
|
162
|
+
};
|
|
163
|
+
exports.orchardKeygenWithCompatibleExtras = orchardKeygenWithCompatibleExtras;
|
|
164
|
+
/**
|
|
165
|
+
* Derive the Orchard UFVK + unified address for a FROST share bundle.
|
|
166
|
+
*
|
|
167
|
+
* The group_public is already the 32-byte serialised `ak`, so `ak‖nk‖rivk`
|
|
168
|
+
* trivially yields the Orchard FVK the PCZT will embed and verify against.
|
|
169
|
+
* Backfills missing `orchardExtras` (mutating the bundle so the caller can
|
|
170
|
+
* persist it) — without them the derived UFVK would not match the FROST
|
|
171
|
+
* signer's `ak` and every shielded send would fail.
|
|
172
|
+
*
|
|
173
|
+
* @returns the address pair, or null if extras can't be produced / the WASM
|
|
174
|
+
* lacks the FROST-native helpers.
|
|
175
|
+
*/
|
|
176
|
+
const deriveOrchardAddressFromBundle = (wasm, bundle) => {
|
|
177
|
+
const groupPublicHex = bundle.publicKeyPackage.groupPublic;
|
|
178
|
+
if (!bundle.orchardExtras) {
|
|
179
|
+
try {
|
|
180
|
+
bundle.orchardExtras = (0, exports.generateOrchardExtras)(wasm, groupPublicHex);
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
console.error('[cosign/orchard] could not backfill orchardExtras:', err.message);
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (!wasm.build_orchard_ufvk_from_frost || !wasm.build_orchard_unified_address_from_frost) {
|
|
188
|
+
console.error('[cosign/orchard] WASM lacks build_orchard_*_from_frost — rebuild/redeploy.');
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const ufvk = wasm.build_orchard_ufvk_from_frost(groupPublicHex, bundle.orchardExtras);
|
|
193
|
+
const unifiedAddress = wasm.build_orchard_unified_address_from_frost(groupPublicHex, bundle.orchardExtras);
|
|
194
|
+
return { unifiedAddress, ufvk };
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
console.error('[cosign/orchard] FROST-native address derivation failed:', err.message);
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
exports.deriveOrchardAddressFromBundle = deriveOrchardAddressFromBundle;
|
|
202
|
+
/** Round 1: produce this signer's nonces (opaque) + commitments (shareable). */
|
|
203
|
+
const orchardCommitNonces = (wasm, secretShareHex) => {
|
|
204
|
+
const result = JSON.parse(wasm.commit_nonces(secretShareHex));
|
|
205
|
+
return { noncesOpaque: result.nonces_opaque, commitments: result.commitments };
|
|
206
|
+
};
|
|
207
|
+
exports.orchardCommitNonces = orchardCommitNonces;
|
|
208
|
+
/**
|
|
209
|
+
* Round 2: produce this signer's signature share using its pre-committed
|
|
210
|
+
* nonces. Both parties MUST pass the same `allCommitmentsJson`, `messageHex`
|
|
211
|
+
* (sighash) and `randomizerHex` (the PCZT's per-action `alpha`).
|
|
212
|
+
*/
|
|
213
|
+
const orchardSignWithNonces = (wasm, identifierHex, secretShareHex, publicHex, groupPublicHex, noncesOpaqueHex, allCommitmentsJson, messageHex, randomizerHex) => wasm.sign_with_nonces(identifierHex, secretShareHex, publicHex, groupPublicHex, noncesOpaqueHex, allCommitmentsJson, messageHex, randomizerHex);
|
|
214
|
+
exports.orchardSignWithNonces = orchardSignWithNonces;
|
|
215
|
+
/**
|
|
216
|
+
* Aggregate signature shares into a 64-byte RedPallas signature.
|
|
217
|
+
* Returns the raw WASM JSON (`{ signature, ... }`); callers read `.signature`.
|
|
218
|
+
*/
|
|
219
|
+
const orchardAggregate = (wasm, commitmentsJson, messageHex, sigSharesJson, signerPubkeysJson, groupPublicHex, randomizerHex) => wasm.aggregate(commitmentsJson, messageHex, sigSharesJson, signerPubkeysJson, groupPublicHex, randomizerHex);
|
|
220
|
+
exports.orchardAggregate = orchardAggregate;
|
|
221
|
+
/** Generate a random 32-byte scalar usable as a FROST randomizer (tests only — the live path uses the PCZT's alpha). */
|
|
222
|
+
const orchardGenerateRandomizer = (wasm) => wasm.generate_randomizer();
|
|
223
|
+
exports.orchardGenerateRandomizer = orchardGenerateRandomizer;
|
|
224
|
+
/** Derive the (un-randomized) group verifying key from a group_public. */
|
|
225
|
+
const orchardGroupVerifyingKey = (wasm, groupPublicHex) => wasm.get_group_verifying_key(groupPublicHex);
|
|
226
|
+
exports.orchardGroupVerifyingKey = orchardGroupVerifyingKey;
|
|
227
|
+
//# sourceMappingURL=orchardFrost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchardFrost.js","sourceRoot":"","sources":["../../src/cosign/orchardFrost.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFH,yEAAyE;AAC5D,QAAA,0BAA0B,GAAG,EAAE,CAAC;AAE7C,uEAAuE;AAEvE,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2C,CAAC;AAErE,MAAM,eAAe,GAAG,CAAC,MAAoB,EAAU,EAAE,CACxD,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,kBAAkB,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAE1F;;;;;;;GAOG;AACI,MAAM,oBAAoB,GAAG,CAAC,MAAoB,EAAmC,EAAE;IAC7F,IAAI,MAAM,CAAC,oBAAoB,EAAE;QAChC,OAAO,MAAM,CAAC,oBAAoB,EAAE,CAAC;KACrC;IAED,MAAM,KAAK,GAAG,GAAG,MAAM,CAAC,WAAW,yBAAyB,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IACtF,MAAM,OAAO,GAAG,GAAG,MAAM,CAAC,WAAW,8BAA8B,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IAE7F,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,OAAO,GAAG,CAAC,KAAK,IAAqC,EAAE;;QAC5D,IAAI;YACH,MAAM,IAAI,GAAG,CAAC,YAAgC,KAAK,0DAAC,CAAsC,CAAC;YAC3F,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YAC3E,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;SACZ;QAAC,OAAO,GAAG,EAAE;YACb,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxB,MAAM,IAAI,KAAK,CACd,gDAAgD,MAAM,CAAC,WAAW,KAAM,GAAa,CAAC,OAAO,EAAE,CAC/F,CAAC;SACF;IACF,CAAC,CAAC,EAAE,CAAC;IAEL,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC;AA3BW,QAAA,oBAAoB,wBA2B/B;AAEF,uEAAuE;AAEvE,2EAA2E;AACpE,MAAM,uBAAuB,GAAG,CACtC,IAA4B,EAC5B,UAAkB,EAClB,UAAkB,EACI,EAAE;IACxB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAoC,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAA6B,CAAC,EAAE;QAClF,MAAM,CAAC,KAAK,CAAC,GAAG;YACf,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,WAAW,EAAE,KAAK,CAAC,YAAY;YAC/B,SAAS,EAAE,KAAK,CAAC,MAAM;YACvB,WAAW,EAAE,KAAK,CAAC,YAAY;SAC/B,CAAC;KACF;IACD,OAAO;QACN,MAAM;QACN,gBAAgB,EAAE;YACjB,aAAa,EAAE,MAAM,CAAC,kBAAkB,CAAC,cAAc;YACvD,WAAW,EAAE,MAAM,CAAC,kBAAkB,CAAC,YAAY;SACnD;KACD,CAAC;AACH,CAAC,CAAC;AAtBW,QAAA,uBAAuB,2BAsBlC;AAEF,+EAA+E;AACxE,MAAM,qBAAqB,GAAG,CAAC,IAA4B,EAAE,cAAsB,EAAU,EAAE;IACrG,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;KACtG;IACD,OAAO,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC;AACnD,CAAC,CAAC;AALW,QAAA,qBAAqB,yBAKhC;AAEF;;;;;;GAMG;AACI,MAAM,iCAAiC,GAAG,CAAC,cAAsB,EAAW,EAAE;IACpF,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACrF,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5D,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAPW,QAAA,iCAAiC,qCAO5C;AAEF;;;;;GAKG;AACI,MAAM,iCAAiC,GAAG,CAChD,IAA4B,EAC5B,UAAkB,EAClB,UAAkB,EAClB,UAAoC,EAAE,EACZ,EAAE;IAC5B,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;KACtG;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,IAAI,kCAA0B,CAAC,CAAC;IACnF,IAAI,SAAS,GAAY,IAAI,CAAC;IAC9B,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE;QACxD,MAAM,MAAM,GAAG,IAAA,+BAAuB,EAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC;QACxD,IAAI,CAAC,IAAA,yCAAiC,EAAC,WAAW,CAAC,EAAE;YACpD,SAAS,GAAG,IAAI,KAAK,CAAC,0CAA0C,OAAO,GAAG,CAAC,CAAC;YAC5E,SAAS;SACT;QACD,IAAI;YACH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;SACnG;QAAC,OAAO,GAAG,EAAE;YACb,SAAS,GAAG,GAAG,CAAC;SAChB;KACD;IACD,MAAM,MAAM,GAAG,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,IAAI,eAAe,CAAC,CAAC;IACrG,MAAM,IAAI,KAAK,CAAC,yEAAyE,WAAW,cAAc,MAAM,EAAE,CAAC,CAAC;AAC7H,CAAC,CAAC;AA1BW,QAAA,iCAAiC,qCA0B5C;AAEF;;;;;;;;;;;GAWG;AACI,MAAM,8BAA8B,GAAG,CAC7C,IAA4B,EAC5B,MAAwB,EACM,EAAE;IAChC,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC;IAE3D,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE;QAC1B,IAAI;YACH,MAAM,CAAC,aAAa,GAAG,IAAA,6BAAqB,EAAC,IAAI,EAAE,cAAc,CAAC,CAAC;SACnE;QAAC,OAAO,GAAG,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,oDAAoD,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;YAC5F,OAAO,IAAI,CAAC;SACZ;KACD;IAED,IAAI,CAAC,IAAI,CAAC,6BAA6B,IAAI,CAAC,IAAI,CAAC,wCAAwC,EAAE;QAC1F,OAAO,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAC5F,OAAO,IAAI,CAAC;KACZ;IAED,IAAI;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,6BAA6B,CAAC,cAAc,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QACtF,MAAM,cAAc,GAAG,IAAI,CAAC,wCAAwC,CAAC,cAAc,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QAC3G,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;KAChC;IAAC,OAAO,GAAG,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,0DAA0D,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;QAClG,OAAO,IAAI,CAAC;KACZ;AACF,CAAC,CAAC;AA5BW,QAAA,8BAA8B,kCA4BzC;AAcF,gFAAgF;AACzE,MAAM,mBAAmB,GAAG,CAAC,IAA4B,EAAE,cAAsB,EAAmB,EAAE;IAC5G,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;IAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,aAAa,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;AAChF,CAAC,CAAC;AAHW,QAAA,mBAAmB,uBAG9B;AAEF;;;;GAIG;AACI,MAAM,qBAAqB,GAAG,CACpC,IAA4B,EAC5B,aAAqB,EACrB,cAAsB,EACtB,SAAiB,EACjB,cAAsB,EACtB,eAAuB,EACvB,kBAA0B,EAC1B,UAAkB,EAClB,aAAqB,EACZ,EAAE,CACX,IAAI,CAAC,gBAAgB,CACpB,aAAa,EACb,cAAc,EACd,SAAS,EACT,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,UAAU,EACV,aAAa,CACb,CAAC;AApBU,QAAA,qBAAqB,yBAoB/B;AAEH;;;GAGG;AACI,MAAM,gBAAgB,GAAG,CAC/B,IAA4B,EAC5B,eAAuB,EACvB,UAAkB,EAClB,aAAqB,EACrB,iBAAyB,EACzB,cAAsB,EACtB,aAAqB,EACZ,EAAE,CACX,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC;AATjG,QAAA,gBAAgB,oBASiF;AAE9G,wHAAwH;AACjH,MAAM,yBAAyB,GAAG,CAAC,IAA4B,EAAU,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;AAAjG,QAAA,yBAAyB,6BAAwE;AAE9G,0EAA0E;AACnE,MAAM,wBAAwB,GAAG,CAAC,IAA4B,EAAE,cAAsB,EAAU,EAAE,CACxG,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,CAAC;AADjC,QAAA,wBAAwB,4BACS"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview WB32COSIGN relay client + Orchard FROST initiator ceremony.
|
|
3
|
+
*
|
|
4
|
+
* A framework-agnostic port of the initiator half of WINBIT32's
|
|
5
|
+
* `cosignerRelay`, scoped to the `frost-orchard` protocol. Wire format, QR
|
|
6
|
+
* payload, AES-256-GCM envelopes and the two-round message protocol are
|
|
7
|
+
* byte-compatible with WINBIT32, so the existing `cosign.exe` cosigner
|
|
8
|
+
* interoperates unchanged. (Canonical home — ported from Secresea's
|
|
9
|
+
* `services/cosign/relay.ts`.)
|
|
10
|
+
*
|
|
11
|
+
* Reuse-oriented: the WASM engine is injected (no module-global), encryption
|
|
12
|
+
* uses standard Web Crypto, and message delivery goes through any
|
|
13
|
+
* {@link CosignTransport}. The DKLS / Schnorr / Sapling protocols and the
|
|
14
|
+
* trusted-dealer DKG regen path are intentionally omitted — Secresea
|
|
15
|
+
* co-signs an *existing* Orchard vault share, never creates one.
|
|
16
|
+
*/
|
|
17
|
+
import type { CosignTransport } from './transports';
|
|
18
|
+
import { type OrchardFrostWasmModule } from './orchardFrost';
|
|
19
|
+
export interface SigningDisplay {
|
|
20
|
+
chain: string;
|
|
21
|
+
amount?: string;
|
|
22
|
+
toAddress?: string;
|
|
23
|
+
ticker?: string;
|
|
24
|
+
memo?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface CosignSessionParams {
|
|
27
|
+
sessionId: string;
|
|
28
|
+
encKeyHex: string;
|
|
29
|
+
/** Relay URL embedded in the QR (informational; transport may override). */
|
|
30
|
+
relayUrl: string;
|
|
31
|
+
}
|
|
32
|
+
export interface FrostOrchardSetup {
|
|
33
|
+
/** Per-action Orchard sighash (hex). */
|
|
34
|
+
sighash: string;
|
|
35
|
+
/** Per-action `alpha` randomiser the PCZT pre-committed to (64 hex chars). */
|
|
36
|
+
randomizer: string;
|
|
37
|
+
pubKeyPackage: {
|
|
38
|
+
signerPubkeys: Record<string, string>;
|
|
39
|
+
groupPublic: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface OrchardKeyShareForCosign {
|
|
43
|
+
id: string;
|
|
44
|
+
secretShare: string;
|
|
45
|
+
publicKey: string;
|
|
46
|
+
groupPublic: string;
|
|
47
|
+
}
|
|
48
|
+
export interface CosignCallbacks {
|
|
49
|
+
onProgress?: (phase: string) => void;
|
|
50
|
+
onCosignerJoined?: (partyId: string) => void;
|
|
51
|
+
signal?: AbortSignal;
|
|
52
|
+
}
|
|
53
|
+
export interface MPCSignatureResult {
|
|
54
|
+
/** 64-byte RedPallas signature (hex). */
|
|
55
|
+
signature: string;
|
|
56
|
+
rawSignatureBytes: Uint8Array;
|
|
57
|
+
}
|
|
58
|
+
/** Thrown when the cosigner asks to (re)derive keys — Secresea won't do that. */
|
|
59
|
+
export declare class OrchardShareMismatchError extends Error {
|
|
60
|
+
readonly code = "ORCHARD_SHARE_MISMATCH";
|
|
61
|
+
constructor();
|
|
62
|
+
}
|
|
63
|
+
export declare const generateCosignQR: (params: CosignSessionParams) => string;
|
|
64
|
+
export declare const parseCosignQR: (qr: string) => CosignSessionParams | null;
|
|
65
|
+
/** Create a fresh session (random id + AES-256 key) and its QR payload. */
|
|
66
|
+
export declare const createCosignSession: (relayUrl?: string) => {
|
|
67
|
+
params: CosignSessionParams;
|
|
68
|
+
qrPayload: string;
|
|
69
|
+
};
|
|
70
|
+
/** Tell the cosigner the session is finished so it stops polling. */
|
|
71
|
+
export declare const endCosignSession: (encKeyHex: string, transport: CosignTransport) => Promise<void>;
|
|
72
|
+
export interface WaitForCosignerParams {
|
|
73
|
+
encKeyHex: string;
|
|
74
|
+
transport: CosignTransport;
|
|
75
|
+
/** Vultisig localPartyIds permitted to join this vault's session. */
|
|
76
|
+
validSignerIds: string[];
|
|
77
|
+
callbacks?: CosignCallbacks;
|
|
78
|
+
}
|
|
79
|
+
/** Block until a valid cosigner scans the QR and joins; returns its partyId. */
|
|
80
|
+
export declare const waitForCosignerJoin: (p: WaitForCosignerParams) => Promise<string>;
|
|
81
|
+
export interface RunOrchardInitiatorParams {
|
|
82
|
+
/** Loaded Orchard FROST WASM engine. */
|
|
83
|
+
wasm: OrchardFrostWasmModule;
|
|
84
|
+
encKeyHex: string;
|
|
85
|
+
transport: CosignTransport;
|
|
86
|
+
myPartyId: string;
|
|
87
|
+
orchardKeyShare: OrchardKeyShareForCosign;
|
|
88
|
+
frostOrchardData: FrostOrchardSetup;
|
|
89
|
+
display: SigningDisplay;
|
|
90
|
+
callbacks?: CosignCallbacks;
|
|
91
|
+
/** Keep the cosigner connected for a subsequent action (multi-action PCZTs). */
|
|
92
|
+
keepAlive?: boolean;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Run the two-round FROST-Orchard ceremony for a single Orchard action and
|
|
96
|
+
* return its aggregated 64-byte signature. Mirrors WINBIT32's
|
|
97
|
+
* `runInitiatorFrostOrchard` (minus the DKG regen branch).
|
|
98
|
+
*/
|
|
99
|
+
export declare const runOrchardInitiatorAction: (p: RunOrchardInitiatorParams) => Promise<MPCSignatureResult>;
|
|
100
|
+
//# sourceMappingURL=relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/cosign/relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAIN,KAAK,sBAAsB,EAC3B,MAAM,gBAAgB,CAAC;AAgBxB,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IACjC,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9E;AAED,MAAM,WAAW,wBAAwB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,UAAU,CAAC;CAC9B;AAED,iFAAiF;AACjF,qBAAa,yBAA0B,SAAQ,KAAK;IACnD,QAAQ,CAAC,IAAI,4BAA4B;;CAOzC;AA6JD,eAAO,MAAM,gBAAgB,WAAY,mBAAmB,KAAG,MAG9D,CAAC;AAEF,eAAO,MAAM,aAAa,OAAQ,MAAM,KAAG,mBAAmB,GAAG,IAUhE,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,cAAe,MAAM;YAAa,mBAAmB;eAAa,MAAM;CAKvG,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,cAAqB,MAAM,aAAa,eAAe,KAAG,QAAQ,IAAI,CAOlG,CAAC;AAIF,MAAM,WAAW,qBAAqB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,eAAe,CAAC;IAC3B,qEAAqE;IACrE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,MAAa,qBAAqB,KAAG,QAAQ,MAAM,CAsBlF,CAAC;AAIF,MAAM,WAAW,yBAAyB;IACzC,wCAAwC;IACxC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,wBAAwB,CAAC;IAC1C,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,gFAAgF;IAChF,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,MAAa,yBAAyB,KAAG,QAAQ,kBAAkB,CAsIxG,CAAC"}
|