Repository navigation
feat(minter): automatic deposit flow - #274
gregorydemay wants to merge 2 commits into
Conversation
8e2c061 to
dd0421b
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Raw provider responses cannot reliably reach consensus on mainnet, causing scans to fail and retry indefinitely.
1 open finding
What changed in this PR
Adds automatic SOL deposit detection through an expiring watchlist, scheduled balance scans, and automatic deposit fees.
Changes:
- Adds the watch endpoint, scan timer, batching, concurrency handling, and upgrade persistence.
- Tracks automatic fees, deposit history, metrics, and dashboard data.
- Extends Candid types and comprehensive unit/integration coverage.
| File | Description |
|---|---|
minter/templates/dashboard.html |
Displays automatic-deposit data. |
minter/src/utils/timed_sized_map/tests.rs |
Tests the bounded TTL map. |
minter/src/utils/timed_sized_map/mod.rs |
Implements the bounded TTL map. |
minter/src/utils/mod.rs |
Exports the new map module. |
minter/src/test_fixtures/runtime.rs |
Improves inter-canister call simulation. |
minter/src/test_fixtures/mod.rs |
Adds automatic-deposit fixtures. |
minter/src/test_fixtures/flow/deposit.rs |
Supports automatic deposit test flows. |
minter/src/storage/mod.rs |
Tracks scan outcomes. |
minter/src/state/watchlist/tests.rs |
Tests watchlist behavior. |
minter/src/state/watchlist/mod.rs |
Implements watch registration and scheduling. |
minter/src/state/tests.rs |
Tests persistence, fees, and validation. |
minter/src/state/mod.rs |
Integrates watchlist and fee state. |
minter/src/state/event/candid/tests.rs |
Updates Candid event tests. |
minter/src/state/event/candid/mod.rs |
Converts new event types. |
minter/src/state/event.rs |
Adds automatic-deposit and snapshot events. |
minter/src/state/deposits/tests.rs |
Tests returned dropped deposits. |
minter/src/state/deposits/sweeps/tests.rs |
Tests automatic fee deductions. |
minter/src/state/deposits/sweeps/mod.rs |
Applies automatic fees to mints. |
minter/src/state/deposits/mod.rs |
Tracks automatic and latest deposits. |
minter/src/state/audit.rs |
Replays new state transitions. |
minter/src/rpc/tests.rs |
Tests batched balance RPC handling. |
minter/src/rpc/mod.rs |
Adds getMultipleAccounts support. |
minter/src/metrics.rs |
Exposes automatic-flow metrics. |
minter/src/main.rs |
Exposes endpoint and scan timer. |
minter/src/lifecycle/tests.rs |
Tests watchlist snapshots. |
minter/src/lifecycle.rs |
Persists watchlist before upgrades. |
minter/src/deposit/sweep/tests.rs |
Tests manual/automatic race handling. |
minter/src/deposit/sweep/mod.rs |
Shares deposit queueing logic. |
minter/src/deposit/mod.rs |
Exports the automatic flow. |
minter/src/deposit/automatic/tests.rs |
Tests watch endpoint behavior. |
minter/src/deposit/automatic/scan/tests.rs |
Tests scheduled balance scans. |
minter/src/deposit/automatic/scan/mod.rs |
Implements concurrent scans. |
minter/src/deposit/automatic/mod.rs |
Implements watch registration API. |
minter/src/dashboard/tests.rs |
Tests automatic-flow dashboard output. |
minter/src/dashboard/mod.rs |
Builds watchlist dashboard data. |
minter/src/cycles.rs |
Adds RPC-cost-only charging. |
minter/src/constants.rs |
Defines scan and RPC limits. |
minter/src/canbench.rs |
Updates benchmark fixtures. |
minter/cksol_minter.did |
Extends the public Candid interface. |
minter/Cargo.toml |
Promotes serde_json to runtime dependency. |
libs/types/src/lib.rs |
Adds public watch API types. |
libs/types-internal/src/lib.rs |
Adds fee configuration fields. |
libs/types-internal/src/event.rs |
Adds debug event types. |
integration_tests/tests/tests.rs |
Adds end-to-end watch-flow tests. |
integration_tests/tests/solana_test_validator.rs |
Tests mixed automatic/manual sweeping. |
integration_tests/src/lib.rs |
Adds integration client helpers. |
integration_tests/src/fixtures.rs |
Adds batched RPC mocks. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
e25dd6b to
781f9fc
Compare
781f9fc to
4cc47f8
Compare
4cc47f8 to
56121ee
Compare
| automatic: Some(AutomaticDeposit { | ||
| fee: automatic_deposit_fee, | ||
| valid_until: watched.valid_until, |
| record_failed_read(scan.scanned_at, chunk); | ||
| record_deposit_address_scans(ScanOutcome::Failed, chunk.len() as u64); |
56121ee to
71d78f9
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The test and documentation changes are coherent, with only a minor non-blocking documentation clarification requested.
7 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Qualify latest_deposit_id availability and successful response conditions · New Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
|
|
||
| 3. **Let the minter detect the deposit.** The minter reads the balance of every registered deposit address on a schedule, frequently right after the registration and then hourly. Once the balance reaches the minimum deposit amount, the minter queues the deposit as if `deposit_sol` had been called, and the sweep and mint of step 4 follow; the automatic deposit fee in force at detection is deducted from the minted amount instead of cycles. | ||
|
|
||
| 4. **Track the deposit.** Call `watch_deposit_address` again: once the deposit is detected, the status is `Detected` with the deposit id, which you can follow with `deposit_sol_status` as in step 5. The id of the latest deposit of your account is returned in every case. Once the deposit is minted, calling `watch_deposit_address` registers the address anew, so that the next deposit to the same address only needs another call. |
There was a problem hiding this comment.
🟢 Approval recommended
The integration test and documentation consistently reflect the implemented automatic deposit behavior.
7 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
23ae093 to
692dada
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The test and documentation changes are consistent with the implemented automatic deposit behavior.
7 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
692dada to
8a795c3
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The test and documentation changes consistently validate and describe the completed automatic deposit flow.
7 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
8a795c3 to
bbd5813
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The integration coverage and documentation consistently reflect the implemented automatic deposit behavior.
7 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
User documentation incorrectly implies scans cover the full 24-hour registration window despite the final scan occurring about 30 minutes earlier.
7 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
There was a problem hiding this comment.
🟢 Approval recommended
The test and documentation changes consistently reflect the implemented automatic-deposit behavior.
7 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
Production-facing guidance omits the known RPC consensus limitation that can prevent automatic deposit detection.
8 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Document mainnet RPC consensus limitation and manual deposit flow · New Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
|
|
||
| ## Register your deposit address for automatic deposits | ||
|
|
||
| Instead of calling `deposit_sol` after each transfer, call `watch_deposit_address` to have the minter watch your deposit address for about 24 hours and queue the deposit itself once the balance reaches the minimum deposit amount. The call is free and needs no cycles, so no proxy canister is required; the automatic deposit fee reported by `get_minter_info` (`automatic_deposit_fee` field) is deducted from the minted amount instead. The owner is always your calling identity, so pass only the `subaccount` used when calling `get_deposit_address`: |
There was a problem hiding this comment.
🔵 Needs a closer look
User-facing instructions need to reflect the known mainnet detection limitation and last-scan cutoff.
8 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Document mainnet RPC consensus limitation and manual deposit flow Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
The automatic-deposit guide needs to disclose the known mainnet detection limitation before users rely on automatic crediting.
9 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Warn about mainnet RPC consensus limits and recommend deposit_sol · New Document mainnet RPC consensus limitation and manual deposit flow Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
|
|
||
| ### Automatic deposits | ||
|
|
||
| If you cannot call the minter after the transfer, for example because the SOL comes straight from an exchange, register your deposit address with `watch_deposit_address` instead of calling `deposit_sol`: |
There was a problem hiding this comment.
🔵 Needs a closer look
User-facing instructions recommend automatic crediting without disclosing the acknowledged mainnet RPC-consensus limitation.
9 open findings
Use current fee when validating and queueing deposits after await Mainnet scans fail due to inconsistent provider response contexts Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Warn about mainnet RPC consensus limits and recommend deposit_sol Document mainnet RPC consensus limitation and manual deposit flow Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
Deterministic execution of the live-timer integration test needs confirmation before approval.
8 open findings
Use current fee when validating and queueing deposits after await Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Warn about mainnet RPC consensus limits and recommend deposit_sol Document mainnet RPC consensus limitation and manual deposit flow Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
1 resolved since last review
🧠 Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
Timer coordination in the live integration test needs validation before its reliability can be confirmed.
8 open findings
Use current fee when validating and queueing deposits after await Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Warn about mainnet RPC consensus limits and recommend deposit_sol Document mainnet RPC consensus limitation and manual deposit flow Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
The previously reported timer-synchronization concern remains unresolved and can make the integration test fail despite correct minter behavior.
8 open findings
Use current fee when validating and queueing deposits after await Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Warn about mainnet RPC consensus limits and recommend deposit_sol Document mainnet RPC consensus limitation and manual deposit flow Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced
…ator Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s list Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The new integration test’s timer-ordering assumptions need human verification before approval.
8 open findings
Use current fee when validating and queueing deposits after await Prevent sweep timer from interleaving before deposits are queued Failed-read metric counts registrations no longer advanced Warn about mainnet RPC consensus limits and recommend deposit_sol Document mainnet RPC consensus limitation and manual deposit flow Qualify latest_deposit_id availability and successful response conditions Clarify finalization deadline before the last watch scan Disclose final-scan boundary in CLI watch guidance
🧠 Review effort: Balanced



Last pull request of the stack implementing the automatic deposit flow designed in #272, on top of #276 to #287, which add the flow piece by piece: the fee parameter, the watchlist and its schedule, the
watch_deposit_addressendpoint, the fee deduction, the batched balance reads, the scan timer, the re-arm of dropped sweeps, the watchlist snapshot on upgrade, the concurrency rule betweendeposit_soland the scan, and the metrics.This one adds the end-to-end test on
solana-test-validator, in which two deposits detected by the scan timer and two queued withdeposit_solare swept in a single transaction, minted with and without the automatic deposit fee, and the collected fees are reported byget_minter_info. It also adds the user documentation of the flow and the changelog entry.Prerequisite on the SOL RPC canister. The scan uses the typed
getMultipleAccountsof dfinity/sol-rpc-canister#394, which strips the context slot before the consensus comparison and is not released yet: the SOL RPC crates are pinned to that commit, and the integration tests run against a SOL RPC canister built from it and downloaded from a public bucket, until a release lets both pins go.🤖 Generated with Claude Code