What you’ll be able to do
- Create and fund a smart account.
- Approve and execute transactions with one or multiple signers.
- Update the account’s signers and approval requirements.
Configure the factory and signers
Install public packages withpnpm add @metalntwx/metal-ts@0.3.2 viem@2.57.7.
Use relayerWallet to submit transactions and pay gas. The wallet clients
walletA, walletB and walletC represent the three signers that approve
operations.
Keep the signers’ keys separate and request each signature independently.
Maintain access to enough signers to meet the approval threshold. Before
discarding a temporary test signer, use the current signers to approve its
removal and set a threshold the remaining signers can meet. Verify that change
at finality before discarding the key.
On Metal Testnet, the factory recorded by @metalntwx/metal-pay@0.3.4 is
0x3dbED5DebA965A639bB0Fd40BE96b97922070FA8. Verify factory code and
implementation() against the current network configuration before
creating an account.
[signers[0]], [1n] and 1n instead. Every
weight must be positive and the threshold must be reachable. Factory creation
is permissionless and idempotent for the exact configuration. An existing
account may have changed its signers since creation, so always inspect its
current configuration.
Create and fund the account
Use the relayer to callcreateAccount(signers, weights, threshold). Simulate
and estimate this call using Estimate and record fees.
Sign it with signMip20Contract as in
Prepare a transfer,
substituting the factory address, ABI, function and arguments above.
Save the signed attempt
before sending it.
Verify successful execution, the receipt’s block hash and finality. For a new
account, AccountCreated must name the predicted address. If the account
already existed, the factory returns its address without emitting another
creation event. Verify code at that address, getSignerCount(),
getSigners(0, count), each signerWeight and threshold() against the
intended current configuration.
Fund accountAddress with a small MIP20 transfer using
Direct payment. The MetalAccount
supplies the payment amount for its outgoing calls. Fund the relayer’s signing
account separately so it can pay transaction fees from its balance in the gas
token.
Build the operation
This operation transfersamount of the MIP20 token from the MetalAccount to
recipient. Verify the token address and convert the amount to base units using
the direct-payment guide. Check the MetalAccount’s spendable balance before
requesting approval.
value is zero because the MIP20 function transfers the token amount.
A nonce combines a 192-bit key in the high bits and a 64-bit sequence. The call
above reads the nonce for key zero. Coordinate operation preparation for each
key so requests receive distinct sequence numbers.
Collect approvals and submit
The EIP-712 domain uses the MetalAccount asverifyingContract. Review the
target, decoded calldata, amount, recipient and nonce before requesting
signatures. Compare the locally computed digest with the account’s
executeDigest.
validUntil is the latest block timestamp at which the approval can execute.
This example allows one hour. Save the deadline with the operation; extending
it requires new signatures.
For the single-signer configuration, encode that signer’s address and signature.
Each signer contributes its weight once. To use other ERC-7913 signer types,
provide their verifier and signature encoding. A contract signer requires
ERC-1271 signature validation, including ERC-7739 domain binding when the signer
is another MetalAccount.
Estimate operation for the relayer, sign the outer transaction with
signMip20Contract, and save its bytes and hash before submission. Save the
operation bytes, nonce, deadline, approvals and expected target effect in the same durable
operation record. A changed operation requires fresh approvals.
Require Executed(nonce) from the MetalAccount and verify the expected result
of its calls. For this transfer, verify the token transfer from accountAddress
to recipient, the receipt’s block hash and finality using
Verify a finalized transfer.
Read the nonce again and require the sequence to advance once.
Change the signers and threshold
Administration functions accept calls only from the account itself. Encode an ERC-7821 batch whosetarget is accountAddress and whose calldata calls
addSigners, removeSigners, setSignerWeights or setThreshold. Approve and
submit that batch through the same executeSigned procedure with the required
signing weight under the account’s current threshold and a fresh nonce.
To replace one signer in a two-of-three account, batch addSigners([newSigner])
followed by removeSigners([oldSigner]). A newly added signer has weight one.
Keep the threshold at two. To change weights, call setSignerWeights before
raising the threshold. Lower the threshold before a removal that would make
it unreachable. All calls in the batch revert together if any step fails.
After finality, read back the signer list, weights and threshold. Confirm that
the replacement can approve a new operation and the removed signer no longer
contributes weight. Signer changes preserve the account’s address and funds.
Schedule submission
An approvedexecuteSigned operation runs when its transaction is included.
To submit it later, use the network
contract scheduler, on a network
that has one; Metal Testnet does not have the scheduler yet. Set the
approval’s validUntil to cover the intended execution window and reconcile
its nonce before submitting the same operation through another path.