@aptos-labs/wallet-adapter-core 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +4 -0
- package/README.md +3 -0
- package/package.json +47 -0
- package/src/WalletCore.ts +251 -0
- package/src/constants.ts +25 -0
- package/src/error/index.ts +96 -0
- package/src/index.ts +3 -0
- package/src/types.ts +101 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/localStorage.ts +15 -0
- package/src/utils/scopePollingDetectionStrategy.ts +46 -0
- package/tsconfig.json +9 -0
package/.eslintrc.js
ADDED
package/README.md
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aptos-labs/wallet-adapter-core",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Aptos Wallet Adapter Core",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"license": "Apache-2.0",
|
|
9
|
+
"exports": {
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/aptos-labs/aptos-wallet-adapter.git"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/aptos-labs/aptos-wallet-adapter",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/aptos-labs/aptos-wallet-adapter/issues"
|
|
21
|
+
},
|
|
22
|
+
"author": "aptoslabs.com",
|
|
23
|
+
"keywords": [
|
|
24
|
+
"Aptos",
|
|
25
|
+
"Aptos Labs",
|
|
26
|
+
"Wallet",
|
|
27
|
+
"Wallet Adapter",
|
|
28
|
+
"Aptos Wallet"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
32
|
+
"dev": "tsup src/index.ts --format esm,cjs --watch --dts",
|
|
33
|
+
"lint": "TIMING=1 eslint \"src/**/*.ts*\"",
|
|
34
|
+
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@aptos-labs/wallet-adapter-tsconfig": "workspace:*",
|
|
38
|
+
"eslint": "^8.15.0",
|
|
39
|
+
"@aptos-labs/eslint-config-adapter": "workspace:*",
|
|
40
|
+
"tsup": "^5.10.1",
|
|
41
|
+
"typescript": "^4.5.3"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"aptos": "^1.3.17",
|
|
45
|
+
"eventemitter3": "^4.0.7"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { Types } from "aptos";
|
|
2
|
+
import { EventEmitter } from "eventemitter3";
|
|
3
|
+
|
|
4
|
+
import { WalletReadyState } from "./constants";
|
|
5
|
+
import {
|
|
6
|
+
WalletAccountChangeError,
|
|
7
|
+
WalletAccountError,
|
|
8
|
+
WalletConnectionError,
|
|
9
|
+
WalletDisconnectionError,
|
|
10
|
+
WalletGetNetworkError,
|
|
11
|
+
WalletNetworkChangeError,
|
|
12
|
+
WalletNotConnectedError,
|
|
13
|
+
WalletNotReadyError,
|
|
14
|
+
WalletNotSelectedError,
|
|
15
|
+
WalletSignAndSubmitMessageError,
|
|
16
|
+
WalletSignMessageError,
|
|
17
|
+
WalletSignTransactionError,
|
|
18
|
+
} from "./error";
|
|
19
|
+
import {
|
|
20
|
+
AccountInfo,
|
|
21
|
+
NetworkInfo,
|
|
22
|
+
WalletName,
|
|
23
|
+
SignMessagePayload,
|
|
24
|
+
SignMessageResponse,
|
|
25
|
+
Wallet,
|
|
26
|
+
WalletInfo,
|
|
27
|
+
WalletCoreEvents,
|
|
28
|
+
} from "./types";
|
|
29
|
+
import {
|
|
30
|
+
removeLocalStorage,
|
|
31
|
+
setLocalStorage,
|
|
32
|
+
scopePollingDetectionStrategy,
|
|
33
|
+
} from "./utils";
|
|
34
|
+
|
|
35
|
+
export class WalletCore extends EventEmitter<WalletCoreEvents> {
|
|
36
|
+
private _wallets: Wallet[] = [];
|
|
37
|
+
private _wallet: Wallet | null = null;
|
|
38
|
+
private _account: AccountInfo | null = null;
|
|
39
|
+
private _network: NetworkInfo | null = null;
|
|
40
|
+
|
|
41
|
+
private _connecting: boolean = false;
|
|
42
|
+
private _connected: boolean = false;
|
|
43
|
+
|
|
44
|
+
constructor(plugins: Wallet[]) {
|
|
45
|
+
super();
|
|
46
|
+
this._wallets = plugins;
|
|
47
|
+
this.scopePollingDetectionStrategy();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private scopePollingDetectionStrategy() {
|
|
51
|
+
this._wallets?.forEach((wallet: Wallet) => {
|
|
52
|
+
wallet.readyState =
|
|
53
|
+
typeof window === "undefined" || typeof document === "undefined"
|
|
54
|
+
? WalletReadyState.Unsupported
|
|
55
|
+
: WalletReadyState.NotDetected;
|
|
56
|
+
if (typeof window !== "undefined") {
|
|
57
|
+
scopePollingDetectionStrategy(() => {
|
|
58
|
+
if (Object.keys(window).includes(wallet.name.toLowerCase())) {
|
|
59
|
+
wallet.readyState = WalletReadyState.Installed;
|
|
60
|
+
wallet.provider = window[wallet.name.toLowerCase() as any];
|
|
61
|
+
this.emit("readyStateChange", wallet);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private isWalletExists(): boolean | WalletNotConnectedError {
|
|
71
|
+
if (!this._connected || this._connecting || !this._wallet)
|
|
72
|
+
throw new WalletNotConnectedError().name;
|
|
73
|
+
if (
|
|
74
|
+
!(
|
|
75
|
+
this._wallet.readyState === WalletReadyState.Loadable ||
|
|
76
|
+
this._wallet.readyState === WalletReadyState.Installed
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
throw new WalletNotReadyError().name;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private clearData() {
|
|
84
|
+
this._connected = false;
|
|
85
|
+
this.setWallet(null);
|
|
86
|
+
this.setAccount(null);
|
|
87
|
+
this.setNetwork(null);
|
|
88
|
+
removeLocalStorage();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
setWallet(wallet: Wallet | null) {
|
|
92
|
+
this._wallet = wallet;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setAccount(account: AccountInfo | null) {
|
|
96
|
+
this._account = account;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setNetwork(network: NetworkInfo | null) {
|
|
100
|
+
this._network = network;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
isConnected(): boolean {
|
|
104
|
+
return this._connected;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get wallets(): Wallet[] {
|
|
108
|
+
return this._wallets;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
get wallet(): WalletInfo | null {
|
|
112
|
+
try {
|
|
113
|
+
if (!this._wallet) return null;
|
|
114
|
+
return {
|
|
115
|
+
name: this._wallet.name,
|
|
116
|
+
icon: this._wallet.icon,
|
|
117
|
+
url: this._wallet.url,
|
|
118
|
+
};
|
|
119
|
+
} catch (error: any) {
|
|
120
|
+
throw new WalletNotSelectedError(error).message;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
get account(): AccountInfo | null {
|
|
125
|
+
try {
|
|
126
|
+
return this._account;
|
|
127
|
+
} catch (error: any) {
|
|
128
|
+
throw new WalletAccountError(error).message;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
get network(): NetworkInfo | null {
|
|
133
|
+
try {
|
|
134
|
+
return this._network;
|
|
135
|
+
} catch (error: any) {
|
|
136
|
+
throw new WalletGetNetworkError(error).message;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async connect(walletName: WalletName): Promise<void> {
|
|
141
|
+
try {
|
|
142
|
+
const selectedWallet = this._wallets?.find(
|
|
143
|
+
(wallet: Wallet) => wallet.name === walletName
|
|
144
|
+
);
|
|
145
|
+
if (!selectedWallet) return;
|
|
146
|
+
if (selectedWallet.readyState !== WalletReadyState.Installed) return;
|
|
147
|
+
if (this._connected) {
|
|
148
|
+
await this.disconnect();
|
|
149
|
+
}
|
|
150
|
+
this._connecting = true;
|
|
151
|
+
this.setWallet(selectedWallet);
|
|
152
|
+
const account = await selectedWallet.connect();
|
|
153
|
+
this.setAccount({ ...account });
|
|
154
|
+
const network = await selectedWallet.network();
|
|
155
|
+
this.setNetwork({ ...network });
|
|
156
|
+
setLocalStorage(selectedWallet.name);
|
|
157
|
+
this._connected = true;
|
|
158
|
+
this.emit("connect", account);
|
|
159
|
+
} catch (error: any) {
|
|
160
|
+
this.clearData();
|
|
161
|
+
throw new WalletConnectionError(error).message;
|
|
162
|
+
} finally {
|
|
163
|
+
this._connecting = false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async disconnect(): Promise<void> {
|
|
168
|
+
try {
|
|
169
|
+
this.isWalletExists();
|
|
170
|
+
await this._wallet?.disconnect();
|
|
171
|
+
this.clearData();
|
|
172
|
+
this.emit("disconnect");
|
|
173
|
+
} catch (error: any) {
|
|
174
|
+
throw new WalletDisconnectionError(error).message;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async signAndSubmitTransaction(
|
|
179
|
+
transaction: Types.TransactionPayload
|
|
180
|
+
): Promise<any> {
|
|
181
|
+
try {
|
|
182
|
+
this.isWalletExists();
|
|
183
|
+
const response = await this._wallet?.signAndSubmitTransaction(
|
|
184
|
+
transaction
|
|
185
|
+
);
|
|
186
|
+
return response;
|
|
187
|
+
} catch (error: any) {
|
|
188
|
+
const errMsg =
|
|
189
|
+
typeof error == "object" && "message" in error ? error.message : error;
|
|
190
|
+
throw new WalletSignAndSubmitMessageError(errMsg).message;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async signTransaction(
|
|
195
|
+
transaction: Types.TransactionPayload
|
|
196
|
+
): Promise<Uint8Array | null> {
|
|
197
|
+
try {
|
|
198
|
+
if (this._wallet && !("signTransaction" in this._wallet)) return null;
|
|
199
|
+
this.isWalletExists();
|
|
200
|
+
const response = await (this._wallet as any).signTransaction(transaction);
|
|
201
|
+
return response;
|
|
202
|
+
} catch (error: any) {
|
|
203
|
+
const errMsg =
|
|
204
|
+
typeof error == "object" && "message" in error ? error.message : error;
|
|
205
|
+
throw new WalletSignTransactionError(errMsg).message;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async signMessage(
|
|
210
|
+
message: SignMessagePayload
|
|
211
|
+
): Promise<SignMessageResponse | null> {
|
|
212
|
+
try {
|
|
213
|
+
this.isWalletExists();
|
|
214
|
+
if (!this._wallet) return null;
|
|
215
|
+
const response = await this._wallet?.signMessage(message);
|
|
216
|
+
return response;
|
|
217
|
+
} catch (error: any) {
|
|
218
|
+
const errMsg =
|
|
219
|
+
typeof error == "object" && "message" in error ? error.message : error;
|
|
220
|
+
throw new WalletSignMessageError(errMsg).message;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async onAccountChange(): Promise<void> {
|
|
225
|
+
try {
|
|
226
|
+
this.isWalletExists();
|
|
227
|
+
await this._wallet?.onAccountChange((data: AccountInfo) => {
|
|
228
|
+
this.setAccount({ ...data });
|
|
229
|
+
this.emit("accountChange", this._account);
|
|
230
|
+
});
|
|
231
|
+
} catch (error: any) {
|
|
232
|
+
const errMsg =
|
|
233
|
+
typeof error == "object" && "message" in error ? error.message : error;
|
|
234
|
+
throw new WalletAccountChangeError(errMsg).message;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async onNetworkChange(): Promise<void> {
|
|
239
|
+
try {
|
|
240
|
+
this.isWalletExists();
|
|
241
|
+
await this._wallet?.onNetworkChange((data: NetworkInfo) => {
|
|
242
|
+
this.setNetwork({ ...data });
|
|
243
|
+
this.emit("networkChange", this._network);
|
|
244
|
+
});
|
|
245
|
+
} catch (error: any) {
|
|
246
|
+
const errMsg =
|
|
247
|
+
typeof error == "object" && "message" in error ? error.message : error;
|
|
248
|
+
throw new WalletNetworkChangeError(errMsg).message;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export enum WalletReadyState {
|
|
2
|
+
/**
|
|
3
|
+
* User-installable wallets can typically be detected by scanning for an API
|
|
4
|
+
* that they've injected into the global context. If such an API is present,
|
|
5
|
+
* we consider the wallet to have been installed.
|
|
6
|
+
*/
|
|
7
|
+
Installed = "Installed",
|
|
8
|
+
NotDetected = "NotDetected",
|
|
9
|
+
/**
|
|
10
|
+
* Loadable wallets are always available to you. Since you can load them at
|
|
11
|
+
* any time, it's meaningless to say that they have been detected.
|
|
12
|
+
*/
|
|
13
|
+
Loadable = "Loadable",
|
|
14
|
+
/**
|
|
15
|
+
* If a wallet is not supported on a given platform (eg. server-rendering, or
|
|
16
|
+
* mobile) then it will stay in the `Unsupported` state.
|
|
17
|
+
*/
|
|
18
|
+
Unsupported = "Unsupported",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export enum NetworkName {
|
|
22
|
+
Mainnet = "mainnet",
|
|
23
|
+
Testnet = "testnet",
|
|
24
|
+
Devnet = "devnet",
|
|
25
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export class WalletError extends Error {
|
|
2
|
+
public error: any;
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
5
|
+
constructor(message?: string, error?: any) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.error = error;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class WalletNotSelectedError extends WalletError {
|
|
12
|
+
name = "WalletNotSelectedError";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class WalletNotReadyError extends WalletError {
|
|
16
|
+
name = "WalletNotReadyError";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class WalletLoadError extends WalletError {
|
|
20
|
+
name = "WalletLoadError";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class WalletConfigError extends WalletError {
|
|
24
|
+
name = "WalletConfigError";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class WalletConnectionError extends WalletError {
|
|
28
|
+
name = "WalletConnectionError";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class WalletDisconnectedError extends WalletError {
|
|
32
|
+
name = "WalletDisconnectedError";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class WalletDisconnectionError extends WalletError {
|
|
36
|
+
name = "WalletDisconnectionError";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class WalletAccountError extends WalletError {
|
|
40
|
+
name = "WalletAccountError";
|
|
41
|
+
}
|
|
42
|
+
export class WalletGetNetworkError extends WalletError {
|
|
43
|
+
name = "WalletGetNetworkError";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class WalletAccountChangeError extends WalletError {
|
|
47
|
+
name = "WalletAccountChangeError";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class WalletNetworkChangeError extends WalletError {
|
|
51
|
+
name = "WalletNetworkChangeError";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class WalletPublicKeyError extends WalletError {
|
|
55
|
+
name = "WalletPublicKeyError";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export class WalletKeypairError extends WalletError {
|
|
59
|
+
name = "WalletKeypairError";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class WalletNotConnectedError extends WalletError {
|
|
63
|
+
name = "WalletNotConnectedError";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export class WalletSendTransactionError extends WalletError {
|
|
67
|
+
name = "WalletSendTransactionError";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export class WalletSignMessageError extends WalletError {
|
|
71
|
+
name = "WalletSignMessageError";
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export class WalletSignAndSubmitMessageError extends WalletError {
|
|
75
|
+
name = "WalletSignAndSubmitMessageError";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export class WalletSignTransactionError extends WalletError {
|
|
79
|
+
name = "WalletSignTransactionError";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export class WalletTimeoutError extends WalletError {
|
|
83
|
+
name = "WalletTimeoutError";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export class WalletWindowBlockedError extends WalletError {
|
|
87
|
+
name = "WalletWindowBlockedError";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export class WalletWindowClosedError extends WalletError {
|
|
91
|
+
name = "WalletWindowClosedError";
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export class WalletResponseError extends WalletError {
|
|
95
|
+
name = "WalletResponseError";
|
|
96
|
+
}
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Types } from "aptos";
|
|
2
|
+
import { NetworkName, WalletReadyState } from "./constants";
|
|
3
|
+
|
|
4
|
+
// WalletName is a nominal type that wallet adapters should use, e.g. `'MyCryptoWallet' as WalletName<'MyCryptoWallet'>`
|
|
5
|
+
export type WalletName<T extends string = string> = T & {
|
|
6
|
+
__brand__: "WalletName";
|
|
7
|
+
};
|
|
8
|
+
export type NetworkInfo = {
|
|
9
|
+
name: NetworkName | undefined;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type AccountInfo = {
|
|
13
|
+
address: string;
|
|
14
|
+
publicKey: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export interface AptosWalletErrorResult {
|
|
18
|
+
code: number;
|
|
19
|
+
name: string;
|
|
20
|
+
message: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PluginProvider {
|
|
24
|
+
connect: () => Promise<AccountInfo>;
|
|
25
|
+
account: () => Promise<AccountInfo>;
|
|
26
|
+
disconnect: () => Promise<void>;
|
|
27
|
+
signAndSubmitTransaction: (
|
|
28
|
+
transaction: any,
|
|
29
|
+
options?: any
|
|
30
|
+
) => Promise<{ hash: Types.HexEncodedBytes } | AptosWalletErrorResult>;
|
|
31
|
+
signMessage: (message: SignMessagePayload) => Promise<SignMessageResponse>;
|
|
32
|
+
network: () => Promise<NetworkName>;
|
|
33
|
+
onAccountChange: (
|
|
34
|
+
listener: (newAddress: AccountInfo) => Promise<void>
|
|
35
|
+
) => Promise<void>;
|
|
36
|
+
onNetworkChange: (
|
|
37
|
+
listener: (network: { networkName: NetworkInfo }) => Promise<void>
|
|
38
|
+
) => Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface AdapterPluginEvents {
|
|
42
|
+
onNetworkChange(callback: any): Promise<any>;
|
|
43
|
+
onAccountChange(callback: any): Promise<any>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface AdapterPluginProps<Name extends string = string> {
|
|
47
|
+
name: WalletName<Name>;
|
|
48
|
+
url: string;
|
|
49
|
+
icon: `data:image/${"svg+xml" | "webp" | "png" | "gif"};base64,${string}`;
|
|
50
|
+
provider: any;
|
|
51
|
+
connect(): Promise<any>;
|
|
52
|
+
disconnect: () => Promise<any>;
|
|
53
|
+
network: () => Promise<any>;
|
|
54
|
+
signAndSubmitTransaction<T extends Types.TransactionPayload, V>(
|
|
55
|
+
transaction: T,
|
|
56
|
+
options?: V
|
|
57
|
+
): Promise<{ hash: Types.HexEncodedBytes }>;
|
|
58
|
+
signMessage<T extends SignMessagePayload>(
|
|
59
|
+
message: T
|
|
60
|
+
): Promise<SignMessageResponse>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type AdapterPlugin<Name extends string = string> =
|
|
64
|
+
AdapterPluginProps<Name> & AdapterPluginEvents;
|
|
65
|
+
|
|
66
|
+
export type Wallet<Name extends string = string> = AdapterPlugin<Name> & {
|
|
67
|
+
readyState?: WalletReadyState;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type WalletInfo = {
|
|
71
|
+
name: WalletName;
|
|
72
|
+
icon: string;
|
|
73
|
+
url: string;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export declare interface WalletCoreEvents {
|
|
77
|
+
connect(account: AccountInfo | null): void;
|
|
78
|
+
disconnect(): void;
|
|
79
|
+
readyStateChange(wallet: Wallet): void;
|
|
80
|
+
networkChange(network: NetworkInfo | null): void;
|
|
81
|
+
accountChange(account: AccountInfo | null): void;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface SignMessagePayload {
|
|
85
|
+
address?: boolean; // Should we include the address of the account in the message
|
|
86
|
+
application?: boolean; // Should we include the domain of the dapp
|
|
87
|
+
chainId?: boolean; // Should we include the current chain id the wallet is connected to
|
|
88
|
+
message: string; // The message to be signed and displayed to the user
|
|
89
|
+
nonce: string; // A nonce the dapp should generate
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface SignMessageResponse {
|
|
93
|
+
address: string;
|
|
94
|
+
application: string;
|
|
95
|
+
chainId: number;
|
|
96
|
+
fullMessage: string; // The message that was generated to sign
|
|
97
|
+
message: string; // The message passed in by the user
|
|
98
|
+
nonce: string;
|
|
99
|
+
prefix: "APTOS"; // Should always be APTOS
|
|
100
|
+
signature: string; // The signed full message
|
|
101
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { WalletName } from "../types";
|
|
2
|
+
|
|
3
|
+
const LOCAL_STORAGE_ITEM_KEY = "AptosWalletName";
|
|
4
|
+
|
|
5
|
+
export function setLocalStorage(walletName: WalletName) {
|
|
6
|
+
localStorage.setItem(LOCAL_STORAGE_ITEM_KEY, walletName);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function removeLocalStorage() {
|
|
10
|
+
localStorage.removeItem(LOCAL_STORAGE_ITEM_KEY);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getLocalStorage() {
|
|
14
|
+
localStorage.getItem(LOCAL_STORAGE_ITEM_KEY);
|
|
15
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export function scopePollingDetectionStrategy(detect: () => boolean): void {
|
|
2
|
+
// Early return when server-side rendering
|
|
3
|
+
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
4
|
+
|
|
5
|
+
const disposers: (() => void)[] = [];
|
|
6
|
+
|
|
7
|
+
function detectAndDispose() {
|
|
8
|
+
const detected = detect();
|
|
9
|
+
if (detected) {
|
|
10
|
+
for (const dispose of disposers) {
|
|
11
|
+
dispose();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Strategy #1: Try detecting every second.
|
|
17
|
+
const interval =
|
|
18
|
+
// TODO: #334 Replace with idle callback strategy.
|
|
19
|
+
setInterval(detectAndDispose, 1000);
|
|
20
|
+
disposers.push(() => clearInterval(interval));
|
|
21
|
+
|
|
22
|
+
// Strategy #2: Detect as soon as the DOM becomes 'ready'/'interactive'.
|
|
23
|
+
if (
|
|
24
|
+
// Implies that `DOMContentLoaded` has not yet fired.
|
|
25
|
+
document.readyState === "loading"
|
|
26
|
+
) {
|
|
27
|
+
document.addEventListener("DOMContentLoaded", detectAndDispose, {
|
|
28
|
+
once: true,
|
|
29
|
+
});
|
|
30
|
+
disposers.push(() =>
|
|
31
|
+
document.removeEventListener("DOMContentLoaded", detectAndDispose)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Strategy #3: Detect after the `window` has fully loaded.
|
|
36
|
+
if (
|
|
37
|
+
// If the `complete` state has been reached, we're too late.
|
|
38
|
+
document.readyState !== "complete"
|
|
39
|
+
) {
|
|
40
|
+
window.addEventListener("load", detectAndDispose, { once: true });
|
|
41
|
+
disposers.push(() => window.removeEventListener("load", detectAndDispose));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Strategy #4: Detect synchronously, now.
|
|
45
|
+
detectAndDispose();
|
|
46
|
+
}
|