@hot-labs/kit 1.0.56 → 1.1.0-beta.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.
Files changed (214) hide show
  1. package/README.md +2 -9
  2. package/build/HotConnector.d.ts +6 -6
  3. package/build/HotConnector.js +18 -23
  4. package/build/HotConnector.js.map +1 -1
  5. package/build/OmniConnector.d.ts +4 -0
  6. package/build/OmniConnector.js +5 -5
  7. package/build/OmniConnector.js.map +1 -1
  8. package/build/OmniWallet.d.ts +10 -17
  9. package/build/OmniWallet.js +14 -19
  10. package/build/OmniWallet.js.map +1 -1
  11. package/build/core/Intents.d.ts +23 -39
  12. package/build/core/Intents.js +104 -115
  13. package/build/core/Intents.js.map +1 -1
  14. package/build/core/api.d.ts +1 -0
  15. package/build/core/api.js +10 -2
  16. package/build/core/api.js.map +1 -1
  17. package/build/core/bridge.js +1 -1
  18. package/build/core/bridge.js.map +1 -1
  19. package/build/core/chains.js +1 -1
  20. package/build/core/chains.js.map +1 -1
  21. package/build/core/index.d.ts +1 -1
  22. package/build/core/index.js +1 -1
  23. package/build/core/index.js.map +1 -1
  24. package/build/core/types.d.ts +17 -0
  25. package/build/core/utils.d.ts +1 -0
  26. package/build/core/utils.js +10 -0
  27. package/build/core/utils.js.map +1 -1
  28. package/build/cosmos/connector.js +2 -2
  29. package/build/cosmos/connector.js.map +1 -1
  30. package/build/cosmos/wallet.d.ts +2 -4
  31. package/build/cosmos/wallet.js +3 -8
  32. package/build/cosmos/wallet.js.map +1 -1
  33. package/build/evm/connector.d.ts +2 -3
  34. package/build/evm/connector.js +7 -11
  35. package/build/evm/connector.js.map +1 -1
  36. package/build/evm/injected.js +3 -3
  37. package/build/evm/injected.js.map +1 -1
  38. package/build/evm/wallet.d.ts +2 -1
  39. package/build/evm/wallet.js +7 -5
  40. package/build/evm/wallet.js.map +1 -1
  41. package/build/exchange.d.ts +4 -1
  42. package/build/exchange.js +21 -20
  43. package/build/exchange.js.map +1 -1
  44. package/build/hot-wallet/google.js +10 -5
  45. package/build/hot-wallet/google.js.map +1 -1
  46. package/build/hot-wallet/iframe.d.ts +36 -3
  47. package/build/hot-wallet/iframe.js +134 -27
  48. package/build/hot-wallet/iframe.js.map +1 -1
  49. package/build/hot-wallet/proxy.d.ts +8 -0
  50. package/build/hot-wallet/proxy.js +45 -0
  51. package/build/hot-wallet/proxy.js.map +1 -0
  52. package/build/index.d.ts +1 -0
  53. package/build/index.js +1 -0
  54. package/build/index.js.map +1 -1
  55. package/build/near/connector.js +2 -2
  56. package/build/near/connector.js.map +1 -1
  57. package/build/{core/nearRpc.d.ts → near/rpc.d.ts} +0 -1
  58. package/build/{core/nearRpc.js → near/rpc.js} +5 -11
  59. package/build/near/rpc.js.map +1 -0
  60. package/build/near/wallet.d.ts +2 -4
  61. package/build/near/wallet.js +4 -9
  62. package/build/near/wallet.js.map +1 -1
  63. package/build/solana/{protocol.d.ts → WalletStandard.d.ts} +1 -1
  64. package/build/solana/{protocol.js → WalletStandard.js} +1 -1
  65. package/build/solana/WalletStandard.js.map +1 -0
  66. package/build/solana/connector.d.ts +1 -1
  67. package/build/solana/connector.js +11 -10
  68. package/build/solana/connector.js.map +1 -1
  69. package/build/solana/injected/account.js +1 -2
  70. package/build/solana/injected/account.js.map +1 -1
  71. package/build/solana/injected/index.js +16 -19
  72. package/build/solana/injected/index.js.map +1 -1
  73. package/build/solana/injected/solana-wallet.js.map +1 -1
  74. package/build/solana/wallet.d.ts +3 -5
  75. package/build/solana/wallet.js +3 -8
  76. package/build/solana/wallet.js.map +1 -1
  77. package/build/solana/{wallets.js → walletStandartList.js} +1 -1
  78. package/build/solana/walletStandartList.js.map +1 -0
  79. package/build/stellar/connector.d.ts +10 -6
  80. package/build/stellar/connector.js +38 -30
  81. package/build/stellar/connector.js.map +1 -1
  82. package/build/stellar/freigher.d.ts +46 -0
  83. package/build/stellar/freigher.js +110 -0
  84. package/build/stellar/freigher.js.map +1 -0
  85. package/build/stellar/{injected.d.ts → hotWallet.d.ts} +1 -6
  86. package/build/stellar/hotWallet.js +28 -0
  87. package/build/stellar/hotWallet.js.map +1 -0
  88. package/build/stellar/wallet.d.ts +10 -8
  89. package/build/stellar/wallet.js +12 -16
  90. package/build/stellar/wallet.js.map +1 -1
  91. package/build/ton/connector.d.ts +0 -1
  92. package/build/ton/connector.js +7 -7
  93. package/build/ton/connector.js.map +1 -1
  94. package/build/ton/injected.js +6 -6
  95. package/build/ton/injected.js.map +1 -1
  96. package/build/ton/wallet.d.ts +2 -3
  97. package/build/ton/wallet.js +3 -4
  98. package/build/ton/wallet.js.map +1 -1
  99. package/build/tron/connector.d.ts +51 -0
  100. package/build/tron/connector.js +65 -0
  101. package/build/tron/connector.js.map +1 -0
  102. package/build/tron/index.d.ts +6 -0
  103. package/build/tron/index.js +5 -0
  104. package/build/tron/index.js.map +1 -0
  105. package/build/tron/wallet.d.ts +52 -0
  106. package/build/tron/wallet.js +122 -0
  107. package/build/tron/wallet.js.map +1 -0
  108. package/build/ui/Popup.js +1 -1
  109. package/build/ui/Popup.js.map +1 -1
  110. package/build/ui/connect/AuthPopup.js +1 -1
  111. package/build/ui/connect/AuthPopup.js.map +1 -1
  112. package/build/ui/connect/ConnectWallet.d.ts +2 -1
  113. package/build/ui/connect/ConnectWallet.js +2 -2
  114. package/build/ui/connect/ConnectWallet.js.map +1 -1
  115. package/build/ui/icons/arrow-right.js +1 -1
  116. package/build/ui/icons/arrow-right.js.map +1 -1
  117. package/build/ui/icons/close.js +1 -1
  118. package/build/ui/icons/close.js.map +1 -1
  119. package/build/ui/icons/exchange.js +1 -1
  120. package/build/ui/icons/exchange.js.map +1 -1
  121. package/build/ui/icons/logout.js +1 -1
  122. package/build/ui/icons/logout.js.map +1 -1
  123. package/build/ui/icons/pending.js +1 -1
  124. package/build/ui/icons/pending.js.map +1 -1
  125. package/build/ui/icons/qr.js +1 -1
  126. package/build/ui/icons/qr.js.map +1 -1
  127. package/build/ui/icons/search.js +1 -1
  128. package/build/ui/icons/search.js.map +1 -1
  129. package/build/ui/icons/switch.js +1 -1
  130. package/build/ui/icons/switch.js.map +1 -1
  131. package/build/ui/icons/wallet.js +1 -1
  132. package/build/ui/icons/wallet.js.map +1 -1
  133. package/build/ui/payment/Bridge.js +7 -2
  134. package/build/ui/payment/Bridge.js.map +1 -1
  135. package/build/ui/payment/Payment.d.ts +16 -8
  136. package/build/ui/payment/Payment.js +116 -21
  137. package/build/ui/payment/Payment.js.map +1 -1
  138. package/build/ui/payment/Profile.js +1 -1
  139. package/build/ui/payment/Profile.js.map +1 -1
  140. package/build/ui/payment/SelectToken.js +1 -1
  141. package/build/ui/payment/SelectToken.js.map +1 -1
  142. package/build/ui/payment/TokenCard.js +1 -1
  143. package/build/ui/payment/TokenCard.js.map +1 -1
  144. package/build/ui/router.d.ts +2 -1
  145. package/build/ui/router.js +2 -2
  146. package/build/ui/router.js.map +1 -1
  147. package/build/ui/styles.js +4 -3
  148. package/build/ui/styles.js.map +1 -1
  149. package/package.json +10 -5
  150. package/src/HotConnector.ts +21 -29
  151. package/src/OmniConnector.ts +9 -9
  152. package/src/OmniWallet.ts +24 -25
  153. package/src/core/Intents.ts +123 -139
  154. package/src/core/api.ts +13 -2
  155. package/src/core/bridge.ts +3 -2
  156. package/src/core/chains.ts +1 -1
  157. package/src/core/index.ts +1 -1
  158. package/src/core/types.ts +21 -0
  159. package/src/core/utils.ts +11 -0
  160. package/src/cosmos/connector.ts +2 -2
  161. package/src/cosmos/wallet.ts +3 -7
  162. package/src/evm/connector.ts +9 -12
  163. package/src/evm/injected.ts +3 -3
  164. package/src/evm/wallet.ts +9 -6
  165. package/src/exchange.ts +20 -20
  166. package/src/hot-wallet/google.ts +12 -5
  167. package/src/hot-wallet/iframe.ts +151 -24
  168. package/src/hot-wallet/proxy.ts +54 -0
  169. package/src/index.ts +2 -0
  170. package/src/near/connector.ts +2 -2
  171. package/src/{core/nearRpc.ts → near/rpc.ts} +4 -11
  172. package/src/near/wallet.ts +4 -9
  173. package/src/solana/{protocol.ts → WalletStandard.ts} +2 -4
  174. package/src/solana/connector.ts +11 -10
  175. package/src/solana/injected/account.ts +1 -2
  176. package/src/solana/injected/index.ts +15 -18
  177. package/src/solana/injected/solana-wallet.ts +6 -6
  178. package/src/solana/wallet.ts +4 -8
  179. package/src/stellar/connector.ts +40 -32
  180. package/src/stellar/freigher.ts +119 -0
  181. package/src/stellar/{injected.ts → hotWallet.ts} +8 -12
  182. package/src/stellar/wallet.ts +17 -17
  183. package/src/ton/connector.ts +15 -15
  184. package/src/ton/injected.ts +6 -6
  185. package/src/ton/wallet.ts +3 -3
  186. package/src/tron/connector.ts +89 -0
  187. package/src/tron/index.ts +7 -0
  188. package/src/tron/wallet.ts +146 -0
  189. package/src/ui/Popup.tsx +7 -3
  190. package/src/ui/connect/AuthPopup.tsx +2 -1
  191. package/src/ui/connect/ConnectWallet.tsx +3 -2
  192. package/src/ui/icons/arrow-right.tsx +2 -2
  193. package/src/ui/icons/close.tsx +1 -1
  194. package/src/ui/icons/exchange.tsx +4 -4
  195. package/src/ui/icons/logout.tsx +6 -6
  196. package/src/ui/icons/pending.tsx +2 -4
  197. package/src/ui/icons/qr.tsx +1 -2
  198. package/src/ui/icons/search.tsx +4 -4
  199. package/src/ui/icons/switch.tsx +4 -4
  200. package/src/ui/icons/wallet.tsx +2 -4
  201. package/src/ui/payment/Bridge.tsx +9 -2
  202. package/src/ui/payment/Payment.tsx +259 -31
  203. package/src/ui/payment/Profile.tsx +10 -8
  204. package/src/ui/payment/SelectToken.tsx +1 -1
  205. package/src/ui/payment/TokenCard.tsx +1 -1
  206. package/src/ui/router.tsx +5 -6
  207. package/src/ui/styles.ts +4 -3
  208. package/build/core/nearRpc.js.map +0 -1
  209. package/build/solana/protocol.js.map +0 -1
  210. package/build/solana/wallets.js.map +0 -1
  211. package/build/stellar/injected.js +0 -32
  212. package/build/stellar/injected.js.map +0 -1
  213. /package/build/solana/{wallets.d.ts → walletStandartList.d.ts} +0 -0
  214. /package/src/solana/{wallets.ts → walletStandartList.ts} +0 -0
