Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
cfa14e7
fix: connection problems, healthcheck postgres
markettes May 23, 2025
2d6e049
Merge pull request #1 from markettes/connectivity-issue
markettes May 23, 2025
79fa4c8
feat: added ui and minimal functionality to display bumpfee pop up (n…
Anon2148 Jun 3, 2025
8f7ee68
Merge branch 'Elenpay:main' into main
markettes Jun 4, 2025
15c8f2e
feat: added actions column in withdrawal requests datagrid and functi…
Anon2148 Jun 3, 2025
e623755
fix: changed bumpefee modal rendering condition, although not tested
Anon2148 Jun 9, 2025
2933be8
wip
Anon2148 Jun 9, 2025
60adbf7
feat: added fee rate check, user cannot bumpfee with a lower new fee …
Anon2148 Jun 10, 2025
67bc76b
wip: submit confirmation modal fails when trying to bumpfee
Anon2148 Jun 12, 2025
fb9f324
feat: enhance fee rate display in withdrawal requests datagrid to cla…
Rubenro01 Jun 13, 2025
907800c
wip: bumpfee works partially, although the previous transaction is st…
Anon2148 Jun 16, 2025
d3d8be1
feat: add Parent Tx column and metadata handling in withdrawal requests
scrpti Jun 17, 2025
57c5d2c
fix: update Docker Compose to use host.docker.internal for BTC RPC UR…
scrpti Jun 17, 2025
cca0645
wip: adding utxos to bumped transaction, not working yet, problem wit…
Anon2148 Jun 19, 2025
bb27615
feat: add handling for changeless transactions in bumpfee process to …
scrpti Jun 22, 2025
081693b
wip: modified how withdrawals register bumped withdrawals, already no…
Anon2148 Jun 23, 2025
3e0103d
wip: keep working on updating the UTXOs, the request could be updated…
Anon2148 Jun 24, 2025
70662ab
Merge branch 'popup-bumpfee-ui' of https://github.com/markettes/NodeG…
scrpti Jun 25, 2025
f6cfe50
feat: added bumping object to WalletWithdrawalRequest and added utxos…
Anon2148 Jun 26, 2025
d7146d3
feat: add display of last fee used and its type in bumpfee modal
Rubenro01 Jun 28, 2025
3460ca6
fix: improve error message for insufficient fee in bumpfee modal
Rubenro01 Jul 1, 2025
a557b0f
feat: enhance bump fee functionality with error handling for changele…
scrpti Jul 1, 2025
4402b87
Merge branch 'popup-bumpfee-ui' of https://github.com/markettes/NodeG…
scrpti Jul 1, 2025
17c0a4e
feat: added bumped state and modified logic when bumping transaction …
Anon2148 Jul 4, 2025
d056df3
refactor: specify function for wds while also including the wallet wd…
markettes Jul 7, 2025
07aa9be
remove unused variable for changeless amount in BitcoinService
scrpti Jul 7, 2025
9dfd2c8
feat: changeless transactions bump fee method is available
scrpti Jul 7, 2025
5742520
chore: add mempool space to docker compose
markettes Jul 7, 2025
50dc4f3
Merge branch 'Elenpay:main' into main
markettes Jul 10, 2025
51840d2
Merge branch 'main' into rbf
markettes Jul 21, 2025
dfd4e03
fix: bad handling of the vars
markettes Jul 21, 2025
84481ac
fix: fixing migrations
markettes Jul 21, 2025
3b9939c
fix: when a bumping tx fails update the other one to onchainconfpendi…
markettes Jul 22, 2025
7ca75d1
fix: remove unused imports
markettes Jul 23, 2025
9e293d0
fix: if formats and remove todo
markettes Jul 23, 2025
b4800ad
feat: dont return dust
markettes Jul 23, 2025
95ed09c
fix: return after error
markettes Jul 23, 2025
6997448
fix: exception
markettes Jul 23, 2025
58c7af1
fix: nit
markettes Jul 23, 2025
2e90a9a
fix: remove dbtrie
markettes Jul 23, 2025
e3aa62e
fix: remove dupl
markettes Jul 23, 2025
dafda20
test: set rbf flag
markettes Jul 23, 2025
3f08a47
erge remote-tracking branch 'upstream/main'
markettes Jul 23, 2025
cb02dcb
Merge branch 'main' into rbf
markettes Jul 23, 2025
ce61f7c
fix: error on failed broadcasting
markettes Jul 25, 2025
97b1e05
fix: bad conditional
markettes Jul 23, 2025
31aaa4e
feat: add mempool profile to docker
markettes Jul 25, 2025
57facd6
fix: old migration
markettes Jul 25, 2025
2734d2c
refactor: change from sats vb to sat vb
markettes Jul 25, 2025
e536090
fix: casing
markettes Jul 25, 2025
83d25f1
fix: naming
markettes Jul 25, 2025
9b9d45f
fix: remove async
markettes Jul 25, 2025
6122f4c
feat: make constant Money
markettes Jul 25, 2025
c1a2f71
feat: add help line to indicate % of fee and amount of fees
markettes Jul 29, 2025
a7892ca
fix: refactor variable name
markettes Jul 29, 2025
a766a86
fix: spacing
markettes Jul 30, 2025
245bfbc
feat: add max of 200
markettes Jul 30, 2025
0032dba
fix: bug on multisig
markettes Jul 31, 2025
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
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"POSTGRES_CONNECTIONSTRING": "Host=127.0.0.1;Port=5432;Database=nodeguard;Username=rw_dev;Password=rw_dev",
"POSTGRES_CONNECTIONSTRING": "Host=127.0.0.1;Port=25432;Database=nodeguard;Username=rw_dev;Password=rw_dev",
"BITCOIN_NETWORK": "REGTEST",
"MAXIMUM_WITHDRAWAL_BTC_AMOUNT": "21000000",
"NBXPLORER_ENABLE_CUSTOM_BACKEND": "true",
Expand Down
105 changes: 97 additions & 8 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '3.4'
version: "3.4"

name: nodeguard
services:
Expand All @@ -22,7 +22,9 @@ services:
platform: linux/amd64
hostname: nbxplorer
ports:
- "32838:32838"
- "32838:32838"
depends_on:
- nbxplorer_postgres
environment:
NBXPLORER_NETWORK: regtest
NBXPLORER_BIND: 0.0.0.0:32838
Expand All @@ -36,7 +38,7 @@ services:
NBXPLORER_BTCNODEENDPOINT: host.docker.internal:19444
command: ["--noauth"]
volumes:
- "bitcoin_datadir:/root/.bitcoin"
- "bitcoin_datadir:/root/.bitcoin"

nbxplorer_postgres:
container_name: nbxplorer_postgres
Expand All @@ -51,12 +53,99 @@ services:
- nbxplorer_postgres_data:/var/lib/postgresql/data
ports:
- 35432:5432
healthcheck:
test: ["CMD", "pg_isready", "-U", "rw_dev"]
interval: 10s
timeout: 5s
retries: 5

mempool-frontend-btc:
Comment thread
Jossec101 marked this conversation as resolved.
profiles: ["mempool"]
environment:
FRONTEND_HTTP_PORT: "8080"
BACKEND_MAINNET_HTTP_HOST: "mempool-backend-btc"
LIQUID_ENABLED: false
LIQUID_TESTNET_ENABLED: false
image: mempool/frontend:latest
container_name: 40swap_mempool_frontend_btc
user: "1000:1000"
restart: always
command: "./wait-for mempool-db-btc:3306 --timeout=720 -- nginx -g 'daemon off;'"
ports:
- 7084:8080

mempool-backend-btc:
profiles: ["mempool"]
environment:
MEMPOOL_BACKEND: "electrum"
CORE_RPC_HOST: "host.docker.internal"
CORE_RPC_PORT: "18443"
CORE_RPC_USERNAME: "polaruser"
CORE_RPC_PASSWORD: "polarpass"
DATABASE_ENABLED: "true"
DATABASE_HOST: "mempool-db-btc"
DATABASE_DATABASE: "mempool_btc"
DATABASE_USERNAME: "mempool"
DATABASE_PASSWORD: "mempool"
STATISTICS_ENABLED: "true"
ELECTRUM_HOST: "electrumx"
ELECTRUM_PORT: "50001"
ELECTRUM_TLS_ENABLED: "false"
image: mempool/backend:latest
container_name: 40swap_mempool_backend_btc
user: "1000:1000"
restart: always
command: "./wait-for-it.sh mempool-db-btc:3306 --timeout=720 --strict -- ./start.sh"
depends_on:
- mempool-db-btc
volumes:
- mempool-backend-btc-data:/backend/cache

mempool-db-btc:
profiles: ["mempool"]
environment:
MYSQL_DATABASE: "mempool_btc"
MYSQL_USER: "mempool"
MYSQL_PASSWORD: "mempool"
MYSQL_ROOT_PASSWORD: "admin"
image: mariadb:10.5.8
container_name: 40swap_mempool_db_btc
restart: always
volumes:
- mempool-db-btc-data:/var/lib/mysql

electrumx:
profiles: ["mempool"]
image: andgohq/electrumx:1.8.7
container_name: 40swap_electrumx
command: ["wait-for-it.sh", "host.docker.internal:18443", "--", "init"]
ports:
- "51002:50002"
- "51001:50001"
expose:
- "50001"
- "50002"
volumes:
- electrumx-data:/data
environment:
# bitcoind is valid
- DAEMON_URL=http://polaruser:polarpass@host.docker.internal:18443
- COIN=BitcoinSegwit
- NET=regtest
# 127.0.0.1 or electrumx is valid for RPC_HOST
- RPC_HOST=electrumx
- RPC_PORT=18443
- HOST=electrumx
- TCP_PORT=50001
- SSL_PORT=50002
restart: always

volumes:
nodeguard_postgres_data:
bitcoin_datadir:
nbxplorer_datadir:
nbxplorer_postgres_data:
nodeguard_data_keys_dir:
nodeguard_postgres_data:
bitcoin_datadir:
nbxplorer_datadir:
nbxplorer_postgres_data:
nodeguard_data_keys_dir:
mempool-backend-btc-data:
mempool-db-btc-data:
electrumx-data:
11 changes: 10 additions & 1 deletion src/Data/Models/WalletWithdrawalRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@
/// <summary>
/// The PSBT is being signed by NodeGuard after all human required signatures have been collected
/// </summary>
FinalizingPSBT = 7
FinalizingPSBT = 7,

/// <summary>
/// The tx was bumped by Replace by Fee (RBF) method
/// </summary>
Bumped = 8
}

