# Aptos

To use Bitget Wallet with your dApp, your users must first install the Bitget Wallet Chrome extension in their browser. Bitget Wallet injects an bitkeep.aptos object into the window (opens new window) of any web app the user visits.

This feature is supported by the following versions of Bitget Wallet.

Platform Version Description
Chrome Extension >=v1.3.8
App(IOS) >=v7.2.5
App(Android) >=v7.2.5

# npm package

# Installed or not

To check if the user has installed Bitget Wallet, perform the below check:

const isBitKeepInstalled = window.bitkeep && window.bitkeep.aptos;
1

# Detecting the Aptos provider

If Bitget Wallet is not installed, you can prompt the user to first install Bitget Wallet and provide the below installation instructions. For example, see below:

function getAptosWallet() {
  const provider = window.bitkeep && window.bitkeep.aptos;
  if (!provider) {
    window.open('https://web3.bitget.com/en/wallet-download?type=2');
    throw 'Please go to https://web3.bitget.com/en/wallet-download?type=2 to download!!';
  }
  return provider;
}
1
2
3
4
5
6
7
8

# Connecting to Bitget Wallet

After confirming that the web app has the bitkeep.aptos object, we can connect to Bitget Wallet by calling wallet.connect().

When you call wallet.connect(), it prompts the user to allow your web app to make additional calls to Bitget Wallet, and obtains from the user basic information such as the address and public key.

Note:

After the user has approved the connnection for the first time, the web app's domain will be remembered for the future sessions.

See the example code below:

const wallet = getAptosWallet();
try {
  const response = await wallet.connect();
  console.log(response); // { address: string, address: string }
  const account = await wallet.account();
  console.log(account); // { address: string, address: string }
} catch (error) {
  // { code: 4001, message: "User rejected the request."}
}
1
2
3
4
5
6
7
8
9
10

# Sending a Transaction

After your web app is connected to Bitget Wallet, the web app can prompt the user to sign and send transactions to the Aptos blockchain.

Bitget Wallet API handles the transactions in two ways:

  1. Sign a transaction and submit it to the Aptos blockchain. Return a pending transaction to the web app.
  2. Sign a transaction but do not submit the transaction to the Aptos blockchain. Return the signed transaction to the web app for the web app to submit the transaction.

See the below examples for both the options.

Note:

For more on Aptos transactions, see the Aptos SDKs (opens new window) and Transactions guide from Aptos (opens new window).

# Sign and submit

The below code example shows how to use the signAndSubmitTransaction() API to sign the transaction and send it to the Aptos blockchain.

const wallet = getAptosWallet(); // see "Connecting"
// Example Transaction, following an [EntryFunctionPayload](https://github.com/aptos-labs/aptos-core/blob/main/ecosystem/typescript/sdk/src/generated/models/EntryFunctionPayload.ts#L8-L21)
const transaction = {
    arguments: [address, '717'],
    function: '0x1::coin::transfer',
    type: 'entry_function_payload',
    type_arguments: ['0x1::aptos_coin::TestCoin'],
};
/**
 *  Custom gas fee
 *  default {
        "gas_unit_price":"100",
        "max_gas_amount":"10000"
    }
 */
