/* Ċ Ġ* ĠCopyright ĠD 3 ĠLed ger , ĠInc . ĠAll ĠRights ĠReserved . Ċ Ġ* ĠSPDX - License - Identifier : ĠApache - 2 . 0 Ċ Ġ*/ Ċ Ċ package Ġcom . d 3 . btc . withdraw al . provider Ċ Ċ import Ġcom . d 3 . btc . helper . address . out Put To Base 5 8 Address Ċ import Ġcom . d 3 . btc . provider . network . Btc Network Config Provider Ċ import Ġcom . d 3 . btc . storage . Btc Address Storage Ċ import Ġcom . d 3 . btc . withdraw al . init . WITH DRAW AL _ OPERATION Ċ import Ġcom . d 3 . btc . withdraw al . transaction . Withdraw al Details Ċ import Ġcom . d 3 . btc . withdraw al . transaction . is D ust Ċ import Ġcom . d 3 . commons . model . D 3 ErrorException Ċ import Ġcom . github . kit tin un f . result . Result Ċ import Ġmu . K Logging Ċ import Ġorg . bitcoin j . core . Address Ċ import Ġorg . bitcoin j . core . Coin Ċ import Ġorg . bitcoin j . core . Transaction Ċ import Ġorg . bitcoin j . core . Transaction Output Ċ import Ġorg . bitcoin j . wallet . Wallet Ċ import Ġorg . springframework . stereotype . Component Ċ Ċ const Ġval ĠTX _ F EE _ SAT Ġ= Ġ 6 0 0 0 Ċ private Ġconst Ġval ĠMAX _ UT XO _ ITEMS Ġ= Ġ 2 0 Ċ Ċ /* ĊĠĠ ĠProvider Ġthat Ġis Ġused Ġto Ġcollect Ġinputs , Ġoutputs Ġand Ġetc Ċ Ġ*/ Ċ @ Component Ċ class ĠU TX O Provider ( ĊĠĠĠ Ġprivate Ġval Ġtransfers Wallet : ĠWallet , ĊĠĠĠ Ġprivate Ġval Ġbtc Network Config Provider : ĠB tc Network Config Provider , ĊĠĠĠ Ġprivate Ġval Ġbtc Address Storage : ĠB tc Address Storage , ĊĠĠĠ Ġprivate Ġval Ġused UT XO Provider : ĠUsed UT XO Provider Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġut xo Comparator : ĠComparator < Transaction Output > Ġ= ĠComparator Ġ{ Ġoutput 1 , Ġoutput 2 Ġ-> ĊĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠ ĠOutputs Ġare Ġcompared Ġby Ġvalues . ĊĠĠĠĠĠĠĠ ĠIt Ġwill Ġhelp Ġus Ġhaving Ġa Ġlittle Ġamount Ġof Ġinputs . ĊĠĠĠĠĠĠĠ ĠLess Ġinputs Ġ-> Ġsmaller Ġtx Ġsize Ġ-> Ġsmaller Ġfee */ ĊĠĠĠĠĠĠĠ Ġval Ġvalue Comparison Ġ= Ġ- output 1 . value . value . compareTo ( output 2 . value . value ) ĊĠĠĠĠĠĠĠ Ġ// If Ġvalues Ġare Ġthe Ġsame , Ġwe Ġcompare ĠU TX O Ġby Ġpointers ĊĠĠĠĠĠĠĠ Ġif Ġ( value Comparison Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput 1 Pointer Ġ= Ġoutput 1 . parent Transaction Hash ?. toString () Ġ+ Ġ":" Ġ+ Ġoutput 1 . index ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput 2 Pointer Ġ= Ġoutput 2 . parent Transaction Hash ?. toString () Ġ+ Ġ":" Ġ+ Ġoutput 2 . index ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput 1 Pointer . compareTo ( output 2 Pointer ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Comparison ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġoutputs ( destination Ġand Ġchange Ġaddresses ) Ġto Ġa Ġgiven Ġtransaction ĊĠĠĠĠ Ġ* Ġ@ param Ġtransaction Ġ- Ġcurrent Ġtransaction ĊĠĠĠĠ Ġ* Ġ@ param Ġtotal Amount Sat Ġ- Ġtotal Ġamount Ġof Ġassets ĊĠĠĠĠ Ġ* Ġ@ param Ġdestination Address Ġ- Ġreceiver 's Ġbase 5 8 ĠBitcoin Ġaddress ĊĠĠĠĠ Ġ* Ġ@ param Ġamount ToS pend Ġ- Ġamount Ġof ĠS AT Ġto Ġspend ( used Ġto Ġcompute Ġchange ) ĊĠĠĠĠ Ġ* Ġ@ param Ġchange Address Ġ- Ġaddress Ġthat Ġis Ġused Ġto Ġstore Ġchange ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd Outputs ( ĊĠĠĠĠĠĠĠ Ġtransaction : ĠTransaction , ĊĠĠĠĠĠĠĠ Ġtotal Amount Sat : ĠLong , ĊĠĠĠĠĠĠĠ Ġdestination Address : ĠString , ĊĠĠĠĠĠĠĠ Ġamount ToS pend : ĠLong , ĊĠĠĠĠĠĠĠ Ġchange Address : ĠAddress ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtransaction . add Output ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCoin . valueOf ( amount ToS pend ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAddress . from Base 5 8 ( btc Network Config Provider . getConfig (), Ġdestination Address ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġchange Ġ= Ġtotal Amount Sat Ġ- Ġamount ToS pend Ġ- ĠTX _ F EE _ SAT ĊĠĠĠĠĠĠĠ Ġtransaction . add Output ( Coin . valueOf ( change ), Ġchange Address ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCollect s Ġpreviously Ġsent Ġtransactions , Ġthat Ġmay Ġbe Ġused Ġas Ġan Ġinput Ġfor Ġnewly Ġcreated Ġtransaction ĊĠĠĠĠ Ġ* Ġ@ param Ġwithdraw al Details Ġ- Ġdetails Ġof Ġwithdraw al ĊĠĠĠĠ Ġ* Ġ@ param Ġconfidence Level Ġ- Ġminimum Ġdepth Ġof Ġtransactions ĊĠĠĠĠ Ġ* Ġ@ return Ġresult Ġwith Ġlist Ġfull Ġof Ġun spent Ġtransactions ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcollect Un sp ents ( ĊĠĠĠĠĠĠĠ Ġwithdraw al Details : ĠWith draw al Details , ĊĠĠĠĠĠĠĠ Ġconfidence Level : ĠInt ĊĠĠĠ Ġ): ĠResult < List < Transaction Output >, ĠException > Ġ= ĠResult . of Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġun sp ents Ġ= ĠArrayList ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Available Un sp ents ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwithdraw al Details , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransfers Wallet . un sp ents , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconfidence Level ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġif Ġ( un sp ents . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠD 3 ErrorException . fatal ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailed Operation Ġ= ĠWITH DRAW AL _ OPERATION , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= Ġ" Cannot Ġget Ġenough ĠU TX O Ġfor Ġwithdraw al Ġ$ withdraw al Details " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġcollected Un sp ents Ġ= ĠArrayList < Transaction Output >() ĊĠĠĠĠĠĠĠ Ġun sp ents . sort With ( ut xo Comparator ) ĊĠĠĠĠĠĠĠ Ġval Ġamount And Fee Ġ= Ġwithdraw al Details . amount Sat Ġ+ ĠTX _ F EE _ SAT ĊĠĠĠĠĠĠĠ Ġvar Ġcollected Amount Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġun sp ents . forEach Ġ{ Ġun spent Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( collected Amount Ġ>= Ġamount And Fee ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ forEach ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcollected Amount Ġ+= Ġun spent . value . value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcollected Un sp ents . add ( un spent ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( collected Amount Ġ< Ġamount And Fee ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠD 3 ErrorException . fatal ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailed Operation Ġ= ĠWITH DRAW AL _ OPERATION , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= Ġ" Cannot Ġget Ġenough ĠBTC Ġamount Ġfor Ġwithdraw al Ġ$ withdraw al Details Ġ( required Ġ$ amount And Fee , Ġcollected Ġ$ collected Amount ) Ġusing Ġcurrent Ġun spent Ġtx Ġcollection " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcollected Un sp ents ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġcurrently Ġavailable Ġun sp ents ĊĠĠĠĠ Ġ* Ġ@ param Ġwithdraw al Details Ġ- Ġdetails Ġof Ġwithdraw al ĊĠĠĠĠ Ġ* Ġ@ param Ġun sp ents Ġ- Ġall Ġthe Ġun sp ents Ġthat Ġwe Ġpos ses ĊĠĠĠĠ Ġ* Ġ@ param Ġconfidence Level Ġ- Ġminimum Ġdepth Ġof Ġtransactions ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Available Un sp ents ( ĊĠĠĠĠĠĠĠ Ġwithdraw al Details : ĠWith draw al Details , ĊĠĠĠĠĠĠĠ Ġun sp ents : ĠList < Transaction Output >, ĊĠĠĠĠĠĠĠ Ġconfidence Level : ĠInt ĊĠĠĠ Ġ): ĠList < Transaction Output > Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġut xo Count Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġreturn Ġun sp ents . sorted With ( ut xo Comparator ). filter Ġ{ Ġun spent Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ut xo Count Ġ>= ĠMAX _ UT XO _ ITEMS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ filter Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġavailable ToS pend Ġ= Ġ! is D ust ( un spent . value . value ) Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Only Ġconfirmed Ġun sp ents Ġmay Ġbe Ġused ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun spent . parent Transaction Depth In Blocks Ġ>= Ġconfidence Level ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// We Ġuse Ġregistered Ġclients Ġoutputs Ġonly ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġis Available Output ( un spent ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Cannot Ġuse Ġalready Ġused Ġun sp ents ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġ! used UT XO Provider . is Used ( withdraw al Details , Ġun spent ). get () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( available ToS pend ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġut xo Count ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġavailable ToS pend ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠComputes Ġtotal Ġun spent Ġvalue ĊĠĠĠ Ġprotected Ġfun ĠgetTotal Un spent Value ( un sp ents : ĠList < Transaction Output >): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġtotal Value Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġun sp ents . forEach Ġ{ Ġun spent Ġ-> Ġtotal Value Ġ+= Ġun spent . value . value Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtotal Value ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠChecks Ġif Ġfee Ġoutput Ġwas Ġaddressed Ġto Ġavailable Ġaddress ĊĠĠĠ Ġprotected Ġfun Ġis Available Output ( ĊĠĠĠĠĠĠĠ Ġoutput : ĠTransaction Output ĊĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbtc Address Ġ= Ġout Put To Base 5 8 Address ( output ) ĊĠĠĠĠĠĠĠ Ġreturn Ġbtc Address Storage . is W atched Address ( btc Address ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLogger ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġcompanion Ġobject Ġ: ĠK Logging () Ċ } Ċ