/// <summary>
Expand Down Expand Up @@ -187,8 +192,12 @@
public ApplicationUser UserRequestor { get; set; }
public int WalletId { get; set; }

public Wallet Wallet { get; set; }

Check warning on line 195 in src/Data/Models/WalletWithdrawalRequest.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Nullability of reference types in type of parameter 'value' of 'void WalletWithdrawalRequest.Wallet.set' doesn't match implicitly implemented member 'void IBitcoinRequest.Wallet.set' (possibly because of nullability attributes).

public int? BumpingWalletWithdrawalRequestId { get; set; }

public WalletWithdrawalRequest? BumpingWalletWithdrawalRequest { get; set; }

public List<WalletWithdrawalRequestPSBT> WalletWithdrawalRequestPSBTs { get; set; }

public List<FMUTXO> UTXOs { get; set; }
Expand Down
15 changes: 15 additions & 0 deletions src/Data/Repositories/FUTXORepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,21 @@ public async Task<List<FMUTXO>> GetAll()
return _repository.Update(type, applicationDbContext);
}

public async Task<List<FMUTXO>> GetLockedUTXOsByWithdrawalId(int walletWithdrawalRequestId)
{
await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync();

var result = new List<FMUTXO>();
result = await applicationDbContext.WalletWithdrawalRequests
.Include(x => x.UTXOs)
.Where(x => x.Id == walletWithdrawalRequestId)
.SelectMany(x => x.UTXOs)
.Include(x => x.WalletWithdrawalRequests)
.ToListAsync();

return result;
}

