-
Notifications
You must be signed in to change notification settings - Fork 0
feat(turnkey): Integrate Turnkey support for remote signer functionality #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "encoding/json" | ||
| "fmt" | ||
| "io" | ||
| "net/http" | ||
| "strings" | ||
|
|
||
| "github.com/ethereum/go-ethereum/log" | ||
| ) | ||
|
|
||
| func (w *wizard) turnkeyBase() string { | ||
| return fmt.Sprintf("http://%s:%s", w.host, w.httpPort) | ||
| } | ||
|
|
||
| func (w *wizard) turnkeyListWallets() { | ||
| resp, err := http.Get(w.turnkeyBase() + "/turnkey/wallets") | ||
| if err != nil { | ||
| log.Error("Turnkey list wallets failed", "err", err) | ||
| return | ||
| } | ||
| defer resp.Body.Close() | ||
| body, _ := io.ReadAll(resp.Body) | ||
| if resp.StatusCode != http.StatusOK { | ||
| log.Error("Turnkey list wallets", "status", resp.StatusCode, "body", string(body)) | ||
| return | ||
| } | ||
| fmt.Println(string(body)) | ||
|
Comment on lines
+18
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: In Go's net/http package, http.Get and http.Post use http.DefaultClient by default when no custom http.Client is provided. The DefaultClient is defined as var DefaultClient = &Client{}, which is the zero value of Client. The Client struct has a Timeout field of type time.Duration, and the documentation explicitly states: "A Timeout of zero means no timeout." The client.do method checks if c.Timeout > 0 before applying any deadline; since it is zero, no timeout is set. This behavior is consistent across Go versions, including recent ones like go1.25.1, and is confirmed by multiple secondary sources warning that the default client has no timeout, allowing requests to hang indefinitely. Citations:
🏁 Script executed: # Find the file and check its size
fd wizard_turnkey.goRepository: eliteprox/go-livepeer Length of output: 99 🏁 Script executed: # Read the entire file to see all HTTP calls
cat -n cmd/livepeer_cli/wizard_turnkey.goRepository: eliteprox/go-livepeer Length of output: 3139 Add a bounded HTTP client for Turnkey wizard calls. All four actions use the default 🔧 Minimal fix sketch import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
+ "time"
"github.com/ethereum/go-ethereum/log"
)
+var turnkeyHTTPClient = &http.Client{Timeout: 10 * time.Second}
+
func (w *wizard) turnkeyListWallets() {
- resp, err := http.Get(w.turnkeyBase() + "/turnkey/wallets")
+ resp, err := turnkeyHTTPClient.Get(w.turnkeyBase() + "/turnkey/wallets")
if err != nil {
log.Error("Turnkey list wallets failed", "err", err)
return
}
@@
- resp, err := http.Post(w.turnkeyBase()+"/turnkey/create-wallet", "application/json", bytes.NewReader(payload))
+ resp, err := turnkeyHTTPClient.Post(w.turnkeyBase()+"/turnkey/create-wallet", "application/json", bytes.NewReader(payload))
@@
- resp, err := http.Post(w.turnkeyBase()+"/turnkey/create-account", "application/json", bytes.NewReader(payload))
+ resp, err := turnkeyHTTPClient.Post(w.turnkeyBase()+"/turnkey/create-account", "application/json", bytes.NewReader(payload))
@@
- resp, err := http.Post(w.turnkeyBase()+"/turnkey/select-address", "application/json", bytes.NewReader(payload))
+ resp, err := turnkeyHTTPClient.Post(w.turnkeyBase()+"/turnkey/select-address", "application/json", bytes.NewReader(payload))🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| func (w *wizard) turnkeyCreateWallet() { | ||
| fmt.Println("Wallet name?") | ||
| name := w.readString() | ||
| payload, _ := json.Marshal(map[string]string{"walletName": name}) | ||
| resp, err := http.Post(w.turnkeyBase()+"/turnkey/create-wallet", "application/json", bytes.NewReader(payload)) | ||
| if err != nil { | ||
| log.Error("Turnkey create wallet failed", "err", err) | ||
| return | ||
| } | ||
| defer resp.Body.Close() | ||
| body, _ := io.ReadAll(resp.Body) | ||
| if resp.StatusCode != http.StatusOK { | ||
| log.Error("Turnkey create wallet", "status", resp.StatusCode, "body", string(body)) | ||
| return | ||
| } | ||
| fmt.Println(string(body)) | ||
| } | ||
|
|
||
| func (w *wizard) turnkeyCreateAccount() { | ||
| fmt.Println("Wallet ID?") | ||
| wid := w.readString() | ||
| payload, _ := json.Marshal(map[string]string{"walletId": wid}) | ||
| resp, err := http.Post(w.turnkeyBase()+"/turnkey/create-account", "application/json", bytes.NewReader(payload)) | ||
| if err != nil { | ||
| log.Error("Turnkey create account failed", "err", err) | ||
| return | ||
| } | ||
| defer resp.Body.Close() | ||
| body, _ := io.ReadAll(resp.Body) | ||
| if resp.StatusCode != http.StatusOK { | ||
| log.Error("Turnkey create account", "status", resp.StatusCode, "body", string(body)) | ||
| return | ||
| } | ||
| fmt.Println(string(body)) | ||
| } | ||
|
|
||
| func (w *wizard) turnkeySelectAddress() { | ||
| fmt.Println("Ethereum address (0x…)?") | ||
| addr := w.readString() | ||
| if !strings.HasPrefix(addr, "0x") { | ||
| addr = "0x" + addr | ||
| } | ||
| payload, _ := json.Marshal(map[string]string{"address": addr}) | ||
| resp, err := http.Post(w.turnkeyBase()+"/turnkey/select-address", "application/json", bytes.NewReader(payload)) | ||
| if err != nil { | ||
| log.Error("Turnkey select address failed", "err", err) | ||
| return | ||
| } | ||
| defer resp.Body.Close() | ||
| body, _ := io.ReadAll(resp.Body) | ||
| if resp.StatusCode != http.StatusOK { | ||
| log.Error("Turnkey select address", "status", resp.StatusCode, "body", string(body)) | ||
| return | ||
| } | ||
| fmt.Println(string(body)) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't silently pick
accts[0]when multiple Turnkey accounts exist.This makes the signer identity restart-dependent and also loses any address selected at runtime via the Turnkey API. If more than one Ethereum account exists, require
-ethAcctAddror load a persisted default instead of relying on API order.🔧 Safer startup behavior
📝 Committable suggestion
🤖 Prompt for AI Agents