I want to send some erc20s to someone, but I don't have their address, I only have their twitter handle.
I want to be able to send crypto to a wallet generated by their twitter handle, but that wallet currently does not exist.
Newly Generated Wallet Address = CREATE2(factory contract address, twitter handle, fun wallet bytecode)
Done, do FunWallet.getAddressOffline(uniqueId, index, rpcUrl, factoryAddress)
const {FunWallet} = require("../wallet")
await FunWallet.getAddressOffline("twitter###paradigmeng420", 0)
Then, they can just transfer eth to that address.
Time estimate: 2-3 hours
Put this in a FunWallet.sol
mapping(bytes32 => bytes32) commits;
struct commit {
uint256 expiration;
bytes32 hash;
}
// @param commitKey keccak(socialHandle + loginType)
// @param hash keccak256(private seed, newOwner address)
function commit(bytes32 commitKey, bytes32 hash) {
require(commits[commitKey].expiration < block.timestamp);
commitExpiration = block.timestamp + 10 minutes;
commits[commitKey] = commit(commitExpiration, hash);
}
TODO: Add this function and tests in the funwallet
Time estimate: 1-2 hours
Call createAccount
with
salt = can be anything
loginType = LoginTypes.TWITTER
socialHandle = twitter###paradigmeng420
enum LoginType{
EOA;
Twitter;
...
}
struct SocialLoginData {
uint8 loginType
uint8 index
bytes socialHandle
address newFunWalletOwner
}
function (SocialLoginData sld){
newOwner = validateSocialLogin()
// change validationInitData to set Owner
... rest of initialize
}
function validateSocialLogin(SocialLoginData sld){
hashFromOracle, newOwnerAddress = getHashFromOracle(socialHandle, loginType)
commitKey = keccak(socialHandle, loginType)
require(hashFromOracle == commits[commitKey].hash);
salt = keccak(socialHandle + loginType + index)
return newOwnerAddress
}
function getHashFromOracle(bytes socialHandle, uint8 loginType){
if (loginType == LoginType.Twitter){
tweet = gelato.fetchTweet(twitterhandle);
return keccak(tweet), address;
}
}
TODO: Create a Oracle that monitors a given user's twitter posts OR that given a tweet link, can return the contents. Then, using the tweet contents, call the reveal function.
Time estimate: 6-8 hours
Scraping twitter:
https://www.scrapingdog.com/blog/scrape-twitter/
https://github.com/trevorhobenshield/twitter-api-client#get-all-usertweet-data
https://www.npmjs.com/package/rettiwt-api
TODO: Write an E2E test transferring stuff from twitter accounts and claiming it.
Also, write a few unit tests
Total Time estimate: 9 - 13 hours
Basically, we want some permissioned system to fetch the secret from twitter, then pass it into reveal. Here are a few ways to do this:
Alternate implementation
Tradeoff: This will make createAccount more expensive for everyone, but idk where else we can put a check for this since we need this everytime someone calls createAccount to make sure they can't just create a funwallet from a twitter account
function createAccount(bytes calldata, address impl, bytes32 salt, uint8 loginType, bytes calldata socialHandle, uint8 index) {
if (loginType == Twitter){
hash, newOwnerAddress = getHashFromOracle(socialHandle);
commitKey = keccak256(socialHandle + loginType)
require(hash == commits[commitKey].hash);
// note, we change to hashing the salt here instead of passing in a hashed salt
salt = keccak(socialHandle + loginType)
require(newOwnerAddress == initializerCalldata.address)
}
// Handle rest of logic in createAccount like normal
salt = uniqueId + index
}