Hot Potatoes are ERC721 NFTs deployed on Arbitrum that are associated with a unique key pair. Signatures can be triggerd using a signHash(hash) method on the NFT without ever revealing the private key. This works using a bridge to the Internet Computer and Threshold Signing.
Some use cases that are enabled through this:
- Transfering a whole cross-chain portfolio with a single NFT transfer
- Trading staked or locked positions
- Allowing DAOs on one chain to hold assets on another chain
- Allowing smart contracts including DAOs to sign personal messages (e.g. for transfer with authorization or UniswapX)
- Programming any of the above use smart contracts
A significant achievement of this project is a WalletConnect integration that lets you use the Potato's wallet on any dapp that support WalletConnect
Hot Potatoes are a standard ERC721 NFT deployed on Arbitrum, with the addition of a signHash method that can be used to create arbitrary signatures on behalf of the potato. The flow for signHash is as follows:
- signHash checks that msg.sender is the owner of the NFT
- It then invokes the Frosty Functions contract, which is a bridge between EVM and the Internet Computer. The token ID and hash to sign are passed as call data
- Both the NFT and the FrostyBridge emit events that will later be used to check that a signature for the given token and hash was authorized
To create the signature that was authorized, the Frosty contract on the Internet Computer (ICP) needs to be invoked with the block number in which to find the event. The Hot Potato frontend takes care of all that transparently, but under the hood the following happens:
- Frosty Functions checks that the Hot Potato function was actually invoked by using ICP's EVM canister (ICP's smart contracts). That canister performs a HTTP outcall via JSON RPC's providers using eth_getLogs. (Note that all nodes of ICP have to reach consensus on the result of HTTP calls, so they need to be deterministic)
- If the event was found, the Hot Potato function is invoked. It will parse the call data to derive the signer for the specific Hot Potato. It then triggers the signature, which is performed by ICP's fiduciary subnet
- The r and s of the signature is logged
- The Hot Potato SDK takes care of parsing r and s from the logs and then recovers v using the public key of the Potato (which can be derived using ICP's known root public key).
A large part of this project revolved around building a WalletConnect integration in the frontend (see video). As part of that, I built a rudimentary wallet interface that can handle both personal_sign and eth_sendTransaction requests. For transaction requests, I autofil gas parameters and the nonce using ethers.