@tomo-inc/inject-providers 0.0.1
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/CHANGELOG.md +3 -0
- package/README.md +58 -0
- package/eth-rpc-errors.d.ts +37 -0
- package/package.json +41 -0
- package/project.json +59 -0
- package/src/btc/index.ts +3 -0
- package/src/btc/types.ts +38 -0
- package/src/btc/unisat.ts +332 -0
- package/src/const.ts +0 -0
- package/src/dogecoin/dogecoin.ts +304 -0
- package/src/dogecoin/index.ts +3 -0
- package/src/dogecoin/types.ts +38 -0
- package/src/evm/index.ts +3 -0
- package/src/evm/messages.ts +39 -0
- package/src/evm/metamask.ts +890 -0
- package/src/evm/shimWeb3.ts +49 -0
- package/src/evm/type.ts +81 -0
- package/src/evm/utils.ts +85 -0
- package/src/global.d.ts +37 -0
- package/src/index.ts +7 -0
- package/src/solana/index.ts +3 -0
- package/src/solana/phantom.ts +424 -0
- package/src/solana/types.ts +63 -0
- package/src/solana/utils.ts +30 -0
- package/src/tron/index.ts +3 -0
- package/src/tron/tronLink.ts +341 -0
- package/src/tron/types.ts +56 -0
- package/src/types/dapp.ts +7 -0
- package/src/types/index.ts +34 -0
- package/src/utils/dapp-info.ts +96 -0
- package/src/utils/dom.ts +29 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/ready-promise.ts +44 -0
- package/src/utils/utils.ts +23 -0
- package/src/utils.ts +35 -0
- package/tsconfig.json +7 -0
- package/tsup.config.ts +10 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Cluster, VersionedTransaction, Transaction, PublicKey } from "@solana/web3.js";
|
|
2
|
+
|
|
3
|
+
// solana standard data define.
|
|
4
|
+
|
|
5
|
+
export interface SignInParams {
|
|
6
|
+
domain?: string;
|
|
7
|
+
statement?: string;
|
|
8
|
+
nonce?: string;
|
|
9
|
+
chainId?: string;
|
|
10
|
+
version?: string;
|
|
11
|
+
issuedAt?: string;
|
|
12
|
+
resources?: string[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface IPhantomProvider {
|
|
16
|
+
_isUnlocked: boolean;
|
|
17
|
+
name: string;
|
|
18
|
+
icon: string;
|
|
19
|
+
publicKey: PublicKey | null;
|
|
20
|
+
chainIds: string[];
|
|
21
|
+
|
|
22
|
+
// APIs
|
|
23
|
+
connect(params?: { onlyIfTrusted: boolean }): Promise<any>;
|
|
24
|
+
disconnect(): Promise<any>;
|
|
25
|
+
getAccount(): Promise<any>;
|
|
26
|
+
signMessage(message: Uint8Array, display: "utf8" | "hex"): Promise<any>;
|
|
27
|
+
signIn(params?: SignInParams): Promise<any>;
|
|
28
|
+
signTransaction(tx: VersionedTransaction | Transaction): Promise<any>;
|
|
29
|
+
signAllTransactions(txs: (VersionedTransaction | Transaction)[]): Promise<any>;
|
|
30
|
+
signAndSendTransaction(tx: VersionedTransaction | Transaction): Promise<any>;
|
|
31
|
+
signAndSendAllTransactions(txs: (VersionedTransaction | Transaction)[]): Promise<any>;
|
|
32
|
+
sendSolana(tx: OriginTransaction): Promise<any>;
|
|
33
|
+
sendToken(tx: OriginTransaction): Promise<any>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type SignInInput = {
|
|
37
|
+
domain?: string;
|
|
38
|
+
statement?: string;
|
|
39
|
+
version?: string;
|
|
40
|
+
nonce?: string;
|
|
41
|
+
chainId?: Cluster;
|
|
42
|
+
issuedAt?: string;
|
|
43
|
+
resources?: `https://${string}`[];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export interface SolanaChainInfo {
|
|
47
|
+
id: Cluster;
|
|
48
|
+
name: string;
|
|
49
|
+
rpcUrl: string;
|
|
50
|
+
explorer: string;
|
|
51
|
+
symbol: string;
|
|
52
|
+
decimals: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface OriginTransaction {
|
|
56
|
+
from: string;
|
|
57
|
+
to: string;
|
|
58
|
+
amount: number;
|
|
59
|
+
tokenAddress?: string;
|
|
60
|
+
decimals?: number;
|
|
61
|
+
priorityFee?: number;
|
|
62
|
+
chainId?: Cluster;
|
|
63
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Transaction, VersionedTransaction } from "@solana/web3.js";
|
|
2
|
+
|
|
3
|
+
export const txToHex = (tx: VersionedTransaction | Transaction) => {
|
|
4
|
+
if (typeof tx === "string") {
|
|
5
|
+
return tx;
|
|
6
|
+
}
|
|
7
|
+
if ((tx as VersionedTransaction)?.message && (tx as VersionedTransaction)?.signatures.length > 0) {
|
|
8
|
+
return Buffer.from(tx.serialize()).toString("hex");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return Buffer.from(
|
|
12
|
+
tx.serialize({
|
|
13
|
+
requireAllSignatures: false,
|
|
14
|
+
verifySignatures: false,
|
|
15
|
+
}),
|
|
16
|
+
).toString("hex");
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const hexToTx = (hexString: string): Transaction | VersionedTransaction => {
|
|
20
|
+
try {
|
|
21
|
+
const buffer = Buffer.from(hexString, "hex");
|
|
22
|
+
try {
|
|
23
|
+
return VersionedTransaction.deserialize(buffer);
|
|
24
|
+
} catch (e) {
|
|
25
|
+
return Transaction.from(buffer);
|
|
26
|
+
}
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(`Failed to deserialize transaction: ${error}`);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { ethErrors } from "eth-rpc-errors";
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
import { TronWeb } from "tronweb";
|
|
4
|
+
import type { Transaction } from "tronweb/lib/esm/types/Transaction";
|
|
5
|
+
|
|
6
|
+
import { ChainTypes, IConnectors, IProductInfo } from "../types";
|
|
7
|
+
import { ReadyPromise, domReadyCall, getDappInfo } from "../utils/index";
|
|
8
|
+
|
|
9
|
+
const chainType = ChainTypes.TRON;
|
|
10
|
+
|
|
11
|
+
interface StateProvider {
|
|
12
|
+
accounts: any[] | null;
|
|
13
|
+
isConnected: boolean;
|
|
14
|
+
isUnlocked: boolean;
|
|
15
|
+
initialized: boolean;
|
|
16
|
+
isPermanentlyDisconnected: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class TomoTronProvider extends EventEmitter {
|
|
20
|
+
_isUnlocked = false;
|
|
21
|
+
name = "";
|
|
22
|
+
icon = "";
|
|
23
|
+
ready = false;
|
|
24
|
+
tronWeb: TronWeb | null = null;
|
|
25
|
+
sendRequest: (chainType: string, data: any) => void;
|
|
26
|
+
onResponse: any;
|
|
27
|
+
events = {
|
|
28
|
+
connect: true,
|
|
29
|
+
disconnect: true,
|
|
30
|
+
accountChanged: true,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
_state: StateProvider = {
|
|
34
|
+
accounts: null,
|
|
35
|
+
isConnected: false,
|
|
36
|
+
isUnlocked: false,
|
|
37
|
+
initialized: false,
|
|
38
|
+
isPermanentlyDisconnected: false,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// private _pushEventHandlers: PushEventHandlers;
|
|
42
|
+
private _requestPromise = new ReadyPromise(0);
|
|
43
|
+
|
|
44
|
+
constructor(productInfo: IProductInfo, { sendRequest, onResponse }: IConnectors) {
|
|
45
|
+
super();
|
|
46
|
+
|
|
47
|
+
this.setMaxListeners(100);
|
|
48
|
+
this.name = productInfo.name;
|
|
49
|
+
this.icon = productInfo.icon;
|
|
50
|
+
this.sendRequest = sendRequest;
|
|
51
|
+
this.onResponse = onResponse;
|
|
52
|
+
|
|
53
|
+
this.initialize();
|
|
54
|
+
this._handleAccountsChanged = this._handleAccountsChanged.bind(this);
|
|
55
|
+
// this._pushEventHandlers = new PushEventHandlers(this);
|
|
56
|
+
|
|
57
|
+
this.on("connect", (res: any) => {
|
|
58
|
+
this._state.isConnected = true;
|
|
59
|
+
|
|
60
|
+
this._initTronWeb(res);
|
|
61
|
+
|
|
62
|
+
window.postMessage(
|
|
63
|
+
{
|
|
64
|
+
message: {
|
|
65
|
+
action: "connect",
|
|
66
|
+
data: res,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
window.location.origin,
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
this.on("disconnect", (result: any) => {
|
|
74
|
+
this._state.isConnected = false;
|
|
75
|
+
|
|
76
|
+
this.tronWeb = null;
|
|
77
|
+
|
|
78
|
+
window.postMessage(
|
|
79
|
+
{
|
|
80
|
+
message: {
|
|
81
|
+
action: "disconnect",
|
|
82
|
+
data: result,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
window.location.origin,
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
this.on("accountChanged", (address: any) => {
|
|
90
|
+
window.postMessage(
|
|
91
|
+
{
|
|
92
|
+
message: {
|
|
93
|
+
action: "accountChanged",
|
|
94
|
+
data: {
|
|
95
|
+
address,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
window.location.origin,
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private _initTronWeb = async (res: any) => {
|
|
105
|
+
const { fullHost = "https://api.trongrid.io", address } = res || {};
|
|
106
|
+
this.tronWeb = new TronWeb({
|
|
107
|
+
fullHost,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
this.tronWeb.defaultAddress.base58 = address;
|
|
111
|
+
this.tronWeb.defaultAddress.hex = TronWeb.address.toHex(address);
|
|
112
|
+
|
|
113
|
+
(this.tronWeb as any)["request"] = async ({ method, params }: any) => {
|
|
114
|
+
return await this.request({ method, params });
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const trx = this.tronWeb.trx;
|
|
118
|
+
this.tronWeb.trx = new Proxy(trx, {
|
|
119
|
+
get: (target: any, prop: string) => {
|
|
120
|
+
switch (prop) {
|
|
121
|
+
case "sign":
|
|
122
|
+
case "signMessage":
|
|
123
|
+
throw new Error("Not supported");
|
|
124
|
+
case "signMessageV2":
|
|
125
|
+
return async (message: string, privateKey?: string) => {
|
|
126
|
+
return await this.signMessage(message);
|
|
127
|
+
};
|
|
128
|
+
case "multiSign":
|
|
129
|
+
return async (transaction: Transaction, privateKey?: string) => {
|
|
130
|
+
const signedTransaction = await this.signTransaction(transaction);
|
|
131
|
+
return signedTransaction;
|
|
132
|
+
};
|
|
133
|
+
case "sendTransaction":
|
|
134
|
+
return async (to: string, amount: number) => {
|
|
135
|
+
const signedTransaction = await this.sendTransaction({ from: address, to, amount });
|
|
136
|
+
return signedTransaction;
|
|
137
|
+
};
|
|
138
|
+
case "sendToken":
|
|
139
|
+
return async (to: string, amount: number, tokenId: string) => {
|
|
140
|
+
const signedTransaction = await this.sendToken({ from: address, to, amount, tokenAddress: tokenId });
|
|
141
|
+
return signedTransaction;
|
|
142
|
+
};
|
|
143
|
+
// case "sendRawTransaction":
|
|
144
|
+
// return async (transaction: Transaction, privateKey?: string) => {
|
|
145
|
+
// const res = await this.sendRawTransaction(transaction);
|
|
146
|
+
// return res;
|
|
147
|
+
// };
|
|
148
|
+
default:
|
|
149
|
+
return Reflect.get(target, prop);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
initialize = async () => {
|
|
156
|
+
//dapp tab switch send data;
|
|
157
|
+
document.addEventListener("visibilitychange", async () => {
|
|
158
|
+
if (document.visibilityState === "visible") {
|
|
159
|
+
this._request({
|
|
160
|
+
method: "wallet_sendDomainMetadata",
|
|
161
|
+
params: await getDappInfo(),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// this._bcm.connect().on("message", this._handleBackgroundMessage);
|
|
167
|
+
domReadyCall(async () => {
|
|
168
|
+
this._request({
|
|
169
|
+
method: "wallet_sendDomainMetadata",
|
|
170
|
+
params: await getDappInfo(),
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
window.addEventListener("message", (event: MessageEvent<any>) => {
|
|
175
|
+
const { data, type, method } = event.data;
|
|
176
|
+
if (type === "subscribeWalletEvents" && method) {
|
|
177
|
+
this.subscribeWalletEventsCallback({ data, method });
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
this._state.initialized = true;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
subscribeWalletEventsCallback = ({ method, data }: { method: string; data: any }) => {
|
|
185
|
+
if (method === "accountsChanged") {
|
|
186
|
+
const accounts = data?.[chainType];
|
|
187
|
+
this._handleAccountsChanged(accounts);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
on(eventName: string, listener: (...args: unknown[]) => void) {
|
|
192
|
+
if (!this.events[eventName as keyof typeof this.events]) {
|
|
193
|
+
throw Error("${eventName} no supported.");
|
|
194
|
+
}
|
|
195
|
+
return super.on(eventName, listener);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private _handleAccountsChanged(accounts: any[]): void {
|
|
199
|
+
let _accounts = accounts;
|
|
200
|
+
|
|
201
|
+
if (!Array.isArray(accounts)) {
|
|
202
|
+
console.error(`${this.name}: Received invalid accounts parameter.`, accounts);
|
|
203
|
+
_accounts = [];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (this._state.accounts !== _accounts) {
|
|
207
|
+
this._state.accounts = _accounts;
|
|
208
|
+
|
|
209
|
+
const { address } = _accounts[0] || {};
|
|
210
|
+
|
|
211
|
+
// finally, after all state has been updated, emit the event
|
|
212
|
+
if (this._state.initialized) {
|
|
213
|
+
this.emit("accountChanged", address);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
_request = async (data: any, responseAdaptor?: any) => {
|
|
219
|
+
if (!data || !data.method) {
|
|
220
|
+
throw ethErrors.rpc.invalidRequest();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const dappInfo = await getDappInfo();
|
|
224
|
+
|
|
225
|
+
this.sendRequest(chainType, { ...data, dappInfo });
|
|
226
|
+
|
|
227
|
+
return this.onResponse(data).then((res: any) => {
|
|
228
|
+
const { data, method } = res || {};
|
|
229
|
+
if (method === "tron_requestAccounts") {
|
|
230
|
+
this.emit("connect", data);
|
|
231
|
+
}
|
|
232
|
+
if (responseAdaptor) {
|
|
233
|
+
return responseAdaptor(data);
|
|
234
|
+
}
|
|
235
|
+
return data;
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
request = async ({ method, params }: { method: string; params: any }, responseAdaptor?: any) => {
|
|
240
|
+
return this._request(
|
|
241
|
+
{
|
|
242
|
+
method,
|
|
243
|
+
params,
|
|
244
|
+
},
|
|
245
|
+
responseAdaptor,
|
|
246
|
+
);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
//tronLink api
|
|
250
|
+
connect = async () => {
|
|
251
|
+
return this._request(
|
|
252
|
+
{
|
|
253
|
+
method: "connect",
|
|
254
|
+
},
|
|
255
|
+
(data: any) => {
|
|
256
|
+
this.emit("connect", data);
|
|
257
|
+
this.ready = true;
|
|
258
|
+
return data;
|
|
259
|
+
},
|
|
260
|
+
);
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
disconnect = async () => {
|
|
264
|
+
return this._request(
|
|
265
|
+
{
|
|
266
|
+
method: "disconnect",
|
|
267
|
+
},
|
|
268
|
+
(data: any) => {
|
|
269
|
+
this.emit("disconnect", true);
|
|
270
|
+
this.ready = false;
|
|
271
|
+
return data;
|
|
272
|
+
},
|
|
273
|
+
);
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
signMessage = async (message: string) => {
|
|
277
|
+
return this._request(
|
|
278
|
+
{
|
|
279
|
+
method: "signMessage",
|
|
280
|
+
params: {
|
|
281
|
+
message,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
(data: any) => {
|
|
285
|
+
return data;
|
|
286
|
+
},
|
|
287
|
+
);
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
signTransaction = async (transaction: Transaction) => {
|
|
291
|
+
return this._request(
|
|
292
|
+
{
|
|
293
|
+
method: "signTransaction",
|
|
294
|
+
params: {
|
|
295
|
+
transaction,
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
(data: any) => {
|
|
299
|
+
return data;
|
|
300
|
+
},
|
|
301
|
+
);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
sendRawTransaction = async (transaction: Transaction) => {
|
|
305
|
+
return this._request(
|
|
306
|
+
{
|
|
307
|
+
method: "sendRawTransaction",
|
|
308
|
+
params: {
|
|
309
|
+
transaction,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
(data: any) => {
|
|
313
|
+
return data;
|
|
314
|
+
},
|
|
315
|
+
);
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
sendTransaction = async (params: any) => {
|
|
319
|
+
return this._request(
|
|
320
|
+
{
|
|
321
|
+
method: "sendTransaction",
|
|
322
|
+
params,
|
|
323
|
+
},
|
|
324
|
+
(data: any) => {
|
|
325
|
+
return data;
|
|
326
|
+
},
|
|
327
|
+
);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
sendToken = async (params: any) => {
|
|
331
|
+
return this._request(
|
|
332
|
+
{
|
|
333
|
+
method: "sendToken",
|
|
334
|
+
params,
|
|
335
|
+
},
|
|
336
|
+
(data: any) => {
|
|
337
|
+
return data;
|
|
338
|
+
},
|
|
339
|
+
);
|
|
340
|
+
};
|
|
341
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Transaction, SignedTransaction } from "tronweb/lib/esm/types/Transaction";
|
|
2
|
+
import type { TronLinkWallet } from "@tronweb3/tronwallet-adapter-tronlink"; // Import TronLink wallet class
|
|
3
|
+
|
|
4
|
+
export interface ITomoTronProvider extends TronLinkWallet {
|
|
5
|
+
address: string | null;
|
|
6
|
+
connect(options?: Record<string, unknown>): Promise<void | any>;
|
|
7
|
+
disconnect(): Promise<void | any>;
|
|
8
|
+
signMessage(message: string, privateKey?: string): Promise<any>;
|
|
9
|
+
signTransaction(transaction: Transaction, privateKey?: string): Promise<SignedTransaction>;
|
|
10
|
+
switchChain?: (chainId: string) => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export enum SupportedTronRequestMethods {
|
|
14
|
+
tron_requestAccounts = "tron_requestAccounts",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//https://docs.tronlink.org/tronlink-wallet-extension/request-tronlink-extension/connect-website
|
|
18
|
+
//https://docs.tronlink.org/tronlink-app/deeplink/result-code
|
|
19
|
+
export enum ResponseCode {
|
|
20
|
+
UNKNOWN_REASON = -1,
|
|
21
|
+
SUCCESS = 200,
|
|
22
|
+
REPEAT_REQUEST = 4000,
|
|
23
|
+
NOT_CONNECTED = 4100,
|
|
24
|
+
USER_REJECTED = 4001,
|
|
25
|
+
METHOD_NOT_SUPPORTED = 4200,
|
|
26
|
+
INVALID_PARAMS = 4300,
|
|
27
|
+
|
|
28
|
+
INCORRECT_JSON = 10001,
|
|
29
|
+
MISSING_ACTION = 10002,
|
|
30
|
+
UNKNOWN_ACTION = 10003,
|
|
31
|
+
MISSING_ACTIONID = 10004,
|
|
32
|
+
INCORRECT_DAPP_URL = 10005,
|
|
33
|
+
INCORRECT_CALLBACKURL = 10006,
|
|
34
|
+
EMPTY_DAPP_NAME = 10007,
|
|
35
|
+
VERSION_NUMBER_NOT_SUPPORTED = 10008,
|
|
36
|
+
CURRENT_NETWORK_NOT_SUPPORTED = 10009,
|
|
37
|
+
THE_URL_IS_NOT_SUPPORTED_TO_OPEN_TRONLINK = 10010,
|
|
38
|
+
UNKNOWN_SIGNTYPE = 10011,
|
|
39
|
+
INCORRECT_TRANSACTION_FORMAT = 10012,
|
|
40
|
+
INCORRECT_METHOD_FORMAT = 10013,
|
|
41
|
+
INCORRECT_MESSAGE_FORMAT = 10014,
|
|
42
|
+
INCORRECT_TOADDRESS = 10015,
|
|
43
|
+
NO_WALLET_CREATED_IN_TRONLINK = 10016,
|
|
44
|
+
INCORRECT_FROMADDRESS = 10017,
|
|
45
|
+
INCORRECT_CONTACTADDRESS = 10018,
|
|
46
|
+
INCORRECT_CHAINID = 10019,
|
|
47
|
+
INCORRECT_AMOUNT = 10020,
|
|
48
|
+
THE_INITIATING_ADDRESS_DOES_NOT_MATCH_THE_CURRENT_WALLET = 10021,
|
|
49
|
+
INCORRECT_LOGINADDRESS = 10022,
|
|
50
|
+
SYSTEM_CONTRACT_NOT_SUPPORT = 10023,
|
|
51
|
+
INCORRECT_TOKENID = 10024,
|
|
52
|
+
TOKENID_CONTRACT_ADDRESS_SHOULD_NOT_BE_EXIST_TOGETHER = 10025,
|
|
53
|
+
TRANSACTION_CANCELED = 300,
|
|
54
|
+
TRANSACTION_EXECUTED_IN_TRONLINK = 301,
|
|
55
|
+
BROADCAST_FAILURE = 302,
|
|
56
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export * from "./dapp";
|
|
2
|
+
|
|
3
|
+
export interface IProductInfo {
|
|
4
|
+
name: string;
|
|
5
|
+
rdns: string;
|
|
6
|
+
icon: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IWalletNamespaces {
|
|
10
|
+
global: string;
|
|
11
|
+
doge: string;
|
|
12
|
+
evm: string;
|
|
13
|
+
solana?: string;
|
|
14
|
+
tron?: string;
|
|
15
|
+
btc?: string;
|
|
16
|
+
shop?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface IConnectors {
|
|
20
|
+
sendRequest: (chainType: string, data: any) => void;
|
|
21
|
+
onResponse: (data: any) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export enum ChainTypes {
|
|
25
|
+
BTC = "btc",
|
|
26
|
+
DOGE = "doge",
|
|
27
|
+
EVM = "evm",
|
|
28
|
+
SOL = "sol",
|
|
29
|
+
SUI = "sui",
|
|
30
|
+
TON = "ton",
|
|
31
|
+
TRON = "tron",
|
|
32
|
+
COSMOS = "cosmos",
|
|
33
|
+
APTOS = "aptos",
|
|
34
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const $ = document.querySelector.bind(document);
|
|
2
|
+
|
|
3
|
+
export async function getDappInfo() {
|
|
4
|
+
return {
|
|
5
|
+
origin: window.top?.location.origin,
|
|
6
|
+
// host: window.location.hostname,
|
|
7
|
+
favicon: await getSiteIcon(window),
|
|
8
|
+
title: getSiteName(window),
|
|
9
|
+
desc: getSiteDesc(window),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Extracts a name for the site from the DOM
|
|
15
|
+
*/
|
|
16
|
+
function getSiteName(windowObject: typeof window): string {
|
|
17
|
+
const { document } = windowObject;
|
|
18
|
+
|
|
19
|
+
const siteName: HTMLMetaElement | null = document.querySelector('head > meta[property="og:site_name"]');
|
|
20
|
+
if (siteName) {
|
|
21
|
+
return siteName.content;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const metaTitle: HTMLMetaElement | null = document.querySelector('head > meta[name="title"]');
|
|
25
|
+
if (metaTitle) {
|
|
26
|
+
return metaTitle.content;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (document.title && document.title.length > 0) {
|
|
30
|
+
return document.title;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return window.location.hostname;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getSiteDesc(windowObject: typeof window): string {
|
|
37
|
+
const { document } = windowObject;
|
|
38
|
+
|
|
39
|
+
const siteName: HTMLMetaElement | null = document.querySelector('head > meta[property="og:description"]');
|
|
40
|
+
if (siteName) {
|
|
41
|
+
return siteName.content;
|
|
42
|
+
}
|
|
43
|
+
const siteNameX: HTMLMetaElement | null = document.querySelector('head > meta[property="twitter:description"]');
|
|
44
|
+
if (siteNameX) {
|
|
45
|
+
return siteNameX.content;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const metaTitle: HTMLMetaElement | null = document.querySelector('head > meta[name="description"]');
|
|
49
|
+
if (metaTitle) {
|
|
50
|
+
return metaTitle.content;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (document.title && document.title.length > 0) {
|
|
54
|
+
return document.title;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return document.body.innerText.split("\n")[0] || "";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Extracts an icon for the site from the DOM
|
|
62
|
+
* @returns an icon URL
|
|
63
|
+
*/
|
|
64
|
+
async function getSiteIcon(windowObject: typeof window): Promise<string | null> {
|
|
65
|
+
const { document } = windowObject;
|
|
66
|
+
|
|
67
|
+
const icon =
|
|
68
|
+
($('head > link[rel~="icon"]') as HTMLLinkElement)?.href ||
|
|
69
|
+
($('head > meta[itemprop="image"]') as HTMLMetaElement)?.content;
|
|
70
|
+
if (!icon) {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
const isOK = await imgExists(icon);
|
|
74
|
+
if (isOK) {
|
|
75
|
+
return icon;
|
|
76
|
+
}
|
|
77
|
+
return "";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Returns whether the given image URL exists
|
|
82
|
+
* @param url - the url of the image
|
|
83
|
+
* @returns Whether the image exists.
|
|
84
|
+
*/
|
|
85
|
+
function imgExists(url: string): Promise<boolean> {
|
|
86
|
+
return new Promise((resolve, reject) => {
|
|
87
|
+
try {
|
|
88
|
+
const img = document.createElement("img");
|
|
89
|
+
img.onload = () => resolve(true);
|
|
90
|
+
img.onerror = () => resolve(false);
|
|
91
|
+
img.src = url;
|
|
92
|
+
} catch (e) {
|
|
93
|
+
reject(e);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
package/src/utils/dom.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
let tryCount = 0;
|
|
2
|
+
const checkLoaded = (callback: () => void) => {
|
|
3
|
+
tryCount++;
|
|
4
|
+
if (tryCount > 600) {
|
|
5
|
+
// some error happen?
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
if (document.readyState === "complete") {
|
|
9
|
+
callback();
|
|
10
|
+
return true;
|
|
11
|
+
} else {
|
|
12
|
+
setTimeout(() => {
|
|
13
|
+
checkLoaded(callback);
|
|
14
|
+
}, 100);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
export const domReadyCall = (callback: () => void) => {
|
|
18
|
+
// checkLoaded(callback);
|
|
19
|
+
|
|
20
|
+
if (document.readyState === "complete") {
|
|
21
|
+
callback();
|
|
22
|
+
} else {
|
|
23
|
+
const domContentLoadedHandler = (e: Event) => {
|
|
24
|
+
callback();
|
|
25
|
+
document.removeEventListener("DOMContentLoaded", domContentLoadedHandler);
|
|
26
|
+
};
|
|
27
|
+
document.addEventListener("DOMContentLoaded", domContentLoadedHandler);
|
|
28
|
+
}
|
|
29
|
+
};
|