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
12 changes: 7 additions & 5 deletions embedded/modules/call/call.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ function buildParametersFromABI(functionDef, paramValues) {

if (value !== undefined) {
parameters.push({
ParameterFlag: paramDef.flag,
ParameterValue: formatParameterValue(paramDef.type, value),
Parameter: {
ParameterName: Buffer.from(paramDef.name).toString('hex').toUpperCase(),
ParameterValue: formatParameterValue(paramDef.type, value),
},
});
}
}
Expand Down Expand Up @@ -148,6 +150,7 @@ async function callContract(config) {
contract_account,
function_name,
network_url,
rpc_url,
wallet_seed,
abi_path,
parameters,
Expand Down Expand Up @@ -268,9 +271,8 @@ async function callContract(config) {
// Local nodes: use HTTP RPC to avoid WebSocket hangs under emulation
await client.disconnect();

const rpcUrl = network_url
.replace('ws://', 'http://').replace('wss://', 'https://')
.replace('localhost:6006', 'localhost:5005');
const rpcUrl = rpc_url || network_url
.replace('ws://', 'http://').replace('wss://', 'https://');

const submitResult = await httpRPC(rpcUrl, 'submit', { tx_blob: signed.tx_blob }, 120000);

Expand Down
6 changes: 3 additions & 3 deletions embedded/modules/deploy/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ async function deployContract(config) {
wasm_path,
abi_path,
network_url,
rpc_url,
wallet_seed,
faucet_url,
fee,
Expand Down Expand Up @@ -390,9 +391,8 @@ async function deployContract(config) {
// Local nodes: use HTTP RPC to avoid WebSocket hangs under emulation
await client.disconnect();

const rpcUrl = network_url
.replace('ws://', 'http://').replace('wss://', 'https://')
.replace('localhost:6006', 'localhost:5005');
const rpcUrl = rpc_url || network_url
.replace('ws://', 'http://').replace('wss://', 'https://');

const submitResult = await httpRPC(rpcUrl, 'submit', { tx_blob: signed.tx_blob }, 120000);

Expand Down
3 changes: 2 additions & 1 deletion internal/cli/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ func runAccount(cmd *cobra.Command, args []string) error {
if accountNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 63456,
}
} else {
return fmt.Errorf("network '%s' not found in config", accountNetwork)
}
}

client := chain.NewClient(networkCfg.URL)
client := chain.NewClient(networkCfg.URL, networkCfg.GetRPCURL())
ctx := cmd.Context()

switch subcommand {
Expand Down
2 changes: 2 additions & 0 deletions internal/cli/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ func runCall(cmd *cobra.Command, args []string) error {
if callNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 0, // Local network uses network ID 0
}
} else {
Expand Down Expand Up @@ -134,6 +135,7 @@ func runCall(cmd *cobra.Command, args []string) error {
ContractAccount: contractAccount,
FunctionName: functionName,
NetworkURL: networkCfg.URL,
RPCURL: networkCfg.GetRPCURL(),
NetworkID: networkCfg.NetworkID,
WalletSeed: walletSeed,
Algorithm: callAlgorithm,
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/clawback.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func runClawback(cmd *cobra.Command, args []string) error {
networkCfg, ok := cfg.Networks[clawbackNetwork]
if !ok {
if clawbackNetwork == "local" {
networkCfg = config.NetworkConfig{URL: "ws://localhost:6006", NetworkID: 63456}
networkCfg = config.NetworkConfig{URL: "ws://localhost:6006", RPCURL: "http://localhost:5005", NetworkID: 63456}
} else {
return fmt.Errorf("network '%s' not found in config", clawbackNetwork)
}
Expand Down
1 change: 1 addition & 0 deletions internal/cli/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func runConsole(cmd *cobra.Command, args []string) error {
if consoleNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 63456,
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func runDelete(cmd *cobra.Command, args []string) error {
networkCfg, ok := cfg.Networks[deleteNetwork]
if !ok {
if deleteNetwork == "local" {
networkCfg = config.NetworkConfig{URL: "ws://localhost:6006", NetworkID: 63456}
networkCfg = config.NetworkConfig{URL: "ws://localhost:6006", RPCURL: "http://localhost:5005", NetworkID: 63456}
} else {
return fmt.Errorf("network '%s' not found in config", deleteNetwork)
}
Expand Down
2 changes: 2 additions & 0 deletions internal/cli/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func runDeploy(cmd *cobra.Command, args []string) error {
if deployNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 63456,
FaucetURL: "http://localhost:8080/faucet",
}
Expand Down Expand Up @@ -220,6 +221,7 @@ func runDeploy(cmd *cobra.Command, args []string) error {
WasmPath: wasmPath,
ABIPath: abiPath,
NetworkURL: networkCfg.URL,
RPCURL: networkCfg.GetRPCURL(),
NetworkID: networkCfg.NetworkID,
WalletSeed: walletSeed,
Algorithm: deployAlgorithm,
Expand Down
3 changes: 2 additions & 1 deletion internal/cli/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,15 @@ func runEvents(cmd *cobra.Command, args []string) error {
if eventsNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 63456,
}
} else {
return fmt.Errorf("network '%s' not found in config", eventsNetwork)
}
}

client := chain.NewClient(networkCfg.URL)
client := chain.NewClient(networkCfg.URL, networkCfg.GetRPCURL())
ctx := cmd.Context()

color.Cyan("Contract Events\n")
Expand Down
1 change: 1 addition & 0 deletions internal/cli/faucet.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func runFaucet(cmd *cobra.Command, args []string) error {
if isLocal {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 0, // Local network uses network ID 0
}
} else {
Expand Down
3 changes: 2 additions & 1 deletion internal/cli/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ func runInfo(cmd *cobra.Command, args []string) error {
if infoNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 63456,
}
} else {
return fmt.Errorf("network '%s' not found in config", infoNetwork)
}
}

client := chain.NewClient(networkCfg.URL)
client := chain.NewClient(networkCfg.URL, networkCfg.GetRPCURL())
ctx := cmd.Context()

color.Cyan("Contract Info\n")
Expand Down
1 change: 1 addition & 0 deletions internal/cli/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ ledger_interval = 1000

[networks.local]
url = "ws://localhost:6006"
rpc_url = "http://localhost:5005"
network_id = 63456
faucet_url = "http://localhost:8080/faucet"

Expand Down
6 changes: 4 additions & 2 deletions internal/cli/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,15 @@ func runLedger(cmd *cobra.Command, args []string) error {
if ledgerNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 63456,
}
} else {
return fmt.Errorf("network '%s' not found in config", ledgerNetwork)
}
}

client := chain.NewClient(networkCfg.URL)
client := chain.NewClient(networkCfg.URL, networkCfg.GetRPCURL())
ctx := cmd.Context()

ledgerIndex := "current"
Expand Down Expand Up @@ -108,14 +109,15 @@ func runTx(cmd *cobra.Command, args []string) error {
if txNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 63456,
}
} else {
return fmt.Errorf("network '%s' not found in config", txNetwork)
}
}

client := chain.NewClient(networkCfg.URL)
client := chain.NewClient(networkCfg.URL, networkCfg.GetRPCURL())
ctx := cmd.Context()

color.Cyan("Transaction Details\n")
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/modify.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func runModify(cmd *cobra.Command, args []string) error {
networkCfg, ok := cfg.Networks[modifyNetwork]
if !ok {
if modifyNetwork == "local" {
networkCfg = config.NetworkConfig{URL: "ws://localhost:6006", NetworkID: 63456}
networkCfg = config.NetworkConfig{URL: "ws://localhost:6006", RPCURL: "http://localhost:5005", NetworkID: 63456}
} else {
return fmt.Errorf("network '%s' not found in config", modifyNetwork)
}
Expand Down
38 changes: 30 additions & 8 deletions internal/cli/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,21 @@ func nodeStart(ctx context.Context, manager *network.Manager) error {
// Convert ledger interval from milliseconds to duration
ledgerInterval := time.Duration(cfg.LocalNode.LedgerInterval) * time.Millisecond

// Resolve local network URLs from config
localCfg, ok := cfg.Networks["local"]
if !ok {
localCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: DefaultLocalRPCURL,
}
}
rpcURL := localCfg.GetRPCURL()

opts := network.StartOptions{
DockerImage: cfg.LocalNode.DockerImage,
ConfigDir: cfg.LocalNode.ConfigDir,
LedgerInterval: ledgerInterval,
RPCURL: DefaultLocalRPCURL,
RPCURL: rpcURL,
}

if err := manager.Start(ctx, opts); err != nil {
Expand All @@ -98,7 +108,7 @@ func nodeStart(ctx context.Context, manager *network.Manager) error {
fmt.Println()

// Start the ledger daemon in background
if err := startLedgerDaemon(cfg.LocalNode.LedgerInterval); err != nil {
if err := startLedgerDaemon(cfg.LocalNode.LedgerInterval, rpcURL); err != nil {
color.Yellow("Warning: Failed to start ledger daemon: %v\n", err)
color.Yellow("Ledgers will not advance automatically.\n")
} else {
Expand All @@ -107,8 +117,8 @@ func nodeStart(ctx context.Context, manager *network.Manager) error {

fmt.Println()
color.Cyan("Connection Details:\n")
fmt.Println(" WebSocket URL: ws://localhost:6006")
fmt.Println(" RPC URL: http://localhost:5005")
fmt.Printf(" WebSocket URL: %s\n", localCfg.URL)
fmt.Printf(" RPC URL: %s\n", rpcURL)
fmt.Println()
color.Cyan("Ledger Service:\n")
fmt.Printf(" Auto-advance interval: %v\n", ledgerInterval)
Expand All @@ -123,7 +133,7 @@ func nodeStart(ctx context.Context, manager *network.Manager) error {
}

// startLedgerDaemon spawns the ledger daemon as a background process
func startLedgerDaemon(intervalMs int) error {
func startLedgerDaemon(intervalMs int, rpcURL string) error {
// Get the path to the current executable
executable, err := os.Executable()
if err != nil {
Expand All @@ -143,7 +153,7 @@ func startLedgerDaemon(intervalMs int) error {

// Start the daemon process
cmd := exec.Command(executable, "_ledger-daemon",
"--rpc-url", DefaultLocalRPCURL,
"--rpc-url", rpcURL,
"--interval", strconv.Itoa(intervalMs),
)
cmd.Stdout = logFile
Expand Down Expand Up @@ -250,11 +260,23 @@ func nodeStatus(ctx context.Context, manager *network.Manager) error {
}

if status.Running {
// Resolve local network URLs from config
cfg, _ := config.LoadFromWorkingDir()
localCfg := config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: DefaultLocalRPCURL,
}
if cfg != nil {
if lc, ok := cfg.Networks["local"]; ok {
localCfg = lc
}
}

color.Green("✓ Local node is running\n")
fmt.Println()
color.Cyan("Connection Details:\n")
fmt.Println(" WebSocket URL: ws://localhost:6006")
fmt.Println(" RPC URL: http://localhost:5005")
fmt.Printf(" WebSocket URL: %s\n", localCfg.URL)
fmt.Printf(" RPC URL: %s\n", localCfg.GetRPCURL())
fmt.Println()

// Show ledger daemon status
Expand Down
3 changes: 2 additions & 1 deletion internal/cli/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ func runRPC(cmd *cobra.Command, args []string) error {
if rpcNetwork == "local" {
networkCfg = config.NetworkConfig{
URL: "ws://localhost:6006",
RPCURL: "http://localhost:5005",
NetworkID: 63456,
}
} else {
return fmt.Errorf("network '%s' not found in config", rpcNetwork)
}
}

client := chain.NewClient(networkCfg.URL)
client := chain.NewClient(networkCfg.URL, networkCfg.GetRPCURL())
ctx := cmd.Context()

var params []interface{}
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/user_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func runUserDelete(cmd *cobra.Command, args []string) error {
networkCfg, ok := cfg.Networks[userDeleteNetwork]
if !ok {
if userDeleteNetwork == "local" {
networkCfg = config.NetworkConfig{URL: "ws://localhost:6006", NetworkID: 63456}
networkCfg = config.NetworkConfig{URL: "ws://localhost:6006", RPCURL: "http://localhost:5005", NetworkID: 63456}
} else {
return fmt.Errorf("network '%s' not found in config", userDeleteNetwork)
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/caller/caller.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ func (c *Caller) Call(ctx context.Context, config CallConfig) (*CallResult, erro
"verbose": c.verbose,
}

if config.RPCURL != "" {
jsConfig["rpc_url"] = config.RPCURL
}

if config.ABIPath != "" {
jsConfig["abi_path"] = config.ABIPath
}
Expand Down
1 change: 1 addition & 0 deletions pkg/caller/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type CallConfig struct {
ContractAccount string
FunctionName string
NetworkURL string
RPCURL string // HTTP RPC URL (optional, derived from NetworkURL if empty)
NetworkID uint32
WalletSeed string
Algorithm string
Expand Down
14 changes: 9 additions & 5 deletions pkg/chain/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ type RPCError struct {
Message string `json:"message"`
}

// NewClient creates a new XRPL RPC client from a WebSocket or HTTP URL
func NewClient(url string) *Client {
// NewClient creates a new XRPL RPC client from a WebSocket or HTTP URL.
// An optional rpcURL can be provided to override the derived HTTP URL.
func NewClient(url string, rpcURL ...string) *Client {
httpURL := toHTTPURL(url)
if len(rpcURL) > 0 && rpcURL[0] != "" {
httpURL = rpcURL[0]
}
return &Client{
httpURL: httpURL,
httpClient: &http.Client{
Expand Down Expand Up @@ -121,12 +125,12 @@ func (c *Client) CallTyped(ctx context.Context, target interface{}, method strin
return nil
}

// toHTTPURL converts a WebSocket URL to an HTTP URL for JSON-RPC
// toHTTPURL converts a WebSocket URL to an HTTP URL for JSON-RPC.
// This is a fallback conversion (ws:// -> http://, wss:// -> https://).
// For local development where ports differ, use NetworkConfig.GetRPCURL() or pass rpcURL to NewClient.
func toHTTPURL(rawURL string) string {
if strings.HasPrefix(rawURL, "ws://") {
rawURL = strings.Replace(rawURL, "ws://", "http://", 1)
// Local dev: WS port 6006 maps to JSON-RPC port 5005
rawURL = strings.Replace(rawURL, "localhost:6006", "localhost:5005", 1)
} else if strings.HasPrefix(rawURL, "wss://") {
rawURL = strings.Replace(rawURL, "wss://", "https://", 1)
}
Expand Down
Loading