# Integrating with an Angular App
# Creating a dApp
Before you start integrating you need to go and create and config your dApp on our self service portal, which you can access through here. Once you have created your dApp you will be given an appId which you will use in your integration.
# GitHub Repo
A full React code integration example can be seen here.
# HTTPS
Your domain must ALWAYS run on https
when pointing to the Wallet, otherwise it will be rejected. This is also required for local development.
# Set Up HTTPS on localhost
Firstly, please grab the ssl
folder with all the files from here and drop it into the root of your project.
Then edit your start
script in the package.json to pass in ssl
and ssl-cert
as parameters - example below:
ng serve --ssl true --ssl-cert \"ssl/server.crt\" --ssl-key \"ssl/server.key\"
You will need to install the HTTPS cert as shown below:
# Installing the FunFair Wallet SDK
# TypeScript Typings
Make sure you use all the typings supplied in the SDK. As the SDK is exposed on the window object, you should use the window object supplied by the SDK. This extends the Window
object as well, so you can use it for standard window calls. This will give you full compile time errors on your Wallet integration.
import window from '@funfair-tech/wallet-sdk/window';
All the other typings can be imported directly from the module itself.
TypeScript
:
import {
NetworkDetails,
MessageListeners,
EventResponse,
FunWalletSdkWindow,
ChangeNetworkResponse,
PendingTransactionResponse,
... // loads more
} from '@funfair-tech/wallet-sdk';
HINT it seems VSCODE
has a mind of its own sometimes, so if it autocompletes with a long path i.e. sdk/src/type...
, just revert it to the root npm package namespace (@funfair-tech/wallet-sdk
) and then VSCODE
should sort itself out.
If you find anything without a type, or any issues with it, please raise a GitHub issue for us to triage.
# Hooking up the SDK
Most of our integrators have many wallets they support. For this case our wallet is lazy loaded aka only loaded when you need it.
# Authentication
It's up to the integration to show the user the login and logout buttons, which allows flexibility on designs.
# Login
You should not call this until restoreAuthenticationCompleted event has emitted, at that point the wallet is ready.
Method to login with the fun wallet.
await window.funwallet.sdk.auth.login();
This will load a login screen for the user to enter their details. The promise will not resolve until successful or unsuccessful actions has happened on the authentication login window. If the user closes the login screen then the login
promise will reject, if the user successfully authenticates the login
promise will resolve successfully returning back AuthenticationCompletedResponeData
which is exposed in our sdk typings:
export interface AuthenticationCompletedResponeData {
authenticationCompleted: {
playerProtection: ExclusionStatusResponse;
ethereumAddress: string;
currentCurrency: string;
currentNetwork: NetworkDetails;
userAccountId: string;
};
}
NOTE Chrome and other browsers can block popups if triggered without a genuine user click. Make sure whenever you call the authentication method that it's from a click event from the user to avoid any cross-browser issues.
# Logout
Method to logout the authenticated user.
await window.funwallet.sdk.auth.logout();
# Authentication Refresh
As the server never sees the private key and all the decryption of it happens on the client side, once you refresh your tab, your private key is no longer in memory. We have handled a way to restore authentication on refresh and keep the user logged in. What this means for the developer is they must wait for restoreAuthenticationCompleted to complete before they show any UI, this is super fast, but needed to avoid showing login buttons then flashing to logout buttons. Let's walk you through how you would do this.
If you want to read more about how this works and keeps your private key safe read here.
We just add a loading state to our data which is default true
, this will then turn to false
once the restoreAuthenticationCompleted has completed. We then in the template just add some loading state to hide and show the buttons.
# Show Wallet UI
# Angular Package
You only need to install this package if you want to show the UI.
We have created an Angular package component library this package holds components allowing you to hook the UI for the wallet into an Angular app easier. A full code integration example can be seen here
Usage:
<lib-wallet-follower></lib-wallet-follower>
If you want to deep link into a page on the Wallet, see here. By default the main /funds
page will load. Please note, you must only show if the user is authenticated.
# KYC - Feature Request Only!
KYC is a billable feature due to costs we have to pay third party KYC providers. You will have to get in contact with FunFair if you'd like this feature turned on. To get in contact with us please join our Discord by clicking here.
If you do not want to have KYC as a feature on your dApp please ignore this section completely.
To read more about our providers and countries we cover, please read here
It is up to the dApp to decide if they want to use our KYC feature or not and at which stage. The events get fired regardless but it's up to the dApp to listen to them if they want to use it. The dApp needs to listen to isKycVerified event which will fire when the user has successfully passed or failed KYC. It also fires on initial login with the status of that logged-in user's KYC status. You can listen to kycProcessCancelled event which will fire when the user cancels or closes the KYC modal. The reason we made the dApp handle this is to give them greater flexibility on when you show the KYC stage and what your client does after it was cancelled.
To check if the user has KYC'd or not you can call isKycVerified.
const isKycVerified = await window.funwallet.sdk.kyc.isVerified();
If that returns false (i.e. they are not KYC'd), you can trigger the KYC modal to open by calling the sdk.kyc.start() SDK method:
await window.funwallet.sdk.kyc.start();
Once completed, you will get the status of the pass/fail through the isKycVerified event. Obviously, if they do not complete the KYC you will see them cancel it with the kycProcessCancelled event.
# Speaking to the Blockchain (web3/etherjs)
Now you have the Wallet all hooked up, you can start speaking to the blockchain. Most developers use web3
and etherjs
to interact with the blockchain. The SDK exposes our own EIP-1193 compatible Ethereum provider.
// provider lives here in the FunFair Wallet SDK object
window.funwallet.sdk.ethereum;
To read more about the Ethereum provider please read here.
This can be injected into any new web3
or ethers
instance. This means you can use the standard web3
or ethers
interface to do all your blockchain calls, and our Ethereum provider makes sure all those calls go through the authenticated leader Wallet instance. This means minimal changes to your blockchain code.
Once you the leader has loaded, the SDK will expose the Ethereum provider on the window, which can be used as the provider you inject when you create a new web3
or ethers
instance.
Example:
# web3
# etherjs
All your web3 or ethers calls now will work as normal but proxy through to the Wallet. Use the library to now send transaction and do all things blockchain.
NOTE
We don't support eth_sign
, eth_signTransaction
and eth_sendRawTransaction
, due to the security concerns with signing and not sending. You can only sign and send with our Wallet. Also eth_newFilter
, eth_newBlockFilter
, eth_getFilterChanges
, eth_getFilterLogs
, eth_uninstallFilter
and eth_newPendingTransactionFilter
are not supported by our nodes so will not work.
# Demo Using web3 in the Example Code Above
First, you need to make sure web3 is installed:
# Destroying the fun wallet injected logic
Many dApps support many wallets and you may want to destroy all trace of the fun wallet logic once the user is done using it. A destroy method is exposed on the FunWalletEmbed
class which will remove everything the wallet injected from your dApp.
import { FunWalletEmbed } from '@funfair-tech/wallet-sdk';
FunWalletEmbed.destroy();