Giter Site home page Giter Site logo

gnosis / safe-ios-legacy Goto Github PK

View Code? Open in Web Editor NEW
41.0 10.0 17.0 457.14 MB

Gnosis Safe is a multi signature (2FA) wallet for personal usage.

License: GNU General Public License v3.0

Ruby 0.42% Shell 0.21% Swift 42.58% Objective-C 21.10% C 33.40% C++ 2.24% Python 0.04%

safe-ios-legacy's Introduction

safe-ios-legacy

Download in the AppStore

Getting Started

To set up all project dependencies, run from the project directory in terminal:

$> scripts/bootstrap.sh

To get the app built, copy example files:

$> cp .env.default.example .env.default
$> cp AppConfig.example.yml AppConfig.yml
$> cp GoogleService-Info.example.plist safe/safe/GoogleService-Info.plist

Then comment out the lines 40-43 in the safe/safe/AppDelegate.swift file to disable Firebase. This will make your app running in simulator.

safe-ios-legacy's People

Contributors

dependabot[bot] avatar dmitrybespalov avatar sche avatar tschubotz avatar valeriyvan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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  avatar  avatar  avatar  avatar

safe-ios-legacy's Issues

Implement Transaction Details screen functionality

  • Displaying of transaction data
  • In case of pending transaction: update of the transaction data on status changes
  • Different timestamp display based on the status
  • Opening the transaction details in the browser screen

Text Input & Verifiable input components

Adjust designs for existing and add missing input components.
(-) TextInput
-- add icon
(-) PasswordInput
(-) AddressInput
-- Address takes 2 lines
(-) TokenInput

Make Browser Extension optional

  • Enable creating safe without extension set up
    • number of owners: 3 (2 device keys, 1 paper wallet)
    • threshold: 1
  • Disable messaging to browser extension
    • when safe is created
    • when transaction is created
  • Disable transaction confirmation flow when no browser extension
    • make transaction 'ready' to submit right after editing
    • only sign with device
    • change transaction review screen texts / views
    • proceed to signing.
    • Do not notify extension when transaction is created
  • Make sure that safe is generating 2 EOAs for the device

Address Input component

Address input

  • Two lines always
  • Show alert with actions:
  • Paste from Clipboard
  • Scan QR Code

Strip whitespaces after recovery phrase words confirm

Describe the bug

  • Clean app install
  • Go through device setup
  • On the screen where you confirm mnemonic words: use iOS autocomplete
    -> this adds a whitespace
    -> When trying to continue, the word gets marked as incorrect.

Expected behavior

  • Ideally we would strip whitespaces and the end and the beginning to prevent that from happening.

Thanks to @mikheevm for reporting.

Implement sending ERC-20 tokens

Currently, on every step of transaction handling, we assume the user is sending ETH. That has its limitations.
The user-view of the transaction and underlying ethereum and safe-contract specifics are intermingled. We need clear separation of these.

From a business point of view, both ETH and ERC-20 tokens transfer are conceptually similar.

  • sender - always safe
  • recipient - another account.
  • amount - amount of tokens [token ID, and number of tokens to transfer]
  • fee - fee that will be deducted from the safe's ETH account, it is an estimation.

In the UI, we should use these conceptual values, but for the TX, the recipient might be a contract address, and the data can be ABI encoded call.
These changes affect the hash.

Upon transaction mining, the fee will be deducted from safe ETH account, and amount will be deducted from safe token account. After transaction mined, we should update the balances, because the fee was just an estimation.

  • data - for ETH it is nil, for ERC-20 it is "transfer(recipient, amount)" encoded call. This is implementation detail.
  • hash - safe hash of the transaction. Implementation detail.
  • all addresses must be formatted according to EIP, when sent to our backend

Fix crashes from TestFlight

Description

Since the 0.8.0 (4) version we have crashes coming up with the same exception:

Fatal error: 'try!' expression unexpectedly raised an error: Database.SQLiteDatabase.Error.failedToOpenDatabase

More debugging and enhancing of the thrown exception information led to the