const options = {
    gas_unit_price:100,
    max_gas_amount:10000
} 
try {
    const pendingTransaction = await window.bitkeep.aptos.signAndSubmitTransaction(transaction);
    // const pendingTransaction = await window.bitkeep.aptos.signAndSubmitTransaction(transaction, options);
    // In most cases a dApp will want to wait for the transaction, in these cases you can use the typescript sdk
    const client = new AptosClient('https://testnet.aptoslabs.com');
    client.waitForTransaction(pendingTransaction.hash);
} catch (error) {
    // see "Errors"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# Sign only

IMPORTANT: We don't recommend using this because in most cases you don't need it, and it isn't super safe for users. They will receive an extra warning for this.

The below code example shows how to use the signTransaction() API to only sign the transaction, without submitting it to the Aptos blockchain.

const wallet = getAptosWallet(); // see "Connecting"
// Example Transaction
const transaction = {
    arguments: [address, '717'],
    function: '0x1::coin::transfer',
    type: 'entry_function_payload',
    type_arguments: ['0x1::aptos_coin::TestCoin'],
};
/** Custom gas fee
 *  default {
        "gas_unit_price":"100",
        "max_gas_amount":"10000"
    }
 */
const options = {
    gas_unit_price: 100,
    max_gas_amount:10000
} 
try {
    const signTransaction = await window.bitkeep.aptos.signTransaction(transaction)
    // const signTransaction = await window.bitkeep.aptos.signTransaction(transaction, options)
} catch (error) {
    // see "Errors"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# Signing Messages

A web app can also request the user to sign a message, by using Bitget Wallet API: wallet.signMessage(payload: SignMessagePayload)

  • signMessage(payload: SignMessagePayload) prompts the user with the payload.message to be signed
  • returns Promise<SignMessageResponse>

Types:

export interface SignMessagePayload {
  address?: boolean; // Should we include the address of the account in the message
  application?: boolean; // Should we include the domain of the dapp
  chainId?: boolean; // Should we include the current chain id the wallet is connected to
  message: string; // The message to be signed and displayed to the user
  nonce: string; // A nonce the dapp should generate
}
export interface SignMessageResponse {
  address: string;
  application: string;
  chainId: number;
  fullMessage: string; // The message that was generated to sign
  message: string; // The message passed in by the user
  nonce: string;
  prefix: string; // Should always be APTOS
  signature: string; // The signed full message
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Example message

signMessage({nonce: 1234034, message: "Welcome to dapp!" }) This would generate the fullMessage to be signed and returned as the signature:

    APTOS
    nonce: 1234034
    message: Welcome to dapp!
1
2
3

# Verifying

The most common use case for signing a message is to verify ownership of a private resource.

import nacl from 'tweetnacl';
const message = "hello";
const nonce = "random_string"
try {
  const response = await window.bitkeep.aptos.signMessage({
    message,
    nonce,
  });
  const { publicKey } = await window.bitkeep.aptos.account();
  // Remove the 0x prefix
  const key = publicKey!.slice(2, 66);
  const verified = nacl.sign.detached.verify(Buffer.from(response.fullMessage),
                                             Buffer.from(response.signature, 'hex'),
                                             Buffer.from(key, 'hex'));
  console.log(verified);
} catch (error) {
  console.error(error);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# Event Listening

# onNetworkChange() and network()

A DApp may want to make sure a user is on the right network. In this case, you will need to check what network the wallet is using.

network

We support network: Mainnet | Devnet

'Testnet' has been modified to 'Mainnet'`

Default networks provided by the Bitget Wallet:

// default networks in the wallet
enum Network {
  Mainnet = 'Mainnet'
  Devnet = 'Devnet'
}
// Current network
let network = await window.bitkeep.aptos.network();
// event listener for network changing
window.bitkeep.aptos.onNetworkChange((newNetwork) => {
  network = newNetwork; // { networkName: 'Mainnet' }
});
1
2
3
4
5
6
7
8
9
10
11
12
13

# onAccountChange()

In Bitget Wallet, a user may change accounts while interacting with your app. To check for these events, listen to them with: onAccountChange.

// get current account
let currentAccount = await window.bitkeep.aptos.account();
// event listener for disconnecting
window.bitkeep.aptos.onAccountChange((newAccount) => {
  // If the new account has already connected to your app then the newAccount will be returned
  if (newAccount) {
    currentAccount = newAccount;
  } else {
    // Otherwise you will need to ask to connect to the new account
    currentAccount = window.bitkeep.aptos.connect();
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13

# Errors

When making requests to Bitget Wallet API, you may receive an error. The following is a partial list of the possible errors and their corresponding codes:

 {
    code: 4100,
    message:"The requested method and/or account has not been authorized by the user."
 }
1
2
3
4
  • 4100 The requested method and/or account has not been authorized by the user.
  • 4000 No accounts found.
  • 4001 The user rejected the request

# npm package

# Use Aptos Wallet Adapter (opens new window)

#

Note:

This is a single repository consisting of the wallet adapter and a simple Web application

Check the official demo (opens new window)

# Install

Install npm package

yarn add @manahippo/aptos-wallet-adapter
1

Then initialize in the application

import React, { useMemo, useState } from 'react';
import {
  WalletProvider,
  BitkeepWalletAdapter,
} from '@manahippo/aptos-wallet-adapter';
import MainPage from './MainPage';
const App = () => {
  const [auto, setAuto] = useState(false);
  const wallets = useMemo(
    () => [
      new BitkeepWalletAdapter(),
    ],
    []
  );
  return (
    <WalletProvider
      wallets={wallets}
      autoConnect={auto}
      onError={(error) => {
        console.log('wallet errors: ', error);
      }}>
      { /* Your app's components go here, nested within the context providers. */}
    </WalletProvider>
  );
};
export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

Sign message

import { useMemo, useState } from 'react';
import { useWallet } from '@manahippo/aptos-wallet-adapter';
const MainPage = () => {
    const {
        connect,
        account,
        wallets,
        connecting,
        connected,
        disconnecting,
        wallet: currentWallet,
        signMessage,
    } = useWallet();
    const messageToSign = useMemo(
        () =>
            `Hello from account ${Array.isArray(account?.publicKey)
                ? JSON.stringify(account.publicKey, null, 2)
                : account?.publicKey?.toString() || account?.address?.toString() || ''
            }`,
        [account]
    );
    const [signature, setSignature] = useState('');
    const handleSign = async () => {
        const signedMessage = await signMessage({
            message: messageToSign,
            nonce: 'random_string'
        });
        setSignature(signedMessage.signature)
    }
    const renderWalletConnectorGroup = () => {
        return wallets.map((wallet) => {
            const option = wallet.adapter;
            return (
                <button
                    onClick={() => {
                        connect(option.name);
                    }}
                    id={option.name.split(' ').join('_')}
                    key={option.name}>
                    {option.name}
                </button>
            );
        });
    };
    const renderContent = () => {
        if (connecting || disconnecting) {
            return 'loading...'
        }
        if (connected && account) {
            return (
                <div >
                    <div>Wallet: {currentWallet?.adapter.name}</div>
                    <div>Address: {account?.address?.toString()}</div>
                    <div>signdMessage: {signature}</div>
                    <button onClick={() => handleSign()} >Sign Message</button>
                </div>
            );
        } else {
            return <div >{renderWalletConnectorGroup()}</div>;
        }
    };
    return (
        <div>
            <div>{renderContent()}</div>
        </div>
    );
}
export default MainPage;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
Last Updated: 9/7/2023, 1:53:50 PM