# 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;
# 检测 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;
}
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."}
}
2
3
4
5
6
7
8
9
10
# 发送交易
在您的网络应用程序连接到 Bitget Wallet 后,网络应用可以提示用户签署并发送交易到 Aptos 区块链。
Bitget WalletAPI 以两种方式处理交易。
- 签署交易并提交给 Aptos 区块链。向网络应用程序返回一个待定交易。
- 签署一个交易,但不提交给 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"
}
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"
}
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
}
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!
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);
}
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' }
});
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();
}
});
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."
}
2
3
4
- 4100 要求的方法或账户没有得到用户的授权。
- 4000 账户未找到。
- 4001 用户拒绝了请求。
# npm package
# 使用 Aptos Wallet Adapter (opens new window)
#
# 安装
安装npm包
yarn add @manahippo/aptos-wallet-adapter
然后在应用中初始化
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;
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;
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