Skip to content

MagicSpend++ Architecture

Overview

MagicSpend++ is a protocol that allows users to spend their funds on any chain they need. It consists of two main components: MagicSpendWithdrawalManager contract and user's balance in Pimlico dashboard.

MagicSpendWithdrawalManager

MagicSpendWithdrawalManager is a contract that manages the liquidity of the MagicSpend++ protocol. It allows users to request withdrawals on any chain they need. This contract has no user's funds and stores only liquidity, added by Pimlico. Users can request withdrawals of their funds, if they provide a Withdrawal message, signed by Pimlico.

Withdrawal message

/// @notice Helper struct that represents a call to make.
struct Call {
    address to;
    uint256 value;
    bytes data;
}
 
/// @notice This struct represents a withdrawal request.
/// @dev signed by the signer it allows to withdraw funds from the `MagicSpendWithdrawalManager` contract
struct Withdrawal {
    /// @dev Token that will be withdrawn.
    address token;
    /// @dev The requested amount to withdraw.
    uint128 amount;
    /// @dev Chain id of the network, where the withdrawal will be executed.
    uint128 chainId;
    /// @dev Address that will receive the funds.
    address recipient;
    /// @dev Calls that will be made before the funds are sent to the user.
    Call[] preCalls;
    /// @dev Calls that will be made after the funds are sent to the user.
    Call[] postCalls;
    /// @dev The time in which the withdrawal is valid until.
    uint48 validUntil;
    /// @dev The time in which this withdrawal is valid after.
    uint48 validAfter;
    /// @dev The salt of the withdrawal.
    uint48 salt;
}
 

Withdrawal is a message that Pimlico signs and sends to user. It contains the details of the withdrawal, such as the asset, amount, recipient, chain id, etc.

MagicSpend++ Flow

This section describes the flow of the MagicSpend++ protocol.

  1. User adds funds in Pimlico dashboard.
  2. User enables MagicSpend++ for their API key.
  3. User sends a pimlico_sponsorMagicSpendWithdrawal call, where they specify the asset, amount, recipient, chain id, etc.
  4. Pimlico signs the corresponding Withdrawal and returns it with a signature to user. Pimlico also "locks" the corresponding amount of funds from user's balance.
  5. User sends a transaction, which contains MagicSpendWithdrawalManager.withdraw(Withdrawal withdrawal, bytes signature) call and receives the funds. It can be ERC4337 user operation or a regular transaction.
  6. If Withdrawal is not executed until the validUntil time, Pimlico releases the locked funds back to user's balance.