staticaddr: expose addresses in deposit listings

Include the owning static address in every deposit RPC response and CLI
listing. Users can distinguish deposits created by different receive and
change addresses without reconstructing scripts externally.

Update generated RPC artifacts and command replay fixtures for the new
field.
This commit is contained in:
Slyghtning 2026-05-11 13:43:43 +02:00
parent 88039c2125
commit 4bc75d8ec6
No known key found for this signature in database
GPG key ID: F82D456EA023C9BF
17 changed files with 159 additions and 69 deletions

View file

@ -65,6 +65,7 @@
" \"id\": \"bb7f050df0b7c3e1fe61010e10ad45e30ddf7acd301fa6e05a2ddb825b5c2efb\",\n",
" \"outpoint\": \"56cd081a3a6eadf25b7d3fe0b61207389352ed69a622d2ec28c5d669bf6a5313:0\",\n",
" \"state\": \"WITHDRAWING\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" }\n",

View file

@ -92,6 +92,7 @@
" \"id\": \"68262a104c9ec325de6bec37b8e31bd875bbd2f5f0b9ce2da20cf0bd636fc448\",\n",
" \"outpoint\": \"edcdab8f0b1138d853a453b8b7a5ac3c694bd53ad38b7ccf062e45f99440e6e6:0\",\n",
" \"state\": \"WITHDRAWN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -101,6 +102,7 @@
" \"id\": \"86b5e2cdf9694c8e7398e42afde109766d7cd2142203905ba63fbd0eb1370ef3\",\n",
" \"outpoint\": \"bb358e4f73ae97c4e2d99c6d64e852bba7cf56e13105b05d1200b8ae1796665e:0\",\n",
" \"state\": \"WITHDRAWN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -110,6 +112,7 @@
" \"id\": \"6c290f7536ea5097946afffac6a69906a26d775823ebbacedfe6f2d69c0745e4\",\n",
" \"outpoint\": \"5eaa7dd7a291665393eddf5dece91feef901f22665933cce7a0732a9b81c3001:0\",\n",
" \"state\": \"WITHDRAWN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -119,6 +122,7 @@
" \"id\": \"0182b4d895b1c467290ae7b5c6c42ff76b2a4225807a94211c973170d5a883eb\",\n",
" \"outpoint\": \"7e6360d6e6a394cfd096adf0bfe1275c5a83541eb573e90e463a78dc715f8894:0\",\n",
" \"state\": \"WITHDRAWN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" }\n",

View file

@ -65,6 +65,7 @@
" \"id\": \"8fbd6da2f945de2905aa7fa93860744d9387d3464484360e96e467a51de3bc9d\",\n",
" \"outpoint\": \"9fa0d5dd5348794aa0541dd2729497f0907890606d044e1c4757bdc848f38df8:0\",\n",
" \"state\": \"LOOPED_IN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"84302337424036419396ab7964dd78b85b1a481a9f1db73db5cddee57c2443e7\",\n",
" \"value\": \"500000\"\n",
" }\n",

View file

@ -110,6 +110,7 @@
" \"id\": \"68262a104c9ec325de6bec37b8e31bd875bbd2f5f0b9ce2da20cf0bd636fc448\",\n",
" \"outpoint\": \"edcdab8f0b1138d853a453b8b7a5ac3c694bd53ad38b7ccf062e45f99440e6e6:0\",\n",
" \"state\": \"WITHDRAWN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -119,6 +120,7 @@
" \"id\": \"86b5e2cdf9694c8e7398e42afde109766d7cd2142203905ba63fbd0eb1370ef3\",\n",
" \"outpoint\": \"bb358e4f73ae97c4e2d99c6d64e852bba7cf56e13105b05d1200b8ae1796665e:0\",\n",
" \"state\": \"WITHDRAWN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -128,6 +130,7 @@
" \"id\": \"6c290f7536ea5097946afffac6a69906a26d775823ebbacedfe6f2d69c0745e4\",\n",
" \"outpoint\": \"5eaa7dd7a291665393eddf5dece91feef901f22665933cce7a0732a9b81c3001:0\",\n",
" \"state\": \"WITHDRAWN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -137,6 +140,7 @@
" \"id\": \"0182b4d895b1c467290ae7b5c6c42ff76b2a4225807a94211c973170d5a883eb\",\n",
" \"outpoint\": \"7e6360d6e6a394cfd096adf0bfe1275c5a83541eb573e90e463a78dc715f8894:0\",\n",
" \"state\": \"WITHDRAWN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -146,6 +150,7 @@
" \"id\": \"8fbd6da2f945de2905aa7fa93860744d9387d3464484360e96e467a51de3bc9d\",\n",
" \"outpoint\": \"9fa0d5dd5348794aa0541dd2729497f0907890606d044e1c4757bdc848f38df8:0\",\n",
" \"state\": \"LOOPED_IN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"84302337424036419396ab7964dd78b85b1a481a9f1db73db5cddee57c2443e7\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -155,6 +160,7 @@
" \"id\": \"bb7f050df0b7c3e1fe61010e10ad45e30ddf7acd301fa6e05a2ddb825b5c2efb\",\n",
" \"outpoint\": \"56cd081a3a6eadf25b7d3fe0b61207389352ed69a622d2ec28c5d669bf6a5313:0\",\n",
" \"state\": \"WITHDRAWING\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" }\n",