public async Task<List<FMUTXO>> GetLockedUTXOs(int? ignoredWalletWithdrawalRequestId = null, int? ignoredChannelOperationRequestId = null)
{
await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync();
Expand Down
5 changes: 5 additions & 0 deletions src/Data/Repositories/Interfaces/IFMUTXORepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ public interface IFMUTXORepository
/// <returns></returns>
Task<List<FMUTXO>> GetLockedUTXOs(int? ignoredWalletWithdrawalRequestId = null, int? ignoredChannelOperationRequestId = null);
Task<List<FMUTXO>> GetLockedUTXOsByWalletId(int walletId);
/// <summary>
/// Gets the current list of UTXOs locked on WalletWithdrawalRequest by passing its id
/// </summary>
/// <returns></returns>
Task<List<FMUTXO>> GetLockedUTXOsByWithdrawalId(int walletWithdrawalRequestId);
}
2 changes: 2 additions & 0 deletions src/Data/Repositories/WalletWithdrawalRequestRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ INBXplorerService nBXplorerService
.Include(x => x.UserRequestor)
.Include(x => x.WalletWithdrawalRequestPSBTs)
.Include(x => x.WalletWithdrawalRequestDestinations)
.Include(x => x.UTXOs)
.SingleOrDefaultAsync(x => x.Id == id);