package/src/core/types.ts CHANGED
@@ -40,9 +40,30 @@ export interface AuthCallIntent {
40
40
  intent: "auth_call";
41
41
  }
42
42
 
43
+ export interface AddPublicKeyIntent {
44
+ intent: "add_public_key";
45
+ public_key: string;
46
+ }
47
+
48
+ export interface RemovePublicKeyIntent {
49
+ intent: "remove_public_key";
50
+ public_key: string;
51
+ }
52
+
53
+ export interface NftWithdrawIntent {
54
+ intent: "nft_withdraw";
55
+ token_id: string;
56
+ receiver_id: string;
57
+ memo?: string;
58
+ msg?: string;
59
+ min_gas?: string;
60
+ }
61
+
43
62
  export interface Commitment {
44
63
  signature: string;
45
64
  public_key?: string;
46
65
  payload: Record<string, any> | string;
47
66
  standard: string;
48
67
  }
68
+
69
+ export type Intent = TransferIntent | MtWithdrawIntent | FtWithdrawIntent | TokenDiffIntent | AuthCallIntent | AddPublicKeyIntent | RemovePublicKeyIntent | NftWithdrawIntent;
package/src/core/utils.ts CHANGED
@@ -160,4 +160,15 @@ export const formatter = {
160
160
  wait(ms: number) {
161
161
  return new Promise((resolve) => setTimeout(resolve, ms));
162
162
  },
163
+
164
+ chunk(array: any[], size: number) {
165
+ return array.reduce((acc, item, index) => {
166
+ const chunkIndex = Math.floor(index / size);
167
+ if (!acc[chunkIndex]) {
168
+ acc[chunkIndex] = [];
169
+ }
170
+ acc[chunkIndex].push(item);
171
+ return acc;
172
+ }, []);
173
+ },
163
174
  };
