Giter Club home page Giter Club logo

v1-safe-app's Introduction

Sablier V1 Safe App

This is the legacy app for Sablier V1. If you're looking for the Sablier V2 Safe App, just search for "Sablier" in the Safe Apps Explorer.

This app brings real-time finance to Safe users by allowing them to use the Sablier V1 token streaming protocol. You can read more about Safe Apps here.

Sablier opens up the opportunity for organizations to pay and interact with each other in new ways without having to give custody of funds to a single member:

  1. Vesting; stream governance tokens to early investors.
  2. Continuous payroll or freelancing.
  3. Subscriptions, paying for a product or a service in real-time.

Usage 💸

Create Stream Page Dashboard

Using this Safe App, you can:

  • Create new streams.
  • View details on your incoming and outgoing streams.
  • Cancel streams as a sender.
  • Withdraw from streams as a recipient.

Deployments 🌍

There are multiple ways to access the Safe App:

The Vercel deployment will automatically update to the newest version of the Sablier V1 Safe app, however for additional security you may want to use the production-ready version on the Safe UI.

Alternatives

If you don't have a Safe multisig but would like to use Sablier V1, you can use the original interfaces:

Contributing 🙋‍♀️

We highly encourage participation from the community to help shape the development of Sablier. If you are interested in contributing or have any questions, ping us on Discord.

Contributing

To start developing on the Sablier V1 Safe App, first clone this repository and enter the new directory.

git clone https://github.com/sablier-labs/v1-safe-app.git
cd sablier-safe-app

You will need to create a .env file. We have provided .env.example as a template.

cp .env.example .env

Now, install the node dependencies and start the dev server:

yarn install
yarn start

The app will be hosted on http://localhost:3000.

React App Rewired

In order to allow the Safe UI to access the app while it's running on localhost, we need to edit the headers on the dev server (node_modules/react-scripts/config/webpackDevServer.config.js) to avoid CORS issues:

headers: {
    "Access-Control-Allow-Origin": "\*",
    "Access-Control-Allow-Methods": "GET",
    "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
}

We automate injecting these headers in to the server config through react-app-rewired.

v1-safe-app's People

Contributors

chillichelli avatar latenthero avatar maxdesalle avatar paulrberg avatar razgraf avatar tomafrench avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

v1-safe-app's Issues

Add ENS support

  • Forward resolution in the address input
  • reverse resolution in the stream display table

Use the Payroll ABI instead of the core Sablier

Totally my fault here. I was laser-focused on the payroll use case when designing the smart contracts for Sablier, and I ended up coding a generic contract (a proxy) that has a bespoke name (Payroll.sol).

If we're not using the Payroll ABI, the receiving party won't be able to cash-in his earnings on app.sablier.finance.

@TomAFrench, I'll take this one myself when I do the migration to ethers.

Add handling for non-integer stream rate

Currently we don't enforce that a user will create a transaction which will satisfy the deposit % vars.duration == 0 requirement in Sablier.sol.

We should add a quick safeDeposit = Math.floor(deposit/streamLength)*streamLength line in the correct place to fix this.

