What you’ll be able to do
- Connect a user’s browser wallet to Metal Testnet.
- Request signatures for transactions or typed data.
- Submit an approved transaction.
Prepare the application
Use an existing browser application with TypeScript and an EIP-1193 provider. Let the user select a provider when several wallets are installed. Install the public dependencies for the flows below:nativeCurrency display metadata. Metal charges the
default gas token for standard Ethereum transactions and exposes its
balance through eth_getBalance. Set transaction value to 0n. Token payments
call the MIP20 contract’s transfer function.
Connect from a user action
CallconnectWallet(provider, rpcUrl) from a Connect button. Show failures in the
application without automatically opening another wallet prompt. Only the
wallet’s unknown-chain error 4902 triggers the add-network request.
session.valid becomes false and reconnect through
another explicit user action. Call dispose() when replacing the connection or
unmounting the UI. Check assertCurrent() before requesting a signature and
again before broadcasting bytes held by the application.
Prepare the payment for approval
Resolvetoken, recipient, and amount using
Direct payment. Reject invalid
addresses, nonpositive amounts, excess decimal precision, and amounts beyond
uint256. Read token metadata and balances through the public client.
Use Estimate and record fees to obtain a
successful estimate, apply headroom, and verify affordability. The signing
account needs the transfer amount in the token being sent. The signing account’s
balance in the gas token must cover the maximum gas cost. If those are the same
token, account for both debits together.
Show the user the network, token address and symbol, recipient, amount, gas
token, and maximum gas cost before opening the approval request. Keep the
application operation ID and expected payment fields in durable application storage. Disable
repeat submission while the request is awaiting approval or reconciliation.
Submit a standard wallet transaction
A standard wallet transaction uses the network’s default gas token. SupplygasLimit, maxFeePerGas, and maxPriorityFeePerGas from the fee procedure.
Estimate without fee fields first, because wallet-added fee fields can trigger
a zero-allowance estimate failure on this network.
connection is the result of connectWallet. The nonpayable token call
omits value, so the transaction carries zero native value. The wallet handles signing
and broadcast, and returns a transaction hash. Save that hash against the
existing operation immediately, even if a subsequent wallet event invalidates
the connection. Verify the result through the public client independently of
the wallet’s current network.
eth_sendTransaction does not expose signed bytes before broadcast.
If the wallet submits but its response is lost, the application may have no
transaction hash. Mark the operation uncertain, inspect the wallet’s activity
and the signing account’s transaction history, and identify the exact call before
retrying.
Sign typed data before broadcasting
For a selected MIP20 gas token,signMip20Contract asks the wallet to sign Metal’s
EIP-712 transaction data and returns the encoded 0x7f envelope without sending
it. The signature authorizes that exact transaction, including chain, nonce,
call, and fee fields.
Create a durable browser store with idb, which wraps IndexedDB:
expectedPayment contains the chain,
token, sender, recipient, amount, gas token, and fee bounds. Encode bigint fields
as decimal strings when sending this record to the server.
maxFeePerGas for both its maximum and priority fee. Passing the
successful estimate as gasLimit avoids silently proceeding after an estimation
failure. See TypeScript SDK for the
exact transaction fields.
Serialize signing for each account and reconcile an unresolved attempt before
creating another. Browser storage is local to the profile and can be cleared.
For recovery across devices, save the attempt to the service’s durable store
and wait for its acknowledgement before broadcasting.
After a reload, read the saved attempt. Verify its hash first. If submission is
still uncertain, use the identical raw bytes as described in
Recover an uncertain submission.
Verify and display the result
A returned hash means submission, not payment completion. Wait for the receipt, check execution, and match the exact token, sender, recipient, and amount in itsTransfer event. Verify the canonical containing block and finality through
Best practices in processing payments.
Update the order once from that verified result.
Test refusal, unknown chain, account changes during a signature, disconnect,
and an uncertain broadcast with a controlled provider fixture. Then exercise
consent and one finalized payment with a clean real-wallet profile. A provider
fixture establishes application behavior but does not establish wallet support.