Fatal error: 'try!' expression unexpectedly raised an error: Database.SQLiteDatabase.Error.failedToOpenDatabase("status: (23) (unknown error code)")

Which shows that SQLite returns SQLITE_AUTH error when a database connection is created.

The crashes mostly happen when the app is in the background.

Cause

The cause is that the database files are locked when the app is locked, and the sync process happening regularly in the background tries to access the file but gets an error from the operating system.

Remedy

Search through similar issues on GitHub found the problem described in GRDB.swift repository, which says the SQLITE_IOERR and SQLITE_AUTH errors could be thrown when the database uses files protected by OS's encryption. The corresponding APIs are in UIKit:

  • UIApplication.isProtectedDataAvailable
  • UIApplicationDelegate.applicationProtectedDataDidBecomeAvailable(_:)
  • UIApplicationDelegate.applicationProtectedDataWillBecomeUnavailable(_:)
  • NSNotification.Name.protectedDataDidBecomeAvailableNotification
  • NSNotification.Name.protectedDataWillBecomeUnavailableNotification

We would encounter this problem or be aware of it when developing the app if we would use the GRDB.swift library to work with SQLite, but at this point, I'm reluctant to switch. Sorry, not invented here syndrome.

Proposed solution

After a short team discussion, the proposed treatment for the crash is the following.

Currently, the crash is happening in the implementation modules of repositories, more specifically, when an SQLite connection is created.

Our previous assumption was that any reason that makes a database request erroring (except busy state) is a programming error, meaning the app without working database is not worth functioning, that's why every kind of error on database opening was treated as crashable. This assumption proved to be wrong.

Considering the following points:

  • We'd like to keep our repositories' interfaces clean from throwing errors (as it makes programming easier)
  • We'd like to know if there are any other errors except SQLITE_IOERR and SQLITE_AUTH happening on the devices when a connection is created
  • We'd like to keep the SQL database lib separate from UIKit lib

The proposed solution is:

  • At the call site of opening the database file, if the error occurs:
    • Retry the opening with 5-second interval 3 times or until locked event is received
    • After 3 unsuccessful retries, crash the app
    • If lock event is received, then sleep until unlock event is received
  • At the UIKit level (in sync service implementation):
    • Publish lock and unlock events upon protected data becoming unavailable and available
  • The opening of the database file is a blocking operation, and the notifications from UIKit are assumed to be received on a different thread than the database access thread. This has to be verified.

As always, test that the crases are not happening in the internal beta.

Refactor send transaction process

  • Request confirmation
  • Save fee estimation
  • Limit maximum character count to 150 [done in components, max = (2^256 - 1).length]
  • Restrict invalid character input [done in components]
  • Save entered partial data [invalid state]

browser extension doesn't progress

i've had the browser extension since it was first announced but was unable to use it without access to an android. now that i've got the testflight ios app installed i've connected the browser extension to the app and successfully moved money into my safe. I'm attempting to make a new transfer of eth from the safe, and after confirming i am at the "Review tranaction" page with a loader telling me "awaiting confirmation". My browser app hasn't updated past the page telling me to download the android app or show the qr code. should the confirmation happen automatically or would it be waiting for me on another part of the chrome extension? i've hit "re-send confirmation" a few times with the extension open and unlocked as well as closed but see no difference.

Create password glitch

Describe the bug
We have the following password requirements:

  • min 8 chars
  • min 1 number and min 1 letter
  • no triple chars

I cannot advance when choosing rich987ard as a password

To Reproduce

  • Clean install of app
  • Enter rich987ard as password
    -> I cannot continue
    (I can continue as soon as I enter an uppcase letter though)

Expected behavior
I can use this password since it clearly satisfies the pw requirements :)

Screenshots

Smartphone (please complete the following information):

  • Device: iPhone SE
  • iOS Version: 12.1
  • App Version: 0.8.0 (4) from testflight

Additional context

Implement Transactions List screen