Uncaught (in promise) Error: missing response (serverError={}

Not sure what's the cause of this, or if it does any harm at all:

index.js:165 Uncaught (in promise) Error: missing response (serverError={}, url="https://mainnet.infura.io/v3/84842078b09946638c03157f83405213", code=SERVER_ERROR, version=web/5.0.0-beta.141)
    at Logger.makeError (index.js:165)
    at Logger.throwError (index.js:174)
    at index.js:100
    at Generator.throw (<anonymous>)
    at rejected (index.js:6)

Let the user select the start time

Some users may be confused by the default 1 hour initial delay, even that is a perfectly reasonable buffer given the current gas prices on Ethereum.

A good example to follow is sablier.me, since this feature is already available there.

Fix ordering by id in stream table

When ordering by id, the sorting algorithm considers the id a string, not a number. This results in an incorrect output, such as 108 appearing ahead of 100005.

Apply correct colours to elements

Currently not much thought has gone into whether a component is the primary or secondary colour. We should go through and check that these make sense.

Upgrade dependencies to build with Node.js V17 and later

If you try to build the app with Node.js 17 or later, you will be getting the following error:

error:0308010C:digital envelope routines::unsupported

As explained here, this error is due to a security hole in the SSL provider, which was fixed in Node.js v17.

A temporary solution is to stick with Node.js v16 in the CI. However, we should consider the more permanent solution, which is to upgrade all dependencies to their latest major releases.

This answer recommends an alternative solution that involves changing the hash function used by Webpack, but to make that work, we would need to use a newer version of Webpack, hence we're back to square one.

Sablier safe app is using user's web3 provider

https://github.com/TomAFrench/sablier-safe-app/blob/94eee2e77c40f0a5caa01615e2ad315d55aed3db/src/components/CreateStreamForm/index.tsx#L167

  1. A safe app shouldn't access user's web3 provider for security reasons
  2. Users of safe multisig do not always have an injected provider in their browser. For example, users can use walletconnect to connect to their wallet. If you need a web3 provider to perform calls like .balanceOf, you should use your own provider connected to an ethereum API (infura for example). Also I've seen that you're using The Graph, it could work for this use case too.

We're working on improving 2) so you can expect in future versions of sdk that we will export our own provider for making requests :)

Add stream withdrawal support

In the MVP we only allow Safes to create streams, there is no way for them to receive a stream and withdraw from it. This will be a commonly used feature so should be added in v1.0.

required steps:

  • add new graphql query to get incoming streams
  • create new set of table columns for incoming streams ("From" rather than "To")
  • add interface to switch between showing outgoing and incoming streams
  • Add a withdrawFromStreamfunction similar to cancelStream

Add a status for "waiting to start"

Currently we show streams which haven't begun yet as "Active". We should differentiate these two cases to make it clear why the balances aren't yet changing.

Please add 'ICHI' to gnosis safe app

ICHI contract address: 0x903bEF1736CDdf2A537176cf3C64579C3867A881

ICHI has $7M worth in Sablier Finance - it should be added to gnosis app. Please help.

Show streaming amounts in "Transaction" page

We certainly can't fix this from our own app, but Gnosis could:

Capture d’écran 2020-06-09 à 20 02 43

They probably check whether the transaction is an ERC20 transfer and, if yes, they pull the data from the Transfer event.

I'm sure we could do a PR that adds our own checkers for CreateStream, WithdrawFromStream and CancelStream.

Display the time zone in all time fields

One of our users asked this very good question recently:

Can you please confirm which timezone the start date is using on the Sablier Ul?

I think that it would be helpful to add a reference to the time zone in the UI itself.

Round up stream amounts

Due to #17 all stream values are displaying as "x.9999". This will likely cause some confusion for users so we should round these up before displaying them.

Screenshot_2020-06-04_21-05-24

Replace icons with SVGs

Currently the image in the manifest file is a png. We should swap this out for an svg at some point.

Stream with any token address

We've been getting loads of requests for adding new tokens, and the trend will only continue as Sablier is increasingly used for vesting. Letting people stream any token they want, even if there would be no logo, sounds like a wise feature to add.

Add support for streaming ETH

The Sablier contracts only support streaming ERC20 tokens and in order to stream ETH it needs to first be wrapped into WETH in a separate transaction.

With a standard wallet this requires a separate transaction but by taking advantage of Gnosis batching transactions we can transparently wrap and unwrap on stream entry and exit. This can be done simply by adding a "wrap" transaction onto the beginning of a function similar to createStreamTxs.

Use the Sablier branding color

We currently use this light green, probably a left over from the Compound app.

We should switch to using the primary orange used in Sablier, that is, "#f77423".

Capture d’écran 2020-06-04 à 23 41 46

Redesign interface

The StreamTable is starting to take over the available app space. This will only get worse as we add additional columns to show the stream status (active, ended, etc.)

We can take some cues from the pay.sablier.finance interface to deal with this. We can place the entire "Create Stream" form within a modal and allow the table to use the full app area.

In order to deal with an unappealing empty state for new users we can place a call-to-action within this empty space similar to that used at pay.sablier.finance.

For future interactions there can be a menu displayed above the table giving a similar experience to the Assets page on a Safe

("Sending | Receiving" on the left hand side and a "Create Stream" button to bring up the modal)

Update SDK version

We're a few versions behind now and the newer versions allow us to track transaction status after we send them. We could probably do something interesting with that.

Support EIP-3770

At gnosis safe, we started supporting https://ethereum-magicians.org/t/chain-specific-addresses/6449 because we had a lot of occasions where people would send assets to their Safe address on a different network where the Safe doesn't exist.

Some people reported that copying such addresses into Sablier safe app doesn't work and the app doesn't provide any visual feedback, and users get stuck.

It'd be awesome if Sablier started supporting such addresses.

Incorrect graphql query

Currently the graphql query is querying stream objects so we never get a response as the streams we're interested in are "from" the Payroll proxy. We should update the query in order to point at proxyStreams

Handle the case where the network is different

I'm not sure if we have to fix this at all. Maybe the fact that the app is intended to be run under an inframe on the Gnosis websites makes this a non-issue.

The error I get when MetaMask is set to a network other than Mainnet or Rinkeby:

Capture d’écran 2020-05-31 à 19 45 04

This is from my local development tree, not yet pushed to origin.

Add a manifest.json file

As per the docs provided by Gnosis:

Once your app is ready you need to deploy it on the internet. It is mandatory that your app exposes a manifest.json file in the root dir.

Example structure:

{
  "name": "YourAppName",
  "description": "A description of what your app do",
  "iconPath": "myAppIcon.svg"
}

Add info tooltip for the duration input

This is arguably the hardest stream property to convey the meaning of to end users. A nice little tooltip that explains what the duration is about would be a boon.

The black box on the left-hand side of this image is what I'm referring to:

Tooltip Image

Migrate to ethers@v5 from web3

web3.js has gotten behind the curve on many fronts. ethers is a much suitable frontend library for connecting to Ethereum smart contracts.

Just one example out of many: I spent 15 minutes trying to the right way to import the Contract type in web3, whereas in ethers it's clearly documented.

"Error while getting the withdrawable amount" immediately after withdrawal

Shortly after making a withdrawal, this is what get logged in the console:

Capture d’écran 2021-11-17 à 00 03 51

It gets logged continuously. I suspect that the problem is that the state of the stream is not correctly updated - there should be some hook somewhere taking care of the state transition from "stream not yet withdrawn" to "stream withdrawn".

Use the same font everwyhere

The Compound app (and I think the Gnosis UI styleguide) uses this font family:

fontFamily: `'Averta', 'Roboto', 'Helvetica Neue', 'Arial', 'Segoe UI', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', '-apple-system', 'BlinkMacSystemFont', sans-serif`

But we're not using it uniformly. At least the "Amount" and the "Recipient" text fields don't have it.

Capture d’écran 2020-06-04 à 22 44 34

Tap row item and open the Sablier Interface page

It'd be nice to redirect the user to the Sablier Interface when they tap a row in the "Manage Created Streams" table.

There's no way we will ever fit as much rich data in the Safe App as there can be displayed on the canonical web app.

Compress stream length component size

Currently we have several Select boxes for each time increment in the stream creation UI, this is contributing to us overflowing the available area (and doesn't look great besides).

One way to handle this is to pull in the equivalent component from pay.sablier.finance

Screenshot_2020-05-29_19-29-27

@PaulRBerg are you happy for us to pull that component across and restyle it to match the gnosis style?

Adjust "Back" button on stream page appearance

This back button here looks a little misaligned with the title. I think this might be caused by the text being smaller resulting in the majority of the "weight" of the text being lower.

We should play with this to get something which looks nice at some point.

Screenshot_2020-06-09_20-19-58

Add proper empty state handling for stream table.

Currently we have a situation where when navigating to the stream table page while no streams exist it results in a permanent loading spinner. We could add an empty state to the table to avoid user confusion.

I'm of a mind to instead move the querying of the subgraph into the App component and pass the streams in as a prop in order to hide the loading time. We could solve this issue at the same time by disabling the Manage Created Streams button if this list is empty.

App crashes in Safari

TypeError: undefined is not an object (evaluating 'ethereum.enable')

To be fair, this is common among web3 apps. Safari uses a quirky extension system that doesn't resemble Chrome, Brave or Firefox at all.

Capture d’écran 2020-06-08 à 00 27 32

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.