From 28af0c0df34d40ac06613a7083e54f479f92071a Mon Sep 17 00:00:00 2001 From: Harvmaster Date: Fri, 30 Jan 2026 02:08:56 +0000 Subject: [PATCH] add locking bytecode to template --- Electrum.sqlite-journal | Bin 12824 -> 0 bytes src/controllers/invitation-controller.ts | 14 ++------------ src/tui/screens/ActionWizard.tsx | 23 +++++++++++++++++++++-- 3 files changed, 23 insertions(+), 14 deletions(-) delete mode 100644 Electrum.sqlite-journal diff --git a/Electrum.sqlite-journal b/Electrum.sqlite-journal deleted file mode 100644 index 36a5776683ba290b97106af378076a85d51c84d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12824 zcmeI2XOtbqmB-&`q(f z&omsbZmr%{t@Vm3FI7HKSymZSDVBd&ex%IHLrc3$PnL9PLg~z2ZO-$~qs|=1BVFWa zvW`q6{fjRYA1f{@CdFLgnZnk>ZG~F?#r)&>`|{W13r#<0+SPP-(~v%|^!Z$$&OYP& zoYDJdz2DP&c5k=wP~%gLYa6FF_UrZAULS6FreRyd%!Yw*=pX#Vjf)z;xpkz+LzQ|W zlbK?PNYW$?m>bhLpl-@l8u`={KP%Uv&JlDoo^$EO8D})}c|w^dgGdBkz-i+7S(3t^K*Z8lf>S=di#4|W{d_n!k5bR`-4I{N zXv9+H$9|gmp;A1Q)OSV9Gs;E3i@HzeCe#nTgej54evpXROj8Ph5^sKAW|$sSiK~2aiM-3x<*#2)vQE8R4eJf*@D2@QA>vB0NM zD3Rwl$gO3008#%#ZA;W$4B{c0C#)xS1z1qb&4M%@N`nQ|hIh3SY92xrwYzt+NweOtX}R33pS5Qbp2)4E>Da zx>A-YU->*%g7P$b@X0#6L}o(a_*9|D{EUV0JPiUSX$(@h>x&HaW~1&8T2yBjq^=)E zEJPtD+zV0RGKqpP^Z+G*793&oRK$HR9XF)T&P#mZF&fY?OlT&3=0*w2Vy*yS$RgC6 zM}r8Rz>}3n>g`;P`b|;LE(<(ASiK!C#8ZqTUP&Z_OrZuS*bCEGCNT?BFNPy5&4Amc zI=jft66OgR(-c`&F;7uGBICky1p?&9acbX{p@{m9t+Qhhb+a%Q0c9LzNCR|;I7QB) z1e`}flE#9jA&aSh#b@g5sF1#ki$eo~n=(~aCY~!f^O)yJiGWIX6tA;G*F~UH zl&DmJkP*v-&ydh0PTUL~3VkaACya$jv0t|x3R5L6(sr^6gFpz$RFtMc>bVI(pg|DF zk_yy|w|qmLof{-*@L3$kk&Kz=qPNos-6~>n6!~}+pm^XdW{20S+m2^Gut7UR524Hz zB1{6b7RB8xlU^p`5R=6X(e7z7_DG!_=w>PaKj;vC;JPVw1+K_PnFi=+Tna@)t|Bx$ zzs^teE>IF!4$vlTal{P$*M?qZ%ok{Ps21r9#lq%$>&^!@F+jY?i_#3Gf~G(bddgxy zb}<^#$a7;BMIM*DkRgDBtAr1CGn^GX1n6tS{CYbSFT<>p zev~8#PJ;Q%0EdTRgYrx;c2V!1tCX8RyUs4~SP-FkVq#}1^Q0T2ya7G);I-#P7-H}! zp+IB#@4D?0Bv)VvxONKo3UetF9z_@R&>N)iR1&KskQ{FWeScGDhp~Z56JeTo8HLQlhrfwB_0 z&bme)hXJ|?l90*Bm%uI#;~*Ar)2EmK)OEAS!;nF_#>2vHMg>WS ziE;2aMt2A)${_Z=gd@TN8wN5E3Um%I6{o^4*4ZJ&Q6>W}Bc2A-E(MgyG|mu5G__1| z%mI8QM2orL#cn&)vg^iPEHfX3Vf3ijb~b_YFy-3r?=lf)_$&>JAFQ)O^q3ty)I~Tk z8!%@$I7X9U82%A1Poycp@D+16*4bg1Pzo_%JoG$#AH_z&2Sysm0)>8xL7t%NWZ9Ho z*4g8Bdi(NCEe`Y3%l*8NR^+UC-`9+dYlC!q&x}~ zrXb=KQeUu0Vt)$|ziQp}(NqfbA(w_W@*?D(kCh9PNn$g|5}Y^mG0Bxexi!}Li9Ijn zc3qWN1yJLd(CC%1hy69d1dJJW8x%gLZXyb!>-z;*L18l&(>P^p;hH)-^t}uRjL=4SWXn{ck)k@&0NViy9RoRy6$Ts^_t)hQ>mTwQ zp_`+m(4A~Mlh{k0Jy$i3sa?(_LcfOd(#g_|HMuu}$Tn>br2@Bx}zl=uv* z8$Ods;pRF!>}@v32s&0=)NhJ>hTs*q2MpzoeKF<%$GBI~tc7)U0qzCRUxE<%W~eFV zVu&&-qfFqg0h^w}>KqCH;`MpHvW&tV{4u}*$DH#XofYMKr ztGc>R=VFwjm3x`JC?6{ovW43kv`x-&my^a=xYHEf1v}fowmLi9F4827D3&VDq{3Yk zFn4`h$y8Eh7kX^77?7^NpnLBLGXxMTyN{bk+_7TQ4zQ@Y5eNxKnPOT5ArbRZFokou4<~ws~y$()vVfzCkE51 zH&m~!j;_+`sOsQqt=hkOR@JHYt{kfzsJvWxvGPLY=anBwNj`wlnbi8!1^h)Wa((g*YDE(LId!=udzEb*J=@X@ol-^f*XX)Y6 z=F*x{XK7h!acOQzmhLLuQkqg4Um8=oycCp1lrAYtIY*p*&i^`pbbjOf z%=w}79p`J#7oAT#A9p_FyvKRO+3sv`Ryq$lOPw}nw!@vI`xQ zIB#*vP7^sn4w2pDPvpPJFUfP{KgqYqQ{+kVN%HUH{p8=szmhFvEz#tD(oW_PMP`v( z$y73dj3rl)kc=dkk_$;cawZ|9v3Rt&zxdbU{}g{)e7^Xj;M}6|XN|U5txfaai%9;(5is#Y!=cXElSs33?&_^ZbwV-_3s`|K!x{If>D(dJl3kPfqR7^L0o8~|Btc9tNE%#H^k3(bxNkT$cU6|%tWm_K9)&{x5Y`YtByV*7kGSh4u3%Si~3m~_cZ5KmsHrx6_ZZg}NAT!L? ze}POlTW3S2nXNM+Q_a>JAXCiNDv;Fm0WHw&_VPiy(p7ltMhSX$HhKo34Y5GMgx5q}g;SWQ5t& z3>j`V6(GaR#$}M9X5+n(A!g$pkill-M98IPGaDGB*=!gLImc}12kC1z6d`Xh>+gr0ZPw#=BFFrdn04(CV%AAW(X6`}QZVbThvdz= z2-3%_8v^NV*7b)pnso%yVAd|r<;V%Mb{^!YS$h}ch*>)sa@efB8gj_2bs_uB+JTUL zX6;#!-DYhgb;uO7KU%XI3tNeAlc5f8<%S z68w?xn3dpvXN&=V zf&h|UHSz0Bk$BF zz#n;sJ^}v7+x3YXA&=-2;E(LmC%_+hn?3>l$WDC%{E;2{1o$J{^>Oe=w&~;Gk8IV) z!5`V8k6#Dbq>qC?vQZxge`JF`4*tk`eH{FewfY$NBWv_A@JCkbW8jah(#OCbS*eeK zKVtMT@JF;hb|Iuw9|M2nA$_a?@}NEn{>TIRDEK4y>!aY0EYnB9AGuE-1%G6zJ_`QG z5`7f>kq&(n{E>Ej1pJZ3`p8_!B7Fq>k%jsQ_#+GS5%5Rm=_BBe%+*K0AGuc_0e@tU zJ_7#8Y<(E~k$d!E3CZ+f@JEzB4E~7Jhru5a`Y`w-sXh$;2-kdwxmcJSLkmYZ>K4kfu zrVm;Ers_kMzbX3Axsb{FkmYZZK4|&7Q6IGY-JlOz{wC;ymcQ}(pyh9zK4|%C(FZMm z*Xe_nzp?tDKX;TmC$~-}2|`{g%JW^nT0VD80|}H&XAj{Eg82EPuoG zKFi-Qz3+0!5WUaxH(2kp{9UT|S^h53do6z#>%Er0i}YU0-ypr$@;6ZLwfxoeUd!Kw zdavd00=>5{?wT6vaML<;@fG;a-+y45LylhiX?X2lZ}<-!W7OjJ zmaEG#NB)?ruBd#nI=Xzg(pH{U{!(dux#0Y|g>4`v31bQOS6M>!x^hBU10zDDv zi9k;T{y!sd56L$V9^9bI9Xy?f{GQ6Q`+p(%^>NoCQ+d*S=^T z?k!sRl8&~MuUk(!UaNP?%hCgdd^4pDdcdnbb}Z%#+PUbM)3#vN)WvOWS^JFE*S}Xh z-Q(APHZ|Lfl+_crC5hYoGf)z@FfsTa_m{|BzOzbU7$$Tu}l z8TzK2Za>Z4_CkB_eDh_OHR!&tI*MN{FIMgCv&PS9?`T`RY)0#8Z}d6c-P1mQQy!1$ z)6{(PWpC{9X~(oqpY~Rh&iBeU4, ): Promise { - // Ensure each input has an inputIdentifier (sync server requires it) - const inputsWithIds = inputs.map((input, index) => ({ - ...input, - inputIdentifier: input.inputIdentifier ?? `senderInput_${Date.now()}_${index}`, - })); - return this.flowManager.appendToInvitation(invitationId, { inputs: inputsWithIds }); + return this.flowManager.appendToInvitation(invitationId, { inputs }); } /** @@ -158,12 +153,7 @@ export class InvitationController extends EventEmitter { roleIdentifier?: string; }>, ): Promise { - // Ensure each output has an outputIdentifier (sync server may require it) - const outputsWithIds = outputs.map((output, index) => ({ - ...output, - outputIdentifier: output.outputIdentifier ?? `changeOutput_${Date.now()}_${index}`, - })); - return this.flowManager.appendToInvitation(invitationId, { outputs: outputsWithIds }); + return this.flowManager.appendToInvitation(invitationId, { outputs }); } /** diff --git a/src/tui/screens/ActionWizard.tsx b/src/tui/screens/ActionWizard.tsx index d410b5c..de815bc 100644 --- a/src/tui/screens/ActionWizard.tsx +++ b/src/tui/screens/ActionWizard.tsx @@ -276,7 +276,7 @@ export function ActionWizardScreen(): React.ReactElement { * Create invitation and add variables. */ const createInvitationWithVariables = useCallback(async () => { - if (!templateIdentifier || !actionIdentifier || !roleIdentifier) return; + if (!templateIdentifier || !actionIdentifier || !roleIdentifier || !template) return; setIsProcessing(true); setStatus('Creating invitation...'); @@ -305,6 +305,25 @@ export function ActionWizardScreen(): React.ReactElement { inv = updated.invitation; } + // Add template-required outputs for the current role + // This is critical - the template defines which outputs the initiator must create + const action = template.actions?.[actionIdentifier]; + const transaction = action?.transaction ? template.transactions?.[action.transaction] : null; + + if (transaction?.outputs && transaction.outputs.length > 0) { + setStatus('Adding required outputs...'); + + // Add each required output with its identifier + // The engine will automatically generate the locking bytecode based on the template + const outputsToAdd = transaction.outputs.map((outputId: string) => ({ + outputIdentifier: outputId, + roleIdentifier: roleIdentifier, + })); + + const updated = await invitationController.addOutputs(invId, outputsToAdd); + inv = updated.invitation; + } + setInvitation(inv); // Check if next step is inputs @@ -323,7 +342,7 @@ export function ActionWizardScreen(): React.ReactElement { } finally { setIsProcessing(false); } - }, [templateIdentifier, actionIdentifier, roleIdentifier, variables, invitationController, steps, currentStep, showError, setStatus, loadAvailableUtxos]); + }, [templateIdentifier, actionIdentifier, roleIdentifier, template, variables, invitationController, steps, currentStep, showError, setStatus, loadAvailableUtxos]); /** * Add selected inputs and change output to invitation.