## Example Use Cases
- Save `wallet address` as Sam
- Send 2 eth to Sam
- What is my current wallet holding?
- How much eth do I have?
- Swap my 100 USDC to ETH
- Send 1 eth on 1st of month for next six months to Sam
- If eth price falls below $1,700 in next seven days, buy 5 eth
## User Stories
- I want to be able to save a wallet address under a name so I can use the name for future interactions
- I want to be able to send token/NFTs to a different wallet
- I want to be able to swap my assets (eg: USDC to ETH)
- I want to be able to make my send and swap transactions recurring/conditional so I don't have to manually do those trasncations over and over again
- Conditional will be based on balance or value of asset in a given period of time
- I want to be able to view my current wallet holdings like what assets I have, how many and what their current value is in my chosen fiat currency (USD, Euro) so I have clear understanding of my assets
- I want to be able to view all the recurring actions I have scheduled so that I can manage them (view, cancel or schedule more)
- I want to be able to view all the conditional actions I have scheduled so that I can manage them (view, cancel or schedule more)
## List of wraps to support
- Uniswap
- approve
- swap
- Ethers
- Converts wei to eth and vice versa
- getSignerBalance
- getSignerAddress
- getGasPrice
- signMessage
- signTransaction
- getChainID
- getSignerAddress
- getSignerBalance
- getGasPrice
- estimateEip1559Fees
- awaiteTransaction
- sendTransaction
- sendTransactionAndWait
- signMessage
- signTransaction
- signTypedData
- ENS (https://etherscan.io/address/0x283af0b28c62c092c9727f1ee09c02ca627eb7f5#writeContract)
- getOwner
- checkIfRecordExists
- getAddress
- getAddressFromDomain
- getContentHash
- getContentHashFromDomain
- getExpiryTime
- getNameFromAddress
- getTextRecord
- registerDomain
- reverseRegisterDomain
- setName
- setAddress
- setOwner
- setSubdomainOwner
- setRecord
- setSubdomainRecord
- setContentHash
- setAddressFromDomain
- setContentHashFromDomain
- setTextRecord
- rentPrice (read)
- available (read)
- renew (write)
- transferOwnership
- Safe
- createProxy
- proxyCreationCode
- getNonce
- getVersion
- approvedHashes
- approveHash
- getSafeContractNetworks
- encodeExecTransaction
- deploySafe
- predictSafeAddress
- getSafeAddress
- safeIsDeployed
- encodeDeploySafe
- getSafeInitializer
- createTransaction
- createMultiSendTransaction
- addSignature
- getTransactionHash
- signTransactionHash
- encodeEnableModuleData
- encodeDisableModuleData
- encodeMultiSendData
- encodeAddOwnerWithThresholdData
- encodeRemoveOwnerData
- encodeSwapOwnerData
- encodeChangeThresholdData
- approveTransactionHash
- executeTransaction
- getOwnersWhoApprovedTx
- getSignature
- getOwners
- getThreshold
## To Train AI
* Prompt: I want to save `0x36e0237324b1a52d1d439fd9a0d65fc609008bb4` as Sam
- Actions:
```json!
[
{
"wrap": "adressBook",
"method": "setAddress",
"args": {
"name": "Sam",
"address": "0x36e0237324b1a52d1d439fd9a0d65fc609008bb4"
}
}
]
```
* Prompt: I want to send 2 eth to Sam
- Actions:
```json!
[
{
"wrap": "adressBook",
"method": "getAddress",
"args": {
"name": "Sam"
}
},
{
"wrap": "ethers",
"method": "sendTransaction",
"args": {
"tx": {
"to": "$1",
"value": "2000000000000000000"
}
}
}
]
```
* Prompt:Can you tell me how much eth I have in `blubberfish.eth`?
- Actions:
```json!
[
{
"wrap": "ens",
"method": "getOwner",
"args": {
"domain": "blubberfish.eth",
"registryAddress": "0x..."
}
},
{
"wrap": "ethers",
"method": "getBalance",
"args": {
"address": "$1"
}
}
]
```
* Prompt: Can you help me swap 100 USDC to eth?
- Actions: Ethers: Read how much eth will be given for the selected USDC value + Unisawp: approve + execSawp
* Prompt: register `0x36e0237324b1a52d1d439fd9a0d65fc609008bb4` as bluesky.eth
- Actions:
```json!
[{
wrap: ensWrap,
method: "registerDomain",
args: {
domain: "bluesky.eth",
owner: "0x36e0237324b1a52d1d439fd9a0d65fc609008bb4",
registrarAddress
}
}]
```
* Prompt: is `fun.eth` available to buy?
- Actions:
```json!
[{
wrap: ensWrap,
method: "getOwner",
args: {
domain: "fun.eth",
registryAddress
}
}]
```
-- if owner is null, then is available to buy
* Prompt: For how long is `blubberfish.eth` registered?
- Actions:
```json!
[{
wrap: ensWrap,
method: "getExpiryTimes",
args: {
domain: "blubberfish.eth",
registrarAddress: "0x.."
}
}]
```
* Prompt: I want to renew my registration of `blubberfish.eth`
* //TODO Recheck
- Actions:
```json!
[{
wrap: ensWrap,
method: ""
}]
```
* Prompt: Tell me all the safes I am in
- Actions: Needs API Kit (Which should be developed soon). The endpoint is: `https://safe-transaction-mainnet.safe.global/api/v1/owners/{ADDRESS_OWNER}/safes/`
* Prompt: Tell me all the snapshots I follow
- Actions: Needs a wrap of this method https://docs.snapshot.org/tools/api#follows
* Prompt: Show me all the pending transactions in the safes I am in
- Actions: Needs API Kit (Which should be developed soon). The endpoint is: `https://safe-transaction-mainnet.safe.global/api/v1/safes/0xB8ACBe98581A529a1D7EE1e845A331FD0390B251/multisig-transactions/?executed=false`
* Prompt: I want to send 200 USDC to John
- Actions:
- - Look into supported tokens list
- - Multiply amount w/decimals
- - Pass the new amount
```json!
[
{
wrap: ethersWrap,
method: "callContractMethod",
args: {
address: USDC_ADDRESS,
method: "function transfer(address, uint256)",
args: [JOHN_ADDRESS, MULTIPLIED_AMOUNT]
}
}
]
```
* Prompt: I want to create a new Safe
- - Actions:
```json!
[
{
wrap: safeWrap,
method: "deploySafe",
args: {
input: {
safeAccountConfig: {
owners: [ADDRESS_OF_USER],
threshold: 1
}
}
}
}
]
```
* Prompt: I want to sign "Hello world" with my wallet
- - Actions:
```json!
[
{
wrap: ethersWrap,
method: "signMessage",
args: {
message: "Hello world"
}
}
]
```
* Prompt: I want to know the gas price
- - Actions:
```json!
[
{
wrap: ethersWrap,
method: "getGasPrice"
}
]
```
* Prompt: I want to know the address of john.eth
- - Actions:
```json!
[
{
wrap: ensWrap,
method: "getOwner",
args: {
domain: "john.eth".
registryAddress: "..."
}
}
]
```
* Prompt: I want to know the owners of the dorg.eth SAFE
- - Actions:
```json!
[
{
wrap: ensWrap,
method: "getOwner",
args: {
domain: "dorg.eth".
registryAddress: "..."
}
},
{
wrap: safeWrap,
method: "getOwners",
args: {
safeAddress: ADDRESS_OF_DORG_ETH
}
}
]
```
* Prompt: I want to register foo.bar.eth
- - Actions:
```json!
[
{
wrap: ensWrap,
method: "registerDomainAndSubdomainsRecursively",
args: {
domain: "foo.bar.eth",
registryAddress: "...",
resolverAddress: "...",
registrarAddress: "...",
owner: USER_ADDRESS,
ttl: "0" // TODO: Make sure this works as expected (Probably it should be the amount of time in seconds)
}
}
]
```
* Prompt: I want to send 400 USD to Jane, and 200 to John
* Prompt: I want to know which snapshot spaces am I a member of
* Prompt: I want to see which safe transactions I have pending for signature
-- Actions: Needs API Kit (Which should be developed soon). The endpoint is: `https://safe-transaction-mainnet.safe.global/api/v1/safes/0xB8ACBe98581A529a1D7EE1e845A331FD0390B251/multisig-transactions/?executed=false` & then need to check confirmations attribute which is an array that has `owner` attribute; all the transactions that doesn't have the logged in wallet in its array should appear
* Prompt: I want to know which open proposals I should see on Snapshot
* Prompt: I want to see what are the voting options, results and comments from the proposal with description "Invest in apple"
* Prompt: I want to create a proposal in snapshot that has
* Prompt: I want to add a signer to my safe
* Prompt: I want to send 200 usdc to jhon.eth
* Prompt: I want to see my wallet balances in usd
* Prompt: I want to see all pending transactions from my safe
* Prompt: I want to propose a transaction to my safe
* Prompt: I want to execute an already signed transaction
* Prompt: I want to see what does the transaction number 46 from my safe does
* Prompt: I want to fetch the file Qm... from IPFS
<!-- * Prompt: I want to upload a file to IPFS -->
* Prompt: I want to upload the image from this link URL_TO_IMAGE to opensea and sell it for 200 usdc
* Prompt: I want to convert 300 USDC from ethereum to arbitrum
## MVP: Must-haves
- Gallery with actions and workflows
- Recurrent/conditional workflows
- Being able to create your own workflows with or without AI
- AI that helps you understand you intention and saves you time
- Being able to save workflows as if we were talking about a dune dashboard.
- Take a look here to dune or flipside
- Save as much data as possible from intentations.
- We are using prompting to boostrap the idea, but we are gonna end up needing to fine tune a model with this data. This a new task we need to teach the model.
- Use cases:
- System actions: Address book (save, retrieve contacts)
- Ethereum wrap: Full ethereum wallet functionality (send, receive, save contacts, ENS names as first class citizens, historical data)
- Uniswap wrap: Swapping
- Multi-send
- On-ramping/Off-ramping (We can use 3rd party api)
- User analytics
## MVP: Nice-to-haves
- Use the result of a previous action as input of the following
- Use cases:
- Cross-chain bridging
- Account abstraction for gas payment in ERC20
## Future goals
- Recommendation system for each user
## Open questions
- What's the main primitive? Workflows or actions?
- How do we achieve recurring actions?
- Can system actions be wraps? Should they?
- How's compatibility handled between action blocks? Not all action blocks are compatible with each other. For example: sending ETH -> creating a SAFE. It doesn't make sense to use the output of the first action as the input of the following.
--------------
## Decisions
- AI model training: don't have the AI model understand Polywrap or its underlying mechanisms. The AI should only understand high level actions and their inputs.
--------------
Future Fine-tuning examples:
- input: send eth
- Output modelo: [eth_send, {}]
- I want to sent eth to fabian.eth
- Output: [eth_send, {to:fabian.eth}]
- I want to sent eth to fabian.eth each week
- Output: [(eth_send, {to:fabian.eth, recurrent: 1}), ]
- input: send 9 eth
- Output: [eth_send, {value: 9}]
---
## User flows
### Case 1: Manual Workflow building
1. User starts workflow builder
2. Workflow gets created in the backend with an autogenerated ID, to be retrieved later. Each user action on the workflow re-saves workflow state in the backend
3. User selects action blocks
4. User fills inputs for each block
5. User hits executes
6. User gets prompted to give the workflow a name and description (maybe make it public?). Incentivize people to give workflows names and useful descriptions
### Case 2: Intention based Workflow building
1. User types intention in input box
2. The backend saves the user intention + the AI response
3. The backend creates a workflow based on the AI response with an autogenerated ID and returns it to the app. Process continues from Case 1's step 3