@@ -125,7 +125,7 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
125
125
  const address = account.bech32Address;
126
126
 
127
127
  this.setStorage({ type: "walletconnect", id });
128
- const wallet = new CosmosWallet(this, {
128
+ const wallet = new CosmosWallet({
129
129
  address: address,
130
130
  publicKeyHex: publicKey,
131
131
  disconnect: () => this.disconnectWalletConnect(),
@@ -170,7 +170,7 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
170
170
 
171
171
  async setKeplrWallet(keplr: Keplr, address: string, publicKey: string) {
172
172
  return this.setWallet(
173
- new CosmosWallet(this, {
173
+ new CosmosWallet({
174
174
  address: address,
175
175
  publicKeyHex: publicKey,
176
176
  disconnect: () => keplr.disable(),
@@ -13,10 +13,11 @@ interface ProtocolWallet {
13
13
  }
14
14
 
15
15
  export default class CosmosWallet extends OmniWallet {
16
+ readonly icon = "https://legacy.cosmos.network/presskit/cosmos-brandmark-dynamic-dark.svg";
16
17
  readonly type = WalletType.COSMOS;
17
18
 
18
- constructor(readonly connector: CosmosConnector, readonly wallet: ProtocolWallet) {
19
- super(connector);
19
+ constructor(readonly wallet: ProtocolWallet) {
20
+ super();
20
21
  }
21
22
 
22
23
  get address() {
@@ -31,11 +32,6 @@ export default class CosmosWallet extends OmniWallet {
31
32
  return "";
32
33
  }
33
34
 
34
- async disconnect() {
35
- super.disconnect();
36
- this.wallet.disconnect?.();
37
- }
38
-
39
35
  sendTransaction(signDoc: any): Promise<string> {
40
36
  if (!this.wallet.sendTransaction) throw "Not impl";
41
37
  return this.wallet.sendTransaction(signDoc);
@@ -1,10 +1,10 @@
1
- import MetaMaskSDK from "@metamask/sdk";
2
1
  import { runInAction } from "mobx";
3
2
 
4
- import { ConnectorType, OmniConnector, WC_ICON } from "../OmniConnector";
3
+ import HOT from "../hot-wallet/iframe";
5
4
  import { Network, WalletType } from "../core/chains";
6
- import { isInjected } from "../hot-wallet/iframe";
5
+ import { ConnectorType, OmniConnector, WC_ICON } from "../OmniConnector";
7
6
  import { HotConnector } from "../HotConnector";
7
+
8
8
  import EvmWallet, { EvmProvider } from "./wallet";
9
9
 
10
10
  class EvmConnector extends OmniConnector<EvmWallet, { provider: EvmProvider }> {
@@ -14,14 +14,6 @@ class EvmConnector extends OmniConnector<EvmWallet, { provider: EvmProvider }> {
14
14
  name = "EVM Wallet";
15
15
  id = "evm";
16
16
 
17
- MMSDK = new MetaMaskSDK({
18
- dappMetadata: {
19
- name: "Wibe3",
20
- url: window.location.href,
21
- // iconUrl: "https://mydapp.com/icon.png" // Optional
22
- },
23
- });
24
-
25
17
  constructor(wibe3: HotConnector) {
26
18
  super(wibe3);
27
19
 
@@ -104,7 +96,7 @@ class EvmConnector extends OmniConnector<EvmWallet, { provider: EvmProvider }> {
104
96
  }
105
97
 
106
98
  async getConnectedWallet() {
107
- if (isInjected()) return { type: "wallet", id: "org.hot-labs" };
99
+ if (HOT.isInjected) return { type: "wallet", id: "org.hot-labs" };
108
100
  return await this.getStorage();
109
101
  }
110
102
 
@@ -129,6 +121,11 @@ class EvmConnector extends OmniConnector<EvmWallet, { provider: EvmProvider }> {
129
121
 
130
122
  return await this.connectWallet(id, wallet.provider);
131
123
  }
124
+
125
+ async disconnect() {
126
+ this.wallets.forEach((w) => w.disconnect());
127
+ super.disconnect();
128
+ }
132
129
  }
133
130
 
134
131
  export default EvmConnector;
@@ -1,4 +1,4 @@
1
- import { isInjected, requestHot } from "../hot-wallet/iframe";
1
+ import HOT from "../hot-wallet/iframe";
2
2
 
3
3
  class HotEvmProvider {
4
4
  _events = new Map<string, Set<any>>();
@@ -6,7 +6,7 @@ class HotEvmProvider {
6
6
  isHotWallet = true;
7
7
  isMetaMask = true;
8
8
 
9
- request = (request: any) => requestHot("ethereum", request);
9
+ request = (request: any) => HOT.request("ethereum", request);
10
10
  removeListener() {}
11
11
  on() {}
12
12
  }
@@ -31,7 +31,7 @@ function announceProvider(provider: HotEvmProvider) {
31
31
  );
32
32
  }
33
33
 
34
- if (isInjected()) {
34
+ if (HOT.isInjected) {
35
35
  const hotProvider = new HotEvmProvider();
36
36
  window.addEventListener("eip6963:requestProvider", () => announceProvider(hotProvider));
37
37
  announceProvider(hotProvider);
package/src/evm/wallet.ts CHANGED
@@ -22,7 +22,15 @@ class EvmWallet extends OmniWallet {
22
22
  readonly type = WalletType.EVM;
23
23
 
24
24
  constructor(readonly connector: OmniConnector, readonly address: string, readonly provider: EvmProvider) {
25
- super(connector);
25
+ super();
26
+ }
27
+
28
+ async disconnect() {
29
+ await this.provider.request?.({ method: "wallet_revokePermissions", params: [{ eth_accounts: {} }] });
30
+ }
31
+
32
+ get icon() {
33
+ return this.connector.icon;
26
34
  }
27
35
 
28
36
  private rpcs: Record<number, JsonRpcProvider> = {};
@@ -42,11 +50,6 @@ class EvmWallet extends OmniWallet {
42
50
  return this.address.toLowerCase();
43
51
  }
44
52
 
45
- async disconnect() {
46
- this.provider.request?.({ method: "wallet_revokePermissions", params: [{ eth_accounts: {} }] });
47
- await super.disconnect();
48
- }
49
-
50
53
  async fetchBalances(chain: number, whitelist: string[]): Promise<Record<string, bigint>> {
51
54
  const native = await this.fetchBalance(chain, "native");
52
55
  try {
package/src/exchange.ts CHANGED
@@ -300,7 +300,7 @@ export class Exchange {
300
300
  };
301
301
  }
302
302
 
303
- async makeSwap(review: BridgeReview, pending: { log: (message: string) => void }) {
303
+ async makeSwap(review: BridgeReview, pending: { log: (message: string) => void }): Promise<{ review: BridgeReview; processing?: () => Promise<BridgeReview> }> {
304
304
  const { sender, recipient } = review;
305
305
 
306
306
  if (review.qoute === "withdraw") {
@@ -309,7 +309,7 @@ export class Exchange {
309
309
  const recipientWallet = this.wibe3.wallets.find((w) => w.address === recipient.address);
310
310
  if (recipientWallet) this.wibe3.fetchToken(review.to, recipientWallet);
311
311
  this.wibe3.fetchToken(review.from, sender);
312
- return review;
312
+ return { review };
313
313
  }
314
314
 
315
315
  if (review.qoute === "deposit") {
@@ -319,7 +319,7 @@ export class Exchange {
319
319
 
320
320
  const recipientWallet = this.wibe3.wallets.find((w) => w.address === recipient.address);
321
321
  if (recipientWallet) this.wibe3.fetchToken(review.to, recipientWallet);
322
- return review;
322
+ return { review };
323
323
  }
324
324
 
325
325
  if (sender !== "qr") {
@@ -335,7 +335,8 @@ export class Exchange {
335
335
  const depositAddress = review.qoute.depositAddress!;
336
336
  let hash = "";
337
337
  if (review.from.chain === Network.Hot) {
338
- hash = await sender.intents
338
+ hash = await this.wibe3
339
+ .intentsBuilder(sender)
339
340
  .transfer({
340
341
  amount: review.amountIn,
341
342
  token: review.from.address as OmniToken,
@@ -347,31 +348,30 @@ export class Exchange {
347
348
  receiver: depositAddress,
348
349
  amount: review.amountIn,
349
350
  comment: review.qoute.depositMemo,
350
- token: review.from,
351
351
  gasFee: review.fee ?? undefined,
352
+ token: review.from,
352
353
  });
353
354
  }
354
355
 
355
- pending.log("Submitting tx");
356
356
  this.wibe3.fetchToken(review.from, sender);
357
- await OneClickService.submitDepositTx({ txHash: hash, depositAddress }).catch(() => {});
358
- }
359
-
360
- if (sender !== "qr") {
361
- wait(1000).then(() => this.wibe3.fetchToken(review.to, sender));
357
+ OneClickService.submitDepositTx({ txHash: hash, depositAddress }).catch(() => {});
362
358
  }
363
359
 
364
- pending.log("Processing...");
365
- const recipientWallet = this.wibe3.wallets.find((w) => w.address === recipient.address);
366
- if (!recipientWallet) return await this.processing(review);
360
+ return {
361
+ review,
362
+ processing: async () => {
363
+ const recipientWallet = this.wibe3.wallets.find((w) => w.address === recipient.address);
364
+ if (!recipientWallet) return await this.processing(review);
367
365
 
368
- const beforeBalance = await this.wibe3.fetchToken(review.to, recipientWallet).catch(() => null);
369
- if (!beforeBalance) return await this.processing(review);
366
+ const beforeBalance = await this.wibe3.fetchToken(review.to, recipientWallet).catch(() => null);
367
+ if (!beforeBalance) return await this.processing(review);
370
368
 
371
- return await Promise.race([
372
- this.waitBalance(review.to, recipientWallet, beforeBalance, review),
373
- this.processing(review), //
374
- ]);
369
+ return await Promise.race([
370
+ this.waitBalance(review.to, recipientWallet, beforeBalance, review),
371
+ this.processing(review), //
372
+ ]);
373
+ },
374
+ };
375
375
  }
376
376
 
377
377
  async waitBalance(to: Token, wallet: OmniWallet, beforeBalance: bigint, review: BridgeReview): Promise<BridgeReview> {
@@ -50,12 +50,19 @@ class GoogleConnector extends OmniConnector<OmniWallet> {
50
50
  if (account.type === WalletType.STELLAR) {
51
51
  const signMessage = async (message: string) => request("stellar:signMessage", { message });
52
52
  const signTransaction = async (transaction: Transaction) => request("stellar:signTransaction", { transaction: transaction.toXDR() });
53
- this.wallets.push(new StellarWallet(this, { address: account.address, signMessage, signTransaction }));
53
+ this.wallets.push(
54
+ new StellarWallet({
55
+ rpc: this.wibe3.hotBridge.stellar,
56
+ address: account.address,
57
+ signMessage,
58
+ signTransaction,
59
+ })
60
+ );
54
61
  }
55
62
 
56
63
  if (account.type === WalletType.TON) {
57
64
  this.setWallet(
58
- new TonWallet(this, {
65
+ new TonWallet({
59
66
  sendTransaction: (params) => request("ton:sendTransaction", params),
60
67
  signData: (params) => request("ton:signData", params),
61
68
  account: { address: account.address, publicKey: account.publicKey },
@@ -65,21 +72,21 @@ class GoogleConnector extends OmniConnector<OmniWallet> {
65
72
 
66
73
  if (account.type === WalletType.NEAR) {
67
74
  this.setWallet(
68
- new NearWallet(this, account.address, account.publicKey, {
75
+ new NearWallet(account.address, account.publicKey, {
69
76
  signAndSendTransaction: (params: SignAndSendTransactionParams) => request("near:signAndSendTransaction", params),
70
77
  signAndSendTransactions: (params: SignAndSendTransactionsParams) => request("near:signAndSendTransactions", params),
71
78
  signMessage: (params: SignMessageParams) => request("near:signMessage", params),
72
79
  getAccounts: async () => [{ accountId: account.address, publicKey: account.publicKey }],
73
80
  signIn: () => request("near:signIn", {}),
74
- signOut: async () => {},
75
81
  manifest: {} as unknown as WalletManifest,
82
+ signOut: async () => {},
76
83
  }) as NearWallet
77
84
  );
78
85
  }
79
86
 
80
87
  if (account.type === WalletType.SOLANA) {
81
88
  this.setWallet(
82
- new SolanaWallet(this, {
89
+ new SolanaWallet({
83
90
  sendTransaction: async (transaction: unknown, _: unknown, options?: unknown) => await request("solana:sendTransaction", { transaction, options }),
84
91
  signMessage: async (message: string) => await request("solana:signMessage", { message }),
85
92
  disconnect: async () => {},
@@ -1,32 +1,159 @@
1
- const ancestorOrigins = new Set(["http://localhost:1234", "https://my.herewallet.app", "https://tgapp-dev.herewallet.app", "https://tgapp.herewallet.app", "https://beta.herewallet.app", "https://app.hot-labs.org"]);
1
+ import uuid4 from "uuid4";
2
+ import { createRequest, getResponse } from "./proxy";
3
+ import { base58 } from "@scure/base";
2
4
 
3
- export const isInjected = () => {
4
- if (typeof window === "undefined") return false;
5
- if (window.self === window.top) return false;
6
- return ancestorOrigins.has(window.location.ancestorOrigins?.[0]);
5
+ declare global {
6
+ interface Window {
7
+ hotExtension?: {
8
+ autoRun: boolean;
9
+ request: (method: string, args: any) => any;
10
+ subscribe: (event: string, args: any) => () => void;
11
+ evm: any;
12
+ };
13
+ }
14
+ }
15
+
16
+ export const wait = (timeout: number) => {
17
+ return new Promise<void>((resolve) => setTimeout(resolve, timeout));
7
18
  };
8
19
 
9
- export const uuid4 = () => {
10
- try {
11
- return crypto.randomUUID();
12
- } catch {
13
- const temp_url = URL.createObjectURL(new Blob());
14
- const uuid = temp_url.toString();
15
- URL.revokeObjectURL(temp_url);
16
- return uuid.split(/[:/]/g).pop()!.toLowerCase(); // remove prefixes
20
+ export class RequestFailed extends Error {
21
+ name = "RequestFailed";
22
+ constructor(readonly payload: any) {
23
+ super();
17
24
  }
18
- };
25
+ }
19
26
 
20
- export const requestHot = (method: string, request: any) => {
21
- const id = uuid4();
22
- return new Promise<any>((resolve, reject) => {
23
- const handler = (e: any) => {
24
- if (e.data.id !== id) return;
25
- window?.removeEventListener("message", handler);
26
- return e.data.success ? resolve(e.data.payload) : reject(e.data.payload);
27
- };
27
+ export const getExtension = () => {
28
+ if (typeof window === "undefined") return null;
29
+ return window.hotExtension;
30
+ };
28
31
 
29
- window?.parent.postMessage({ $hot: true, method, request, id }, "*");
30
- window?.addEventListener("message", handler);
32
+ let connector: HTMLDivElement | undefined;
33
+ if (typeof window !== "undefined") {
34
+ window.addEventListener("message", (e: any) => {
35
+ if (e.data === "hot-close") {
36
+ connector?.remove();
37
+ connector = undefined;
38
+ }
31
39
  });
40
+ }
41
+
42
+ const createIframe = (widget: string) => {
43
+ connector?.remove();
44
+ connector = document.createElement("div");
45
+
46
+ const iframe = document.createElement("iframe");
47
+ connector?.appendChild(iframe);
48
+
49
+ iframe.src = widget;
50
+ iframe.allow = "usb";
51
+ iframe.style.border = "none";
52
+ iframe.style.borderRadius = "16px";
53
+ iframe.style.background = "#fff";
54
+ iframe.style.overflow = "hidden";
55
+ iframe.style.background = "#1D1F20";
56
+ iframe.style.border = "1px solid #2C3034";
57
+ iframe.style.width = "375px";
58
+ iframe.style.height = "560px";
59
+ iframe.onclick = (e) => e.stopPropagation();
60
+
61
+ connector.style.padding = "16px";
62
+ connector.style.zIndex = "100000000000000";
63
+ connector.style.position = "fixed";
64
+ connector.style.display = "flex";
65
+ connector.style.justifyContent = "center";
66
+ connector.style.alignItems = "center";
67
+ connector.style.top = "0";
68
+ connector.style.left = "0";
69
+ connector.style.width = "100%";
70
+ connector.style.height = "100%";
71
+ connector.style.background = "rgba(0, 0, 0, 0.1)";
72
+ connector.style.backdropFilter = "blur(24px)";
73
+ connector.onclick = () => {
74
+ connector?.remove();
75
+ connector = undefined;
76
+ };
77
+
78
+ document.body.appendChild(connector);
79
+ return connector;
32
80
  };
81
+
82
+ class HOT {
83
+ walletId = "https://t.me/herewalletbot/app";
84
+ ancestorOrigins = ["http://localhost:1234", "https://my.herewallet.app", "https://tgapp-dev.herewallet.app", "https://tgapp.herewallet.app", "https://beta.herewallet.app"];
85
+
86
+ get isInjected() {
87
+ if (typeof window === "undefined") return false;
88
+ if (window.hotExtension != null) return window.hotExtension.autoRun;
89
+ return this.ancestorOrigins.includes(window.location.ancestorOrigins?.[0]);
90
+ }
91
+
92
+ openInHotBrowserUrl: string | null = null;
93
+ toggleOpenInHotBrowser(url: string | null) {
94
+ this.openInHotBrowserUrl = url;
95
+ }
96
+
97
+ customProvider?: (data: any, chain: number, address?: string | null) => Promise<any>;
98
+ setupEthProvider(provider?: (data: any, chain: number, address?: string | null) => Promise<any>) {
99
+ this.customProvider = provider;
100
+ }
101
+
102
+ async injectedRequest(method: string, request: any): Promise<any> {
103
+ const id = uuid4();
104
+ return new Promise((resolve, reject) => {
105
+ const handler = (e: any) => {
106
+ if (e.data.id !== id) return;
107
+ window?.removeEventListener("message", handler);
108
+ if (e.data.success) return resolve(e.data.payload);
109
+ else return reject(e.data.payload);
110
+ };
111
+
112
+ window?.parent.postMessage({ $hot: true, method, request, id }, "*");
113
+ window?.addEventListener("message", handler);
114
+ });
115
+ }
116
+
117
+ subscribe(event: string, cb: (e: any) => void) {
118
+ if (!window.hotExtension) return () => {};
119
+ return window.hotExtension.subscribe(event, cb);
120
+ }
121
+
122
+ async request(method: string, request: any): Promise<any> {
123
+ if (window.hotExtension != null) return window.hotExtension.request(method, request);
124
+ if (this.isInjected) return this.injectedRequest(method, request);
125
+
126
+ const id = uuid4();
127
+ const WebApp: any = (window as any)?.Telegram?.WebApp;
128
+
129
+ const requestId = await createRequest({
130
+ inside: !!this.openInHotBrowserUrl || (method === "ethereum" && this.customProvider == null),
131
+ origin: typeof this.openInHotBrowserUrl === "string" ? this.openInHotBrowserUrl : location.href,
132
+ $hot: true,
133
+ method,
134
+ request,
135
+ id,
136
+ });
137
+
138
+ const link = `${this.walletId}?startapp=hotconnect-${base58.encode(Buffer.from(requestId, "utf8"))}`;
139
+ if (WebApp) WebApp?.openTelegramLink(link);
140
+ else {
141
+ const origin = `https://hot-labs.org/hot-widget/index.html`;
142
+ createIframe(`${origin}?hotconnect-${base58.encode(Buffer.from(requestId, "utf8"))}`);
143
+ }
144
+
145
+ const poolResponse = async () => {
146
+ await wait(3000);
147
+ const data: any = await getResponse(requestId).catch(() => null);
148
+ if (data == null) return await poolResponse();
149
+ if (data.success) return data.payload;
150
+ throw new RequestFailed(data.payload);
151
+ };
152
+
153
+ const result = await poolResponse();
154
+ connector?.remove();
155
+ return result;
156
+ }
157
+ }
158
+
159
+ export default new HOT();
@@ -0,0 +1,54 @@
1
+ import uuid4 from "uuid4";
2
+ import { sha1 } from "@noble/hashes/legacy.js";
3
+ import { base58 } from "@scure/base";
4
+
5
+ export const proxyApi = "https://h4n.app";
6
+
7
+ export const getResponse = async (id: string): Promise<object> => {
8
+ const res = await fetch(`${proxyApi}/${id}/response`, {
9
+ headers: { "content-type": "application/json" },
10
+ method: "GET",
11
+ });
12
+
13
+ if (res.ok === false) {
14
+ throw Error(await res.text());
15
+ }
16
+
17
+ const { data } = await res.json();
18
+ return JSON.parse(data);
19
+ };
20
+
21
+ export const deleteRequest = async (id: string) => {
22
+ const res = await fetch(`${proxyApi}/${id}`, {
23
+ headers: { "content-type": "application/json" },
24
+ method: "DELETE",
25
+ });
26
+
27
+ if (res.ok === false) {
28
+ throw Error(await res.text());
29
+ }
30
+ };
31
+
32
+ export const computeRequestId = async (request: object) => {
33
+ const query = base58.encode(Buffer.from(JSON.stringify({ ...request, _id: uuid4() }), "utf8"));
34
+ const hashsum = sha1(Buffer.from(query, "utf8"));
35
+ const id = Buffer.from(hashsum).toString("base64");
36
+ const requestId = id.replaceAll("/", "_").replaceAll("-", "+").slice(0, 13);
37
+ return { requestId, query };
38
+ };
39
+
40
+ export const createRequest = async (request: object, signal?: AbortSignal) => {
41
+ const { query, requestId } = await computeRequestId(request);
42
+ const res = await fetch(`${proxyApi}/${requestId}/request`, {
43
+ body: JSON.stringify({ data: query }),
44
+ headers: { "content-type": "application/json" },
45
+ method: "POST",
46
+ signal,
47
+ });
48
+
49
+ if (res.ok === false) {
50
+ throw Error(await res.text());
51
+ }
52
+
53
+ return requestId;
54
+ };
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import "@lottiefiles/dotlottie-wc";
2
+
1
3
  export { OmniWallet } from "./OmniWallet";
2
4
  export { OmniConnector } from "./OmniConnector";
3
5
  export { HotConnector } from "./HotConnector";
@@ -28,7 +28,7 @@ class Connector extends OmniConnector<NearWallet> {
28
28
  this.connector.on("wallet:signOut", () => this.removeWallet());
29
29
  this.connector.getConnectedWallet().then(async ({ wallet }) => {
30
30
  const [account] = await wallet.getAccounts();
31
- if (account) this.setWallet(new NearWallet(this, account.accountId, account.publicKey, wallet));
31
+ if (account) this.setWallet(new NearWallet(account.accountId, account.publicKey, wallet));
32
32
  });
33
33
 
34
34
  this.connector.whenManifestLoaded.then(() => {
@@ -49,7 +49,7 @@ class Connector extends OmniConnector<NearWallet> {
49
49
  if (!wallet) throw new Error("Wallet not found");
50
50
  const [account] = await wallet.getAccounts();
51
51
  if (!account) throw new Error("No account found");
52
- return this.setWallet(new NearWallet(this, account.accountId, account.publicKey, wallet));
52
+ return this.setWallet(new NearWallet(account.accountId, account.publicKey, wallet));
53
53
  }
54
54
 
55
55
  async disconnect() {
@@ -1,6 +1,8 @@
1
1
  import { JsonRpcProvider } from "@near-js/providers";
2
2
  import { getErrorTypeFromErrorMessage, parseRpcError } from "@near-js/utils";
3
3
  import { TypedError, FinalExecutionOutcome } from "@near-js/types";
4
+ import { api } from "../core/api";
5
+ import { Network } from "../core";
4
6
 
5
7
  let _nextId = 123;
6
8
 
@@ -22,22 +24,13 @@ const wait = (timeout: number) => {
22
24
  return new Promise<void>((resolve) => setTimeout(resolve, timeout));
23
25
  };
24
26
 
25
- const c1 = Math.random() > 0.5;
26
- export const rpcProviders = [
27
- c1 ? "https://c1.rpc.fastnear.com" : "https://c2.rpc.fastnear.com",
28
- c1 ? "https://c2.rpc.fastnear.com" : "https://c1.rpc.fastnear.com",
29
- "https://relmn.aurora.dev",
30
- "https://nearrpc.aurora.dev",
31
- "https://archival-rpc.mainnet.near.org",
32
- ];
33
-
34
27
  export class NearRpc extends JsonRpcProvider {
35
28
  public providers: string[];
36
29
  public currentProviderIndex = 0;
37
30
  public startTimeout;
38
31
 
39
- constructor(providers = rpcProviders, private timeout = 30_000, private triesCountForEveryProvider = 3, private incrementTimout = true) {
40
- super({ url: "" });
32
+ constructor(providers = [api.getRpcUrl(Network.Near)], private timeout = 30_000, private triesCountForEveryProvider = 3, private incrementTimout = true) {
33
+ super({ url: api.getRpcUrl(Network.Near) });
41
34
  this.currentProviderIndex = 0;
42
35
  this.providers = providers;
43
36
  this.startTimeout = timeout;
@@ -1,30 +1,25 @@
1
1
  import { NearWalletBase, SignMessageParams, SignedMessage, SignAndSendTransactionParams } from "@hot-labs/near-connect";
2
2
  import { base64, base58 } from "@scure/base";
3
3
 
4
- import { OmniConnector } from "../OmniConnector";
5
4
  import { OmniWallet } from "../OmniWallet";
6
5
  import { WalletType } from "../core/chains";
7
6
  import { ReviewFee } from "../core/bridge";
8
- import { rpc, TGAS } from "../core/nearRpc";
7
+ import { rpc, TGAS } from "./rpc";
9
8
  import { Token } from "../core/token";
10
9
  import { Commitment } from "../core";
11
10
 
12
11
  export default class NearWallet extends OmniWallet {
12
+ readonly icon = "https://storage.herewallet.app/upload/73a44e583769f11112b0eff1f2dd2a560c05eed5f6d92f0c03484fa047c31668.png";
13
13
  readonly type = WalletType.NEAR;
14
14
 
15
- constructor(readonly connector: OmniConnector, readonly address: string, readonly publicKey?: string, readonly wallet?: NearWalletBase) {
16
- super(connector);
15
+ constructor(readonly address: string, readonly publicKey?: string, readonly wallet?: NearWalletBase) {
16
+ super();
17
17
  }
18
18
 
19
19
  get omniAddress() {
20
20
  return this.address;
21
21
  }
22
22
 
23
- async disconnect() {
24
- await this.wallet?.signOut();
25
- super.disconnect();
26
- }
27
-
28
23
  async fetchBalances(_: number, whitelist: string[]): Promise<Record<string, bigint>> {
29
24
  const balances = await Promise.all(
30
25
  whitelist.map(async (token) => {