From 0c31e3b326717d321dd6d45c88c913d1427c5e92 Mon Sep 17 00:00:00 2001 From: Joe Pegler Date: Fri, 14 Jun 2024 13:10:18 +0100 Subject: [PATCH 01/33] chore: dan skeleton --- bun.lockb | Bin 802471 -> 802623 bytes src/components/Modules/CreateDanSession.tsx | 111 ++++++++++++++++++++ src/components/Modules/UseDanSession.tsx | 33 ++++++ src/components/TabsBody.tsx | 70 +++++++++++- 4 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 src/components/Modules/CreateDanSession.tsx create mode 100644 src/components/Modules/UseDanSession.tsx diff --git a/bun.lockb b/bun.lockb index a51dd95054f86e987875fd2735343a778a6a9970..590e278f5a56485d8c6758c600b27c9568137b9b 100755 GIT binary patch delta 18361 zcmXZg2mEW}9mnz9b?!i@5j!n`@?OL@A+K zxh)l=71e6gilSoYsu8XcJNkRRpXa<@C-3L^+~;JRoD=uD`KyiZA8&kFZqgm+&AD*S zq`T)#Zah3`()`iGlMgU*9npX>eSE57PfptUw#RiNa|Dj?Nf{!#SKnvm@D;A**iIHLnI*|NCF@i3nK2apz}=O-qK5_BLr zSuuhxq^2mAp$F-yiWTTXW}0FZ1`q~{H5fv6x?&whkei{{fHCA}DmEdQrC9-55MNBO z2yI9#u2_N&B$rT(pbIITocU$wL3&B8tUw>7RuBjM77gB2}mZ1mfwG}JShfGSb z3IhngrC5U@WYK(PpINNlKBf(|6piV<`nwUJ^O zdXU~&u>yU_Y@%3&0fd_>)?f(P%@pe}g52hc4H!dy3&kb`8O;jNg7}t-MQB4}E5#CY zAi1?-1YJmNqgaL>q`$3Lfj(rmRjk4Q!tE4mFobNVScehhwpVPx81g$PHX)d;SpixQ z-%+s$ZAk2-Sb`2DcUFv`3#nZc%g}>#RJ+1(ZEFoN73iVYY; zeow_F1bb;#fEL8}RxCmr5;?^ZbRaoLF@i3n_E9WD57PT8R-g}={S>P(fbcttH5fwn zyNY!fL2iG=28|bnVhK8sJX$e=E~JWz zW#~cr7{vJ-H?^dNnzVg>q;IZd$&0|-x7ticenKUA#42y&5P1ICa)L$L|LnVJ=# z1@Rv#7NHG^vlL6vf#lhW5p*GSj$#>lkp8h^1^SRFD^_6u;e=uhhLAm1u?{21ou}A< zG33uzY(nr8%?i+h_yvkZXhY&c#S(NNSy7Cj3#qw^W#~crBE<^yA#<@}6$TLgRIvs_ z$o@>R4kO6@T(JRT$X}w^grKTf0a_5hRIvzcNL;2^f(|5qp%_6IQomFzLl4rwQmjB9 zGM6h>VF2Mg#TpDDTT`sV2y*ik8!(3a6^cy=uGFjmEr?&GScEntu2w8T2a?w)M$m=S zwTflvLAtJ3fj(q@tyqNtgx4w7U+Z7uyhI~`83Betj z6`%$2I~9x2hQ#j`OVEMjU5XKOA@v8vGV~z*N5u;CA#=B46$TKt6l*Yq>;lC)j3DRV+dq5`R%FK?joeDMrwRR9mqOJxJfLSb;ud9#E{p0Kx|q zYcPcDLyC16LGG`L4H!fIZ;DL_9@eY?Er@p%i_nI|BZ?*HK=SX35p*H-sA3s0Q`WeLv^dZwztik}oXBBHOgzSG5>o9`cbBYZZL;iWiCIl~NR)7}7|EpMp zHY8qDEI|j7eZ>g6ka|h63_VD{tXP3QWL{CM!T`co6>Bhr>}!g37(woJ#RiNa|At}{ zf`MiQXhD3TViDSqcvG57KWdR-g}=cND8Ifbd<#8Vn&jRII}Y za_=cNU<~>96`K$&(yRb2h<~71gf=8TR4hRUk{>BX(1p~;ie>0QdZbu^K4d;otik}o zPZeu0gzRUEbr?bJbHxUXA^(M96M`=_D?kh4Unv%$4T-U02|AGcS}}sIn3tOB{@-F* zk3IJ|KRroQpbweJid7guI7P7rLtiuR$(-a#phJ2vdgkZX61!zHhhGG%gkeI1h zf(|5SDMrwR)MAQd=s|jM#R~KxvxH(51`x&-YcPcDl8SX0L2fC<28<#94aFt|OKVnu z7Q~lPEJ7O+%PN+j1IgtSBj`dZp;(3#X5{2x3Xdb z#*kk{u?fMdniZf0@uXrA+K~9BVhK8sTum{8E~HjhEJF{{YbaKr51BO;t1y6YEyWrP zA-lF>9Y&DTZ7{z9W5|C?E1M9kqger35MNiZ2yIBLr&xjxB-dArpbM!D6wAo9`cCW;LhLw-}mCIp*lR)7}7H&-k|8xmV6mY@U4jA8^` zNNuTDh90E1QmjB9GFvNFVF2MaiZvKQ_S=ee7(s4Z#RiNaznx+ef>5&pv>?8{ViDSq z*g>%b9Z1erjGzmt9Tm&agY-^{73f1|XT>TEAlyZ<21CeZ73(m9+^&iZ7(;$H#U=#1 zYgT|3#P?7vLK_l$Dwd!F$-NXK=t635#WM6Dol~qpA2M?kt1y6YAH^CBA-k_)9Y&Db zPq6`G$bUz%3Bh+YD?kh4`zscq4T-#B2|AEGKrwdpt*U<~==6q^tnuUP?F5I;e&2yIB5s91syB!8e7 zK^Iab#WM6DeUf4Y`j9zUu?hnSPf@JF5VEH#)?oy>(-a#phWzP@O$dIdSpixQj}(j0 zhQt|)CFnr%OvMPgkou8g8G4XDOR)ld$egWMg#m=;DAr&I*&i#`VFbCdVgtsIpHOT< zaIR(rXhHlu#UivJalT>+I*|N{Vgy}CU7%Qo9;7c+tUw70b|r^ks?_=tJfgid7gu z_)Ena3?cg~#X5{2ce!E%#*m+<*o2^_SpixQpRZViHYBc4EI|j7S1Lx(h16AwW#~cr zYQ+llA#;sl6$TJqt5|~}Wb2A`7(wpWiVYY;{yN1b1i#U&04<1LuULdOByLbFK?jmI zDn`(S)J=+I=s~)nSb;udZdRU<~<| zViSS|niZf0@jodRp$&;YE0&-G$$Jzd=tAmV#WM6D{TIaw^dWPfVig7uwiRnIgzWu_ zbr?bJ0mTN4A^)Ia6M}~{D?kh4e^o3(8xnt0EI|j74=YB{g;Yne3_VCcqF8}GWd5#L zg#m<*D%M~K*?%b3VFbBu(^AURzz zf-a6wZZ=tE|fVig7uE~Z$6A!HXGc#V(1*Bhr>{g0(7(s4p#RiNazl~xOf^Tb9fEL8JRV+dq65A=3paV($ z(#?;c3#sk3vJ5>)@1R(LK4fMqR$&0)j*2xHLUt#`I*cH$H> zl5ZRPcBQpdtnF=X;@ed=UdylB)Y=rAUv2w3w29aje&ID1x0q}Xwq<;~){TAJ(zm*` z*}iS%+pn$d?AzA9U1u%p+cwtR@He(^VuLy6w$`S`CStMcZSuA4Zri~he1nZAyVGIY zY~OCQ@vgS-Yx|BmI2OCf#!34~`@ahGzwk~Q-{f1~ulv2V!+Z7g+e_MmZ3kJK zYW~6Y$hSlMx<6XGU}h|Kv{|4{#O}7q99vj45A_RMHeM8u#f~)(v*zC50^4`6cAR;H zU-u^)&-U#|-~McES$n>cd6aMW*m!AcCz(h4cCU>`ar^#Hu|d(Id)I%lJ+vo0)jZxW zywAq&gYU8VYJJq+pS-Zx!(|mi_+KtxEG*9=fW8;Qj_d{#$H6F2jfBQP!c7|U!@pqf7 z<>Q$?x-0bpJNO*)N51{T#!oL6iw?Qz?;@C(oN?cdfuvWw2kUPuci5do!1s7y9-S63{Vw!vzs)_1ZS$(30ZMomK&#m?S?f!tZ3HPh_h3!3C=uYk5 z{K7A7Jk_o!cRxSu+gCQ;+TWfXYwm&@+kW{>`)x2Ev*teW*S4Q*V|QmfZn`t*zGrvp z-JS7-Z<8k3`CrQZ^aYDg`RM+$>;6vQ?t*7bcYRE;huifm_C|f1YOU$pv)0@TPqX%b zHFsw`Z*7_xSbM~`m#n!%rdxYd$J+US#XsQ;i(SQ7>{Z`pT6@AD{F*iQBD1VrVeKUw z5B$2ttWEOAF7$12Ytwvt)0!JDVQqWc-S(DS=f3~A1@~j)wzvJkOImY3Hg0>zx23GP zQ|h*Nefx$r_rv10p>OUsbZ69U@A>9#!?o?*FSPc)Z_8Sn_|RPdwk`5;Ils`|Rv-A5 zu;y+tcME;!+w#`jE#}%szO7)*T|@3}`PjD=eRFrq$hVcOoojc5-5C?HPb|7qv$DnW zh_TOnTgBSa{!0JCAH1rySNs+HrEf`Vule?sZ{M``x^H9OR3h<_}I58zO7~L6MyVf-`2MFlHE=2uA1gs%G$Pe=eRp4u;xDS zx2$b9;o}Uya2<==`!>_Jb*=5-+bno&0QJMKQU zZArgwLu*6dCYJIG(-zd=4-nhJ+DX2-e>}Js&RE;bn!CqSzHMpa z&3$wKpm6K9vi714++rYB|vYiHQNU5xwt zmbdYlz8&b>0oL}g<}T3h`4>6R#(VkpecukU=DuQg(H`R4!4o$5+`R+a3O;_%+IhCS z?NHyoZ*$k(c9?I6*u3D|;nv*KxcPc^+qrA!NWbn-8*kv-QGVTF)~>WOt?R$&7andg zVGG^GbBu3C*m!y0j`as0Y0ceY?t(hruRF@d?zi7vJ16*dw2j~J*UX9j*rK(8HFrIg zX4vbSv19DvQ@cRi1$B}?_*ff%=G)2s;Nz^l?=PfN{kr3={nWq6X}+CcZE<_k?wUB= zAA6#Wzp&Hqu8GL6`+@uK@7EUHMRA6YB^yt%gIzn*AAFLH-4BSnPR{b{PPVZ-)$Teu z+qY9}>`t|7=lEk!weeck+_h8o?KB&&>ze!i&-L+i8}Dy##$7z;`}RW{e`zm#uz7(s z`{P(-YAKjJzbKBi^rEllkJY#RhZCCmB6Kn2g*?sb>eY?QMlkL;FPkxPW z7uwjpY4;(o^{rxK_kquzw2%Fh%A)(kb1k}mxw;1tO+t~fh*sZ_8 zw<}KMH+h{)7kqxg^ygPu*ZsqBXWK*DH?!Sctw-4I?#ZKV&%3c5bHIW(E}Fj6q?zu| zH@9_LE?D=c(~p@t>%dES!l}zM*U9^NKL6)ro|FIm-v`I*-~H|SSLG%xb^h#&XHU9s_Tm#*lwpu?g|NYgT|31Wzayp$&0Q`YFW< z^damjR$%~{rxj~3gzUc*>o9`cGl~ruL;hLCCdB`(SpixQJf~QMHYEO|Sb`2Ddx{Zs zA@#gs8G4ZZuVMxI5Wb*Tg#lzEg& ziB}a%(1GM@iV<`n^}1pidXRoYu>ySv-&Cx^05WeW)?f(Pfnps-kejF2fHCCXR%}B2 z9nA{Rg5X`nBD5j#o?;0)kbGY;f-a;!P%J|a(nG}x^dbCEu?hpoe56=|A!O$()?oy> zj};p*hWsarO^AQ0SpixQe5P20HY7%hCFnr%bHxa{korQg3_VDHsaSzNgkLFEVE~!0 z6>Bhr>^F*a7(wn^#RiNaKUQo){5#DG&=S`MQ|#O6+M;gT?siUMk|;q3l9Lr9=t63W zVi|gno~l@ZK7`X0t1y5}T(Jg2$WB+R!w7OS6dN#x{7l6r#Aj(%fEEM`C>Eg&i3Jr) z(1GMaiV<`nr8j3z8G4XjSSu^ghj0iWTTXxU6Co29Q}!u?9oPF0WXJ5#*AJ z4H!dy1;r-BSJbQkEeKXpEJ7O+D=U_u1IbksBj`eERmC#&AibJm1^N)C6ss_R%<76Y z7(#Xp#X5{2x29qP#*kl2u?g|DH7h_1f^`&&(1ygiiY4ekGOZXv7gFmfmZ1mf^%X17 zhj0VMDhwdAp<)e&kljeJ4kO5Itk{4tpTZlzd-0c5sTticen8O1t`Ah(TT1ICcwR}mGEI|j7vlS!gLTWF?GV~z*eZ>m&A>3QB3IoXOqgaC>WPhMohY{rV zRcyc*@_EH3#P`#z04)giS1dvs5(g-jpaaPR6(i_E>W7MD=t24*#R~KxJXo;`1IQE< zYcPcDA&PYvLGDn+28RiP#^dS9X#R~KxEGt%F0GSEJ8Vn(Oo?;zFkUL+o0b|HtpxA`? zg_;$h1;Is%MQB6fV#N}4AX!n2pbM!>6wAXZL&*L_u?{21 z{Zz35W5{2j*o1ghvjVgrxKgnQZAe_DSb`2Df2J5g7g9f0EJF{{S1VSa58*Y6RTx0# zTE!X+AzM?d!w7P76dN#x{B?>=h+nT+0a_5;pjd=9ByLnJK?jmIDMrwR)Xj=z=s~)! zSb;u-wKPfg~4EaAR zHX;5O%?i+h;IE2BXhY(D#S(NN`G8^sT}ZVR%g}@LgNhaCL->$l6$X%bSg{5}$UdT2 zhY{rdrr3ZnMGC z57PfptUw>ao?;aSka=FQ21CgHSFsKw$i1N0fHCA>RBS^0CCv)Zg5ZCOMQB6fWyKP7 zAlX-ppbM#26wAA@#0e8G4X@Pq6}h2;Wz%!T>TKDAr&I*`Z<`Mv(hZu>oVq zf27!i_?7gVf3AHszct1y5}pjd+;WEWPf!w7PVC^ldW`9&3*5MNBQ0<<7lT(Jmk zNGzdPf(|5?RE(etsf1z~dXQd9u>ySvmsYI805Z!c)?f(P?hzJzJ_K6XhE>1ViDSqSWB@49Z0UN7(o|O>nN6?2kCVcE6|59tyqNt zWY$xx!4R_RE7oBIxeXK>FoyhwicN@bq*(!45Nxbigf=8LQ7l0RlA&S*T}W-JScV>? zH&d)YAHvNQt1y7f7K$|(LUv2VI*cH?4^XT?AHo9_t1y7f4;5=LgzQ0z zbr?bJV8sTEAzx5zLi`ZT3ebY!P{ks&A#s>u2|AEGTrq+!q>fN5Ll4qNDpsHm;ZcfJ z7(k||Sc4&Ck5;V12y(|LHed|-V-=eaKTfj(v>-TMu?THQoS;~O4kS-hjGzmtl42Qp zkUmMV0(}TiR;|b(VhK8s zJWDZxE~I{>ScV>?&sMBJAHs7Kt1y7fxr#LyLiWdsbr?aetk{4tnNL-*;f(|4vRE(etsf!fL(1Y~FiWTTXSW&FP05X>-)?f(POBL%dg4|__4H!fI za>XXZf1+6dS`hqHu?THQT%lNk4kW9J5p*GSrD7R+kiJT>0(}U7rdWjmWPYw#gCS(E zR;6uDK7=oVq|5~vL@q08YKnsF<6^qb@L{qT@ z9Z3F0F@i3neydo99;AP#Sb;u-zgMin05X42ticene^ji)2y*u+Hed|-mSPj)b2TeK z3xYo>7NHG^KP#4?1IfQAM$m=SUlq&HgY^B173f3wfMOK}kZCK{Uzy6gf=7|RV+aVl8-4y(1lb-u?#&(KdxATK7@Z)tik{?Pbk)4 z2-$xq)?oy>ClwnohWtMjn-G6WvjVgr=qeVW4T+}}OVEMjzZ4_rLh2dCGV~z*tYQWF z5dK@S3IoVIr&xm_WdEaBhY{p@iVYY;{&~eF#Q&>V0a_5epjd=9Bwkc3K?jmADMrwR z)c+LA(1Y~LiWTTX*jKE=05Y#A)?f(PR~73pg4}D04H!fIb;Tyc-_Wc8EePIJEJ7O+ zZz-0b1IdA61YJnYQ!GOd(r+tPpbz0Yid7gu=3T`a3?ciTVjV`1dtb2uW5|D?*o62{ zvjVgr_)xJ3ZAg5iSb`2D=PO3gh1AE2W#~cr6U7SjA^cRa3IoV|rdWd^WJij17(woH z#RiNa|Ak@`;$Lc3fEEN_DHfp(iLVt)(1GMPiV<`n^{rwVdXOF~R-g~zcZyXQh-)*` z-2W}sbUSpnbFz~}9Y&Cwtk{4ts@ViV#EYgT|31dAvZp$&;e6-&^8 z^tOr>=tH=jVig9E*%j376A+J1AkJ8arHm#nzg zw7Dzp72oFD$sZj*_pm*u&s$((xf!w8p0QYL-RZH|B(rAws@B|=wl>+EWBVGut?$=e zXKfSrL)$j+?Rpz;=i7$9-C%7;-!}5?Mr&ExL~LV=ZhVvN8`xmB8Csia-fa7Kw!3W$ ze{kK#lif45ZA;&7vGLBff8X}4{IR#%I5{O2+uPjMnhj&O+3p_PZ9C}LiCFA*n>=Cr zfwu3c7>nIu;|HeMjcq&mcBhROUnCYg#LW6TyvxQ*SaaL1eqF=HOZv8(Z+BZ;%D3Hp z`-QcoCw$z)$6s1p#+rMOJ*~NS=2y1gv0yBAs5#rO`?Zbl@@+4_?jCE0E)!!~aCbtg?&bPw`~ z?fcs2>9$k+!oS&gRo_na?NMtN*}>l`_{4X)3)wB^9>=G#TSJ!kC*8@n&Ci>KS?@1Eg*YB%y?#t$CzwSjFM}A$+ntQ=7x$|!w zALsb^KWksQpW1evZ!g<;zHit2*0=VVZ#Ve%inYajyV18-tu5}`O}@QmZ6$m56Svyn zW*=X-@hTQwtNZqbjoth<+i$Vvp6i>oyU+f1+i&yh-m7&hP!fAKKV`skrtB-#)Uj`%-c3kG{>f z@zU1ZcAsw_+jy!q_dU|`?Gqb+z7XFdbA9{NTHjsT?(_eX#i{0Jw)bqIyLRvQ3r9Ad zYG>5r<^#TcZsX1UrP#LSPPi{@zs9bJr_D#LxmWz9?I+vVT^Wy??j8KfcK7bNE8_`k z6E1#j`yw`QSHY8h;Wswk#Kt}IDbt-l-`ak!JHWQCZ(|!beS6xPd*JVEf5@7)RsM+$A>8+Izk& zYRz3@uD$P@yZ+tf>8_R!d~?^oYwl_p`nH6%iSz7|aF@o17TsI3q{Z`no9|n~+G74p z|HL1>l(pB~8Eo69zAbI-4c|WVZ5eBC`Zn_Id)5ZDiP+~pE^Bd~MR#d@Va+|6<*d#3 z2Y=<)EpP2J-@f)OY3*}=>^HuxVC@yVn%q_Ot#2z@+sdvScLj~DO?KDcN*1^FF*ZXd zYHVd|+xRxgw^gid>)T{&?g_4HZ5{uMXsTbgnzgm;&fV2A&96&Yd*5BBwoUizR<|~s z@NtG;xQ4}#e4FLln%3s~wxDloS^M0YyZi!whihB=!ncL}x^=9bNpjjXwAJn7p8);9KSMc+2G_Od&`T-llt z+sJO*CF?HdRcQ9_f1A8(KXjY>!^17y#BN?uvCGA`(3-n++*OeBZBrY&uUmH}ukPDs zHeS{~cX#5sKU&;#*xbf<*uZ^+Yx#9s*f>4YK7aQauI=NNHqO|CxX*AM-?p;x%Jz1+ z&v0F9_T$*rHeSZPMYgT)*JZ3NZ_RzK8~EnFWaj#hZbNJC$!u%wFV@^gz43&P+u7tA zi|(@y{lVMY*!{M1pY^7`?O@~A{2gxQkKNJQEBcPLzmk00$=W>MwzB4)bk^G2zHQ_0 zZ(?VQ2l_kQ)*rl!wS%p>6J>k9a911G>|We?vV(8C+4u(EcJys`Yd8D0lfS<`tljFK zfo(hcb$eR7Yl?pV#bUeog*l7&`Ga?}=8l6-MMpwZ-?0UE&mut`eP5ZHn29~PNTRYR#QHk#8ru-@j}6c$SYPTd=P^8F%uW?b}H<{>C2IohRp7vmeJ!w(+I5yU*WU z#_sFj6dS*7?}B^FE7pwIsdh8TntOLI@$EDlUu^A2_xWGyA7Jf7^9tY2^3A=Vs&7BC@zu7wCx4|i_xQ21?dBRE zuks7evH4Hk4{iIIZ|B-Pv?t@XpZoS>Ywl~=z4EJlE8BRoy*l^Gukp=2kbBbZMPBRM zd6Q!M=@q+IS+nR~vAg8lU#ad+uJi2z8@q$;fY=TG;0tZ+{$=de-{{+l?r(A1uBy&G z^@Qm!F1M&VN!+F3E(Ld8A2Iig%ck!zY0}1XAHID0(NkwVRONsZUYNV#mD8WyZPu;s zpP{ym+m{3{PM;gRIOEc{X6^DIzvAD1c { + const classes = useStyles(); + const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e"; + + const [hasSession, setHasSession] = useState(false); + const { address: eoa } = useAccount(); + const { smartAccountAddress, smartAccountClient } = useSmartAccount(); + + const policy: Policy[] = []; + + const createDanSessionHandler = async () => { + if (!smartAccountClient || !smartAccountAddress) { + throw new Error("Smart Account not found"); + } + console.log( + "use", + smartAccountClient, + "address: ", + smartAccountAddress, + "to create the session" + ); + + /* + + // New in SDK + const { wait } = await createDanSession(policy, ...); + + // Wait for the createSessionTx + const { + receipt: { transactionHash }, + success + } = await wait() + + // Handle Success.... + success && setHasSession(true); + */ + setHasSession(true); + }; + + return ( +
+

+ Use Cases {"->"} Modules {"->"} {hasSession ? "Use" : "Create"} Dan + Session +

+ +

+ {hasSession ? "Use" : "Create"} a Dan Session +

+ + + +
policy: {JSON.stringify(policy, bigIntReplacer, 2)}
+ + {!!hasSession ? ( + + ) : ( +
+ ); +}; + +const useStyles = makeStyles(() => ({ + main: { + margin: "auto", + padding: "10px 40px", + color: "#EEEEEE", + }, + subTitle: { + color: "#FFB999", + fontSize: 36, + margin: 0, + }, + h3Title: { + color: "#e6e6e6", + }, + listHover: { + "&:hover": { + color: "#FF9551", + }, + }, +})); + +export default CreateDanSession; diff --git a/src/components/Modules/UseDanSession.tsx b/src/components/Modules/UseDanSession.tsx new file mode 100644 index 0000000..70c5e63 --- /dev/null +++ b/src/components/Modules/UseDanSession.tsx @@ -0,0 +1,33 @@ +import React, { useEffect, useMemo } from "react"; +import "react-toastify/dist/ReactToastify.css"; +import { Hex, encodeFunctionData, parseAbi } from "viem"; +import Button from "../Button"; +import { configInfo, showSuccessMessage } from "../../utils"; +import { polygonAmoy } from "viem/chains"; +import { useSession, useUserOpWait } from "@biconomy/use-aa"; +import { ErrorGuard } from "../../utils/ErrorGuard"; + +interface props { + smartAccountAddress: Hex; + address: string; +} + +const UseDanSession: React.FC = ({ smartAccountAddress }) => { + const useDanSessionHandler = async () => {}; + + const transactions = useMemo( + () => ({ + to: configInfo.nft.address, + data: encodeFunctionData({ + abi: parseAbi(["function safeMint(address _to)"]), + functionName: "safeMint", + args: [smartAccountAddress as Hex], + }), + }), + [smartAccountAddress] + ); + + return - ); -}; + ) +} const useStyles = makeStyles((_: any) => ({ btn: { @@ -60,26 +60,26 @@ const useStyles = makeStyles((_: any) => ({ fontSize: 15, "@media (max-width:599px)": { - padding: "0 5px", + padding: "0 5px" }, "&:hover": { - backgroundColor: "#5B3320", + backgroundColor: "#5B3320" }, // disable button "&:disabled": { cursor: "not-allowed", - opacity: 0.5, + opacity: 0.5 }, "& div": { "@media (max-width:599px)": { margin: 0, - display: "none", - }, - }, - }, -})); + display: "none" + } + } + } +})) -export default Button; +export default Button diff --git a/src/components/Faucet/index.tsx b/src/components/Faucet/index.tsx index 1c6d023..e1fe222 100644 --- a/src/components/Faucet/index.tsx +++ b/src/components/Faucet/index.tsx @@ -1,34 +1,35 @@ -import React, { useEffect, useState } from "react"; -import { makeStyles } from "@mui/styles"; -import { Hex, encodeFunctionData } from "viem"; +import { makeStyles } from "@mui/styles" +import type React from "react" +import { useEffect, useState } from "react" +import { type Hex, encodeFunctionData } from "viem" -import Button from "../Button"; import { useSendTransaction, useSmartAccount, - useUserOpWait, -} from "@biconomy/use-aa"; -import { configInfo as config, showSuccessMessage } from "../../utils"; -import { ErrorGuard } from "../../utils/ErrorGuard"; -import { polygonAmoy } from "viem/chains"; + useUserOpWait +} from "@biconomy/use-aa" +import { polygonAmoy } from "viem/chains" +import { configInfo as config, showSuccessMessage } from "../../utils" +import { ErrorGuard } from "../../utils/ErrorGuard" +import Button from "../Button" const Faucet: React.FC = () => { - const classes = useStyles(); - const { smartAccountAddress: scwAddress } = useSmartAccount(); - const [address, setAddress] = useState(scwAddress); + const classes = useStyles() + const { smartAccountAddress: scwAddress } = useSmartAccount() + const [address, setAddress] = useState(scwAddress) const { mutate, data: userOpResponse, error, - isPending, - } = useSendTransaction(); + isPending + } = useSendTransaction() const { isSuccess: waitIsSuccess, error: waitError, isLoading: waitIsLoading, - data: waitData, - } = useUserOpWait(userOpResponse); + data: waitData + } = useUserOpWait(userOpResponse) const drip = () => mutate({ @@ -37,18 +38,17 @@ const Faucet: React.FC = () => { data: encodeFunctionData({ abi: config.faucet.abi, functionName: "drip", - args: [address as Hex], - }), - }, - }); + args: [address as Hex] + }) + } + }) useEffect(() => { waitIsSuccess && showSuccessMessage( - "Successful mint: " + - `${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` - ); - }, [waitIsSuccess]); + `Successful mint: ${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` + ) + }, [waitIsSuccess, waitData]) return (
@@ -74,8 +74,8 @@ const Faucet: React.FC = () => { />
- ); -}; + ) +} const useStyles = makeStyles(() => ({ main: { @@ -86,35 +86,35 @@ const useStyles = makeStyles(() => ({ color: "#e6e6e6", display: "flex", flexDirection: "column", - alignItems: "start", + alignItems: "start" // justifyContent: "center", }, subTitle: { color: "#FFB999", fontSize: 36, - margin: 0, + margin: 0 }, h3Title: { color: "#FFB999", - margin: 0, + margin: 0 }, container: { // backgroundColor: "rgb(29, 31, 33)", }, containerBtn: { display: "flex", - gap: 15, + gap: 15 // justifyContent: "space-between", }, tab: { padding: "5px 15px", backgroundColor: "#FCF8E8", - marginBottom: 10, + marginBottom: 10 }, listHover: { "&:hover": { - color: "#FF9551", - }, + color: "#FF9551" + } }, input: { maxWidth: 350, @@ -124,8 +124,8 @@ const useStyles = makeStyles(() => ({ outline: "1px solid #5B3320", backgroundColor: "#151520", borderRadius: 6, - border: "none", - }, -})); + border: "none" + } +})) -export default Faucet; +export default Faucet diff --git a/src/components/Forward/MintNft.tsx b/src/components/Forward/MintNft.tsx index d1aae14..62ae6ec 100644 --- a/src/components/Forward/MintNft.tsx +++ b/src/components/Forward/MintNft.tsx @@ -1,47 +1,48 @@ -import { makeStyles } from "@mui/styles"; -import CircularProgress from "@mui/material/CircularProgress"; -import { PaymasterFeeQuote, PaymasterMode } from "@biconomy/account"; -import React, { useEffect, useMemo, useState } from "react"; +import type { PaymasterFeeQuote } from "@biconomy/account" +import CircularProgress from "@mui/material/CircularProgress" +import { makeStyles } from "@mui/styles" +import type React from "react" +import { useEffect, useMemo, useState } from "react" -import Button from "../Button"; import { Options, mergeOptions, useSendTransaction, useSmartAccount, useTokenFees, - useUserOpWait, -} from "@biconomy/use-aa"; -import { configInfo as config, showSuccessMessage } from "../../utils"; -import { Hex, encodeFunctionData, getContract } from "viem"; -import { usePublicClient } from "wagmi"; -import { ErrorGuard } from "../../utils/ErrorGuard"; -import { polygonAmoy } from "viem/chains"; + useUserOpWait +} from "@biconomy/use-aa" +import { type Hex, encodeFunctionData, getContract } from "viem" +import { polygonAmoy } from "viem/chains" +import { usePublicClient } from "wagmi" +import { configInfo as config, showSuccessMessage } from "../../utils" +import { ErrorGuard } from "../../utils/ErrorGuard" +import Button from "../Button" const MintNftForward: React.FC = () => { - const classes = useStyles(); - const publicClient = usePublicClient(); - const { smartAccountAddress } = useSmartAccount(); - const [nftCount, setNftCount] = useState(null); - const [selectedQuote, setSelectedQuote] = useState(); + const classes = useStyles() + const publicClient = usePublicClient() + const { smartAccountAddress } = useSmartAccount() + const [nftCount, setNftCount] = useState(null) + const [selectedQuote, setSelectedQuote] = useState() useEffect(() => { const getNftCount = async () => { - if (!smartAccountAddress || !publicClient) return; + if (!smartAccountAddress || !publicClient) return const nftContract = getContract({ address: config.nft.address as Hex, abi: config.nft.abi, - client: publicClient, - }); + client: publicClient + }) const count = await nftContract.read.balanceOf([ - smartAccountAddress as Hex, - ]); - console.log("count", Number(count)); - setNftCount(Number(count)); - }; - getNftCount(); + smartAccountAddress as Hex + ]) + console.log("count", Number(count)) + setNftCount(Number(count)) + } + getNftCount() // eslint-disable-next-line react-hooks/exhaustive-deps - }, [smartAccountAddress, publicClient]); + }, [smartAccountAddress, publicClient]) const transactions = useMemo( () => ({ @@ -49,51 +50,50 @@ const MintNftForward: React.FC = () => { data: encodeFunctionData({ abi: config.nft.abi, functionName: "safeMint", - args: [smartAccountAddress as Hex], - }), + args: [smartAccountAddress as Hex] + }) }), [smartAccountAddress] - ); + ) - const { data, isLoading: isLoadingFee } = useTokenFees({ transactions }); + const { data, isLoading: isLoadingFee } = useTokenFees({ transactions }) const { mutate, data: userOpResponse, error, - isPending: isLoading, - } = useSendTransaction(); + isPending: isLoading + } = useSendTransaction() const { isLoading: waitIsLoading, isSuccess: waitIsSuccess, error: waitError, - data: waitData, - } = useUserOpWait(userOpResponse); + data: waitData + } = useUserOpWait(userOpResponse) useEffect(() => { waitIsSuccess && showSuccessMessage( - "Successful mint: " + - `${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` - ); - }, [waitIsSuccess]); + `Successful mint: ${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` + ) + }, [waitIsSuccess, waitData]) console.log( mergeOptions([ Options.GasTokenPayment, - Options.getGasTokenFeeQuote(selectedQuote!), + Options.getGasTokenFeeQuote(selectedQuote!) ]) - ); + ) const mintNft = () => { mutate({ transactions, options: mergeOptions([ Options.GasTokenPayment, - Options.getGasTokenFeeQuote(selectedQuote!), - ]), - }); - }; + Options.getGasTokenFeeQuote(selectedQuote!) + ]) + }) + } return (
@@ -123,7 +123,7 @@ const MintNftForward: React.FC = () => { style={{ display: "flex", alignItems: "center", - margin: "0 0 40px 30px", + margin: "0 0 40px 30px" }} > { width: 25, height: 25, marginRight: 10, - color: "#e6e6e6", + color: "#e6e6e6" }} />{" "} {" Loading Fee Options"} @@ -145,7 +145,7 @@ const MintNftForward: React.FC = () => { flexDirection: "column", justifyContent: "start", marginLeft: 0, - gap: 8, + gap: 8 }} > {(data?.feeQuotes ?? []).map((token, ind) => ( @@ -154,7 +154,7 @@ const MintNftForward: React.FC = () => { type="radio" onChange={() => setSelectedQuote(token)} style={{ - color: "#FFB999", + color: "#FFB999" }} name={token.symbol} id={token.symbol} @@ -174,28 +174,28 @@ const MintNftForward: React.FC = () => { />
- ); -}; + ) +} const useStyles = makeStyles(() => ({ main: { margin: "auto", padding: "10px 40px", - color: "#EEEEEE", + color: "#EEEEEE" }, subTitle: { color: "#FFB999", fontSize: 36, - margin: 0, + margin: 0 }, h3Title: { - color: "#e6e6e6", + color: "#e6e6e6" }, listHover: { "&:hover": { - color: "#FF9551", - }, - }, -})); + color: "#FF9551" + } + } +})) -export default MintNftForward; +export default MintNftForward diff --git a/src/components/Forward/index.tsx b/src/components/Forward/index.tsx index 07b744a..d9b6e7c 100644 --- a/src/components/Forward/index.tsx +++ b/src/components/Forward/index.tsx @@ -1,11 +1,11 @@ -import React from "react"; -import { makeStyles } from "@mui/styles"; -import CollectionsIcon from "@mui/icons-material/Collections"; +import CollectionsIcon from "@mui/icons-material/Collections" +import { makeStyles } from "@mui/styles" +import type React from "react" interface Props { - useCase: number; - setUseCase: any; - pageIndexChange: any; + useCase: number + setUseCase: any + pageIndexChange: any } const cardItems = [ @@ -18,19 +18,19 @@ const cardItems = [ - ), - }, -]; + ) + } +] const ForwardFlow: React.FC = ({ useCase: _, setUseCase: __, - pageIndexChange, + pageIndexChange }) => { - const classes = useStyles(); + const classes = useStyles() return (
@@ -52,7 +52,7 @@ const ForwardFlow: React.FC = ({ {cardItems.map((item, index) => (
pageIndexChange(e, item.index)} - key={index} + key={index + 1} className={classes.card} > {item.icon} @@ -62,7 +62,7 @@ const ForwardFlow: React.FC = ({ color: "#FFB999", textAlign: "start", fontSize: "auto", - margin: 0, + margin: 0 }} > {item.title} @@ -71,7 +71,7 @@ const ForwardFlow: React.FC = ({ style={{ fontSize: 14, margin: 0, - textAlign: "center", + textAlign: "center" }} > {item.description} @@ -81,7 +81,7 @@ const ForwardFlow: React.FC = ({ ))}
- ); + ) // return ( //
//

EIP4337: Account Abstraction

@@ -147,18 +147,18 @@ const ForwardFlow: React.FC = ({ // //
// ); -}; +} const useStyles = makeStyles(() => ({ main: { padding: "10px 40px", width: "100%", - color: "#e6e6e6", + color: "#e6e6e6" }, subTitle: { color: "#FFB999", fontSize: 36, - margin: 0, + margin: 0 }, textBox: { display: "flex", @@ -167,14 +167,14 @@ const useStyles = makeStyles(() => ({ alignItems: "center", gap: 8, "@media (max-width:1640px)": { - alignItems: "start", - }, + alignItems: "start" + } }, subSubTitle: { fontFamily: "Rubik", color: "#BDC2FF", fontSize: 20, - margin: 20, + margin: 20 }, cardContainer: { display: "flex", @@ -185,8 +185,8 @@ const useStyles = makeStyles(() => ({ gap: 20, cursor: "pointer", "@media (max-width:1640px)": { - flexDirection: "column", - }, + flexDirection: "column" + } }, card: { // width: "25%", @@ -206,9 +206,9 @@ const useStyles = makeStyles(() => ({ width: "100%", maxWidth: "unset", aspectRatio: "unset", - justifyContent: "space-between", - }, - }, -})); + justifyContent: "space-between" + } + } +})) -export default ForwardFlow; +export default ForwardFlow diff --git a/src/components/Modules/CreateBatchSession.tsx b/src/components/Modules/CreateBatchSession.tsx index 1e3fcbc..584d0a5 100644 --- a/src/components/Modules/CreateBatchSession.tsx +++ b/src/components/Modules/CreateBatchSession.tsx @@ -1,35 +1,36 @@ -import React, { useEffect, useState } from "react"; -import { makeStyles } from "@mui/styles"; -import { useAccount } from "wagmi"; -import Button from "../Button"; +import type { Policy as PolicyFromSDK } from "@biconomy/account" import { Options, bigIntReplacer, mergeOptions, useCreateBatchSession, useSmartAccount, - useUserOpWait, -} from "@biconomy/use-aa"; -import { configInfo, showSuccessMessage } from "../../utils"; -import { polygonAmoy } from "viem/chains"; -import { Hex } from "viem"; -import UseBatchSession from "./UseBatchSession"; -import { ErrorGuard } from "../../utils/ErrorGuard"; -import { Policy as PolicyFromSDK } from "@biconomy/account"; + useUserOpWait +} from "@biconomy/use-aa" +import { makeStyles } from "@mui/styles" +import type React from "react" +import { useEffect, useState } from "react" +import type { Hex } from "viem" +import { polygonAmoy } from "viem/chains" +import { useAccount } from "wagmi" +import { configInfo, showSuccessMessage } from "../../utils" +import { ErrorGuard } from "../../utils/ErrorGuard" +import Button from "../Button" +import UseBatchSession from "./UseBatchSession" -export type Policy = Omit; +export type Policy = Omit const CreateBatchSession: React.FC = () => { - const classes = useStyles(); - const { address } = useAccount(); - const { smartAccountAddress: scwAddress } = useSmartAccount(); - const [hasSession, setHasSession] = useState(false); + const classes = useStyles() + const { address } = useAccount() + const { smartAccountAddress: scwAddress } = useSmartAccount() + const [hasSession, setHasSession] = useState(false) const policyLeaves: Policy[] = [ { interval: { validUntil: 0, - validAfter: 0, + validAfter: 0 }, contractAddress: configInfo.nft.address as Hex, functionSelector: "safeMint(address)", @@ -37,15 +38,15 @@ const CreateBatchSession: React.FC = () => { { offset: 0, condition: 0, - referenceValue: scwAddress, - }, + referenceValue: scwAddress + } ], - valueLimit: 0n, + valueLimit: 0n }, { interval: { validUntil: 0, - validAfter: 0, + validAfter: 0 }, contractAddress: configInfo.nft.address as Hex, functionSelector: "safeMint(address)", @@ -53,45 +54,44 @@ const CreateBatchSession: React.FC = () => { { offset: 0, condition: 0, - referenceValue: scwAddress, - }, + referenceValue: scwAddress + } ], - valueLimit: 0n, - }, - ]; + valueLimit: 0n + } + ] const { mutate, data: userOpResponse, error, - isPending: isLoading, - } = useCreateBatchSession(); + isPending: isLoading + } = useCreateBatchSession() const { isLoading: waitIsLoading, isSuccess: waitIsSuccess, error: waitError, - data: waitData, - } = useUserOpWait(userOpResponse); + data: waitData + } = useUserOpWait(userOpResponse) useEffect(() => { if (waitIsSuccess) { - setHasSession(true); + setHasSession(true) showSuccessMessage( - "Successful mint: " + - `${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` - ); + `Successful mint: ${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` + ) } - }, [waitIsSuccess]); + }, [waitIsSuccess, waitData]) const createSessionHandler = () => mutate({ policy: policyLeaves, options: mergeOptions([ Options.Sponsored, - Options.getIncreasedVerification(50), - ]), - }); + Options.getIncreasedVerification(50) + ]) + }) return (
@@ -118,22 +118,22 @@ const CreateBatchSession: React.FC = () => { )}
- ); -}; + ) +} const useStyles = makeStyles(() => ({ main: { padding: "10px 40px", - color: "#EEEEEE", + color: "#EEEEEE" }, subTitle: { color: "#FFB999", fontSize: 36, - margin: 0, + margin: 0 }, h3Title: { - color: "#e6e6e6", - }, -})); + color: "#e6e6e6" + } +})) -export default CreateBatchSession; +export default CreateBatchSession diff --git a/src/components/Modules/CreateDanSession.tsx b/src/components/Modules/CreateDanSession.tsx index 0d7c134..edd1521 100644 --- a/src/components/Modules/CreateDanSession.tsx +++ b/src/components/Modules/CreateDanSession.tsx @@ -1,126 +1,136 @@ -import React, { useState, useEffect } from "react"; -import { ToastContainer } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; -import { useAccount, useClient } from "wagmi"; -import { bigIntReplacer, useSmartAccount } from "@biconomy/use-aa"; -import Button from "../Button"; -import { makeStyles } from "@mui/styles"; -import { Hex, keccak256, parseUnits } from "viem"; -import { ethers } from "ethers"; -import { CreateSessionDataParams, DEFAULT_SESSION_KEY_MANAGER_MODULE, ERROR_MESSAGES, PaymasterMode, Policy, Session, SessionKeyManagerModule, SessionLocalStorage, Transaction, createABISessionDatum, createDANSessionKeyManagerModule, getDefaultStorageClient } from "@biconomy/account"; -import UseDanSession from "./UseDanSession"; -import * as ed from '@noble/ed25519'; -import * as dotenv from "dotenv"; +import { + type CreateSessionDataParams, + DEFAULT_SESSION_KEY_MANAGER_MODULE, + PaymasterMode, + type Session, + SessionLocalStorage, + type Transaction, + createDANSessionKeyManagerModule +} from "@biconomy/account" +import { bigIntReplacer, useSmartAccount } from "@biconomy/use-aa" +import { makeStyles } from "@mui/styles" +import * as ed from "@noble/ed25519" +import { ethers } from "ethers" +import type React from "react" +import { useEffect, useState } from "react" +import { ToastContainer } from "react-toastify" +import "react-toastify/dist/ReactToastify.css" +import { type Hex, keccak256, parseUnits } from "viem" +import { useAccount, useClient } from "wagmi" +import Button from "../Button" +import UseDanSession from "./UseDanSession" import { - NetworkSigner, - AuthMethod, EOAAuth, - WalletProviderServiceClient, - TypedData, + type IBrowserWallet, type KeygenResponse, - IBrowserWallet, -} from '@silencelaboratories/walletprovider-sdk'; + NetworkSigner, + type TypedData, + WalletProviderServiceClient +} from "@silencelaboratories/walletprovider-sdk" -let ephSK: Uint8Array | null = null; -let ephPK: Uint8Array | null = null; +let ephSK: Uint8Array | null = null +let ephPK: Uint8Array | null = null interface EIP6963ProviderInfo { - uuid: string; - name: string; - icon: string; - rdns: string; + uuid: string + name: string + icon: string + rdns: string } interface RequestArguments { - readonly method: string; - readonly params?: readonly unknown[] | object; + readonly method: string + readonly params?: readonly unknown[] | object } interface EIP1193Provider { - isStatus?: boolean; - host?: string; - path?: string; + isStatus?: boolean + host?: string + path?: string - request: (request: RequestArguments) => Promise; + request: (request: RequestArguments) => Promise } export type WalletProviderDefs = { - walletProviderId: string; - walletProviderUrl: string; -}; + walletProviderId: string + walletProviderUrl: string +} export type Config = { - walletProvider: WalletProviderDefs; -}; + walletProvider: WalletProviderDefs +} const createWalletProviderService = async (config: Config) => new WalletProviderServiceClient({ walletProviderId: config.walletProvider.walletProviderId, - walletProviderUrl: config.walletProvider.walletProviderUrl, - }); + walletProviderUrl: config.walletProvider.walletProviderUrl + }) -let selectedBrowserWallet: EIP1193Provider | null = null; +let selectedBrowserWallet: EIP1193Provider | null = null // Sign data using the secret key stored on Browser Wallet // It creates a popup window, presenting the human readable form of `request` // Throws an error if User rejected signature export class BrowserWallet implements IBrowserWallet { - async signTypedData(from: string, request: TypedData): Promise { + async signTypedData( + from: string, + request: TypedData + ): Promise { //should be provider return await selectedBrowserWallet!.request({ - method: 'eth_signTypedData_v4', - params: [from, JSON.stringify(request)], - }); + method: "eth_signTypedData_v4", + params: [from, JSON.stringify(request)] + }) } } // Function to convert hex string to Uint8Array function hexToUint8Array(hex: string) { if (hex.length % 2 !== 0) { - throw new Error('Hex string must have an even number of characters'); + throw new Error("Hex string must have an even number of characters") } - const array = new Uint8Array(hex.length / 2); + const array = new Uint8Array(hex.length / 2) for (let i = 0; i < hex.length; i += 2) { - array[i / 2] = parseInt(hex.substr(i, 2), 16); + array[i / 2] = Number.parseInt(hex.substr(i, 2), 16) } - return array; + return array } const CreateDanSession: React.FC = () => { - const classes = useStyles(); - const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e"; - const erc20ModuleAddr = "0x3A25b00638fF5bDfD4f300beF39d236041C073c0"; + const classes = useStyles() + const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" + const erc20ModuleAddr = "0x3A25b00638fF5bDfD4f300beF39d236041C073c0" - const { address: eoa, connector } = useAccount(); - const client = useClient(); - const { smartAccountAddress, smartAccountClient } = useSmartAccount(); - const [session, setSession] = useState(null); - const [provider, setProvider] = useState(null); + const { address: eoa, connector } = useAccount() + const client = useClient() + const { smartAccountAddress, smartAccountClient } = useSmartAccount() + const [session, setSession] = useState(null) + const [provider, setProvider] = useState(null) useEffect(() => { const fetchProvider = async () => { if (connector) { - const prov = await connector.getProvider(); - setProvider(prov); - selectedBrowserWallet = prov as EIP1193Provider; + const prov = await connector.getProvider() + prov && setProvider(prov as EIP1193Provider) + selectedBrowserWallet = prov as EIP1193Provider } - }; - fetchProvider(); - }, [connector]); + } + fetchProvider() + }, [connector]) const policyDAN: any[] = [ { - type: 'erc20', - method: 'approve', - to: '0x1234567890123456789012345678901234567890', + type: "erc20", + method: "approve", + to: "0x1234567890123456789012345678901234567890", args: { - spender: '0x1234567890123456789012345678901234567890', + spender: "0x1234567890123456789012345678901234567890", value: 10000, - eq: '<', - }, - }, - ]; + eq: "<" + } + } + ] const policyOnChain = [ { @@ -130,18 +140,18 @@ const CreateDanSession: React.FC = () => { { offset: 0, condition: 0, - referenceValue: smartAccountAddress, - }, + referenceValue: smartAccountAddress + } ], interval: { validUntil: 0, - validAfter: 0, + validAfter: 0 }, - valueLimit: 0n, - }, - ]; + valueLimit: 0n + } + ] - const policy = policyOnChain; + const policy = policyOnChain const permissions = { permissions: policy @@ -150,7 +160,7 @@ const CreateDanSession: React.FC = () => { const createDanSessionHandler = async () => { try { if (!smartAccountClient || !smartAccountAddress) { - throw new Error("Smart Account not found"); + throw new Error("Smart Account not found") } console.log( "use", @@ -158,22 +168,22 @@ const CreateDanSession: React.FC = () => { "address: ", smartAccountAddress, "to create the session" - ); + ) // const sk = ed.utils.randomPrivateKey(); - const sk = hexToUint8Array(process.env.EPHEMERAL_SECRET_KEY!); + const sk = hexToUint8Array(import.meta.env.VITE_EPHEMERAL_KEY!) // Global variable for now - ephSK = sk; - ephPK = await ed.getPublicKeyAsync(sk); + ephSK = sk + ephPK = await ed.getPublicKeyAsync(sk) const clusterConfig = { walletProvider: { walletProviderId: "WalletProvider", walletProviderUrl: "ws://localhost:8090/v1" } - }; + } - const wpClient = await createWalletProviderService(clusterConfig); + const wpClient = await createWalletProviderService(clusterConfig) // Authenticate using EOA const eoaAuth = new EOAAuth( @@ -181,112 +191,112 @@ const CreateDanSession: React.FC = () => { new BrowserWallet(), ephPK, // Lifetime of one hour - 60 * 60, - ); + 60 * 60 + ) - console.log('ephemeral public key:', ephPK); + console.log("ephemeral public key:", ephPK) - const threshold = 11; - const partiesNumber = 20; + const threshold = 11 + const partiesNumber = 20 - const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, eoaAuth); + const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, eoaAuth) // Generate a new key - const resp: KeygenResponse = await sdk.authenticateAndCreateKey(ephPK); + const resp: KeygenResponse = await sdk.authenticateAndCreateKey(ephPK) - console.log('keygen response:', resp); + console.log("keygen response:", resp) // resp.publicKey // get EOA from public key which will be session key EOA - let pubKey = resp.publicKey; + const pubKey = resp.publicKey - if (pubKey.startsWith('0x')) { - let pubKey = resp.publicKey; + if (pubKey.startsWith("0x")) { + const pubKey = resp.publicKey } - // Compute the Keccak-256 hash of the public key - const hash = keccak256(('0x' + pubKey) as Hex); + // Compute the Keccak-256 hash of the public key + const hash = keccak256(("0x" + pubKey) as Hex) - // The Ethereum address is the last 20 bytes of the hash - const sessionKeyEOA = '0x' + hash.slice(-40); + // The Ethereum address is the last 20 bytes of the hash + const sessionKeyEOA = "0x" + hash.slice(-40) - console.log('sessionKeyEOA', sessionKeyEOA); + console.log("sessionKeyEOA", sessionKeyEOA) - // const sessionStorageClient = getDefaultStorageClient(smartAccountAddress); - const sessionStorageClient = new SessionLocalStorage(smartAccountAddress); + // const sessionStorageClient = getDefaultStorageClient(smartAccountAddress); + const sessionStorageClient = new SessionLocalStorage(smartAccountAddress) - const sessionsModule = await createDANSessionKeyManagerModule({ - smartAccountAddress, - sessionStorageClient - }) - - console.log('session module') - console.log(sessionsModule); - - // cretae session key data - const sessionKeyData = ethers.AbiCoder.defaultAbiCoder().encode( - ["address", "address", "address", "uint256"], - [ - sessionKeyEOA, - "0xdA5289fCAAF71d52a80A254da614a192b693e977", - "0x42138576848E839827585A3539305774D36B9602", - parseUnits("50".toString(), 6) - ] - ); - - const createSessionDataParams: CreateSessionDataParams = { - validAfter: 0, - validUntil: 1721757486, - sessionValidationModule: erc20ModuleAddr, - sessionPublicKey: sessionKeyEOA as Hex, - sessionKeyData: sessionKeyData as Hex - } + const sessionsModule = await createDANSessionKeyManagerModule({ + smartAccountAddress, + sessionStorageClient + }) + + console.log("session module") + console.log(sessionsModule) + + // cretae session key data + const sessionKeyData = ethers.AbiCoder.defaultAbiCoder().encode( + ["address", "address", "address", "uint256"], + [ + sessionKeyEOA, + "0xdA5289fCAAF71d52a80A254da614a192b693e977", + "0x42138576848E839827585A3539305774D36B9602", + parseUnits("50".toString(), 6) + ] + ) - // we could use ERC20 SVM as well - const { data: policyData, sessionIDInfo } = - await sessionsModule.createSessionData([createSessionDataParams]) + const createSessionDataParams: CreateSessionDataParams = { + validAfter: 0, + validUntil: 1721757486, + sessionValidationModule: erc20ModuleAddr, + sessionPublicKey: sessionKeyEOA as Hex, + sessionKeyData: sessionKeyData as Hex + } - console.log('policyData', policyData); - console.log('sessionIDInfo', sessionIDInfo); + // we could use ERC20 SVM as well + const { data: policyData, sessionIDInfo } = + await sessionsModule.createSessionData([createSessionDataParams]) - const permitTx = { - to: DEFAULT_SESSION_KEY_MANAGER_MODULE, - data: policyData - } - - const txs: Transaction[] = [] - - const isDeployed = await smartAccountClient.isAccountDeployed() - const enableSessionTx = await smartAccountClient.getEnableModuleData( - DEFAULT_SESSION_KEY_MANAGER_MODULE - ) - - if (isDeployed) { - const enabled = await smartAccountClient.isModuleEnabled( + console.log("policyData", policyData) + console.log("sessionIDInfo", sessionIDInfo) + + const permitTx = { + to: DEFAULT_SESSION_KEY_MANAGER_MODULE, + data: policyData + } + + const txs: Transaction[] = [] + + const isDeployed = await smartAccountClient.isAccountDeployed() + const enableSessionTx = await smartAccountClient.getEnableModuleData( DEFAULT_SESSION_KEY_MANAGER_MODULE ) - if (!enabled) { + + if (isDeployed) { + const enabled = await smartAccountClient.isModuleEnabled( + DEFAULT_SESSION_KEY_MANAGER_MODULE + ) + if (!enabled) { + txs.push(enableSessionTx) + } + } else { txs.push(enableSessionTx) } - } else { - txs.push(enableSessionTx) - } - - txs.push(permitTx) - - const userOpResponse = await smartAccountClient.sendTransaction(txs, { - paymasterServiceData: { mode: PaymasterMode.SPONSORED }, - }) - console.log('userOpResponse', userOpResponse); + txs.push(permitTx) + + const userOpResponse = await smartAccountClient.sendTransaction(txs, { + paymasterServiceData: { mode: PaymasterMode.SPONSORED } + }) - const { - receipt: { transactionHash }, - success - } = await userOpResponse.wait(); + console.log("userOpResponse", userOpResponse) - console.log('transactionHash', transactionHash); + const { + receipt: { transactionHash }, + success + } = await userOpResponse.wait() + + console.log("transactionHash", transactionHash) const resultingSession = { sessionStorageClient, @@ -296,9 +306,9 @@ const CreateDanSession: React.FC = () => { // Handle Success. Keep the "Session" (StorageClient and sessionIDs) and set it to the session success && setSession(resultingSession) } catch (error) { - console.error('Error creating session:', error); + console.error("Error creating session:", error) } - }; + } return (
@@ -332,28 +342,28 @@ const CreateDanSession: React.FC = () => {
- ); -}; + ) +} const useStyles = makeStyles(() => ({ main: { margin: "auto", padding: "10px 40px", - color: "#EEEEEE", + color: "#EEEEEE" }, subTitle: { color: "#FFB999", fontSize: 36, - margin: 0, + margin: 0 }, h3Title: { - color: "#e6e6e6", + color: "#e6e6e6" }, listHover: { "&:hover": { - color: "#FF9551", - }, - }, -})); + color: "#FF9551" + } + } +})) -export default CreateDanSession; \ No newline at end of file +export default CreateDanSession diff --git a/src/components/Modules/CreateSession.tsx b/src/components/Modules/CreateSession.tsx index 3f91ca6..ce6661f 100644 --- a/src/components/Modules/CreateSession.tsx +++ b/src/components/Modules/CreateSession.tsx @@ -1,30 +1,31 @@ -import React, { useEffect, useState } from "react"; -import { ToastContainer } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; -import UseSession from "./UseSession"; -import { useAccount } from "wagmi"; import { Options, bigIntReplacer, useCreateSession, useSmartAccount, - useUserOpWait, -} from "@biconomy/use-aa"; -import Button from "../Button"; -import { makeStyles } from "@mui/styles"; -import { Hex } from "viem"; -import { ErrorGuard } from "../../utils/ErrorGuard"; -import { showSuccessMessage } from "../../utils"; -import { polygonAmoy } from "viem/chains"; + useUserOpWait +} from "@biconomy/use-aa" +import { makeStyles } from "@mui/styles" +import type React from "react" +import { useEffect, useState } from "react" +import { ToastContainer } from "react-toastify" +import "react-toastify/dist/ReactToastify.css" +import type { Hex } from "viem" +import { polygonAmoy } from "viem/chains" +import { useAccount } from "wagmi" +import { showSuccessMessage } from "../../utils" +import { ErrorGuard } from "../../utils/ErrorGuard" +import Button from "../Button" +import UseSession from "./UseSession" const CreateSession: React.FC = () => { - const classes = useStyles(); + const classes = useStyles() - const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e"; + const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e" - const [hasSession, setHasSession] = useState(false); - const { address } = useAccount(); - const { smartAccountAddress: scwAddress } = useSmartAccount(); + const [hasSession, setHasSession] = useState(false) + const { address } = useAccount() + const { smartAccountAddress: scwAddress } = useSmartAccount() const policy = [ { @@ -34,46 +35,45 @@ const CreateSession: React.FC = () => { { offset: 0, condition: 0, - referenceValue: scwAddress, - }, + referenceValue: scwAddress + } ], interval: { validUntil: 0, - validAfter: 0, + validAfter: 0 }, - valueLimit: 0n, - }, - ]; + valueLimit: 0n + } + ] const { mutate, data: userOpResponse, error, - isPending: isLoading, - } = useCreateSession(); + isPending: isLoading + } = useCreateSession() const { isLoading: waitIsLoading, isSuccess: waitIsSuccess, error: waitError, - data: waitData, - } = useUserOpWait(userOpResponse); + data: waitData + } = useUserOpWait(userOpResponse) useEffect(() => { if (waitIsSuccess) { - setHasSession(true); + setHasSession(true) showSuccessMessage( - "Successful mint: " + - `${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` - ); + `Successful mint: ${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` + ) } - }, [waitIsSuccess]); + }, [waitIsSuccess, waitData]) const createSessionHandler = () => mutate({ policy, - options: Options.Sponsored, - }); + options: Options.Sponsored + }) return (
@@ -113,28 +113,28 @@ const CreateSession: React.FC = () => { )}
- ); -}; + ) +} const useStyles = makeStyles(() => ({ main: { margin: "auto", padding: "10px 40px", - color: "#EEEEEE", + color: "#EEEEEE" }, subTitle: { color: "#FFB999", fontSize: 36, - margin: 0, + margin: 0 }, h3Title: { - color: "#e6e6e6", + color: "#e6e6e6" }, listHover: { "&:hover": { - color: "#FF9551", - }, - }, -})); + color: "#FF9551" + } + } +})) -export default CreateSession; +export default CreateSession diff --git a/src/components/Modules/UseBatchSession.tsx b/src/components/Modules/UseBatchSession.tsx index ed50a8f..4caf081 100644 --- a/src/components/Modules/UseBatchSession.tsx +++ b/src/components/Modules/UseBatchSession.tsx @@ -1,16 +1,17 @@ -import React, { useEffect } from "react"; -import { Transaction } from "@biconomy/account"; -import "react-toastify/dist/ReactToastify.css"; -import { Hex, encodeFunctionData, parseAbi } from "viem"; -import Button from "../Button"; -import { configInfo, showSuccessMessage } from "../../utils"; -import { polygonAmoy } from "viem/chains"; -import { useBatchSession, useUserOpWait, Options } from "@biconomy/use-aa"; -import { ErrorGuard } from "../../utils/ErrorGuard"; +import type { Transaction } from "@biconomy/account" +import { Options, useBatchSession, useUserOpWait } from "@biconomy/use-aa" +import type React from "react" +import { useEffect } from "react" +import "react-toastify/dist/ReactToastify.css" +import { type Hex, encodeFunctionData, parseAbi } from "viem" +import { polygonAmoy } from "viem/chains" +import { configInfo, showSuccessMessage } from "../../utils" +import { ErrorGuard } from "../../utils/ErrorGuard" +import Button from "../Button" interface props { - smartAccountAddress?: Hex; - address?: string; + smartAccountAddress?: Hex + address?: string } const UseBatchSession: React.FC = ({ smartAccountAddress }) => { @@ -18,40 +19,39 @@ const UseBatchSession: React.FC = ({ smartAccountAddress }) => { mutate, data: userOpResponse, error, - isPending: isLoading, - } = useBatchSession(); + isPending: isLoading + } = useBatchSession() const { isLoading: waitIsLoading, isSuccess: waitIsSuccess, error: waitError, - data: waitData, - } = useUserOpWait(userOpResponse); + data: waitData + } = useUserOpWait(userOpResponse) const nftMintTx: Transaction = { to: configInfo.nft.address, data: encodeFunctionData({ abi: parseAbi(["function safeMint(address _to)"]), functionName: "safeMint", - args: [smartAccountAddress as Hex], - }), - }; + args: [smartAccountAddress as Hex] + }) + } const txTwice = () => mutate({ transactions: [nftMintTx, nftMintTx], correspondingIndexes: [0, 1], - options: Options.getIncreasedVerification(50), - }); + options: Options.getIncreasedVerification(50) + }) useEffect(() => { if (waitIsSuccess) { showSuccessMessage( - "Successful mint: " + - `${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` - ); + `Successful mint: ${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}` + ) } - }, [waitIsSuccess]); + }, [waitIsSuccess, waitData]) return ( @@ -61,7 +61,7 @@ const UseBatchSession: React.FC = ({ smartAccountAddress }) => { isLoading={isLoading || waitIsLoading} /> - ); -}; + ) +} -export default UseBatchSession; +export default UseBatchSession diff --git a/src/components/Modules/UseDanSession.tsx b/src/components/Modules/UseDanSession.tsx index ddb8061..b4d3f04 100644 --- a/src/components/Modules/UseDanSession.tsx +++ b/src/components/Modules/UseDanSession.tsx @@ -1,35 +1,40 @@ -import React, { useMemo } from "react"; -import "react-toastify/dist/ReactToastify.css"; -import { Hex, encodeFunctionData, parseAbi } from "viem"; -import Button from "../Button"; -import { ethers } from "ethers"; -import { configInfo } from "../../utils"; -import { BaseValidationModule, Session, SessionLocalStorage, createDANSessionKeyManagerModule } from "@biconomy/account"; -import { useSmartAccount } from "@biconomy/use-aa"; -import { useAccount } from "wagmi"; +import { + type Session, + SessionLocalStorage, + createDANSessionKeyManagerModule, + getChain +} from "@biconomy/account" +import { useSmartAccount } from "@biconomy/use-aa" +import type React from "react" +import { useMemo } from "react" +import "react-toastify/dist/ReactToastify.css" +import { type Hex, encodeFunctionData, parseAbi } from "viem" +import { useAccount } from "wagmi" +import { configInfo } from "../../utils" +import Button from "../Button" interface props { - session: Session; + session: Session } // Function to convert hex string to Uint8Array function hexToUint8Array(hex: string) { if (hex.length % 2 !== 0) { - throw new Error('Hex string must have an even number of characters'); + throw new Error("Hex string must have an even number of characters") } - const array = new Uint8Array(hex.length / 2); + const array = new Uint8Array(hex.length / 2) for (let i = 0; i < hex.length; i += 2) { - array[i / 2] = parseInt(hex.substr(i, 2), 16); + array[i / 2] = Number.parseInt(hex.substr(i, 2), 16) } - return array; + return array } const UseDanSession: React.FC = ({ session }) => { - const { address: eoa, connector } = useAccount(); - const { smartAccountAddress, smartAccountClient } = useSmartAccount(); + const { address: eoa } = useAccount() + const { smartAccountAddress, smartAccountClient } = useSmartAccount() - console.log("use dan session: ", smartAccountAddress); - console.log(session); + console.log("use dan session: ", smartAccountAddress) + console.log(session) const transactions = useMemo( () => ({ @@ -37,21 +42,21 @@ const UseDanSession: React.FC = ({ session }) => { data: encodeFunctionData({ abi: parseAbi(["function safeMint(address _to)"]), functionName: "safeMint", - args: [smartAccountAddress as Hex], - }), + args: [smartAccountAddress as Hex] + }) }), [smartAccountAddress] - ); + ) const useDanSessionHandler = async () => { if (!smartAccountClient || !smartAccountAddress) { - throw new Error("Smart Account not found"); + throw new Error("Smart Account not found") } if (!session) { - throw new Error("Session not found"); + throw new Error("Session not found") } - const sessionStorageClient = new SessionLocalStorage(smartAccountAddress); + const sessionStorageClient = new SessionLocalStorage(smartAccountAddress) const sessionsModule = await createDANSessionKeyManagerModule({ smartAccountAddress, @@ -59,34 +64,59 @@ const UseDanSession: React.FC = ({ session }) => { }) // Review if needed. or already baked in - smartAccountClient.setActiveValidationModule(sessionsModule as any); + smartAccountClient.setActiveValidationModule(sessionsModule as any) - console.log('active validation module ', smartAccountClient.activeValidationModule); + console.log( + "active validation module ", + smartAccountClient.activeValidationModule + ) - const sk = hexToUint8Array(process.env.EPHEMERAL_SECRET_KEY!); + const sk = hexToUint8Array(import.meta.env.VITE_EPHEMERAL_KEY!) console.log("use DAN session ever here? =============>") - + + const sessionID = session.sessionIDInfo[0] + + const sessionKeyEOA = ( + await session.sessionStorageClient.getSessionData({ sessionID }) + ).sessionPublicKey + + const allSessions = await sessionStorageClient.getAllSessionData() + + console.log({ allSessions }) + + const sessionSigner = await sessionStorageClient.getSignerBySession( + { + sessionID + }, + getChain(80002) + ) + + console.log({ sessionSigner }) + // Send the transactions using session params const { wait } = await smartAccountClient.sendTransaction(transactions, { - params : { - scwAddress: smartAccountAddress, - eoaAddress: eoa, - ephSK: sk, - threshold: 10, - partiesNumber: 21, + params: { + scwAddress: smartAccountAddress, + eoaAddress: eoa, + ephSK: sk, + threshold: 10, + partiesNumber: 21, + sessionKeyEOA, + sessionSigner, + sessionID } - }); + }) // Wait for the createSessionTx const { receipt: { transactionHash }, - success, - } = await wait(); + success + } = await wait() // Handle Success.... - }; + } - return