# Aptos

要在您的 DApp 中使用 Bitget Wallet,您的用户必须先在浏览器中安装 BitKeep 扩展钱包。Bitget Wallet 钱包会在 window (opens new window) 中注入一个 bitkeep.aptos 对象。

# 支持版本

平台 版本 描述
Chrome Extension >=v1.3.8
App(IOS) >=v7.2.5
App(Android) >=v7.2.5

# 是否安装

要检查用户是否已经安装 Bitget Wallet,请执行以下检查:

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

# 检测 Aptos 提供者

如果 Bitget Wallet 没有安装,你可以提示用户先安装 Bitget Wallet,并提供以下安装说明。例如,见下文:

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

# 连接到 Bitget Wallet

在确认 Web 应用程序拥有bitkeep.aptos对象后,我们可以通过调用wallet.connect()来连接 Bitget Wallet。

当你调用wallet.connect()时,它会提示用户允许你的 Web 应用程序对 Bitget Wallet 进行额外的调用,并从用户那里获得基本信息,如地址和公钥。

提示:

在用户第一次批准连接后,网络应用程序的域名将被记住,用于未来的会话。

见下面的示例代码:

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

# 发送交易

在您的网络应用程序连接到 Bitget Wallet 后,网络应用可以提示用户签署并发送交易到 Aptos 区块链。

Bitget WalletAPI 以两种方式处理交易。

  1. 签署交易并提交给 Aptos 区块链。向网络应用程序返回一个待定交易。
  2. 签署一个交易,但不提交给 Aptos 区块链。将已签署的交易返回给网络应用程序,让网络应用程序提交该交易。

请看下面的例子来了解这两个选项。

提示:

更多关于Aptos交易的信息,请参见Aptos SDKs (opens new window)Aptos的交易指南 (opens new window)

# 签署和提交

下面的代码示例显示了如何使用 signAndSubmitTransaction() API 来签署交易并将其发送到 Aptos 区块链上。

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'],
};
/** 自定义 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

# 只签署

重要:我们不建议使用这个,因为在大多数情况下你不需要它,而且对用户来说也不是超级安全的。他们会因此收到一个额外的警告。

下面的代码例子显示了如何使用 signTransaction() API 来只签署交易,而不提交给 Aptos 区块链。

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'],
};
/** 自定义 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

# 签署消息

Web 应用程序也可以通过使用 Bitget WalletAPI 要求用户签署信息:wallet.signMessage(payload: SignMessagePayload)

  • signMessage(payload: SignMessagePayload)向用户提示要签名的 payload.message
  • 返回 Promise<SignMessageResponse>

类型:

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

# 消息示例

signMessage({nonce: 1234034, message: "Welcome to dapp!" }) 这将生成要签名的 fullMessage 并作为签名返回:

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

# 验证

签署信息的最常见的使用情况是验证私有资源的所有权。

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

# 事件监听

# onNetworkChange() 和 network()

一个 DApp 可能想确保用户是在正确的网络上。在这种情况下,你需要检查钱包使用的是什么网络。

网络

We support network: Mainnet | Devnet

正式Mainnet已经上线,Testnet已经修改成Mainnet

由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()

在 Bitget Wallet 中,用户在与你的应用程序互动时可能会改变账户。要检查这些事件,请使用: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

# 错误

当向 Bitget WalletAPI 发出请求时,你可能会收到一个错误。以下是可能出现的错误及其相应的代码的部分列表:

 {
    code: 4100,
    message:"The requested method and/or account has not been authorized by the user."
 }
1
2
3
4
  • 4100 要求的方法或账户没有得到用户的授权。
  • 4000 账户未找到。
  • 4001 用户拒绝了请求。

# npm package

# 使用 Aptos Wallet Adapter (opens new window)

#

提示:

这是一个由钱包适配器本身、一个简单的 Web 应用程序组成的单存储库

查看官方demo (opens new window)

# 安装

安装npm包

yarn add @manahippo/aptos-wallet-adapter
1

然后在应用中初始化

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

签署消息

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
最后更新: 2023/9/7 13:53:50