:wave: NFT allows creating token cross-sharing between DAO and DAO. Using :wave: NFT instead of swapping DAO tokens directly allows token owners to choose whether to continue an unwilling friendship, reducing the psychological hurdle for token cross-sharing. ![](https://hackmd.io/_uploads/SJ4e09GF3.png) ## Normal flow 1. Requestor sends `wave`, Escrow mints a new :wave: NFT and hold it until the responder answers the request. 2. Responder sends `handshake`, receive the requestor's :wave: NFT from Escrow, and Escrow mints a new :wave: NFT, sends it to the requestor. ![](https://hackmd.io/_uploads/HycII9MKn.png) https://www.figma.com/file/xU8UfY7V4ndP119KPxPLhH/Friendships?type=whiteboard&node-id=0%3A1&t=r7RNdhpxYGfmnyKg-1 ## When the responder denies the friend request 1. Requestor sends `wave`, Escrow mints a new :wave: NFT and hold it until the responder answers the request. 2. Responder sends `deny`, Escrow burns the requestor's :wave: NFT, and withdraws all staking rewards, sends (refunds) the rewards to the requstor. ![](https://hackmd.io/_uploads/H1zPU5Mth.png) https://www.figma.com/file/xU8UfY7V4ndP119KPxPLhH/Friendships?type=whiteboard&node-id=0%3A1&t=r7RNdhpxYGfmnyKg-1 ## UIs // Still in progress... ## Proposed major interfaces ```solidity /* @dev Send a new :wave: as a friendship request. * @param _to Property address of the recipient. * @param _from Property address of the requestor. * @param _amount Amount of the requestor's token to offer. * @param _duration Duration sec for locking the requestor's token as a friendship. * @param _payload Reserved unused argument. * @return Created :wave: NFT ID. */ function wave( address _to, address _from, uint256 _amount, uint256 _duration, bytes32 _paylod, ) external returns(uint256); /* @dev Create a friendship. \ * The caller must be the author of the `_to` Property. (More flexible option??) * @param _wave :wave: NFT ID to respond. * @param _amount Amount of the responder's token to provide. * @param _duration Duration sec for locking the responder's token as a friendship. * @param _payload Reserved unused argument. * @return Created :wave: NFT ID. */ function handshake( uint256 _wave, uint256 _amount, uint256 _duration, bytes32 _paylod, ) external returns(uint256); /* @dev Deny the requested :wave: 👋 \ * Burn the pending :wave: NFT and release/send the locked Property to the :wave: minter, and withdraw/send all staking rewards to the requestor. * The caller must be the author of the `_to` Property. (More flexible option??) * @param _wave :wave: NFT ID to close. * @return Success or failure. */ function deny(uint256 _wave) external returns(bool); /* @dev Burn :wave: NFT. \ * Release/send the locked Property to the :wave: minter, and withdraw/send all staking rewards to the friend. * The caller must be the :wave: minter, and the given duration must have elapsed. * @param _wave :wave: NFT ID to close. * @return Success or failure. */ function bye(uint256 _wave) external returns(bool); /* @dev Withdraw all staking rewards from the :wave: and send it to its current owner. * @param _wave :wave: NFT ID. * @return Success or failure. */ function earn(uint256 _wave) external returns(bool); // Returns the :wave: NFT URI. function tokenURI(uint256 _id) view returns(string memory); ```