diff options
| author | Adam Soltys <[email protected]> | 2026-08-14 20:12:03 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-14 20:12:03 -0700 |
| commit | 222391a31361e42db713d1737d5a6e15cf8d5ed2 (patch) | |
| tree | 4bf06a03b11de7ac898b578971372ca7f843e6f9 /src/ark/send.js | |
| parent | 4bd22c0c45ae35388b2a24e673bedcde5df77961 (diff) | |
| download | coinosv3-222391a31361e42db713d1737d5a6e15cf8d5ed2.tar.gz coinosv3-222391a31361e42db713d1737d5a6e15cf8d5ed2.zip | |
A send covers itself from as many coins as it needs: one atomic package cosign spends them all, the recipient receives several vtxos, and "consolidate with refresh() first" retires from the vocabulary
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
Diffstat (limited to 'src/ark/send.js')
| -rw-r--r-- | src/ark/send.js | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/ark/send.js b/src/ark/send.js index 0e63c7c..f0e471a 100644 --- a/src/ark/send.js +++ b/src/ark/send.js @@ -461,13 +461,25 @@ export function combineCosign({ build, nonces, serverResp, vtxoKeys, serverPubke // full MuSig2 ceremony over the ASP's RequestArkoorCosign export async function cosignWithServer(ark, build, { input, vtxoKeys, serverPubkey, preimage }) { - const nonces = genUserNonces(build, vtxoKeys); + const [sigs] = await cosignPackageWithServer(ark, [{ build, input, vtxoKeys, preimage }], serverPubkey); + return sigs; +} + +// Same ceremony for a PACKAGE of arkoor parts (one per input vtxo) in a single +// atomic request — the server cosigns all or none, so a multi-input send can't +// half-spend. Returns one finalSigs array per part, in order. +export async function cosignPackageWithServer(ark, parts, serverPubkey) { + const noncesList = parts.map((p) => genUserNonces(p.build, p.vtxoKeys)); const req = pbWriter(); - req.bytesField(1, cosignPartBytes({ build, input, vtxoKeys, nonces, preimage })); + parts.forEach((p, i) => req.bytesField(1, cosignPartBytes({ + build: p.build, input: p.input, vtxoKeys: p.vtxoKeys, nonces: noncesList[i], preimage: p.preimage, + }))); const respBytes = await grpcCall(ark, 'bark_server.ArkService/RequestArkoorCosign', req.finish()); - const [serverResp] = parsePackageCosignResponse(respBytes); - if (!serverResp) throw new Error('empty cosign response'); - return combineCosign({ build, nonces, serverResp, vtxoKeys, serverPubkey }); + const resps = parsePackageCosignResponse(respBytes); + if (resps.length !== parts.length) throw new Error('bad cosign response count'); + return parts.map((p, i) => combineCosign({ + build: p.build, nonces: noncesList[i], serverResp: resps[i], vtxoKeys: p.vtxoKeys, serverPubkey, + })); } // assemble the final signed Vtxo<Full> bytes for output `idx`, where idx |
