Skip to content

docs: explain USDCx native gas in current and v0.17 - #379

Merged
BrianSeong99 merged 5 commits into
mainfrom
brian/usdcx-native-gas-376
Oct 14, 2026
Merged

BrianSeong99 merged 5 commits into
mainfrom
brian/usdcx-native-gas-376

Conversation

@BrianSeong99

@BrianSeong99 BrianSeong99 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

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:

  • Full production build passes with NODE_OPTIONS=--max-old-space-size=12288 npm run build, using npm run prepare:docs -- --snapshot 0.17 for missing upstream inputs.
  • Current/v0.17 MDX compilation and content parity, rendered page structure, sidebar placement, local links and all 10 external source URLs pass.
  • The real Web SDK v0.17.3 mock backend passes sync() and feeFaucetId() checks; pinned wallet automatic-claim boundary checks and exact integer amount, balance and withdrawal-quote arithmetic pass.
  • No broken-link warnings. Existing site KaTeX and browser-data warnings remain.

@BrianSeong99
BrianSeong99 marked this pull request as ready for review October 12, 2026 07:19
Comment thread docs/builder/tools/usdcx-funding.mdx Outdated

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"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

Comment thread docs/builder/tools/usdcx-funding.mdx Outdated

## 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).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"use it only after confirming" -> ideally we should confirm this ourselves before publishing this doc, and not leave ambiguity for users

Comment thread docs/builder/tools/usdcx-funding.mdx Outdated
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"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.

Comment thread docs/builder/tools/usdcx-funding.mdx Outdated
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that needed?

Comment thread docs/builder/tools/usdcx-funding.mdx Outdated
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"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

Comment thread docs/builder/tools/usdcx-funding.mdx Outdated

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:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ATM the verification base fee is fixed, so mentioning this in the docs might be more confusing than useful

Comment thread docs/builder/tools/usdcx-funding.mdx Outdated
| 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we set maxFee = 0 but TBC I might have outdated info

Comment thread docs/builder/tools/usdcx-funding.mdx Outdated

## 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove this part, thank you!

@BrianSeong99

Copy link
Copy Markdown
Contributor Author

thank you @mmagician for the review, I have reflected the inaccuracy accordingly!

@BrianSeong99
BrianSeong99 merged commit 20c4bc8 into main Oct 14, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants