Smart Wallet for RSK.
The RIF Wallet is an account abstraction wallet built on the Rootstock network with integration to Bitcoin. Very simplistically, in an Externally Owned Account (EOA) wallet, which is what most wallets are, a user's mnemonic generates a key pair which along with a deviation path derives an address. With Account Abstraction, we take this one step further and have that account/address deploy a smart contract. The address of the smart contract becomes their account and holds their assets (tokens/NFTs/etc).
The main use case of the RIF Wallet using account abstraction is to pay the gas fees with an ERC20 token using RIF Relay. However, additional use cases can be adapted such as social recovery.
- Setup your enviornment using the official instructions
- Use the 'React Native CLI Quickstart' tabs not the 'Expo' tabs.
- Follow the instructions explicitly as a small deviation can cause it to fail.
- Install the dependecies using yarn. This will also run the postinstall script that shims the missing packages:
yarn
- The postinstall script runs the
rn-nodeify
package which adds packages that are native to the browser but not to react native. - For iOS you need to run the additional installation steps:
cd ios
and thenpod install
- The postinstall script runs the
- Set the environment variable
TRACE_ID
in.env
file to connect with backend server with an identifier, i.e. your company name. - Run the app using the desired platform:
yarn ios
yarn android
When you encounter errors running the app, please run yarn clean:ios
or yarn clean:android
first. This will clear the cache and reinstall the native dependecies. When running the iOS command, if you get the error Could not delete [...]/build' because it was not created by the build system.
delete the build folder manually.
The RIF Wallet App uses a backend server to connect to the Rootstock indexer and to collect USD prices. You can run this server yourself locally and connect to it durning development. However, this is not necessary as we have an instance that you can connect to and use.
yarn ios:local
yarn android:local
You can build your own configuration and run
ENVFILE=.env.custom react-native run-ios
You do not need to run the server to run the RIF Wallet app.
The app runs in both Rootstock mainnet and testnet with the default chain set to Testnet. You can configure this by changig the environment variable DEFAULT_CHAIN_TYPE
to MAINNET in the .env file.
The build step for Android includes a clean. When prompted, say 'Yes' to anything related to Android and 'No' to iOS and system updates.
yarn android:build
Open the project up in xCode and select the signing profiles that you wish to use. You may need to signup with appstoreconnect and setup the provisioning profile and certificates. See Apple's documentation for more information. Once the app and profiles are loaded in xCode, create an "archive" of the project by navigating to [Product/Archive]. After it has completed, you can distribute it locally or to the AppStore using the "Organizer" window.
To create an archive to send to the App Store, before opening xCode, install the pod dependecies with the following command:
NO_FLIPPER=1 npx pod-install
At a high level, the RIF Wallet uses the RIF Relay Server to send transactions on behalf of the user. The user creates a transaction in the app, signs it, and then passes it to the RIF Relay Server to get a cost estimation. That estimation is returned to the user, and the user signs an updated transaction with that cost and passes it to the Relay Server.
The server takes the fee as payment for the transaction and broadcasts the transaction to the network paying the gas fee.
In the case that the the RIF Relay Server no longer exists or is not providing the service correctly, the users still have full access to their private key and funds. In the smart wallet contract there is a method called directExecute
which allows a user to send transactions directly to the smart contract. In this scenario, the Externally Owned Account (EOA) can execute transactions directly on the smart contract while paying for the gas in rBTC.
We have created a sample script that shows the basic interaction with the smart contract to allow users to use the wallet without the Relay Server.
In RIF Wallet, bitcoin addresses are automatically generated. The system's fetcher chooses an available index by accessing the endpoint /getNextUnusedIndex/:xpub from rif-wallet-services. This endpoint returns an available index that hasn't been used previously, making it suitable for address creation. Additionally, the endpoint provides multiple indexes, allowing the wallet to select from them for sending any remainder amounts. Using the Bitcoin library rif-wallet-bitcoin, the wallet generates an address based on this index. It also creates several additional addresses to send the remainder amount back to the owner.
Object returned by the endpoint mentioned above:
{
"index": 0,
"availableIndexes": [1, 2, 3, 4, 5]
}
The address creation process is explained in the rif-wallet-libs, in the @rsksmart/rif-wallet-bitcoin package.
See fetchExternalAvailableAddress and fetchExternalAvailableAddresses in BIP.ts for more reference on how it works.
The bitcoin addresses are generated in two parts:
ReceiveScreen -> BIP.ts.fetchExternalAvailableAddress -> which fetches one address at a time and stores it in the state.
bitcoinUtils.ts -> BIP.ts.fetchExternalAvailableAddresses -> which is utilized in the paymentExecutor.ts