View file

@ -77,6 +77,7 @@
" \"id\": \"7a7cbe9b90f23d47aa92eb10a9d323f7ace6e9eaab5b77379c63422c15da19c8\",\n",
" \"outpoint\": \"0e70673c1da3343648c26f779555346f30d235314838b1160826d0d5c29b4fba:1\",\n",
" \"state\": \"CHANNEL_PUBLISHED\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" },\n",
@ -86,6 +87,7 @@
" \"id\": \"ff9a43b2082f906a2e2758934220c4ce32393eb2823b292517ae081e16daded9\",\n",
" \"outpoint\": \"d2d6e50f157f0d31b8688a4af4f064edf3454714e92369b2c8c4d82477edbaca:0\",\n",
" \"state\": \"CHANNEL_PUBLISHED\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"1000000\"\n",
" }\n",

View file

@ -61,6 +61,7 @@
" \"id\": \"ea6abbf0571c0ba82117ae9f2086614eacea8b2913dc0544b70c00de78353e71\",\n",
" \"outpoint\": \"188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0\",\n",
" \"state\": \"DEPOSITED\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"2500000\"\n",
" }\n",

View file

@ -228,6 +228,7 @@
" \"id\": \"ea6abbf0571c0ba82117ae9f2086614eacea8b2913dc0544b70c00de78353e71\",\n",
" \"outpoint\": \"188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0\",\n",
" \"state\": \"LOOPING_IN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"2500000\"\n",
" }\n",

View file

@ -209,6 +209,7 @@
" \"id\": \"8fbd6da2f945de2905aa7fa93860744d9387d3464484360e96e467a51de3bc9d\",\n",
" \"outpoint\": \"9fa0d5dd5348794aa0541dd2729497f0907890606d044e1c4757bdc848f38df8:0\",\n",
" \"state\": \"LOOPING_IN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" }\n",

View file

@ -244,6 +244,7 @@
" \"id\": \"82771323e95dca403d966f70a88be39ef0a475ef6aa78694044ba9b87304ac63\",\n",
" \"outpoint\": \"da52bf383c4fe5c684221c311fc5756ccaee211b6c6e6f5ccc159622a6039271:1\",\n",
" \"state\": \"LOOPING_IN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" }\n",

View file

@ -235,6 +235,7 @@
" \"id\": \"d8a58536d8472873b9e2e1657468328360fda0b94231cfc5e29900cab735da84\",\n",
" \"outpoint\": \"f2280f0f086273be73bde92fd9b982208338a5ecebbe93b83b00c77c4d2f8d1b:0\",\n",
" \"state\": \"LOOPING_IN\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"550000\"\n",
" }\n",

View file

@ -73,6 +73,7 @@
" \"id\": \"68262a104c9ec325de6bec37b8e31bd875bbd2f5f0b9ce2da20cf0bd636fc448\",\n",
" \"outpoint\": \"edcdab8f0b1138d853a453b8b7a5ac3c694bd53ad38b7ccf062e45f99440e6e6:0\",\n",
" \"state\": \"WITHDRAWING\",\n",
" \"static_address\": \"\",\n",
" \"swap_hash\": \"\",\n",
" \"value\": \"500000\"\n",
" }\n",

View file

