aboutsummaryrefslogtreecommitdiffstats
path: root/src/ark
diff options
context:
space:
mode:
Diffstat (limited to 'src/ark')
-rw-r--r--src/ark/manager.js34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/ark/manager.js b/src/ark/manager.js
index e70acfb..2edcd8a 100644
--- a/src/ark/manager.js
+++ b/src/ark/manager.js
@@ -500,6 +500,32 @@ export class ArkManager {
return action.id;
}
+ // A send whose recipient is one of the USER's own foreign-branch keys (the
+ // NWC pouch): no address, no mailbox delivery — the caller receives the
+ // signed recipient vtxo bytes directly and stores them wherever the branch
+ // lives. Same cosign machinery as send(), so all its failure handling holds.
+ async sendToPubkey(destPubkeyHex, amountSat) {
+ const input = this._selectInput(amountSat);
+ const changeSat = input.amountSat - amountSat;
+ const action = {
+ id: `send-${Date.now()}`, type: 'send', step: 'created',
+ inputId: input.id, amountSat, destAddress: null,
+ destPubkey: destPubkeyHex, destBlindedId: null,
+ changeIndex: changeSat > 0 ? this.state.nextKeyIndex++ : null, changeSat,
+ };
+ input.state = 'pending';
+ this.state.actions.push(action);
+ this._save();
+ await this._driveSend(action);
+ if (action.step !== 'done') throw new Error(action.error || 'send did not complete');
+ return {
+ vtxos: (action.destBytesList || []).map((b) => {
+ const v = decodeVtxo(hex.decode(b));
+ return { id: v.id, bytes: b, amountSat: v.amountSat, expiryHeight: v.expiryHeight };
+ }),
+ };
+ }
+
_sendOutputs(action) {
const outputs = [{ amountSat: action.amountSat, userPubkey: hex.decode(action.destPubkey) }];
if (action.changeSat > 0) {
@@ -558,8 +584,12 @@ export class ArkManager {
this._save();
}
if (action.step === 'registered') {
- await postArkoorMessage(this.arkUrl, hex.decode(action.destBlindedId),
- destList().map((b) => hex.decode(b)));
+ // a pouch-bound send has no mailbox to deliver to — the caller takes
+ // the bytes from the returned action instead
+ if (action.destBlindedId) {
+ await postArkoorMessage(this.arkUrl, hex.decode(action.destBlindedId),
+ destList().map((b) => hex.decode(b)));
+ }
for (const b of changeList()) {
const change = this._vtxo(decodeVtxo(hex.decode(b)).id);
if (change && change.state === 'pending') change.state = 'spendable';