Use aptos wallet adaptor

The wallet adapter helps you to integrate many different wallets at once and use the same interface to interact with supported wallet.

Here we give an example of using msafe wallet with the adaptor. For more details, see: https://github.com/hippospace/aptos-wallet-adapter.

Install wallet adapter

npm install @msafe/aptos-wallet-adapter

Create wallet adapter

Example:

App.tsx
import { AptosWalletAdapterProvider } from "@aptos-labs/wallet-adapter-react";
import { MSafeWalletAdapter } from "@msafe/aptos-wallet-adapter";

const wallets = [
    new MSafeWalletAdapter(),
];

You may specify the allowed origin URL your dApp connects to. By default, MSafe allows the application to connect to endpoints deployed by MSafe. For example,

const wallets = [
    // Allow app connect to endpoints deployed by MSafe, including
    //     https://partner.m-safe.io
    //     https://testnet.m-safe.io
    //     https://app.m-safe.io
    new MSafeWalletAdapter();
    
    // connecting to msafe mainnet `https://app.m-safe.io`
    new MSafeWalletAdapter('https://app.m-safe.io'),
    
    // connecting to a custom msafe url, e.g. ${MY_CUSTOM_MSAFE_URL}
    new MSafeWalletAdapter(`${MY_CUSTOM_MSAFE_URL}`)
]
Origin Allowlist

MSafe enforces an origin check to ensure that any transaction requests initiated by dApp is passed on to a pre-defined allowed origin URL. The origin check is to prevent the potential phishing attacks launched from any unauthorized third-party.

MSafe will maintain a default list of allowed endpoints deployed by MSafe in MSafe-wallet repository. If no additional arguments is provided, the default list will be used. The current default allowlist is:

Mainnet: 'https://app.m-safe.io',
Testnet: 'https://testnet.m-safe.io',
Partner: 'https://partner.m-safe.io',

The default allowlist shall meet most requirements for MSafe integration in production and development.

To test with MSafe, directly open the URL does not work. Please check https://doc.m-safe.io/msafe/developers/integrate-with-msafe-dapp/integration-test for steps to user / test the integration with MSafe.

Use wallet adapter

Example:

App.tsx
import React from "react";
import { AptosWalletAdapterProvider } from "@aptos-labs/wallet-adapter-react";
import { MSafeWalletAdapter } from "@msafe/aptos-wallet-adapter";

const wallets = [
    new MSafeWalletAdapter(),
];

const App: React.FC = () => {
  return (
    <AptosWalletAdapterProvider
      wallets={wallets}
      onError={(error: Error) => {
        console.log('Handle Error Message', error)
      }}>
      {/* your website */}
    </AptosWalletAdapterProvider>
  );
};

export default App;

Use wallet adapter hooks

Example:

dapp.tsx
import { useWallet } from "@aptos-labs/wallet-adapter-react";
import { MSafeWalletName } from "@msafe/aptos-wallet-adapter";

const WalletName = MSafeWalletName;

export function DAPP() {
    const {
        account,
        connected,
        wallet,
        network,
        connect,
        disconnect,
        select,
        signAndSubmitTransaction,
    } = useWallet();
}

Use msafe wallet with wallet adapter hooks

In the current implementation, `signAndSubmitTransaction` call is expected to never resolve. This is because when a transaction is initiated, MSafe is actually submitting a transaction to initiate a transaction proposal. It will require other owner's approval until the specific transaction can be executed by the MSafe wallet.

Thus upon a transaction proposal being successfully submitted, the application page will be closed, and the user is redirected to transaction queue page waiting for confirmation from other owners.

Example:

dapp.tsx
import { useWallet } from "@aptos-labs/wallet-adapter-react";
import { MSafeWalletName } from "@msafe/aptos-wallet-adapter";

const WalletName = MsafeWalletName;

export function DAPP() {
    const {
        connect,
        signAndSubmitTransaction,
    } = useWallet();

    return (
        <>
            <button onClick={()=>{connect(WalletName)}}> Connect </button>
            <button onClick={()=>{
                const payload = {
                    type: "entry_function",
                    function: "0x1::coin::transfer",
                    type_arguments: ["0x1::aptos_coin::AptosCoin"],
                    arguments: ["0x997b38d2127711011462bc42e788a537eae77806404769188f20d3dc46d72750", 50]
                };
                // each field of option is optional.
                const option = {
                   sequence_number: "1",
                   max_gas_amount: "4000",
                   gas_unit_price: "100",
                   // Unix timestamp, in seconds + 30 days
                   expiration_timestamp_secs: (Math.floor(Date.now() / 1000) + 30*24*3600).toString(),
                }
                signAndSubmitTransaction(payload, option);
            }}> SignAndSubmit </button>
        </>
    );
}

Last updated