Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions ui/rootui.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ func init() {
ApiKeyItem.Value = state.State.AlchApiKey
}

var SettingsItem = &Item{Label: settingsIcon + " Settings", Details: "Paymasters, Signers, ChainID, ..."}
var UserOpItem = &Item{Label: userOpsIcon + " User Operations", Details: "Manage User Operations"}
var AbisItem = &Item{Label: abisIcon + " ABIs", Details: "Manage ABIs"}

var PaymasterItem = &Item{Label: "Paymaster", Details: "Manage Paymaster settings"}
var UserOpItem = &Item{Label: "User Operations", Details: "Manage User Operations"}
var AbisItem = &Item{Label: "ABIs", Details: "Manage ABIs"}
var SignerItem = &Item{Label: "Signer", Details: "Manage Signer settings"}
var EntryPointItem = &Item{Label: "Entrypoint", Details: "Set Entrypoint"}
var ApiKeyItem = &Item{Label: "Alchemy API Key", Details: "Set Alchemy API Key"}
var SettingsItem = &Item{Label: "Settings", Details: "Paymasters, Signers, ChainID, ..."}

func RootUI() {
items := []*Item{
Expand Down
5 changes: 2 additions & 3 deletions ui/signui.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var PreHashV7Item = &Item{Label: "Pre Hash_v7", Details: "Hash of an encoded use
var PreHashV6Item = &Item{Label: "Pre Hash_v6", Details: "Hash of an encoded user operation"}
var EncodedBytesItem = &Item{Label: "Encoded Bytes", Details: "Encoded bytes of the user operation"}

func GetHashUI(usop *userop.UserOperation) (sig []byte, err error) {
func UtilsUI(usop *userop.UserOperation) (sig []byte, err error) {
var SignItem = &Item{Label: "Sign", Details: "Sign the user operation"}
prompt := promptui.Select{
Label: "Select an option",
Expand Down Expand Up @@ -76,7 +76,6 @@ func GetHashUI(usop *userop.UserOperation) (sig []byte, err error) {
hash, err = userop.GetUserOpHashV6(usop, EntryPoint, ChainID)
fmt.Println("Signing using v6 hashes")
} else {

hash, err = userop.GetUserOpHashV7(usop.Pack(), EntryPoint, ChainID)
fmt.Println("Signing using v7 hashes")
}
Expand Down Expand Up @@ -160,7 +159,7 @@ func SetSignatureUI(userop *userop.UserOperation) (calldata []byte, err error) {
}
return it.Value.([]byte), err
case UseSignerItem.Label:
return GetHashUI(userop)
return UtilsUI(userop)
default:
fmt.Println("Unreachable reached:", sel)
}
Expand Down
13 changes: 9 additions & 4 deletions ui/uitems.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ type Item struct {
Label string
Value interface{}
Details string
DisplayValueString string //could be a function, but I am lazy
DisplayValueString string // could be a function, but I am lazy
IsUserOp bool // To show them in a different color now that there are less menus
}

func (i *Item) DisplayValue() string {
Expand Down Expand Up @@ -89,21 +90,25 @@ func (i *Item) String() string {

const unicorn = "\U0001F984"

const settingsIcon = "\U0001F6E0"
const userOpsIcon = "\U0001F464"
const abisIcon = "\U0001F517"

const (
EXIT = "EXIT"
BACK = "BACK"
)

// Rewrite the above as variable instantiation witt OK=&Item{Label: "OK"} pattern
// Rewrite the above as variable instantiation with OK=&Item{Label: "OK"} pattern
var OK = &Item{Label: "OK", Details: "Confirm and proceed"}
var Back = &Item{Label: BACK, Details: "Go back to previous menu"}
var Exit = &Item{Label: EXIT, Details: "Exit the program"}
var Set = &Item{Label: "Set", Details: "Set the value"}

var ItemTemplate = &promptui.SelectTemplates{
Label: "{{ . | bold | cyan}}",
Inactive: `{{if eq .Label "BACK"}}{{.Label | yellow}}{{else if eq .Label "EXIT"}}{{.Label | red}}{{else if eq .Label "Set"}}{{.Label | green}}{{else}}{{ .Label }}{{with .DisplayValue}}: {{.}}{{end}}{{end}}`,
Active: `{{if eq .Label "BACK"}}{{.Label | yellow | bold | underline}}{{else if eq .Label "EXIT"}}{{.Label | red | bold | underline}}{{else if eq .Label "Set"}}{{.Label | green | bold | underline}}{{else}}{{ .Label | bold | underline }}{{with .DisplayValue}}: {{. | bold}}{{end}}{{end}}`,
Inactive: `{{if eq .IsUserOp true}}{{.Label | magenta}}{{else if eq .Label "BACK"}}{{.Label | yellow}}{{else if eq .Label "EXIT"}}{{.Label | red}}{{else if or (eq .Label "Set") (eq .Label "Export User Operation")}}{{.Label | green}}{{else if eq .Label "Utils: hashes and signatures"}}{{.Label | faint}}{{else}}{{ .Label }}{{with .DisplayValue}}: {{.}}{{end}}{{end}}`,
Active: `{{if eq .IsUserOp true}}{{.Label | magenta | bold | underline}}{{else if eq .Label "BACK"}}{{.Label | yellow | bold | underline}}{{else if eq .Label "EXIT"}}{{.Label | red | bold | underline}}{{else if or (eq .Label "Set") (eq .Label "Export User Operation")}}{{.Label | green | bold | underline}}{{else if eq .Label "Utils: hashes and signatures"}}{{.Label | faint | bold | underline}}{{else}}{{ .Label | bold | underline }}{{with .DisplayValue}}: {{. | bold}}{{end}}{{end}}`,
Selected: "{{. | faint}}",
Details: "{{ .Details | faint }}",
}
144 changes: 61 additions & 83 deletions ui/useropui.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,20 @@ import (
var SelectUserOpItem = &Item{Label: "Select User Operation", Details: "Select a user operation"}
var CreateUserOpItem = &Item{Label: "Create User Operation", Details: "Create a new user operation"}
var CloneUserOpItem = &Item{Label: "Clone User Operation", Details: "Clone a user operation"}
var DeleteUserOpItem = &Item{Label: "Delete User Operation", Details: "Delete a user operation"}

func TopUserOpUI(callbackItem *Item) {

usOpItem := &Item{}
workItem := &Item{}
deleteItem := &Item{}
for {
items := []*Item{}
if usOpItem.Value != nil {
if usop, ok := usOpItem.Value.(*userop.UserOperation); ok {
if callbackItem != nil {
callbackItem.Label = "Select this UserOperation"
callbackItem.Value = usop
items = append(items, callbackItem)
}

workItem = &Item{Label: "Work on User Operation: " + usOpItem.Label, Details: fmt.Sprintf("%s/%v", usop.Sender, usop.Nonce)}
deleteItem = &Item{Label: "Delete User Operation: " + usOpItem.Label, Details: "Delete this user operation"}
items = append(items, workItem, deleteItem)

}
}
items = append(items, []*Item{
SelectUserOpItem,
CreateUserOpItem,
CloneUserOpItem,
}...)
//Select a userOp, create a new one, or go back

userOpItems := GetUserOpItems()
items := append(userOpItems, []*Item{CreateUserOpItem, CloneUserOpItem, DeleteUserOpItem}...)
items = append(items, Back)

// Create a new select prompt
prompt := promptui.Select{
Label: "Select an option",
Items: items,
Templates: ItemTemplate,
Size: 10,
Size: len(items),
}
_, sel, err := prompt.Run()
if err != nil {
Expand All @@ -61,30 +38,19 @@ func TopUserOpUI(callbackItem *Item) {
switch sel {
case Back.Label:
return
case SelectUserOpItem.Label:

SelectUserOpUI(usOpItem)
case CreateUserOpItem.Label:
CreateUserOpUI(usOpItem)
CreateUserOpUI()
case CloneUserOpItem.Label:
CloneUserOpUI(usOpItem)
case workItem.Label:
usop := usOpItem.Value.(*userop.UserOperation) //Has been checked when generating ui, and there should be no concurrency, so it is safe
UserOpUI(usop)
case deleteItem.Label:
delete(state.State.UserOps, usOpItem.Label)
state.State.Save()
return
case callbackItem.Label:
return
CloneUserOpUI()
case DeleteUserOpItem.Label:
DeleteUserOpUI()
default:
fmt.Println("Not implemented yet:", sel)
UserOpContentUI(state.State.UserOps[sel])
}
}

}

func CloneUserOpUI(topIt *Item) {
func CloneUserOpUI() {
it := &Item{}
SelectUserOpUI(it)
if it.Value == nil {
Expand Down Expand Up @@ -121,35 +87,31 @@ func CloneUserOpUI(topIt *Item) {
fmt.Printf("Error cloning UserOp: %v\n", err)
return
}

topIt.Value = clone
topIt.Label = newname
state.State.UserOps[newname] = clone.(*userop.UserOperation)
state.State.Save()
}

func SelectUserOpUI(topit *Item) {
items := []*Item{}
keys := make([]string, 0, len(state.State.UserOps))
for k := range state.State.UserOps {
keys = append(keys, k)
}
if len(keys) == 0 {
fmt.Println("No UserOps available")
func DeleteUserOpUI() {
it := &Item{}
SelectUserOpUI(it)
if it.Value == nil {
fmt.Println("Nothing to delete")
return
}
sort.Strings(keys)
for _, name := range keys {
uop := state.State.UserOps[name]
items = append(items, &Item{Label: name, Details: fmt.Sprintf("Sender: %s, Nonce: %d", uop.Sender, uop.Nonce)})
}
items = append(items, Back)
delete(state.State.UserOps, it.Label)
state.State.Save()
}

func SelectUserOpUI(topit *Item) {
userOpItems := GetUserOpItems()
items := append(userOpItems, Back)

// Create a new select prompt
prompt := promptui.Select{
Label: "Select UserOperation",
Items: items,
Templates: ItemTemplate,
Size: 10,
Size: len(items),
}
_, sel, err := prompt.Run()
if err != nil {
Expand All @@ -164,7 +126,25 @@ func SelectUserOpUI(topit *Item) {

}

func CreateUserOpUI(topIt *Item) {
func GetUserOpItems() []*Item {
items := []*Item{}
keys := make([]string, 0, len(state.State.UserOps))
for k := range state.State.UserOps {
keys = append(keys, k)
}
if len(keys) == 0 {
fmt.Println("No UserOps available")
return items
}
sort.Strings(keys)
for _, name := range keys {
uop := state.State.UserOps[name]
items = append(items, &Item{Label: name, Details: fmt.Sprintf("Sender: %s, Nonce: %d", uop.Sender, uop.Nonce), IsUserOp: true})
}
return items
}

func CreateUserOpUI() {
//prompt for name
prompt := promptui.Prompt{
Label: "Enter UserOp Name",
Expand All @@ -185,21 +165,18 @@ func CreateUserOpUI(topIt *Item) {
fmt.Println(err)
return
}
topIt.Label = name
topIt.Value = nuop
UserOpContentUI(topIt)

UserOpContentUI(nuop)
}

var UserOpContentItem = &Item{Label: "User Operation Content", Details: "Manage user operation content"}
var ExportUserOpItem = &Item{Label: "Export User Operation", Details: "Select the export format"}
var GetHashItem = &Item{Label: "Hashes and signatures", Details: "Get the hash of the user operation with entrypoint and chainid"}
var UtilsItem = &Item{Label: "Utils: hashes and signatures", Details: "Get the hash of the user operation with entrypoint and chainid"}

func UserOpUI(usop *userop.UserOperation) {
items := []*Item{
UserOpContentItem,
ExportUserOpItem,
GetHashItem,
UtilsItem,
Back,
}
// Create a new select prompt
Expand All @@ -218,12 +195,12 @@ func UserOpUI(usop *userop.UserOperation) {
case Back.Label:
return
case UserOpContentItem.Label:
it := &Item{Value: usop}
UserOpContentUI(it)
// it := &Item{Value: usop}
UserOpContentUI(usop)
case ExportUserOpItem.Label:
ExportUserOpUI(usop)
case GetHashItem.Label:
GetHashUI(usop)
case UtilsItem.Label:
UtilsUI(usop)
default:
fmt.Println("Not implemented yet:", sel)
}
Expand All @@ -248,12 +225,8 @@ var PaymasterVerificationGasLimitItem = &Item{Label: "Paymaster Verification Gas
var PaymasterPostOpGasLimitItem = &Item{Label: "Paymaster Post Op Gas Limit", Details: "Set Paymaster Post Op Gas Limit", Value: userop.DefaultPaymasterPostOpGasLimit}
var SignatureItem = &Item{Label: "Signature", Details: "Set Signature"}

func UserOpContentUI(topIt *Item) {
var usop *userop.UserOperation

ok := false
usop, ok = topIt.Value.(*userop.UserOperation)
if !ok || usop == nil {
func UserOpContentUI(usop *userop.UserOperation) {
if usop == nil {
fmt.Println("Invalid UserOp passed to UserOpContentUI")
return
}
Expand All @@ -274,6 +247,8 @@ func UserOpContentUI(topIt *Item) {
PaymasterVerificationGasLimitItem,
PaymasterPostOpGasLimitItem,
SignatureItem,
ExportUserOpItem,
UtilsItem,
Back,
}
copyFromUseropToItems(usop)
Expand All @@ -282,7 +257,7 @@ func UserOpContentUI(topIt *Item) {
Label: "Select an option",
Items: items,
Templates: ItemTemplate,
Size: 22,
Size: len(items),
}
for {
_, sel, err := prompt.Run()
Expand All @@ -292,7 +267,7 @@ func UserOpContentUI(topIt *Item) {
switch sel {
case Back.Label:
copyValuesToUserOp(usop)
topIt.Value = usop
//topIt.Value = usop
return
case NonceItem.Label, CallGasLimitItem.Label, VerificationGasLimitItem.Label,
PreVerificationGasItem.Label, MaxFeePerGasItem.Label, MaxPriorityFeePerGasItem.Label,
Expand Down Expand Up @@ -337,11 +312,13 @@ func UserOpContentUI(topIt *Item) {
it, _ := GetItem(sel, items)
addr, ok := AddressFromBookUI(sel)
if ok {

it.Value = addr
usop.Sender = SenderItem.Value.(*common.Address)

}
case ExportUserOpItem.Label:
ExportUserOpUI(usop)
case UtilsItem.Label:
UtilsUI(usop)
default:
fmt.Println("Not implemented yet:", sel)
}
Expand Down Expand Up @@ -439,6 +416,7 @@ func ExportUserOpUI(uop *userop.UserOperation) {
default:
fmt.Println("Not implemented yet:", sel)
}
// return
}
}

Expand Down