hackquest logo

ShoehornFi

Slide p2p payments into Telegram DMs directly from MetaMask, powered by MetaMask Advanced Permissions.

ビデオ

テックスタック

React
Node
Solidity
TanStack Start
MetaMask Advanced Permissions
Envio

説明

Shoehorn (noun) a smooth, curved piece of plastic or metal that you hold in the back of your shoe when putting it on, to help your foot slide into it .

ShoehornFi is a Telegram bot that leverages MetaMask's Advanced Permissions API (EIP-7702/ERC-7715) to enable seamless, delegated token transfers directly within Telegram conversations. Users can grant one-time permissions to bot session account, allowing automated, recurring transfers without requiring repeated wallet confirmations (unless permission is expired/revoked).

Tip

Quick links to Advanced Permissions Usage, Envio Usage, and Feedback sections.

Key Features

🔐 Delegated Permissions System

  • Users grant periodic transfer permissions to the bot account via MetaMask

  • Bot executes transfers on behalf of users without requiring repeated approvals

  • Supports both ERC20 tokens (USDC, EURC) and native ETH

  • User can update permissions with /permissions command, or revoke them via their MetaMask extension

💸 Inline Token Transfers

  • Send tokens instantly in any Telegram chat (private or group) using inline queries

  • Simple syntax: @bot send 10 usdc or send 0.01 eth

  • Recipients receive a shareable redemption link via Telegram

📝 Ephemeral Notes System

  • Creates temporary, cryptographically-secured token deposits on the EphemeralNotes smart contract

  • Recipients can claim funds by signing with an ephemeral private key embedded in the Telegram bot link

  • Notes can be redeemed to any Ethereum address the recipient chooses

🔄 Reclaim Functionality

  • Users can reclaim their unclaimed ephemeral notes using the /reclaim command

  • Bot queries on-chain data via Envio indexer to find unredeemed notes

  • Batch reclaim functionality returns all unclaimed tokens to the original sender

Technical Implementation

Smart Contracts

  • EphemeralNotes.sol: an escrow contract that holds tokens in cryptographically-secured "notes" based on EphemeralNotes by daimo

  • Notes are identified by ephemeral addresses

  • Recipients redeem notes by providing a signature from the ephemeral private key

  • Contract tracks original sender for reclaim functionality

  • Built with OpenZeppelin libraries (ERC20, SafeERC20, ECDSA, Ownable)

Backend & Bot Infrastructure

  • Telegram Bot (Grammy framework) with conversational flows

  • EIP-7702 Session Accounts for delegated transaction execution

  • Account Abstraction (ERC-4337) using bundler clients and UserOperations

  • Envio Indexer for efficient on-chain data querying

  • Redis (Upstash) for storing user permissions and addresses

  • TanStack Start (React) for web-based permission granting interface

Advanced Permissions Usage

The project implements MetaMask's Advanced Permissions (ERC-7715) to allow the bot to transfer tokens from user wallets. When first onboarding the user, the web frontend will request execution permissions. When the user uses a bot command to send a transfer, the bot backend redeems a permission to perform the transfer via the EphemeralNotes contract.

A backend-owned Metamask 7702 smart account allows executing multi-step transactions (wrap ETH, approve tokens, interact with contracts) while preserving contract deployer account address to authorize owner-only contract functions.

Envio Usage

Bot queries on-chain data via Envio indexer to find unredeemed notes and allow the user to reclaim them. This is implemented with a custom schema and event handlers and a query.

Feedback / Challenges

Challenge 0: Framework Boundaries Confusion (developer experience pain point)

Problem: We found the process of onboarding into the ERC-7710/7715 frameworks by MetaMask challenging due to confusing naming (e.g., that "MetaMask Smart Accounts" aren't actually MetaMask accounts, they are what is known elsewhere as "embedded wallets") and found the intermixed documentation hard to use. Furthering the problem is the reliance of both frameworks on @metamask/smart-accounts-kit, with documentation not sufficiently clear on which examples apply to 7710 vs 7715.

Solution: Instead of searching for solutions in the documentation, we read Smart Account Kit and Delegation Framework codebases and reverse-engineered solutions as needed.

The rest of the challenges highlight some of the less obvious pitfalls when using ERC-7715 delegations:

Challenge 1: Lack of Direct Contract Interaction

Problem: MetaMask's Advanced Permissions API does not currently support delegating smart contract interactions. Permissions are limited to token transfers.  Solution: Implemented a three-step workaround flow:

  1. Transfer tokens from user account → session account (using permissions)

  2. Session account interacts with EphemeralNotes contract

  3. Contract manages token escrow and redemption logic This added complexity but enabled advanced contract features while staying within permission constraints.

Trade-off: This approach makes pre- and post-invariants of the full operation harder to reason about or validate. If one of the batched calls succeeds, but doesn't execute intended logic, this may lead to a loss of funds. Given more time, we would likely opt to develop a custom contract that would redeem delegations, and a contract that would invoke the three steps while also enforcing pre- and post-invariants (e.g., that the steps resulted in the creation of an EphemeralNote with the specified amount).

Challenge 2: Loss of msg.sender Traceability

Problem: When using session accounts as intermediaries, msg.sender in smart contracts becomes the session account address, not the original user's address. This breaks traditional Solidity patterns that rely on msg.sender for access control and user tracking.  Impact: Standard contract patterns like "users can only claim their own deposits" became impossible without redesign Solution: Refactored contract architecture to:

  • Accept user address as an explicit function parameter (_sender)

  • Store original sender in the Note struct

Trade-off: Trust the calling infrastructure to provide accurate sender information This leads to the next challenge:

Challenge 3: Reclaim Functionality Implementation

Problem: To enable users to reclaim their unclaimed notes, we needed a way to identify and return notes to the original sender. However, with session accounts calling the contract, we couldn't rely on msg.sender == note.sender checks.  Solution: Implemented an Ownable pattern with special admin privileges:

  • Made EphemeralNotes contract Ownable (bot session account is the owner)

  • Added returnNoteToSender() function callable only by contract owner

  • Owner function reads note.sender from storage and transfers tokens to that address

  • This required trusting the bot infrastructure with ownership privileges

Trade-off: Introduced centralization (owner trust) to enable user-friendly reclaim functionality in a delegated execution model.

Challenge 4: Native ETH Handling

Problem: EphemeralNotes contract works with ERC20 tokens, but we wanted to support native ETH transfers for better UX.  Solution: Implemented automatic ETH wrapping flow:

  1. Transfer native ETH to session account (with permissions)

  2. Wrap ETH → WETH using WETH deposit function

  3. Approve WETH to EphemeralNotes contract

  4. Create note with WETH token This 4-step atomic operation happens transparently in a single UserOperation.

Use Cases

  • Instant Crypto Gifting: Send tokens to anyone in Telegram without needing their wallet address upfront

  • Group Payments: Split bills or distribute funds in group chats

  • Promotional Campaigns: Distribute token airdrops through shareable Telegram links

  • Privacy-Preserving Transfers: Recipients claim to fresh addresses, not doxxing their main wallet

ハッカソンの進行状況

Developed the bot from scratch.
チームリーダー
AA I
プロジェクトリンク
業界
SocialFi