Inspiration

Account abstractions are a hot topic of conversation. But their current implementation is far from the end user and even further from the dapp developers. The current vision for AA integration requires a complete overhaul of the scenarios for interaction between decentralized applications and the wallet.

We propose a different approach: implement AA as a MetaMask wrapper and use LINK as a gas token. The ability of the blockchain to interact with the chainlink allows you to use LINK even in another chain during execution.

What it does

I think the only painless way to adopt a technology is when it benefits without asking for anything in return.

The classic interaction scheme is the front-end of the provider receiving EIP-1193 from the wallet built into the browser, and the wallet communicates with the preconfigured blockchain node via JSON-RPC. Classic

Even if there are flaws in the scheme (although it seems to me close to ideal), it is almost impossible to change something that is well-established and working. We propose a scheme in which at each step an injection occurs that does not require additional actions from any participant in the scheme: Improve

How we built it

  1. Firstly, we changed the implementation for compatibility with the ERC-712, so that the signature of the operation is human-readable for the user
  2. We set up an api to automatically launch a hardhat fork to simulate user operations and display intermediate results in the UI
  3. When the user has created all the necessary operations, he clicks Commit and he has two choices: send the transaction by himself or use Chainlink Relayer and Paymaster to pay for gas with LINK token.

We use Chainlink as relayer with simple Webhook and external initiator and Paymaster with LINK token and Price Feed (LinkPaymaster added as late submission!)

type                = "webhook"
schemaVersion       = 1
externalInitiators  = [
    { name = "verifier", spec = "{\"jobName\":\"webhook-job\"}" }
]
observationSource   = """
    entry       [type="jsonparse" path="data,entry" data="$(jobRun.requestBody)"]
    signature       [type="jsonparse" path="data,signature" data="$(jobRun.requestBody)"]
    from            [type="jsonparse" path="data,request,from" data="$(jobRun.requestBody)"]
    to              [type="jsonparse" path="data,request,to" data="$(jobRun.requestBody)"]
    gas             [type="jsonparse" path="data,request,gas" data="$(jobRun.requestBody)"]
    nonce           [type="jsonparse" path="data,request,nonce" data="$(jobRun.requestBody)"]
    data            [type="jsonparse" path="data,request,data" data="$(jobRun.requestBody)"]

    encode          [type="ethabiencode"
                        abi="execute(address from, address to, uint256 value, uint256 gas, uint256 nonce, bytes data, bytes signature)"
                        data="{\\"from\\": $(from), \\"to\\": $(to), \\"value\\": \\"0\\", \\"gas\\": $(gas), \\"nonce\\": $(nonce), \\"data\\": $(data), \\"signature\\": $(signature)}"
                    ]

    submit_tx       [type="ethtx"
                        to="$(entry)"
                        data="$(encode)"
                        failOnRevert="true"
                        gasLimit="5000000"
                    ]

    signature -> from -> to -> gas -> nonce -> data -> encode -> submit_tx
"""

Challenges we ran into

Metamask and providers so unpredictable with data types.. and we started too late (few days ago found an opportunity)

Quicknode discovery plan is very limited and fork feature overwhelmed it if target for latest block.

Accomplishments that we're proud of

Successefully managed to make a PoC with hardhat simulation of execution. It's cool :)

What we learned

Submission takes more than expected.

What's next for Chainlink ERC4337 Account Abstractions

We have plan to improve extension, contracts to make it publicly available.

Built With

Share this project:

Updates