Skip to content
Merged
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
25 changes: 25 additions & 0 deletions cmd/loop/liquidity.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,12 @@ var setParamsCommand = &cli.Command{
Usage: "the confirmation target for loop in on-chain " +
"htlcs.",
},
&cli.StringFlag{
Name: "loopinsource",
Usage: "the loop-in source to use for autoloop rules: " +
"wallet or static-address. Static-address " +
"requires loopd --experimental.",
},
&cli.BoolFlag{
Name: "easyautoloop",
Usage: "set to true to enable easy autoloop, which " +
Expand Down Expand Up @@ -555,6 +561,25 @@ func setParams(ctx context.Context, cmd *cli.Command) error {
flagSet = true
}

if cmd.IsSet("loopinsource") {
switch cmd.String("loopinsource") {
case "wallet":
params.LoopInSource =
looprpc.LoopInSource_LOOP_IN_SOURCE_WALLET

case "static-address", "static_address", "static":
params.LoopInSource =
looprpc.LoopInSource_LOOP_IN_SOURCE_STATIC_ADDRESS

default:
return fmt.Errorf("unknown loopinsource value %q "+
"(use \"wallet\" or \"static-address\")",
cmd.String("loopinsource"))
}

flagSet = true
}

// If we are setting easy autoloop parameters, we need to ensure that
// the asset ID is set, and that we have a valid entry in our params
// map.
Expand Down
9 changes: 5 additions & 4 deletions cmd/loop/session_fixture_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func writeSessionFilePath(path string, fixture sessionFile) error {
defer file.Close()

encoder := json.NewEncoder(file)
encoder.SetEscapeHTML(false)
encoder.SetIndent("", " ")

return encoder.Encode(fixture)
Expand Down Expand Up @@ -152,7 +153,7 @@ func rewriteSessionFixture(fixture sessionFile,
func rewriteExitEventRunError(events []sessionEvent, runError *string,
changed bool) ([]sessionEvent, bool, error) {

data, err := json.Marshal(exitPayload{
data, err := marshalSessionJSON(exitPayload{
RunError: cloneOptionalString(runError),
})
if err != nil {
Expand Down Expand Up @@ -338,7 +339,7 @@ func buildReplacementTextEvents(events []sessionEvent, indices []int,

replacements := make([]sessionEvent, 0, len(chunks))
for i, chunk := range chunks {
data, err := json.Marshal(newTextPayload(chunk))
data, err := marshalSessionJSON(newTextPayload(chunk))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -571,7 +572,7 @@ func TestRewriteSessionFixtureSkipsNormalizedTimestampNoise(t *testing.T) {
func textEvent(t *testing.T, timeMS int64, kind, text string) sessionEvent {
t.Helper()

data, err := json.Marshal(newTextPayload(text))
data, err := marshalSessionJSON(newTextPayload(text))
require.NoError(t, err)

return sessionEvent{
Expand All @@ -585,7 +586,7 @@ func textEvent(t *testing.T, timeMS int64, kind, text string) sessionEvent {
func exitEvent(t *testing.T, timeMS int64, runError *string) sessionEvent {
t.Helper()

data, err := json.Marshal(exitPayload{
data, err := marshalSessionJSON(exitPayload{
RunError: cloneOptionalString(runError),
})
require.NoError(t, err)
Expand Down
22 changes: 19 additions & 3 deletions cmd/loop/session_recorder.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bytes"
"context"
"encoding/json"
"errors"
Expand Down Expand Up @@ -48,6 +49,20 @@ var grpcMarshalOptions = protojson.MarshalOptions{
EmitUnpopulated: true,
}

// marshalSessionJSON encodes nested session payloads without HTML escaping so
// recorded fixture strings stay byte-for-byte close to the CLI text.
func marshalSessionJSON(value any) ([]byte, error) {
var buf bytes.Buffer

encoder := json.NewEncoder(&buf)
encoder.SetEscapeHTML(false)
if err := encoder.Encode(value); err != nil {
return nil, err
}

return bytes.TrimSuffix(buf.Bytes(), []byte("\n")), nil
}

// sessionRecorder captures CLI IO and gRPC traffic for replay.
type sessionRecorder struct {
mu sync.Mutex
Expand Down Expand Up @@ -80,9 +95,9 @@ type sessionMetadata struct {
Args []string `json:"args"`
Env map[string]string `json:"env"`
Version string `json:"version"`
ClockStartUnix int64 `json:"clock_start_unix"`
RunError *string `json:"run_error,omitempty"`
Duration *time.Duration `json:"duration,omitempty"`
ClockStartUnix int64 `json:"clock_start_unix"`
}

// sessionEvent records a single timestamped payload entry.
Expand Down Expand Up @@ -262,7 +277,7 @@ func ensureSessionBaseDir(baseDir string) error {

// logEvent records a new event with the elapsed timestamp.
func (r *sessionRecorder) logEvent(kind string, payload any) {
data, err := json.Marshal(payload)
data, err := marshalSessionJSON(payload)
if err != nil {
r.mu.Lock()
if r.eventErr == nil {
Expand Down Expand Up @@ -434,6 +449,7 @@ func (r *sessionRecorder) finalize(runErr error) error {
defer file.Close()

encoder := json.NewEncoder(file)
encoder.SetEscapeHTML(false)
encoder.SetIndent("", " ")
if err := encoder.Encode(fileContent); err != nil {
finalizeErr = errors.Join(err, eventErr, hookErr)
Expand Down Expand Up @@ -563,7 +579,7 @@ func (r *sessionRecorder) logGRPCMessage(method, event string, msg any,
payload.Payload = data
}
} else {
data, err := json.Marshal(msg)
data, err := marshalSessionJSON(msg)
if err == nil {
payload.Payload = data
}
Expand Down
1 change: 1 addition & 0 deletions cmd/loop/testdata/sessions/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Base URL: `http://127.0.0.1:12345`
| `misc/` | `loop terms` |
| `quote/` | `loop quote out` (success + verbose), `loop quote in` (help + verbose), `loop quote out` (help), `loop quote in` (deposit_outpoint success), `loop quote in` (positional + last_hop) |
| `static/` | `loop static withdraw` (no selection error), `loop static withdraw` (invalid utxo), `loop static withdraw` (all success), `loop static withdraw` (utxo + dest_addr success), `loop static listwithdrawals`, `loop static listswaps` |
| `static-autoloop/` | `loop setparams --loopinsource static-address` (success + no-experimental error), `loop getparams` (static-address loop-in source), `loop suggestswaps` (static loop-in suggestion) |
| `static-loop-in/` | `loop static new`, `loop static` (help), `loop static listunspent` (incl alias), `loop static listdeposits`, `loop static summary`, `loop static in` (multiple args/flags cases), `loop static in` (duplicate outpoints), `loop static in` (positional low amount error), `loop static in` (positional + last_hop + payment_timeout), `loop static in` (all cancel) |
| `static-filters/` | `loop static listdeposits --filter ...` for each state (deposited/withdrawing/withdrawn/looping_in/looped_in/publish_expired_deposit/sweep_htlc_timeout/htlc_timeout_swept/wait_for_expiry_sweep/expired/failed) |
| `swaps/` | `loop listswaps` (success + conflicting filters + loop_out_only filters + loop_in_only), `loop swapinfo` (success + invalid id + id flag errors), `loop abandonswap` (help + invalid id + success) |
Expand Down
4 changes: 3 additions & 1 deletion cmd/loop/testdata/sessions/liquidity/01_loop-getparams.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand All @@ -85,6 +86,7 @@
" \"fast_swap_publication\": true,\n",
" \"fee_ppm\": \"20000\",\n",
" \"htlc_conf_target\": 6,\n",
" \"loop_in_source\": \"LOOP_IN_SOURCE_WALLET\",\n",
" \"max_miner_fee_sat\": \"0\",\n",
" \"max_prepay_routing_fee_ppm\": \"0\",\n",
" \"max_prepay_sat\": \"0\",\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -99,7 +100,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -118,7 +119,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"{\n",
" \"disqualified\": [],\n",
" \"loop_in\": [],\n",
" \"loop_out\": []\n",
" \"loop_out\": [],\n",
" \"static_loop_in\": []\n",
"}\n"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -126,7 +127,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -145,7 +146,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -125,7 +126,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -151,7 +152,8 @@
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": [
"AnHW4pMBFZ2eHMXTmDR5pR87PAxoLtp/FqofR9/gmyL3"
]
],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -153,7 +154,8 @@
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": [
"AnHW4pMBFZ2eHMXTmDR5pR87PAxoLtp/FqofR9/gmyL3"
]
],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
"account_addr_type": "ADDRESS_TYPE_UNKNOWN",
"easy_asset_params": {},
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": []
"easy_autoloop_excluded_peers": [],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -152,7 +153,8 @@
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": [
"AnHW4pMBFZ2eHMXTmDR5pR87PAxoLtp/FqofR9/gmyL3"
]
],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": [
"AnHW4pMBFZ2eHMXTmDR5pR87PAxoLtp/FqofR9/gmyL3"
]
],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
},
Expand Down Expand Up @@ -121,7 +122,8 @@
"fast_swap_publication": true,
"easy_autoloop_excluded_peers": [
"AnHW4pMBFZ2eHMXTmDR5pR87PAxoLtp/FqofR9/gmyL3"
]
],
"loop_in_source": "LOOP_IN_SOURCE_WALLET"
}
}
}
Expand Down
Loading
Loading