Details

  • Do not display "DRAFT" group for now.
  • Make sure the transaction is deleted when we are coming back from "send" screen and did not submit the transaction.
  • Adjustments to the Transaction model:
    • Add timestamps for different events:
      • created draft -> createdDate // not null
      • updated Transaction -> updatedDate // not null
      • rejected -> rejectedDate // nullable
      • submitted to blockchain -> submittedDate // nullable
      • failed in blockchain -> failedDate // nullable
      • succeess in blockchain -> succeededDate // nullable
    • Add new transaction type:
      • settings // change in safe settings
    • Add new TransactionData.Status:
      • draft; change in the WalletApplicationService
  • UI adjustments:
    • Update according to Zeplin
    • [POSTPONED] Animation of progress and moving to "Today" section upon completion
  • Display of dates
    • use relative dates and times when displaying dates < 2 days ago
  • If some group is empty, do not display it
  • If no transactions exist, display the empty screen
  • [POSTPONED] Pull to refresh - to update transaction statuses

Other thoughts:

  • How to track transaction state updates? and of multiple transactions?
    • Introduce new event to indicate transactions status sync has finished with new changes
    • Register for this event when app starts & screen is loaded
    • Query local database and re-display the contents upon this event
  • When to trigger the transactions status updates?
    • Together with token balance update on app start
    • After transaction submitted, put the tx update in the background worker
    • [NO] Trigger manually from pull-to-refresh on the screen. [discussed with Andrey: not needed now, because we don't expect new incoming transactions until history service is integrated].
  • Is it possible to batch transaction status requests for multiple transactions? Is it feasible? Should it be done now or can be postponed?
    • Possible through batching via JSON-RPC.
    • Can be postponed because assumed # of pending transactions is low (< 100)
  • Swiping actions on rows: remove/discard transaction. Do we need it now or can it be postponed?
    • [NO] we postpone it for later
  • Should the pending status be displayed starting from signature request or from submitting to the blockchain?
    • From blockchain submission.
  • Refactoring: move all transaction-related functions from WalletApplicationService to a separate TransactionDomainService
    • postponed for now
  • Do we need more concrete transaction description than "settings changed"? How is this implemented in Android? For example, what is displayed when owner is added, removed or swapped? Or when threshold changed? What about sending custom tokens?
    • Android: showing only # of bytes sent (for contract operations) | token transfer amount without # of bytes for sent tokens.
    • What is possible:
      • [THIS] when creating transaction, mark it with certain type and metadata.
      • If TX recipient == safe itself
        • we can decode to restore method ID
        • based on that we can display appropriate info (owner added, threshold change, etc.)
      • If TX recipient is one of the token addresses
        • we must decode and see the and transferred.
      • Otherwise:
        • just display the # of bytes sent
        • can EIP712 help decoding data?
        • Can we get contract interface dynamically and process it and decode the data? [for published contracts]
  • Do we track incoming transactions? How?
    • Not now, through transaction history service.

Grouping Algorithm

input: Array of transactions [T] sorted by 
       success_at, failed_at, submitted_at, rejected_at, updated_at in descending order
output: an array of groups [G] of transactions: 
        [draft, pending, today, yesterday, date1, ... dateN]

Let type G have id, date, and list of transactions [T]
Let type T has status (draft, pending, processed) and date

Function GROUP([T]) -> [G] // [T] is sorted by T.date, descending
0. Create groups D, P, and an array of groups [G].
1. for each transaction T in [T]:
2.    if T is draft
3.      then add it to [D]
4.   if T is pending
5.      then add it to [P]
6.   else
7.     if [G].last not exists or [G].last.date != T.date
8.       then create group G with date = T.date;
9.       append G to array [G]
10.    add T to the group [G].last
11. put groups D and P to the beginning of the array [G]
12. return [G]

Animating Transaction Row changes

To support the animation of the transaction row position changes, we need to track the change in indexes and groups between two sets of transactions. We can compute it automatically, given two group arrays and given IDs of transactions.


// Group is identified by combination of <type> and <date>. 
// Types are: draft, pending, processed. 
// Dates are either a 'null' value or a short date in the form YYYY-MM-DD. 
// Date is only specified for groups of 'processed' type. 
// The Group ID then is a string "<type>:<date>". 
// For example: "draft:null", "pending:null", "processed:2018-02-10", "processed:2018-01-30".

input: 
    - array of groups [G1], each group has list of transactions [T], 
      sorted by date (see Grouping Algorithm), each transaction has unique ID; 
    - new array of groups [G2] with changed transaction positions in the groups, and changed groups.
    - Transaction can appear only in one group at a time.

output: change set of rows and sections: deleted, added, moved.

Let type Index = [Int]

Function BUILD_CHANGESET(L1: [G], L2: [G]) -> (GROUPS: Changeset, ROWS: Changeset)
0. Let M1 = BUILD_ROW_INDEXES(L1), M2 = BUILD_ROW_INDEXES(L2)
1. Let ROW_CHANGESET = CHANGE_SET(M1: M1, M2: M2)
2. Let K1 = BUILD_GROUP_INDEXES(L1), K2 = BUILD_GROUP_INDEXES(L2)
3. Let GROUP_CHANGESET = CHANGE_SET(M1: K1, M2: K2)
4. Return (GROUP_CHANGESET, ROW_CHANGESET)

Function BUILD_ROW_INDEXES: ([G]) -> [T: Index] :
0. Let M = [T: Index]
1. For each group G in [G] with index g:
2.    For each transaction T in G.[T] with index t:
3.      Let M[T] = [g, t]
4. Return M

Function BUILD_GROUP_INDEXES: ([G]) -> [G.id: Index] :
0. Let M = [G.id: Index]
1. For each group G in [G] with index g:
2.   Let M[G.id] = [g]
3. return M

Function CHANGE_SET(M1: [T: Index], M2: [T: Index]) -> (DELETED: [Index], MOVED: [(from: Index, to: Index)], ADDED: [Index])
0. Let DELETED = (M1.keys - M2.keys).map { T in M1[T] }
1. Let MOVED = (M1.keys.intersection(M2.keys)).filter { T in M1[T] != M2[T] }.map { T in (from: M1[T], to: M2[T]) }
2. Let ADDED = (M2.keys - M1.keys).map { T in M2[T] }
3. Return (DELETED, MOVED, ADDED)

Explicit continue button for password screens

Describe the bug (not really a bug, more a feature request ;) )

  • Clean app install
  • I'm on the screen to enter a password
  • Tap somewhere to make the keyboard hide
    -> Now I cannot continue anymore. The only way to reopen the keyboard and tap the keyboard's return button.
  • Same issue exists on the confirm password screen.

