package Ġcc . ether space Ċ Ċ import Ġcc . ether space . call adapter . Call Adapter Ċ import Ġcc . ether space . call adapter . Pass Through Call Adaptor Ċ import Ġcc . ether space . web 3 j . Web 3 j Adapter Ċ import Ġcom . google . common . reflect . Type Token Ċ import Ġmu . Kotlin Logging Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġjava . io . IOException Ċ import Ġjava . lang . reflect . Annotated Element Ċ import Ġjava . lang . reflect . Method Ċ import Ġjava . lang . reflect . Proxy Ċ import Ġjava . lang . reflect . Type Ċ import Ġjava . math . BigInteger Ċ Ċ class ĠE ther Space ( val Ġweb 3 : ĠWeb 3 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcredentials : ĠCredentials ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġcall Adapters : ĠList < Call Adapter < Any , ĠAny >>, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġnonce Provider : ĠN once Provider ) Ġ{ ĊĊĠĠĠ Ġfun Ġ< T > Ġcreate ( contract : ĠSol Address , Ġservice : ĠClass < T >): ĠT Ġ= Ġcreate ( contract . address , Ġservice ) ĊĊĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠ Ġfun Ġ< T > Ġcreate ( contract Address : ĠString , Ġservice : ĠClass < T >): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdefault Options From Classes Ġ= Ġcreate Options From Annotation ( service ) ĊĠĠĠĠĠĠĠ Ġreturn ĠProxy . new Proxy Instance ( service . class Loader , ĠarrayOf ( service )) Ġ{ Ġ_, Ġmethod , Ġargs Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinvoke Function ( contract Address , Ġmethod , Ġargs ?. toList () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġempty List (), Ġdefault Options From Classes ) ĊĠĠĠĠĠĠĠ Ġ} Ġas ĠT ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġinvoke Function ( to Address : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod : ĠMethod , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs : ĠList < Any >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Options : ĠOptions ): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoptions Ġ= Ġ( args . first OrNull Ġ{ Ġit Ġis ĠOptions Ġ} Ġ?: Ġcreate Options From Annotation ( method , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Options )) Ġas ĠOptions ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= Ġargs . filter Ġ{ Ġit Ġ! is ĠOptions Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcall Adapter Ġ= Ġcall Adapters . first Ġ{ Ġit . ad ap table ( method . generic ReturnType , Ġmethod . annotations ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġactual ReturnType Ġ= Ġcall Adapter . to Actual ReturnType ( method . generic ReturnType ) ĊĠĠĠĠĠĠĠ Ġreturn Ġcall Adapter . adapt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcall Annotation Ġ= Ġmethod . getAnnotation ( Call :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( call Annotation Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfunction Name Ġ= Ġcall Annotation . function Name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ adapt Ġinvoke View Function ( to Address , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( function Name . isNotBlank ()) Ġfunction Name Ġelse Ġmethod . name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactual ReturnType , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsend Annotation Ġ= Ġmethod . getAnnotation ( Send :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( send Annotation Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfunction Name Ġ= Ġsend Annotation . function Name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ adapt Ġinvoke Transaction Function ( to Address , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( function Name . isNotBlank ()) Ġfunction Name Ġelse Ġmethod . name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactual ReturnType , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcall Adapter ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" There Ġis Ġno ĠSend / Call Ġannotation Ġon Ġthis Ġmethod ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Options From Annotation ( annotated : ĠAnnot ated Element , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Options : ĠOptions Ġ= ĠOptions ()): ĠOptions Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġannotated . getAnnotation ( Gas :: class . java )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOptions ( gas Ġ= Ġit . gas . to BigInteger (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgas Price Ġ= Ġit . gas Price . to BigInteger ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġdefault Options ĊĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠTransaction FailedException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġinvoke Transaction Function ( to Address : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfunction Name : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs : ĠList < Any >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠreturnType : ĠType , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions : ĠOptions , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcall Adapter : ĠCall Adapter < Any , ĠAny >): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcd Ġ= Ġoptions . credentials Ġ?: Ġcredentials ĊĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalArgumentException (" Credentials Ġnot Ġset ") ĊĠĠĠĠĠĠĠ Ġval Ġnp Ġ= Ġoptions . nonce Provider Ġ?: Ġnonce Provider ĊĊĠĠĠĠĠĠĠ Ġval Ġencoded Function Ġ= Ġweb 3 . abi . encode Function Call ( args , Ġfunction Name ) ĊĠĠĠĠĠĠĠ Ġval Ġtransaction Hash Ġ= Ġnp . provide Nonce ( web 3 , Ġcd . address ) Ġ{ Ġnonce Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" invoke Transaction : from =${ cd . address }, to =$ to Address , function =$ function Name , args =$ args , options =$ options " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransaction Object Ġ= ĠWeb 3 . Transaction Object ( cd . address , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Address , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Function , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnonce ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġweb 3 . eth . send Transaction ( transaction Object , Ġcd ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠreturnType Token Ġ= ĠType Token . of ( returnType ) ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠreturnType Token . is Subtype Of ( String :: class . java ) Ġ-> Ġtransaction Hash ĊĠĠĠĠĠĠĠĠĠĠĠ ĠreturnType Token . is Subtype Of ( Transaction Receipt :: class . java ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTransaction Hash ( web 3 , Ġtransaction Hash , Ġcall Adapter ). request Transaction Receipt Blocking () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠreturnType Token . is Subtype Of ( Transaction Hash :: class . java ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTransaction Hash ( web 3 , Ġtransaction Hash , Ġcall Adapter ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" Unknown Ġreturn Ġtype :${ returnType . typeName }") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġinvoke View Function ( to Address : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfunction Name : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs : ĠList < Any >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠreturnType : ĠType , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions : ĠOptions ): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" invoke View : to =$ to Address , function =$ function Name , args =$ args " Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġencoded Function Ġ= Ġweb 3 . abi . encode Function Call ( args , Ġfunction Name ) ĊĠĠĠĠĠĠĠ Ġval Ġtransaction Object Ġ= ĠWeb 3 . Transaction Object ( null , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Address , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Function , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions ) ĊĠĠĠĠĠĠĠ Ġval Ġdata Ġ= Ġweb 3 . eth . call ( transaction Object ) ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= Ġweb 3 . abi . decode Parameters ( returnType . list Tuple Actual Types (), Ġdata ) ĊĠĠĠĠĠĠĠ Ġreturn ĠreturnType . create Tuple Instance ( values ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" unused ", Ġ" Member Visibility Can Be Private ") ĊĠĠĠ Ġclass ĠBuilder Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġprovider : ĠString Ġ= Ġ" http :// localhost : 8 5 4 5 /" ĊĊĠĠĠĠĠĠĠ Ġvar Ġcredentials : ĠCredentials ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġvar Ġcall Adapters : ĠList < Call Adapter < Any , ĠAny >> Ġ= Ġmutable ListOf () ĊĊĠĠĠĠĠĠĠ Ġvar Ġclient : ĠOk HttpClient ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġvar Ġnonce Provider : ĠN once Provider Ġ= ĠTransaction Count Nonce Provider ĊĊĠĠĠĠĠĠĠ Ġfun Ġprovider ( provider : ĠString ) Ġ= Ġapply Ġ{ Ġthis . provider Ġ= Ġprovider Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġcredentials ( credentials : ĠCredentials ) Ġ= Ġapply Ġ{ Ġthis . credentials Ġ= Ġcredentials Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġclient ( client : ĠOk HttpClient ) Ġ= Ġapply Ġ{ Ġthis . client Ġ= Ġclient Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġadd Call Adapter ( call Adapter : ĠCall Adapter < Any , ĠAny >) Ġ= Ġapply Ġ{ Ġthis . call Adapters Ġ+= Ġcall Adapter Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġbuild (): ĠE ther Space Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġweb 3 Ġ= ĠWeb 3 j Adapter ( provider , Ġclient ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠE ther Space ( web 3 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcredentials , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcall Adapters Ġ+ ĠPass Through Call Adaptor (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnonce Provider ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġobject ĠTransaction Count Nonce Provider Ġ: ĠN once Provider Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġprovide Nonce ( web 3 : ĠWeb 3 , Ġaddress : ĠString , Ġsend Transaction : Ġ( BigInteger ) Ġ-> ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsend Transaction ( get Nonce ( web 3 , Ġaddress )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Nonce ( web 3 : ĠWeb 3 , Ġaddress : ĠString ): ĠBigInteger Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġweb 3 . eth . getTransaction Count ( address , ĠWeb 3 . Default Block . PENDING ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġinline Ġfun Ġbuild ( block : ĠBuilder . () Ġ-> ĠUnit ) Ġ= ĠBuilder (). apply ( block ). build () ĊĠĠĠĠĠĠĠ Ġinternal Ġconst Ġval ĠGET _ TRANSACTION _ RECE IP T _ POL LING _ INTERVAL _ IN _ MS Ġ= Ġ 5 _ 0 0 0 L ĊĠĠĠĠĠĠĠ Ġinternal Ġconst Ġval ĠGET _ TRANSACTION _ RECE IP T _ POL LING _ AT TEMP TS Ġ= Ġ 6 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{} ĊĠĠĠ Ġ} Ċ }