@@ -10,6 +10,7 @@ import (
1010 "os"
1111 "sort"
1212 "strconv"
13+ "time"
1314
1415 "google.golang.org/protobuf/proto"
1516
@@ -106,16 +107,18 @@ func NewKoinosCommandSet() *CommandSet {
106107 cs .AddCommand (NewCommandDeclaration ("import" , "Import a WIF private key to a new wallet file" , false , NewImportCommand , * NewCommandArg ("private-key" , StringArg ), * NewCommandArg ("filename" , FileArg ), * NewOptionalCommandArg ("password" , StringArg )))
107108 cs .AddCommand (NewCommandDeclaration ("list" , "List available commands" , false , NewListCommand ))
108109 cs .AddCommand (NewCommandDeclaration ("upload" , "Upload a smart contract" , false , NewUploadContractCommand , * NewCommandArg ("filename" , FileArg ), * NewOptionalCommandArg ("abi-filename" , FileArg )))
109- cs .AddCommand (NewCommandDeclaration ("call" , "Call a smart contract" , false , NewCallCommand , * NewCommandArg ("contract-id" , StringArg ), * NewCommandArg ("entry-point" , StringArg ), * NewCommandArg ("arguments" , StringArg )))
110+ cs .AddCommand (NewCommandDeclaration ("call" , "Call a smart contract" , false , NewCallCommand , * NewCommandArg ("contract-id" , StringArg ), * NewCommandArg ("entry-point" , HexArg ), * NewCommandArg ("arguments" , StringArg )))
110111 cs .AddCommand (NewCommandDeclaration ("open" , "Open a wallet file" , false , NewOpenCommand , * NewCommandArg ("filename" , FileArg ), * NewOptionalCommandArg ("password" , StringArg )))
111112 cs .AddCommand (NewCommandDeclaration ("unlock" , "Open a wallet file" , true , NewOpenCommand , * NewCommandArg ("filename" , FileArg ), * NewOptionalCommandArg ("password" , StringArg )))
112113 cs .AddCommand (NewCommandDeclaration ("private" , "Show the currently opened wallet's private key" , false , NewPrivateCommand ))
114+ cs .AddCommand (NewCommandDeclaration ("rclimit" , "Set or show the current rc limit. Give no limit to see current calue. Give limit as either mana for a percent (i.e. 80%)." , false , NewRcLimitCommand , * NewOptionalCommandArg ("limit" , StringArg )))
113115 cs .AddCommand (NewCommandDeclaration ("read" , "Read from a smart contract" , false , NewReadCommand , * NewCommandArg ("contract-id" , StringArg ), * NewCommandArg ("entry-point" , StringArg ), * NewCommandArg ("arguments" , StringArg )))
114116 cs .AddCommand (NewCommandDeclaration ("register" , "Register a smart contract's commands" , false , NewRegisterCommand , * NewCommandArg ("name" , StringArg ), * NewCommandArg ("address" , AddressArg ), * NewOptionalCommandArg ("abi-filename" , FileArg )))
115117 cs .AddCommand (NewCommandDeclaration ("transfer" , "Transfer token from an open wallet to a given address" , false , NewTransferCommand , * NewCommandArg ("value" , AmountArg ), * NewCommandArg ("to" , AddressArg )))
116- cs .AddCommand (NewCommandDeclaration ("set_system_call" , "Set a system call to a new contract and entry point" , false , NewSetSystemCallCommand , * NewCommandArg ("system-call" , StringArg ), * NewCommandArg ("contract-id" , StringArg ), * NewCommandArg ("entry-point" , StringArg )))
117- cs .AddCommand (NewCommandDeclaration ("set_system_contract" , "Change a contract's permission level between user and system" , false , NewSetSystemContractCommand , * NewCommandArg ("contract-id" , StringArg ), * NewCommandArg ("system-contract" , StringArg )))
118+ cs .AddCommand (NewCommandDeclaration ("set_system_call" , "Set a system call to a new contract and entry point" , false , NewSetSystemCallCommand , * NewCommandArg ("system-call" , StringArg ), * NewCommandArg ("contract-id" , AddressArg ), * NewCommandArg ("entry-point" , HexArg )))
119+ cs .AddCommand (NewCommandDeclaration ("set_system_contract" , "Change a contract's permission level between user and system" , false , NewSetSystemContractCommand , * NewCommandArg ("contract-id" , AddressArg ), * NewCommandArg ("system-contract" , BoolArg )))
118120 cs .AddCommand (NewCommandDeclaration ("session" , "Create or manage a transaction session (begin, submit, cancel, or view)" , false , NewSessionCommand , * NewCommandArg ("command" , StringArg )))
121+ cs .AddCommand (NewCommandDeclaration ("sleep" , "Sleep for the given number seconds" , true , NewSleepCommand , * NewCommandArg ("seconds" , AmountArg )))
119122 cs .AddCommand (NewCommandDeclaration ("exit" , "Exit the wallet (quit also works)" , false , NewExitCommand ))
120123 cs .AddCommand (NewCommandDeclaration ("quit" , "" , true , NewExitCommand ))
121124
@@ -219,7 +222,7 @@ func (c *CloseCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*
219222 }
220223
221224 // Close the wallet
222- ee .Key = nil
225+ ee .CloseWallet ()
223226
224227 result := NewExecutionResult ()
225228 result .AddMessage ("Wallet closed" )
@@ -398,22 +401,21 @@ func (c *UploadContractCommand) Execute(ctx context.Context, ee *ExecutionEnviro
398401 },
399402 }
400403
401- er := NewExecutionResult ()
402- er .AddMessage (fmt .Sprintf ("Contract uploaded with address %s" , base58 .Encode (ee .Key .AddressBytes ())))
404+ result := NewExecutionResult ()
405+ result .AddMessage (fmt .Sprintf ("Contract uploaded with address %s" , base58 .Encode (ee .Key .AddressBytes ())))
403406
404407 err = ee .Session .AddOperation (op , fmt .Sprintf ("Upload contract with address %s" , base58 .Encode (ee .Key .AddressBytes ())))
405408 if err == nil {
406- er .AddMessage ("Adding operation to transaction session" )
409+ result .AddMessage ("Adding operation to transaction session" )
407410 }
408411 if err != nil {
409- receipt , err := ee .RPCClient . SubmitTransaction ([] * protocol. Operation { op }, ee . Key )
412+ err := ee .SubmitTransaction (result , op )
410413 if err != nil {
411- return nil , err
414+ return nil , fmt . Errorf ( "cannot upload contract, %w" , err )
412415 }
413- er .AddMessage (cliutil .TransactionReceiptToString (receipt , 1 ))
414416 }
415417
416- return er , nil
418+ return result , nil
417419}
418420
419421// ----------------------------------------------------------------------------
@@ -652,7 +654,7 @@ func (c *CallCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*E
652654 }
653655
654656 // Get the argument bytes
655- argumentBytes , err := base64 .StdEncoding .DecodeString (c .Arguments [ 1 :] )
657+ argumentBytes , err := base64 .StdEncoding .DecodeString (c .Arguments )
656658 if err != nil {
657659 return nil , err
658660 }
@@ -675,11 +677,10 @@ func (c *CallCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*E
675677 result .AddMessage ("Adding operation to transaction session" )
676678 }
677679 if err != nil {
678- receipt , err := ee .RPCClient . SubmitTransaction ([] * protocol. Operation { op }, ee . Key )
680+ err := ee .SubmitTransaction (result , op )
679681 if err != nil {
680- return nil , err
682+ return nil , fmt . Errorf ( "cannot call contract, %w" , err )
681683 }
682- result .AddMessage (cliutil .TransactionReceiptToString (receipt , 1 ))
683684 }
684685
685686 return result , nil
@@ -726,15 +727,92 @@ func (c *OpenCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*E
726727 return nil , err
727728 }
728729
729- // Set the wallet keys
730- ee .Key = key
730+ // Open the wallet
731+ ee .OpenWallet ( key )
731732
732733 result := NewExecutionResult ()
733734 result .AddMessage (fmt .Sprintf ("Opened wallet: %s" , c .Filename ))
734735
735736 return result , nil
736737}
737738
739+ // ----------------------------------------------------------------------------
740+ // RcLimit Command
741+ // ----------------------------------------------------------------------------
742+
743+ // RcLimitCommand is a command that sets or checks your cuttent rc limit
744+ type RcLimitCommand struct {
745+ limit * string
746+ }
747+
748+ // NewRcLimitCommand creates a new rc limit command object
749+ func NewRcLimitCommand (inv * CommandParseResult ) Command {
750+ return & RcLimitCommand {limit : inv .Args ["limit" ]}
751+ }
752+
753+ // Execute handles the rc limit command
754+ func (c * RcLimitCommand ) Execute (ctx context.Context , ee * ExecutionEnvironment ) (* ExecutionResult , error ) {
755+ result := NewExecutionResult ()
756+ // If no limit given, display current
757+ if c .limit == nil {
758+ if ee .rcLimit .absolute {
759+ result .AddMessage (fmt .Sprintf ("Current rc limit: %f" , ee .rcLimit .value ))
760+ return result , nil
761+ }
762+
763+ // Otherwise its relative
764+ if ! ee .IsOnline () || ! ee .IsWalletOpen () {
765+ result .AddMessage (fmt .Sprintf ("Current rc limit: %f%%" , ee .rcLimit .value * 100 ))
766+ return result , nil
767+ }
768+
769+ limit , err := ee .RPCClient .GetAccountRc (ee .Key .AddressBytes ())
770+ if err != nil {
771+ return nil , err
772+ }
773+
774+ dAmount , err := util .SatoshiToDecimal (int64 (limit ), cliutil .KoinPrecision )
775+ if err != nil {
776+ return nil , err
777+ }
778+
779+ f , _ := dAmount .Mul (decimal .NewFromFloat (ee .rcLimit .value )).Float64 ()
780+ result .AddMessage (fmt .Sprintf ("Current rc limit: %f%% (%f)" , ee .rcLimit .value * 100 , f ))
781+ return result , nil
782+ }
783+
784+ // Otherwise we are setting the limit
785+ s := * c .limit
786+ if s [len (s )- 1 ] == '%' {
787+ res , err := strconv .ParseFloat (s [:len (s )- 1 ], 64 )
788+ if err != nil {
789+ return nil , err
790+ }
791+
792+ // Check bounds
793+ if res < 0 || res > 100 {
794+ return nil , fmt .Errorf ("%w: percentage rc limit must be between 0%% and 100%%" , cliutil .ErrInvalidParam )
795+ }
796+
797+ ee .rcLimit .value = res / 100.0
798+ ee .rcLimit .absolute = false
799+ result .AddMessage (fmt .Sprintf ("Set rc limit to %f%%" , res ))
800+ return result , nil
801+ }
802+
803+ // Otherwise we are setting the absolute limit
804+ res , err := strconv .ParseFloat (s , 64 )
805+ if err != nil {
806+ return nil , err
807+ }
808+
809+ ee .rcLimit .value = res
810+ ee .rcLimit .absolute = true
811+ result .AddMessage (fmt .Sprintf ("Set rc limit to %f" , res ))
812+
813+ return result , nil
814+ }
815+
738816// ----------------------------------------------------------------------------
739817// Read
740818// ----------------------------------------------------------------------------
@@ -781,6 +859,34 @@ func (c *ReadCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*E
781859 return result , nil
782860}
783861
862+ // ----------------------------------------------------------------------------
863+ // Sleep Command
864+ // ----------------------------------------------------------------------------
865+
866+ // SleepCommand is a command that shows the currently opened wallet's address and private key
867+ type SleepCommand struct {
868+ Duration time.Duration
869+ }
870+
871+ // NewSleepCommand creates a new address command object
872+ func NewSleepCommand (inv * CommandParseResult ) Command {
873+ f , err := strconv .ParseFloat (* inv .Args ["seconds" ], 32 )
874+ if err != nil {
875+ return nil
876+ }
877+
878+ return & SleepCommand {Duration : time .Duration (f * float64 (time .Second ))}
879+ }
880+
881+ // Execute shows wallet address
882+ func (c * SleepCommand ) Execute (ctx context.Context , ee * ExecutionEnvironment ) (* ExecutionResult , error ) {
883+ result := NewExecutionResult ()
884+ result .AddMessage (fmt .Sprintf ("Slept for %s" , c .Duration ))
885+ time .Sleep (c .Duration )
886+
887+ return result , nil
888+ }
889+
784890// ----------------------------------------------------------------------------
785891// Transfer
786892// ----------------------------------------------------------------------------
@@ -881,11 +987,10 @@ func (c *TransferCommand) Execute(ctx context.Context, ee *ExecutionEnvironment)
881987 result .AddMessage ("Adding operation to transaction session" )
882988 }
883989 if err != nil {
884- receipt , err := ee .RPCClient . SubmitTransaction ([] * protocol. Operation { op }, ee . Key )
990+ err := ee .SubmitTransaction (result , op )
885991 if err != nil {
886- return nil , err
992+ return nil , fmt . Errorf ( "cannot transfer, %w" , err )
887993 }
888- result .AddMessage (cliutil .TransactionReceiptToString (receipt , 1 ))
889994 }
890995
891996 return result , nil
@@ -964,11 +1069,10 @@ func (c *SetSystemCallCommand) Execute(ctx context.Context, ee *ExecutionEnviron
9641069 result .AddMessage ("Adding operation to transaction session" )
9651070 }
9661071 if err != nil {
967- receipt , err := ee .RPCClient . SubmitTransaction ([] * protocol. Operation { op }, ee . Key )
1072+ err := ee .SubmitTransaction (result , op )
9681073 if err != nil {
969- return nil , err
1074+ return nil , fmt . Errorf ( "cannot set system call, %w" , err )
9701075 }
971- result .AddMessage (cliutil .TransactionReceiptToString (receipt , 1 ))
9721076 }
9731077
9741078 return result , nil
@@ -1034,11 +1138,10 @@ func (c *SetSystemContractCommand) Execute(ctx context.Context, ee *ExecutionEnv
10341138 result .AddMessage ("Adding operation to transaction session" )
10351139 }
10361140 if err != nil {
1037- receipt , err := ee .RPCClient . SubmitTransaction ([] * protocol. Operation { op }, ee . Key )
1141+ err := ee .SubmitTransaction (result , op )
10381142 if err != nil {
1039- return nil , err
1143+ return nil , fmt . Errorf ( "cannot set contract, %w" , err )
10401144 }
1041- result .AddMessage (cliutil .TransactionReceiptToString (receipt , 1 ))
10421145 }
10431146
10441147 return result , nil
@@ -1095,12 +1198,10 @@ func (c *SessionCommand) Execute(ctx context.Context, ee *ExecutionEnvironment)
10951198 ops [i ] = reqs [i ].Op
10961199 }
10971200
1098- receipt , err := ee .RPCClient . SubmitTransaction (ops , ee . Key )
1201+ err := ee .SubmitTransaction (result , ops ... )
10991202 if err != nil {
11001203 return nil , fmt .Errorf ("error submitting transaction, %w" , err )
11011204 }
1102-
1103- result .AddMessage (cliutil .TransactionReceiptToString (receipt , len (ops )))
11041205 } else {
11051206 result .AddMessage ("Cancelling transaction because session has 0 operations" )
11061207 }
0 commit comments