return request;
Expand Down Expand Up @@ -94,6 +95,7 @@ public async Task<List<WalletWithdrawalRequest>> GetAll()
.Include(x => x.UserRequestor)
.Include(x => x.WalletWithdrawalRequestPSBTs)
.Include(x => x.WalletWithdrawalRequestDestinations)
.Include(x => x.UTXOs)
.AsSplitQuery()
.ToListAsync();
}
Expand Down
4 changes: 3 additions & 1 deletion src/Helpers/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
using System.Globalization;
using System.Reflection;
using NBitcoin;
using NodeGuard.Helpers;

public class Constants
Expand Down Expand Up @@ -75,6 +76,7 @@ public class Constants
public static readonly long MINIMUM_SWEEP_TRANSACTION_AMOUNT_SATS = 25_000_000; //25M sats
public static readonly string DEFAULT_DERIVATION_PATH = "48'/1'";
public static readonly int SESSION_TIMEOUT_MILLISECONDS = 3_600_000;
public static readonly Money BITCOIN_DUST = new Money(0.00000546m, MoneyUnit.BTC); // 546 satoshi in BTC

//Sat/vb ratio
public static decimal MIN_SAT_PER_VB_RATIO = 0.9m;
Expand All @@ -100,7 +102,7 @@ public class Constants
public static readonly string ALICE_PUBKEY = "02dc2ae598a02fc1e9709a23b68cd51d7fa14b1132295a4d75aa4f5acd23ee9527";
public static readonly string ALICE_HOST = "host.docker.internal:10001";
public static readonly string ALICE_MACAROON = "0201036c6e6402f801030a108cdfeb2614b8335c11aebb358f888d6d1201301a160a0761646472657373120472656164120577726974651a130a04696e666f120472656164120577726974651a170a08696e766f69636573120472656164120577726974651a210a086d616361726f6f6e120867656e6572617465120472656164120577726974651a160a076d657373616765120472656164120577726974651a170a086f6666636861696e120472656164120577726974651a160a076f6e636861696e120472656164120577726974651a140a057065657273120472656164120577726974651a180a067369676e6572120867656e657261746512047265616400000620c999e1a30842cbae3f79bd633b19d5ec0d2b6ebdc4880f6f5d5c230ce38f26ab";
public static readonly string BOB_PUBKEY = "038644c6b13cdfc59bc97c2cc2b1418ced78f6d01da94f3bfd5fdf8b197335ea84";
public static readonly string BOB_PUBKEY = "038644c6b13cdfc59bc97c2cc2b1418ced78f6d01da94f3bfd5fdf8b197335ea84";
public static readonly string BOB_HOST = "host.docker.internal:10002";
public static readonly string BOB_MACAROON = "0201036c6e6402f801030a10e0e89a68f9e2398228a995890637d2531201301a160a0761646472657373120472656164120577726974651a130a04696e666f120472656164120577726974651a170a08696e766f69636573120472656164120577726974651a210a086d616361726f6f6e120867656e6572617465120472656164120577726974651a160a076d657373616765120472656164120577726974651a170a086f6666636861696e120472656164120577726974651a160a076f6e636861696e120472656164120577726974651a140a057065657273120472656164120577726974651a180a067369676e6572120867656e657261746512047265616400000620b85ae6b693338987cd65eda60a24573e962301b2a91d8f7c5625650d6368751f";
public static readonly string CAROL_PUBKEY = "03650f49929d84d9a6d9b5a66235c603a1a0597dd609f7cd3b15052382cf9bb1b4";
Expand Down
23 changes: 23 additions & 0 deletions src/Jobs/PerformWithdrawalJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,29 @@ public async Task Execute(IJobExecutionContext context)
catch (Exception e)
{
var request = await _walletWithdrawalRequestRepository.GetById(withdrawalRequestId);

// If an error occurs and the wd was bumping another one, we need to update the status of the withdrawal request to previous status
if (request != null && request!.BumpingWalletWithdrawalRequestId.HasValue)
{
var bumped = await _walletWithdrawalRequestRepository.GetById(request.BumpingWalletWithdrawalRequestId.Value);
if (bumped == null)
{
_logger.LogError("Failed to find withdrawal request with ID {WithdrawalRequestId}", withdrawalRequestId);
return;
}

bumped.Status = WalletWithdrawalRequestStatus.OnChainConfirmationPending;
var (ok, _) = _walletWithdrawalRequestRepository.Update(bumped);
if (!ok)
{
_logger.LogError("Failed to update withdrawal request status to OnChainConfirmationPending for ID {WithdrawalRequestId}", withdrawalRequestId);
}
else
{
_logger.LogInformation("Updated withdrawal request status to OnChainConfirmationPending for ID {WithdrawalRequestId}", withdrawalRequestId);
}
}

request!.Status = WalletWithdrawalRequestStatus.Failed;
var (updated, _) = _walletWithdrawalRequestRepository.Update(request);
if (!updated)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ protected override void Down(MigrationBuilder migrationBuilder)
UPDATE public.""Channels"" SET ""SourceNodeId"" = 1, ""DestinationNodeId"" = 1;
COMMIT;";
migrationBuilder.Sql(query);

}
}
}
8 changes: 2 additions & 6 deletions src/Migrations/20250611142943_MigrateLegacyWithdrawalData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ public partial class MigrateLegacyWithdrawalData : Migration
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
// Execute data migration in an explicit transaction
// Execute data migration
migrationBuilder.Sql(@"
BEGIN;

-- Step 1: Migrate existing data from Amount and DestinationAddress to WalletWithdrawalRequestDestinations
INSERT INTO ""WalletWithdrawalRequestDestinations"" (""Amount"", ""Address"", ""WalletWithdrawalRequestId"", ""CreationDatetime"", ""UpdateDatetime"")
SELECT
Expand All @@ -24,7 +22,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
""UpdateDatetime""
FROM ""WalletWithdrawalRequests""
WHERE ""Amount"" > 0 AND ""DestinationAddress"" IS NOT NULL AND ""DestinationAddress"" != '';

-- Step 2: Verify migration was successful - if any records failed to migrate, rollback
DO $$
DECLARE
Expand All @@ -50,8 +48,6 @@ SELECT COUNT(*) INTO migrated_count
-- Log success
RAISE NOTICE 'Successfully migrated % legacy withdrawal records to destinations table', original_count;
END $$;

COMMIT;
Comment thread
Jossec101 marked this conversation as resolved.
");
}

Expand Down
Loading
Loading