Repository navigation
docs: explain USDCx native gas in current and v0.17 - #379
Conversation
|
|
||
| USDCx represents USDC held in Circle's xReserve on a source chain. An attested deposit lets the Miden faucet mint USDCx; a withdrawal burns USDCx before the service releases source-chain USDC. The Miden integration uses **xReserve**. See the [implementation architecture](https://github.com/0xMiden/miden-usdcx/blob/04e9ef4eab2c5c13c9a79009e0b8cb5b0674d15e/docs/ARCHITECTURE.md). | ||
|
|
||
| “Native gas” means the network's asset for protocol transaction fees. When that asset is USDCx, the same asset can fund a payment and its Miden fee; no additional Miden gas token is required. Identify it by **network and issuing faucet account**, rather than its symbol or logo. Another bridge's USDC token can have a different issuer and cannot substitute for the configured fee asset. |
There was a problem hiding this comment.
"When that asset is USDCx" -> there is only ever one native asset that pays gas.
Once we have multi-asset fee payments, there will still only be one "native gas token" at the protocol level, but batch builders will enable users to pay in some other fees and they'll later convert it to the native token
|
|
||
| ## Fund an empty account | ||
|
|
||
| Use the tested direct xReserve route from **Arc Testnet to Miden Testnet**. Ethereum Sepolia also has a direct-deposit entry in the reviewed wallet configuration, but use it only after confirming that Miden is registered there and deposits are enabled. Its other source-chain routes have additional routing steps; this guide covers the direct xReserve path. Source selection, token addresses and domain registration must match the wallet's [network configuration](https://github.com/0xMiden/wallet/blob/a013fc15e5523bd3facd8e34ad6f24fca7be2796/src/lib/usdcx/constant.ts). |
There was a problem hiding this comment.
"use it only after confirming" -> ideally we should confirm this ourselves before publishing this doc, and not leave ambiguity for users
| 2. In Receive, choose the USDCx route and a direct source network. Connect an EVM wallet holding that network's accepted **test USDC** and enough source-chain gas. Ethereum Sepolia uses test ETH; Arc Testnet uses USDC for gas, so reserve additional USDC there. | ||
| 3. Review the recipient, network, deposit amount and charges. Approve the xReserve allowance if necessary, then submit the deposit. A source transaction receipt establishes the deposit, not a spendable Miden balance. | ||
| 4. Wait for Circle's attestation and the relayer's mint. The faucet emits a recipient-bound funding note. Keep the deposit identifier while delivery is pending. | ||
| 5. Let the wallet claim the note and sync the confirmed account state. The consume transaction receives USDCx **before** authentication pays its fee, so an initially empty compatible account can pay from the incoming funds. The note must cover that fee; custom accounts also need a compatible receiving procedure. The reviewed wallet's automatic claim policy requires incoming native funds to exceed `30 × verification_base_fee` base units; this conservative wallet threshold is separate from the actual protocol fee. |
There was a problem hiding this comment.
"custom accounts also need a compatible receiving procedure"
there's isn't "a" compatible receive procedure - it is "the" receive procedure, otherwise the MAST root differs and the procedure won't be recognized.
The standard P2ID note uses move_note_assets_to_account procedure on the basic wallet, which basically iterates all assets and calls receive_asset on it.
| 5. Let the wallet claim the note and sync the confirmed account state. The consume transaction receives USDCx **before** authentication pays its fee, so an initially empty compatible account can pay from the incoming funds. The note must cover that fee; custom accounts also need a compatible receiving procedure. The reviewed wallet's automatic claim policy requires incoming native funds to exceed `30 × verification_base_fee` base units; this conservative wallet threshold is separate from the actual protocol fee. | ||
| 6. Check the remaining vault balance before sending. Retain enough USDCx for the send and later claims or exits. | ||
|
|
||
| The [October 12 live workflow](https://github.com/0xMiden/wallet/actions/runs/38201067754) passed against Arc Testnet and Miden Testnet. Its [test specification](https://github.com/0xMiden/wallet/blob/a013fc15e5523bd3facd8e34ad6f24fca7be2796/playwright/e2e/ios/tests/usdcx-live-deposit.ios.spec.ts) covers deposit, mint, Guardian-wallet claim, and a subsequent burn with Arc payout; additional Testnet faucet funds supply the larger burn. This is evidence for that tested route and revision; Sepolia configuration alone does not establish equivalent live-test coverage or service availability. Check [network status](./network.md) before funding. |
| fee_base_units = B × (floor(log2(C)) + 1) | ||
| ``` | ||
|
|
||
| The current output-note fee term is zero. Standard authentication withdraws the fee and creates a public `TX_FEE` note; payment takes effect with onchain inclusion. The [fee guide](../smart-contracts/transactions/fees.md#how-the-fee-is-calculated) explains estimation and payment inspection. |
There was a problem hiding this comment.
"The current output-note fee term is zero. " I think that's more confusing than useful at this point until the output-note fee is changed to be non-zero. I'd remove
|
|
||
| USDC and this USDCx implementation both use **six decimals**: `1 USDCx = 1,000,000` base units; `0.01 USDCx = 10,000` base units. The [0.17 amount encoding](https://github.com/0xMiden/protocol/blob/v0.17.0/crates/miden-usdcx/src/xreserve/encoding/amount.rs) preserves these units without decimal rescaling. Use integer base units for amounts and fees; reject excess decimal precision instead of rounding silently. | ||
|
|
||
| The protocol fee pays for verification and batch inclusion. For positive estimated VM cycles `C` and the reference block's verification base fee `B`, its current verification term is: |
There was a problem hiding this comment.
ATM the verification base fee is fixed, so mentioning this in the docs might be more confusing than useful
| | Network-account application fee | The note sender, when the target's policy requires sponsorship; separate from the sender's protocol fee. | | ||
| | Deposit, withdrawal or proving-service charges | According to the selected provider's current policy or quote; separate from the protocol fee. | | ||
|
|
||
| The signed xReserve `maxFee` is a **ceiling**, not the charged amount. The reviewed mint implementation sends the complete attested amount to the recipient; the wallet currently submits a zero deposit-fee ceiling. The charged `feeAmount` is separate: the [current mint transport](https://github.com/0xMiden/protocol/blob/v0.17.1/crates/miden-usdcx/src/note/xreserve_mint.rs) reconstructs it as zero, so an attestation with a nonzero charged fee cannot be minted by that format. A positive `maxFee` alone does not mean a fee was charged. Circle currently documents [no xReserve deposit fee](https://developers.circle.com/xreserve/references/fees); source-chain gas and Miden processing fees remain separate. Confirm provider policy and implementation compatibility before changing the ceiling. |
There was a problem hiding this comment.
I believe we set maxFee = 0 but TBC I might have outdated info
|
|
||
| ## Exit and network limits | ||
|
|
||
| On supported Testnet destinations, choose the wallet's USDCx Send route and review the destination and payout deductions. Creating a public burn note removes the amount from the holder's vault. The faucet's later consumption burns it; destination USDC payout is another step. The withdrawal service requires the burn note to have been committed in an earlier block. A published burn is not a cancellable pending send. For a custom SDK integration, use the matching release's burn-note factory and attachments, and verify that its burn script root is allowed by the deployed faucet before creating the note. An SDK/faucet script mismatch can leave the note unprocessed. |
There was a problem hiding this comment.
Not sure what exactly you mean by a custom SDK integration, but the faucet will never allowlist other burn script roots, so I don't think building anything custom here is possible, at least not for the officially deployed xReserve faucet
There was a problem hiding this comment.
Will remove this part, thank you!
|
thank you @mmagician for the review, I have reflected the inaccuracy accordingly! |
Explain how USDCx pays Miden protocol fees, how an empty Testnet account receives and claims it through the Arc xReserve route, and how withdrawals use the supported standard burn note. Mirror the guide and Tools sidebar entry in current and stable v0.17.
Organize the guide around prerequisites, deposit and claim steps, fee and balance tables, withdrawal stages, and troubleshooting. Keep account, withdrawal-quote and SDK-limit details in expandable sections, with network-specific availability and limits scoped to the selected deployment.
Relates to #376.
Validation:
NODE_OPTIONS=--max-old-space-size=12288 npm run build, usingnpm run prepare:docs -- --snapshot 0.17for missing upstream inputs.sync()andfeeFaucetId()checks; pinned wallet automatic-claim boundary checks and exact integer amount, balance and withdrawal-quote arithmetic pass.