feat: sweep webhooks, balance sync, sweep API improvements, server update webhook (v0.1.6.0-v0.1.8.0) - #34
Open
i2dor wants to merge 7 commits into
Open
feat: sweep webhooks, balance sync, sweep API improvements, server update webhook (v0.1.6.0-v0.1.8.0)#34i2dor wants to merge 7 commits into
i2dor wants to merge 7 commits into
Conversation
Owner
|
Thanks so much for the PR! Will get this reviewed and think through it tomorrow. |
Author
|
Thanks a lot! |
…s, scripts
- POST /api/v1/stores/{storeId}/spark/sync: forces wallet sync, returns
balanceSats/walletRunning/syncedAt; bypasses the 20-second status cache
- Sweep webhook: SweepWebhookUrl field in SweepSettings + SweepSettingsInput;
SparkSweepWebhookNotifier fires POST after SweepOutcomeKind.Swept with
storeId, txId, amountSats, feeSats, destination, trigger, completedAt
- GET .../spark/sweep warnings array: mainnet advisory when thresholds fall
below recommended defaults calibrated on regtest
- scripts/setup-stores.sh: headless multi-store provisioning via Greenfield
API with optional GPG seed encryption
- scripts/flint-logrotate.conf: copytruncate rotation for sdk.log (Rust SDK
holds the file open)
- docs/railway.md: persistent volumes, env vars, log rotation, health check
Tests: SyncBalance added to GreenfieldSparkStoreScopeTests; SparkBalanceSyncData
added to SparkApiContractTests.DocumentedModels; swagger.json updated with new
path and schema; Clone_copies_every_property guarded by SweepWebhookUrl in Clone()
SparkSweepWebhookNotifier now retries up to 3 times with 2s/4s/8s exponential backoff when the webhook endpoint returns a 5xx response or a network error. 4xx responses are not retried (permanent rejection). - MaxAttempts = 4 (1 initial + 3 retries), delays injectable for testing - StubHttpMessageHandler gains Sequence() and FailOnceThenOK() helpers - SparkSweepWebhookNotifierTests: 6 tests covering all retry paths
SparkSweepWebhookNotifier now also fires when a sweep attempt fails. The failure payload carries event: "sweep.failed", storeId, trigger, reason, and optional record fields (idempotencyKey, amountSats, destination) when a record was written before the failure occurred. Success payload gains event: "sweep.swept" so receivers can route both notification types on the same endpoint. - Shared PostWithRetryAsync helper eliminates duplication - StubHttpMessageHandler.Capture() for request-body inspection in tests - 4 new tests covering failure delivery, payload, retry, and URL guard
…e flag (0.1.7.0)
- GET /api/v1/stores/{storeId}/spark/sweep/{idempotencyKey}: retrieve a
specific sweep record by the idempotency key the engine assigned it.
Requires canViewStoreSettings. Returns 404 with sweep-record-not-found
when no record matches.
- destinationAddress in POST sweep request body: overrides the store's
configured sweep destination for this sweep. Validated against the
server's chain. Refused with 422 for EVM cross-chain sweep stores.
- force flag in POST sweep request body: bypasses the configured minimum
sweep amount. The absolute on-chain protocol minimum
(Constants.MinimumOnchainSendSats) still applies unconditionally.
All three fields documented in swagger.json and covered by the existing
contract test suite.
Adds a server-level webhook that fires once per day when a newer Flint
version is available on the BTCPay plugin registry.
New:
- SparkServerSettings: UpdateWebhookUrl + LastNotifiedUpdateVersion
- SparkPluginUpdateChecker (IPeriodicTask, daily): compares installed vs
remote version via PluginService.GetRemotePlugins; POSTs
'plugin.update-available' payload; records notified version to avoid
repeat notifications
Endpoints (CanModifyServerSettings):
GET /api/v1/server/spark - read current settings
PUT /api/v1/server/spark - set/clear updateWebhookUrl
Webhook payload:
{ event, pluginIdentifier, installedVersion, availableVersion }
Swagger updated; store-scope harness passes null for server settings;
API contract tests updated to allow CanModifyServerSettings on /server/
paths; store-scope route count test narrowed to {storeId} routes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds several features built on top of v0.1.5.4, across four releases.
v0.1.6.0 — Balance sync, sweep webhook, config warnings, setup scripts
POST .../spark/sync— forces a wallet sync and returns the current balance (walletRunning,balanceSats,syncedAt). Bypasses the 20-second SDK cache. RequirescanModifyStoreSettings.sweepWebhookUrlin sweep settings causes Flint to POST a JSON payload after each successful sweep:storeId,idempotencyKey,txId,amountSats,feeSats,destination,destinationMode,trigger,completedAt.GET .../spark/sweepnow includes awarningsarray. On mainnet, entries appear when thresholds fall below the recommended defaults calibrated on regtest.scripts/setup-stores.sh— headless multi-store provisioning via Greenfield API with optional GPG seed encryption.scripts/flint-logrotate.conf—copytruncate-based logrotate config forsdk.log(Rust SDK holds the file handle open).docs/railway.md— deployment guide: persistent volumes, environment variables, log rotation, health check.v0.1.6.1 — Sweep webhook retry
v0.1.6.2 — Webhook on failed sweeps
event: "sweep.failed"payload fired when a sweep attempt fails. CarriesstoreId,trigger,reason, and (when a record was created before the failure)idempotencyKey,amountSats,destination,destinationMode.event: "sweep.swept"so receivers can route both event types on the same endpoint.v0.1.7.0 — Sweep API improvements
GET .../spark/sweep/{idempotencyKey}— retrieve a specific sweep record by idempotency key. RequirescanViewStoreSettings. Returns 404 withsweep-record-not-foundwhen no record matches.destinationAddressinPOST .../spark/sweep— overrides the store's configured sweep destination for this one sweep. Validated against the server's chain. Not supported for EVM cross-chain sweep mode (returns 422).forceflag inPOST .../spark/sweep** — bypasses the store's configured minimum sweep amount. The absolute on-chain protocol minimum (Constants.MinimumOnchainSendSats) still applies.v0.1.8.0 — Server-level plugin update webhook
GET/PUT /api/v1/server/spark(requirescanModifyServerSettings) — read or setupdateWebhookUrl.{ event: "plugin.update-available", pluginIdentifier, installedVersion, availableVersion }to the configured URL. Each version is notified at most once.All endpoints are documented in
swagger.json. All new behaviour is covered by the unit test suite (1109 passing, 86 skipped — env-gated Postgres/regtest tests).