Expected behavior
It would be really great to have a specific button for this, e.g. in the top right corner.

change chrome extension association

as an attempt to bypass my issue of transferring eth i tried uninstalling and reinstalling my chrome extension. I'm no longer sure whether my browser is actually associated with my wallet and don't see an option to add edit or remove my mobile wallet browser wallet association. is this possible?

Create terms and conditions screen

  • Must slide up on the 'setup password' button tap in the start screen
  • There are 2 buttons that open web-pages
  • If the user agrees, proceed to password setup
  • If the user does not agree, then close then hides the screen.

Transactions signing

  • Handle ‘sendTransaction’ request from browser extension
  • Push Notification pre-processing (Localize text)

The requirement "No triple character" works wrong

When you repeat a character three or more times, the requirement "No triple characters" turns to green as if it was okay. Then, erasing the written password will turn the other two options to red, leaving "No triple characters" in green.

Pre-Conditions:
Having Safe Wallet with no information, as if it was the first opening,

Steps to reproduce:

  1. Enter the Safe Wallet App for iOS
  2. Tap on "Setup Password"
  3. Advance until password creation
  4. Write a password with more than 8 characters. repeating a character at least three times, then erase all
  5. Observe

Expected result:
"No triple character" requirement should go red when typing the password, and remain red when erased.

Actual result:
"No triple character" requirement goes green and so it remains when the password is erased.

Smartphone:
I-phone 7/X - iOS 12.1

Note:
The password used for this test is Saladsoysing1090

img_20181106_130554221

img_20181106_130546283

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.