@ -1108,24 +1108,13 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
"deposits: %w", err)
}
// TODO(hieblmi): add params to deposit for multi-address
// support.
params, err := s.staticAddressManager.GetStaticAddressParameters(
ctx,
)
if err != nil {
return nil, fmt.Errorf("unable to retrieve static "+
"address parameters: %w", err)
}
info, err := s.lnd.Client.GetInfo(ctx)
if err != nil {
return nil, fmt.Errorf("unable to get lnd info: %w",
err)
}
selectedDeposits, err := loopin.SelectDeposits(
selectedAmount, deposits, params.Expiry,
info.BlockHeight,
selectedAmount, deposits, info.BlockHeight,
)
if err != nil {
return nil, fmt.Errorf("unable to select deposits: %w",
@ -2206,7 +2195,10 @@ func (s *swapClientServer) ListStaticAddressDeposits(ctx context.Context,
f := func(d *deposit.Deposit) bool {
return slices.Contains(outpoints, d.OutPoint.String())
}
filteredDeposits = filter(allDeposits, f)
filteredDeposits, err = s.filterDeposits(allDeposits, f)
if err != nil {
return nil, err
}
if len(outpoints) != len(filteredDeposits) {
return nil, fmt.Errorf("not all outpoints found in " +
@ -2222,11 +2214,14 @@ func (s *swapClientServer) ListStaticAddressDeposits(ctx context.Context,
return d.IsInState(toServerState(req.StateFilter))
}
filteredDeposits = filter(allDeposits, f)
filteredDeposits, err = s.filterDeposits(allDeposits, f)
if err != nil {
return nil, err
}
}
// Calculate the blocks until expiry for each deposit.
err = s.populateBlocksUntilExpiry(ctx, filteredDeposits)
err = s.populateBlocksUntilExpiry(ctx, allDeposits, filteredDeposits)
if err != nil {
infof("Failed to populate blocks until expiry: %v", err)
}
@ -2304,13 +2299,6 @@ func (s *swapClientServer) ListStaticAddressSwaps(ctx context.Context,
return nil, err
}
addrParams, err := s.staticAddressManager.GetStaticAddressParameters(
ctx,
)
if err != nil {
return nil, err
}
// Fetch all deposits at once and index them by swap hash for a quick
// lookup.
allDeposits, err := s.depositManager.GetAllDeposits(ctx)
@ -2351,22 +2339,23 @@ func (s *swapClientServer) ListStaticAddressSwaps(ctx context.Context,
if ds, ok := depositsBySwap[swp.SwapHash]; ok {
protoDeposits = make([]*looprpc.Deposit, 0, len(ds))
for _, d := range ds {
state := toClientDepositState(d.GetState())
confirmationHeight := d.GetConfirmationHeight()
if d.AddressParams == nil {
return nil, fmt.Errorf("missing static "+
"address parameters for deposit %v",
d.OutPoint)
}
blocksUntilExpiry := depositBlocksUntilExpiry(
confirmationHeight, addrParams.Expiry,
confirmationHeight,
d.AddressParams.Expiry,
int64(lndInfo.BlockHeight),
)
pd := &looprpc.Deposit{
Id: d.ID[:],
State: state,
Outpoint: d.OutPoint.String(),
Value: int64(d.Value),
ConfirmationHeight: confirmationHeight,
SwapHash: d.SwapHash[:],
BlocksUntilExpiry: blocksUntilExpiry,
pd, err := s.rpcDeposit(d)
if err != nil {
return nil, err
}
pd.BlocksUntilExpiry = blocksUntilExpiry
protoDeposits = append(protoDeposits, pd)
}
}
@ -2685,11 +2674,14 @@ func (s *swapClientServer) StaticAddressLoopIn(ctx context.Context,
}
// Build a list of used deposits for the response.
usedDeposits := filter(
usedDeposits, err := s.filterDeposits(
loopIn.Deposits, func(d *deposit.Deposit) bool { return true },
)
if err != nil {
return nil, err
}
err = s.populateBlocksUntilExpiry(ctx, usedDeposits)
err = s.populateBlocksUntilExpiry(ctx, loopIn.Deposits, usedDeposits)
if err != nil {
infof("Failed to populate blocks until expiry: %v", err)
}
@ -2731,21 +2723,31 @@ func (s *swapClientServer) StaticAddressLoopIn(ctx context.Context,
// Calculate the blocks until expiry for each deposit and return the modified
// StaticAddressLoopInResponse.
func (s *swapClientServer) populateBlocksUntilExpiry(ctx context.Context,
deposits []*looprpc.Deposit) error {
sourceDeposits []*deposit.Deposit, deposits []*looprpc.Deposit) error {
lndInfo, err := s.lnd.Client.GetInfo(ctx)
if err != nil {
return err
}
bestBlockHeight := int64(lndInfo.BlockHeight)
params, err := s.staticAddressManager.GetStaticAddressParameters(ctx)
if err != nil {
return err
expiryByOutpoint := make(map[string]uint32, len(sourceDeposits))
for _, d := range sourceDeposits {
if d.AddressParams == nil {
continue
}
expiryByOutpoint[d.OutPoint.String()] = d.AddressParams.Expiry
}
bestBlockHeight := int64(lndInfo.BlockHeight)
for i := range len(deposits) {
expiry, ok := expiryByOutpoint[deposits[i].Outpoint]
if !ok {
continue
}
deposits[i].BlocksUntilExpiry = depositBlocksUntilExpiry(
deposits[i].ConfirmationHeight, params.Expiry,
deposits[i].ConfirmationHeight, expiry,
bestBlockHeight,
)
}
@ -2794,35 +2796,65 @@ func (s *swapClientServer) StaticOpenChannel(ctx context.Context,
type filterFunc func(deposits *deposit.Deposit) bool
func filter(deposits []*deposit.Deposit, f filterFunc) []*looprpc.Deposit {
func (s *swapClientServer) filterDeposits(deposits []*deposit.Deposit,
f filterFunc) ([]*looprpc.Deposit, error) {
var clientDeposits []*looprpc.Deposit
for _, d := range deposits {
if !f(d) {
continue
}
swapHash := make([]byte, 0, len(lntypes.Hash{}))
if d.SwapHash != nil {
swapHash = d.SwapHash[:]
}
hash := d.Hash
outpoint := wire.NewOutPoint(&hash, d.Index).String()
deposit := &looprpc.Deposit{
Id: d.ID[:],
State: toClientDepositState(
d.GetState(),
),
Outpoint: outpoint,
Value: int64(d.Value),
ConfirmationHeight: d.GetConfirmationHeight(),
SwapHash: swapHash,
deposit, err := s.rpcDeposit(d)
if err != nil {
return nil, err
}
clientDeposits = append(clientDeposits, deposit)
}
return clientDeposits
return clientDeposits, nil
}
func (s *swapClientServer) rpcDeposit(d *deposit.Deposit) (
*looprpc.Deposit, error) {
swapHash := make([]byte, 0, len(lntypes.Hash{}))
if d.SwapHash != nil {
swapHash = d.SwapHash[:]
}
hash := d.Hash
outpoint := wire.NewOutPoint(&hash, d.Index).String()
deposit := &looprpc.Deposit{
Id: d.ID[:],
State: toClientDepositState(
d.GetState(),
),
Outpoint: outpoint,
Value: int64(d.Value),
ConfirmationHeight: d.GetConfirmationHeight(),
SwapHash: swapHash,
}
if d.AddressParams == nil {
return deposit, nil
}
if s.staticAddressManager == nil {
return nil, fmt.Errorf("static address manager not configured")
}
staticAddress, err := s.staticAddressManager.GetTaprootAddress(
d.AddressParams.ClientPubkey, d.AddressParams.ServerPubkey,
int64(d.AddressParams.Expiry),
)
if err != nil {
return nil, err
}
deposit.StaticAddress = staticAddress.String()
return deposit, nil
}
func toClientDepositState(state fsm.StateType) looprpc.DepositState {

View file

@ -339,6 +339,17 @@ func TestListStaticAddressDepositsReturnsVisibleDeposits(t *testing.T) {
available.SetState(deposit.Deposited)
addrMgr, lnd := newTestStaticAddressContext(t)
addresses, err := addrMgr.GetAllAddresses(context.Background())
require.NoError(t, err)
require.Len(t, addresses, 1)
available.AddressParams = addresses[0]
expectedAddr, err := addrMgr.GetTaprootAddress(
addresses[0].ClientPubkey, addresses[0].ServerPubkey,
int64(addresses[0].Expiry),
)
require.NoError(t, err)
server := &swapClientServer{
depositManager: newTestDepositManager(available),
staticAddressManager: addrMgr,
@ -354,6 +365,10 @@ func TestListStaticAddressDepositsReturnsVisibleDeposits(t *testing.T) {
t, available.OutPoint.String(),
resp.FilteredDeposits[0].Outpoint,
)
require.Equal(
t, expectedAddr.String(),
resp.FilteredDeposits[0].StaticAddress,
)
}
// TestGetStaticAddressSummaryTotalsDeposits verifies visible deposits are

View file

@ -416,6 +416,17 @@ func TestListStaticAddressSwapsPopulatesTimingAndCosts(t *testing.T) {
}
testDeposit.SetState(deposit.LoopedIn)
_, clientPubkey := mock_lnd.CreateKey(1)
_, serverPubkey := mock_lnd.CreateKey(2)
staticAddressParams := &script.Parameters{
ID: 1,
ClientPubkey: clientPubkey,
ServerPubkey: serverPubkey,
Expiry: staticAddressExpiry,
PkScript: []byte("pkscript"),
}
testDeposit.AddressParams = staticAddressParams
initiationTime := time.Unix(1_234, 567).UTC()
lastUpdateTime := time.Unix(2_345, 678).UTC()
staticLoopIn := &loopin.StaticAddressLoopIn{
@ -446,15 +457,8 @@ func TestListStaticAddressSwapsPopulatesTimingAndCosts(t *testing.T) {
}, 1)
require.NoError(t, err)
_, clientPubkey := mock_lnd.CreateKey(1)
_, serverPubkey := mock_lnd.CreateKey(2)
addrStore := &mockAddressStore{
params: []*script.Parameters{{
ClientPubkey: clientPubkey,
ServerPubkey: serverPubkey,
Expiry: staticAddressExpiry,
PkScript: []byte("pkscript"),
}},
params: []*script.Parameters{staticAddressParams},
}
addrMgr, err := address.NewManager(&address.ManagerConfig{
Store: addrStore,

View file

@ -5741,7 +5741,9 @@ type Deposit struct {
BlocksUntilExpiry int64 `protobuf:"varint,6,opt,name=blocks_until_expiry,json=blocksUntilExpiry,proto3" json:"blocks_until_expiry,omitempty"`
// The swap hash of the swap that this deposit is part of. This field is only
// set if the deposit is part of a loop-in swap.
SwapHash []byte `protobuf:"bytes,7,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"`
SwapHash []byte `protobuf:"bytes,7,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"`
// The static address that the deposit was sent to.
StaticAddress string `protobuf:"bytes,8,opt,name=static_address,json=staticAddress,proto3" json:"static_address,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -5825,6 +5827,13 @@ func (x *Deposit) GetSwapHash() []byte {
return nil
}
func (x *Deposit) GetStaticAddress() string {
if x != nil {
return x.StaticAddress
}
return ""
}
type StaticAddressWithdrawal struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The transaction id of the withdrawal transaction.
@ -7062,7 +7071,7 @@ const file_client_proto_rawDesc = "" +
"\x18value_looped_in_satoshis\x18\b \x01(\x03R\x15valueLoopedInSatoshis\x12J\n" +
"\"value_htlc_timeout_sweeps_satoshis\x18\t \x01(\x03R\x1evalueHtlcTimeoutSweepsSatoshis\x122\n" +
"\x15value_channels_opened\x18\n" +
" \x01(\x03R\x13valueChannelsOpened\"\xf6\x01\n" +
" \x01(\x03R\x13valueChannelsOpened\"\x9d\x02\n" +
"\aDeposit\x12\x0e\n" +
"\x02id\x18\x01 \x01(\fR\x02id\x12+\n" +
"\x05state\x18\x02 \x01(\x0e2\x15.looprpc.DepositStateR\x05state\x12\x1a\n" +
@ -7070,7 +7079,8 @@ const file_client_proto_rawDesc = "" +
"\x05value\x18\x04 \x01(\x03R\x05value\x12/\n" +
"\x13confirmation_height\x18\x05 \x01(\x03R\x12confirmationHeight\x12.\n" +
"\x13blocks_until_expiry\x18\x06 \x01(\x03R\x11blocksUntilExpiry\x12\x1b\n" +
"\tswap_hash\x18\a \x01(\fR\bswapHash\"\xc2\x02\n" +
"\tswap_hash\x18\a \x01(\fR\bswapHash\x12%\n" +
"\x0estatic_address\x18\b \x01(\tR\rstaticAddress\"\xc2\x02\n" +
"\x17StaticAddressWithdrawal\x12\x13\n" +
"\x05tx_id\x18\x01 \x01(\tR\x04txId\x12,\n" +
"\bdeposits\x18\x02 \x03(\v2\x10.looprpc.DepositR\bdeposits\x12A\n" +

View file

@ -2100,6 +2100,11 @@ message Deposit {
set if the deposit is part of a loop-in swap.
*/
bytes swap_hash = 7;
/*
The static address that the deposit was sent to.
*/
string static_address = 8;
}
message StaticAddressWithdrawal {

View file

@ -1697,6 +1697,10 @@
"type": "string",
"format": "byte",
"description": "The swap hash of the swap that this deposit is part of. This field is only\nset if the deposit is part of a loop-in swap."
},
"static_address": {
"type": "string",
"description": "The static address that the deposit was sent to."
}
}
},