@hot-labs/kit 1.3.3 → 1.4.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 (187) hide show
  1. package/build/HotConnector.d.ts +9 -13
  2. package/build/HotConnector.js +17 -57
  3. package/build/HotConnector.js.map +1 -1
  4. package/build/activity.d.ts +1 -1
  5. package/build/activity.js +8 -8
  6. package/build/activity.js.map +1 -1
  7. package/build/core/Intents.d.ts +3 -2
  8. package/build/core/Intents.js +11 -1
  9. package/build/core/Intents.js.map +1 -1
  10. package/build/{OmniConnector.d.ts → core/OmniConnector.d.ts} +4 -4
  11. package/build/{OmniConnector.js → core/OmniConnector.js} +2 -2
  12. package/build/core/OmniConnector.js.map +1 -0
  13. package/build/{OmniWallet.d.ts → core/OmniWallet.d.ts} +19 -13
  14. package/build/core/OmniWallet.js +97 -0
  15. package/build/core/OmniWallet.js.map +1 -0
  16. package/build/core/address.d.ts +25 -0
  17. package/build/core/address.js +162 -0
  18. package/build/core/address.js.map +1 -0
  19. package/build/core/chains.d.ts +1 -1
  20. package/build/core/chains.js +5 -5
  21. package/build/core/chains.js.map +1 -1
  22. package/build/{exchange.d.ts → core/exchange.d.ts} +13 -16
  23. package/build/{exchange.js → core/exchange.js} +76 -80
  24. package/build/core/exchange.js.map +1 -0
  25. package/build/core/index.d.ts +1 -1
  26. package/build/core/index.js +1 -1
  27. package/build/core/index.js.map +1 -1
  28. package/build/core/recipient.d.ts +2 -1
  29. package/build/core/recipient.js +6 -0
  30. package/build/core/recipient.js.map +1 -1
  31. package/build/core/telemetry.d.ts +3 -0
  32. package/build/core/telemetry.js.map +1 -1
  33. package/build/core/token.js +3 -3
  34. package/build/core/token.js.map +1 -1
  35. package/build/core/tokens.js +1 -1
  36. package/build/core/tokens.js.map +1 -1
  37. package/build/core/utils.d.ts +1 -0
  38. package/build/core/utils.js +19 -0
  39. package/build/core/utils.js.map +1 -1
  40. package/build/cosmos/connector.d.ts +2 -2
  41. package/build/cosmos/connector.js +2 -2
  42. package/build/cosmos/connector.js.map +1 -1
  43. package/build/cosmos/wallet.d.ts +2 -2
  44. package/build/cosmos/wallet.js +7 -10
  45. package/build/cosmos/wallet.js.map +1 -1
  46. package/build/defaults.d.ts +1 -1
  47. package/build/defaults.js +2 -2
  48. package/build/defaults.js.map +1 -1
  49. package/build/evm/connector.d.ts +4 -4
  50. package/build/evm/connector.js +10 -4
  51. package/build/evm/connector.js.map +1 -1
  52. package/build/evm/wallet.d.ts +5 -5
  53. package/build/evm/wallet.js +24 -23
  54. package/build/evm/wallet.js.map +1 -1
  55. package/build/hot-wallet/google.d.ts +2 -2
  56. package/build/hot-wallet/google.js +4 -4
  57. package/build/hot-wallet/google.js.map +1 -1
  58. package/build/index.d.ts +2 -2
  59. package/build/index.js +2 -2
  60. package/build/index.js.map +1 -1
  61. package/build/near/connector.d.ts +2 -2
  62. package/build/near/connector.js +8 -3
  63. package/build/near/connector.js.map +1 -1
  64. package/build/near/index.d.ts +1 -1
  65. package/build/near/index.js.map +1 -1
  66. package/build/near/standalone.d.ts +2 -0
  67. package/build/near/standalone.js +42 -0
  68. package/build/near/standalone.js.map +1 -0
  69. package/build/near/wallet.d.ts +3 -2
  70. package/build/near/wallet.js +21 -12
  71. package/build/near/wallet.js.map +1 -1
  72. package/build/solana/connector.d.ts +4 -4
  73. package/build/solana/connector.js +11 -4
  74. package/build/solana/connector.js.map +1 -1
  75. package/build/solana/wallet.d.ts +3 -3
  76. package/build/solana/wallet.js +14 -11
  77. package/build/solana/wallet.js.map +1 -1
  78. package/build/stellar/connector.d.ts +2 -2
  79. package/build/stellar/connector.js +3 -2
  80. package/build/stellar/connector.js.map +1 -1
  81. package/build/stellar/wallet.d.ts +3 -3
  82. package/build/stellar/wallet.js +27 -19
  83. package/build/stellar/wallet.js.map +1 -1
  84. package/build/ton/connector.d.ts +2 -2
  85. package/build/ton/connector.js +2 -2
  86. package/build/ton/connector.js.map +1 -1
  87. package/build/ton/wallet.d.ts +3 -3
  88. package/build/ton/wallet.js +26 -17
  89. package/build/ton/wallet.js.map +1 -1
  90. package/build/tron/connector.d.ts +2 -2
  91. package/build/tron/connector.js +1 -1
  92. package/build/tron/connector.js.map +1 -1
  93. package/build/tron/wallet.d.ts +2 -2
  94. package/build/tron/wallet.js +9 -15
  95. package/build/tron/wallet.js.map +1 -1
  96. package/build/ui/bridge/Bridge.d.ts +2 -2
  97. package/build/ui/bridge/Bridge.js +15 -13
  98. package/build/ui/bridge/Bridge.js.map +1 -1
  99. package/build/ui/bridge/SelectRecipient.d.ts +3 -3
  100. package/build/ui/bridge/SelectRecipient.js +8 -7
  101. package/build/ui/bridge/SelectRecipient.js.map +1 -1
  102. package/build/ui/bridge/SelectSender.d.ts +1 -1
  103. package/build/ui/bridge/SelectSender.js +1 -1
  104. package/build/ui/bridge/SelectSender.js.map +1 -1
  105. package/build/ui/bridge/SelectToken.d.ts +1 -1
  106. package/build/ui/bridge/SelectToken.js +2 -2
  107. package/build/ui/bridge/SelectToken.js.map +1 -1
  108. package/build/ui/bridge/TokenCard.d.ts +1 -1
  109. package/build/ui/connect/AuthPopup.d.ts +1 -1
  110. package/build/ui/connect/ConnectWallet.d.ts +1 -1
  111. package/build/ui/connect/ConnectWallet.js +1 -1
  112. package/build/ui/connect/ConnectWallet.js.map +1 -1
  113. package/build/ui/connect/LogoutPopup.d.ts +1 -1
  114. package/build/ui/connect/WCPopup.js +1 -1
  115. package/build/ui/connect/WCPopup.js.map +1 -1
  116. package/build/ui/connect/WalletPicker.d.ts +2 -2
  117. package/build/ui/profile/DepositQR.d.ts +1 -1
  118. package/build/ui/profile/Payment.d.ts +1 -1
  119. package/build/ui/profile/Payment.js +8 -8
  120. package/build/ui/profile/Payment.js.map +1 -1
  121. package/build/ui/profile/Profile.js.map +1 -1
  122. package/build/ui/router.d.ts +3 -3
  123. package/examples-node/package.json +17 -0
  124. package/examples-node/transfer.ts +12 -10
  125. package/examples-node/withdraw.ts +52 -0
  126. package/examples-node/yarn.lock +2691 -0
  127. package/package.json +1 -1
  128. package/src/HotConnector.ts +16 -60
  129. package/src/activity.ts +9 -9
  130. package/src/core/Intents.ts +14 -3
  131. package/src/{OmniConnector.ts → core/OmniConnector.ts} +4 -6
  132. package/src/core/OmniWallet.ts +125 -0
  133. package/src/core/address.ts +155 -0
  134. package/src/core/chains.ts +5 -5
  135. package/src/{exchange.ts → core/exchange.ts} +79 -85
  136. package/src/core/index.ts +1 -1
  137. package/src/core/recipient.ts +8 -1
  138. package/src/core/telemetry.ts +4 -0
  139. package/src/core/token.ts +3 -3
  140. package/src/core/tokens.ts +1 -1
  141. package/src/core/utils.ts +16 -0
  142. package/src/cosmos/connector.ts +3 -3
  143. package/src/cosmos/wallet.ts +8 -11
  144. package/src/defaults.ts +2 -2
  145. package/src/evm/connector.ts +12 -6
  146. package/src/evm/wallet.ts +24 -25
  147. package/src/hot-wallet/google.ts +5 -5
  148. package/src/index.ts +2 -2
  149. package/src/near/connector.ts +6 -3
  150. package/src/near/index.ts +2 -1
  151. package/src/near/standalone.ts +52 -0
  152. package/src/near/wallet.ts +21 -15
  153. package/src/solana/connector.ts +15 -6
  154. package/src/solana/wallet.ts +12 -12
  155. package/src/stellar/connector.ts +5 -4
  156. package/src/stellar/wallet.ts +28 -22
  157. package/src/ton/connector.ts +4 -3
  158. package/src/ton/wallet.ts +24 -18
  159. package/src/tron/connector.ts +2 -2
  160. package/src/tron/wallet.ts +9 -19
  161. package/src/ui/bridge/Bridge.tsx +18 -16
  162. package/src/ui/bridge/SelectRecipient.tsx +23 -16
  163. package/src/ui/bridge/SelectSender.tsx +2 -2
  164. package/src/ui/bridge/SelectToken.tsx +3 -3
  165. package/src/ui/bridge/TokenCard.tsx +1 -1
  166. package/src/ui/connect/AuthPopup.tsx +1 -1
  167. package/src/ui/connect/ConnectWallet.tsx +2 -2
  168. package/src/ui/connect/LogoutPopup.tsx +1 -1
  169. package/src/ui/connect/WCPopup.tsx +1 -1
  170. package/src/ui/connect/WalletPicker.tsx +2 -2
  171. package/src/ui/profile/DepositQR.tsx +1 -1
  172. package/src/ui/profile/Payment.tsx +12 -13
  173. package/src/ui/profile/Profile.tsx +1 -2
  174. package/src/ui/router.tsx +3 -3
  175. package/build/OmniConnector.js.map +0 -1
  176. package/build/OmniWallet.js +0 -61
  177. package/build/OmniWallet.js.map +0 -1
  178. package/build/core/signer.d.ts +0 -51
  179. package/build/core/signer.js +0 -99
  180. package/build/core/signer.js.map +0 -1
  181. package/build/exchange.js.map +0 -1
  182. package/build/ui/utils.d.ts +0 -1
  183. package/build/ui/utils.js +0 -20
  184. package/build/ui/utils.js.map +0 -1
  185. package/src/OmniWallet.ts +0 -85
  186. package/src/core/signer.ts +0 -116
  187. package/src/ui/utils.ts +0 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hot-labs/kit",
3
- "version": "1.3.3",
3
+ "version": "1.4.1",
4
4
  "description": "HOT Labs Kit is chain agnostic connector with omni payments",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -2,14 +2,15 @@ import { computed, makeObservable, observable, runInAction } from "mobx";
2
2
 
3
3
  import packageJson from "../package.json";
4
4
 
5
+ import { Exchange } from "./core/exchange";
6
+ import { Telemetry } from "./core/telemetry";
7
+ import { OmniWallet } from "./core/OmniWallet";
5
8
  import { ChainConfig, chains, Network, WalletType } from "./core/chains";
6
- import { createHotBridge, HotBridge } from "./core/bridge";
7
9
  import { EventEmitter } from "./core/events";
8
10
  import { Recipient } from "./core/recipient";
9
11
  import { OmniToken } from "./core/chains";
10
12
  import { Intents } from "./core/Intents";
11
13
  import { tokens } from "./core/tokens";
12
- import { Telemetry } from "./core/telemetry";
13
14
  import { Token } from "./core/token";
14
15
  import { api } from "./core/api";
15
16
  import { rpc } from "./near/rpc";
@@ -23,11 +24,9 @@ import type StellarWallet from "./stellar/wallet";
23
24
  import type TonWallet from "./ton/wallet";
24
25
 
25
26
  import { openBridge, openConnector, openProfile, openWalletPicker } from "./ui/router";
26
- import { ConnectorType, OmniConnector } from "./OmniConnector";
27
- import { OmniWallet } from "./OmniWallet";
28
- import { Exchange } from "./exchange";
29
- import { Activity } from "./activity";
27
+ import { ConnectorType, OmniConnector } from "./core/OmniConnector";
30
28
  import { DataStorage, LocalStorage } from "./storage";
29
+ import { Activity } from "./activity";
31
30
 
32
31
  interface HotConnectorOptions {
33
32
  apiKey: string;
@@ -48,13 +47,10 @@ interface HotConnectorOptions {
48
47
  export class HotConnector {
49
48
  public storage: DataStorage;
50
49
  public connectors: OmniConnector[] = [];
51
- public balances: Record<string, Record<string, bigint>> = {};
52
50
  public telemetry: Telemetry;
53
-
54
- public activity: Activity;
55
- public hotBridge: HotBridge;
56
51
  public exchange: Exchange;
57
52
 
53
+ public activity: Activity;
58
54
  public version = packageJson.version;
59
55
 
60
56
  private events = new EventEmitter<{
@@ -71,8 +67,6 @@ export class HotConnector {
71
67
 
72
68
  constructor(options?: HotConnectorOptions) {
73
69
  makeObservable(this, {
74
- balances: observable,
75
-
76
70
  priorityWallet: computed,
77
71
  walletsTokens: computed,
78
72
  wallets: computed,
@@ -93,9 +87,8 @@ export class HotConnector {
93
87
 
94
88
  this.storage = options?.storage ?? new LocalStorage();
95
89
  this.telemetry = new Telemetry(this);
96
- this.hotBridge = createHotBridge();
97
- this.exchange = new Exchange(this);
98
90
  this.activity = new Activity(this);
91
+ this.exchange = new Exchange();
99
92
 
100
93
  const connectors: OmniConnector[] = [];
101
94
  const configConnectors = options?.connectors || defaultConnectors;
@@ -116,21 +109,17 @@ export class HotConnector {
116
109
  });
117
110
 
118
111
  this.onConnect((payload) => {
112
+ console.log("onConnect", payload.wallet.type);
113
+ payload.wallet.fetchBalances(Network.Omni);
119
114
  this.fetchTokens(payload.wallet);
120
- this.fetchOmniTokens(payload.wallet);
121
- });
122
-
123
- this.onDisconnect(({ wallet }) => {
124
- if (!wallet) return;
125
- runInAction(() => (this.balances[`${wallet.type}:${wallet.address}`] = {}));
126
115
  });
127
116
 
128
117
  tokens.startTokenPolling();
129
118
  }
130
119
 
131
120
  setOmniChainBranding(branding: { name: string; icon: string }) {
132
- chains.get(Network.Hot).name = branding.name;
133
- chains.get(Network.Hot).logo = branding.icon;
121
+ chains.get(Network.Omni).name = branding.name;
122
+ chains.get(Network.Omni).logo = branding.icon;
134
123
  }
135
124
 
136
125
  getWalletConnector(type: WalletType): OmniConnector | null {
@@ -228,7 +217,7 @@ export class HotConnector {
228
217
  .reduce((acc: number, token: Token) => {
229
218
  return this.wallets.reduce((acc: number, wallet) => {
230
219
  if (token.chain === chain) return acc;
231
- const balance = this.balances[`${wallet.type}:${wallet.address}`][token.id] ?? 0n;
220
+ const balance = wallet.getBalance(token.id);
232
221
  return acc + token.float(balance) * token.usd;
233
222
  }, acc);
234
223
  }, 0);
@@ -236,7 +225,7 @@ export class HotConnector {
236
225
 
237
226
  balance(wallet?: OmniWallet, token?: Token) {
238
227
  if (!wallet || !token) return 0n;
239
- return this.balances[`${wallet.type}:${wallet.address}`]?.[token.id] ?? 0n;
228
+ return wallet.getBalance(token.id);
240
229
  }
241
230
 
242
231
  omniBalance(token: OmniToken) {
@@ -254,37 +243,10 @@ export class HotConnector {
254
243
  }
255
244
 
256
245
  async fetchToken(token: Token, wallet: OmniWallet) {
257
- const key = `${wallet.type}:${wallet.address}`;
258
-
259
- if (token.type === WalletType.OMNI) {
260
- if (!wallet.omniAddress) return 0n;
261
- const balances = await Intents.getIntentsBalances([token.address], wallet.omniAddress);
262
- runInAction(() => (this.balances[key][token.id] = balances[token.address]));
263
- return balances[token.address] ?? 0n;
264
- }
265
-
266
- if (token.type === wallet.type) {
267
- const balance = await wallet.fetchBalance(token.chain, token.address);
268
- runInAction(() => (this.balances[key][token.id] = balance));
269
- return balance;
270
- }
271
-
272
- return 0n;
273
- }
274
-
275
- async fetchOmniTokens(wallet: OmniWallet) {
276
- const key = `${wallet.type}:${wallet.address}`;
277
- const assets = await wallet.getAssets();
278
- runInAction(() => {
279
- Object.keys(assets).forEach((id) => {
280
- this.balances[key][`-4:${id}`] = assets[id];
281
- });
282
- });
246
+ return await wallet.fetchBalance(token.chain, token.address);
283
247
  }
284
248
 
285
249
  async fetchTokens(wallet: OmniWallet) {
286
- const key = `${wallet.type}:${wallet.address}`;
287
- if (!this.balances[key]) runInAction(() => (this.balances[key] = {}));
288
250
  const tokensList = (await tokens.getTokens()).filter((t) => t.type === wallet.type && t.type !== WalletType.OMNI);
289
251
 
290
252
  // Group tokens by their chain
@@ -294,14 +256,8 @@ export class HotConnector {
294
256
  return acc;
295
257
  }, {} as Record<number, string[]>);
296
258
 
297
- Object.entries(groups).forEach(async ([chain, tokens]) => {
298
- const balances = await wallet.fetchBalances(+chain, tokens);
299
- runInAction(() => {
300
- for (const [token, balance] of Object.entries(balances)) {
301
- this.balances[key][`${chain}:${token}`] = balance;
302
- }
303
- });
304
- });
259
+ const tasks = Object.entries(groups).map(([chain, tokens]) => wallet.fetchBalances(+chain, tokens));
260
+ await Promise.allSettled(tasks);
305
261
  }
306
262
 
307
263
  intentsBuilder(wallet?: OmniWallet) {
package/src/activity.ts CHANGED
@@ -3,8 +3,8 @@ import { computed, makeObservable, observable, runInAction } from "mobx";
3
3
  import { hex } from "@scure/base";
4
4
 
5
5
  import { chains, Network, WalletType } from "./core";
6
+ import { OmniWallet } from "./core/OmniWallet";
6
7
  import { HotConnector } from "./HotConnector";
7
- import { OmniWallet } from "./OmniWallet";
8
8
 
9
9
  export class Activity {
10
10
  withdrawals: Record<number, (WithdrawArgsWithPending & { loading?: boolean })[]> = {};
@@ -25,7 +25,7 @@ export class Activity {
25
25
 
26
26
  if (withdrawal.chain === Network.Stellar) {
27
27
  if (!this.kit.stellar) throw new Error("Stellar wallet not connected");
28
- await this.kit.hotBridge.stellar.withdraw({
28
+ await this.kit.exchange.bridge.stellar.withdraw({
29
29
  sendTransaction: (tx: any) => this.kit.stellar!.sendTransaction(tx),
30
30
  sender: this.kit.stellar.address,
31
31
  ...withdrawal,
@@ -34,7 +34,7 @@ export class Activity {
34
34
 
35
35
  if (withdrawal.chain === Network.Solana) {
36
36
  if (!this.kit.solana) throw new Error("Solana wallet not connected");
37
- const solana = await this.kit.hotBridge.solana();
37
+ const solana = await this.kit.exchange.bridge.solana();
38
38
  await solana.withdraw({
39
39
  sendTransaction: (tx: any) => this.kit.solana!.sendTransaction(tx),
40
40
  sender: this.kit.solana.address,
@@ -44,7 +44,7 @@ export class Activity {
44
44
 
45
45
  if (withdrawal.chain === Network.Ton || withdrawal.chain === Network.OmniTon) {
46
46
  if (!this.kit.ton) throw new Error("Ton wallet not connected");
47
- await this.kit.hotBridge.ton.withdraw({
47
+ await this.kit.exchange.bridge.ton.withdraw({
48
48
  sendTransaction: (tx: any) => this.kit.ton!.sendTransaction(tx),
49
49
  refundAddress: this.kit.ton.address,
50
50
  ...withdrawal,
@@ -53,15 +53,15 @@ export class Activity {
53
53
 
54
54
  if (chains.get(withdrawal.chain).type === WalletType.EVM) {
55
55
  if (!this.kit.evm) throw new Error("EVM wallet not connected");
56
- await this.kit.hotBridge.evm.withdraw({
57
- sendTransaction: (tx: any) => this.kit.evm!.sendTransaction(withdrawal.chain, tx),
56
+ await this.kit.exchange.bridge.evm.withdraw({
57
+ sendTransaction: (tx: any) => this.kit.evm!.sendTransaction(tx),
58
58
  ...withdrawal,
59
59
  });
60
60
  }
61
61
 
62
62
  if (withdrawal.chain === Network.Gonka) {
63
63
  if (!this.kit.cosmos) throw new Error("Gonka wallet not connected");
64
- const cosmos = await this.kit.hotBridge.cosmos();
64
+ const cosmos = await this.kit.exchange.bridge.cosmos();
65
65
  await cosmos.withdraw({
66
66
  sendTransaction: (tx: any) => this.kit.cosmos!.sendTransaction(tx),
67
67
  senderPublicKey: hex.decode(this.kit.cosmos.publicKey!),
@@ -70,7 +70,7 @@ export class Activity {
70
70
  });
71
71
  }
72
72
 
73
- await this.kit.hotBridge.clearPendingWithdrawals([withdrawal]).catch(() => {});
73
+ await this.kit.exchange.bridge.clearPendingWithdrawals([withdrawal]).catch(() => {});
74
74
  } finally {
75
75
  runInAction(() => (withdrawal.loading = false));
76
76
  const wallet = this.kit.wallets.find((w) => w.type === chains.get(withdrawal.chain).type);
@@ -85,7 +85,7 @@ export class Activity {
85
85
  }
86
86
 
87
87
  async fetchPendingWithdrawalsByChain(chain: number, wallet: OmniWallet) {
88
- const pendings = await this.kit.hotBridge.getPendingWithdrawalsWithStatus(chain, wallet.address);
88
+ const pendings = await this.kit.exchange.bridge.getPendingWithdrawalsWithStatus(chain, wallet.address);
89
89
  runInAction(() => (this.withdrawals[chain] = pendings.filter((t) => !t.completed)));
90
90
  }
91
91
  }
@@ -1,11 +1,11 @@
1
1
  import { sha256 } from "@noble/hashes/sha2.js";
2
2
 
3
3
  import type { HotConnector } from "../HotConnector";
4
- import type { OmniWallet } from "../OmniWallet";
4
+ import type { OmniWallet } from "./OmniWallet";
5
5
  import { rpc } from "../near/rpc";
6
6
 
7
7
  import type { Intent, Commitment, TokenDiffIntent, MtWithdrawIntent, FtWithdrawIntent, NftWithdrawIntent, TransferIntent } from "./types";
8
- import type { BridgeReview } from "../exchange";
8
+ import type { BridgeReview } from "./exchange";
9
9
 
10
10
  import { OmniToken } from "./chains";
11
11
  import { formatter } from "./utils";
@@ -376,6 +376,7 @@ export class Intents {
376
376
  }
377
377
 
378
378
  async simulate() {
379
+ if (this.unsignedCommitment != null) await this.sign();
379
380
  if (this.commitments.length === 0) throw new Error("No commitments attached");
380
381
  return await Intents.simulateIntents(this.commitments);
381
382
  }
@@ -479,7 +480,7 @@ export class Intents {
479
480
 
480
481
  const payableToken = tokens.get(Array.from(this.need.keys())[0]);
481
482
  const payableAmount = this.need.get(payableToken.omniAddress as OmniToken) || 0n;
482
- await this.signer?.waitUntilBalance({ [payableToken.omniAddress]: payableAmount });
483
+ await this.signer?.waitUntilOmniBalance({ [payableToken.omniAddress]: payableAmount });
483
484
 
484
485
  await this.execute().finally(() => close());
485
486
  }
@@ -518,6 +519,16 @@ export class Intents {
518
519
  return hash;
519
520
  }
520
521
 
522
+ static async getPublicKeys(accountId: string): Promise<string[]> {
523
+ const keys = await rpc.viewMethod({
524
+ args: { account_id: accountId },
525
+ methodName: "public_keys_of",
526
+ contractId: "intents.near",
527
+ });
528
+
529
+ return keys.map((key: string) => key.split(":")[1]);
530
+ }
531
+
521
532
  static async hasPublicKey(accountId: string, publicKey: string): Promise<boolean> {
522
533
  return await rpc.viewMethod({
523
534
  args: { account_id: accountId, public_key: publicKey },
@@ -1,13 +1,10 @@
1
1
  import { makeObservable, observable, runInAction } from "mobx";
2
2
  import UniversalProvider, { NamespaceConfig } from "@walletconnect/universal-provider";
3
3
 
4
- import { EventEmitter } from "./core/events";
5
- import { LocalStorage } from "./storage";
6
- import { HotConnector } from "./HotConnector";
7
-
4
+ import type { HotConnector } from "../HotConnector";
5
+ import { EventEmitter } from "./events";
8
6
  import { OmniWallet } from "./OmniWallet";
9
- import { WalletType } from "./core/chains";
10
- import { openWCRequest } from "./ui/router";
7
+ import { WalletType } from "./chains";
11
8
 
12
9
  export enum ConnectorType {
13
10
  WALLET = "wallet",
@@ -82,6 +79,7 @@ export abstract class OmniConnector<T extends OmniWallet = OmniWallet, O = {}> {
82
79
  }
83
80
 
84
81
  async requestWalletConnect<T>(args: { chain?: string; request: any; deeplink?: string; name?: string; icon?: string }): Promise<T> {
82
+ const { openWCRequest } = await import("../ui/router");
85
83
  return openWCRequest<T>({
86
84
  deeplink: args.deeplink,
87
85
  name: args.name || "WalletConnect",
@@ -0,0 +1,125 @@
1
+ import { hex } from "@scure/base";
2
+ import { action, makeObservable, observable } from "mobx";
3
+
4
+ import type { HotConnector } from "../HotConnector";
5
+ import { Commitment } from "./types";
6
+ import { WalletType } from "./chains";
7
+ import { Intents } from "./Intents";
8
+ import { ReviewFee } from "./bridge";
9
+ import { Token } from "./token";
10
+ import { api } from "./api";
11
+
12
+ export abstract class OmniWallet {
13
+ balances: Record<string, bigint> = {};
14
+
15
+ abstract address: string;
16
+ abstract publicKey?: string;
17
+ abstract omniAddress: string;
18
+ abstract type: WalletType;
19
+ abstract icon: string;
20
+
21
+ constructor() {
22
+ makeObservable(this, { balances: observable, setBalance: action });
23
+ }
24
+
25
+ intents(wibe3?: HotConnector) {
26
+ return new Intents(wibe3).attachWallet(this);
27
+ }
28
+
29
+ setBalance(id: string, balance: bigint) {
30
+ this.balances[id] = balance;
31
+ return balance;
32
+ }
33
+
34
+ getBalance(id: string) {
35
+ return this.balances[id] ?? 0n;
36
+ }
37
+
38
+ async depositNfts(nftIds: string[], receiver: string) {
39
+ throw new Error("Method not implemented.");
40
+ }
41
+
42
+ async getDepositNftsFee(nfts: string[]) {
43
+ return new ReviewFee({ chain: -4 });
44
+ }
45
+
46
+ async withdrawNfts(nftIds: string[], receiver: string) {
47
+ throw new Error("Method not implemented.");
48
+ }
49
+
50
+ async transferNft(nftId: string, receiver: string) {
51
+ throw new Error("Method not implemented.");
52
+ }
53
+
54
+ async sendTransaction(tx: any): Promise<string> {
55
+ throw new Error("Method not implemented.");
56
+ }
57
+
58
+ async getTranferNftFee(nftId: string, receiver: string) {
59
+ return new ReviewFee({ chain: -4 });
60
+ }
61
+
62
+ async getNfts(onLoad: (nfts: string[]) => void) {}
63
+
64
+ async transferFee(token: Token, receiver: string, amount: bigint): Promise<ReviewFee> {
65
+ return new ReviewFee({ chain: -4 });
66
+ }
67
+
68
+ async transfer(args: { token: Token; receiver: string; amount: bigint; comment?: string; gasFee?: ReviewFee }): Promise<string> {
69
+ throw new Error("Method not implemented.");
70
+ }
71
+
72
+ async fetchBalance(chain: number, address: string): Promise<bigint> {
73
+ if (chain !== -4) return 0n;
74
+ const balances = await Intents.getIntentsBalances([address], this.omniAddress);
75
+ return this.setBalance(`${chain}:${address}`, balances[address] || 0n);
76
+ }
77
+
78
+ async fetchBalances(chain: number, whitelist: string[] = []): Promise<Record<string, bigint>> {
79
+ if (chain === -4) {
80
+ const list = whitelist.length > 0 ? whitelist : await Intents.getIntentsAssets(this.omniAddress);
81
+ const balances = await Intents.getIntentsBalances(list, this.omniAddress);
82
+ Object.entries(balances).forEach(([address, balance]) => this.setBalance(`${chain}:${address}`, BigInt(balance as unknown as string)));
83
+ return balances;
84
+ }
85
+
86
+ const res = await fetch(`https://api0.herewallet.app/api/v1/user/balances/${chain}/${this.address}`, { body: JSON.stringify({ whitelist }), method: "POST" });
87
+ const { balances } = await res.json();
88
+
89
+ console.log("fetchBalances", { chain, whitelist, balances, l: Object.keys(balances).length });
90
+ if (Object.keys(balances).length === 0) throw "No balances found";
91
+
92
+ Object.entries(balances).forEach(([address, balance]) => this.setBalance(`${chain}:${address}`, BigInt(balance as string)));
93
+ const native = await this.fetchBalance(chain, "native").catch(() => 0n);
94
+ return { ...balances, native };
95
+ }
96
+
97
+ async signIntents(intents: Record<string, any>[], options?: { nonce?: Uint8Array; deadline?: number; signerId?: string }): Promise<Commitment> {
98
+ throw new Error("Method not implemented.");
99
+ }
100
+
101
+ async auth<T = string>(intents?: Record<string, any>[], options?: { domain?: string; signerId?: string; customAuth?: (commitment: Commitment, seed: string) => Promise<T> }): Promise<T> {
102
+ const authFn = async () => {
103
+ const seed = hex.encode(new Uint8Array(window.crypto.getRandomValues(new Uint8Array(32))));
104
+ const msgBuffer = new TextEncoder().encode(`${options?.domain || window.location.origin}_${seed}`);
105
+ const nonce = await window.crypto.subtle.digest("SHA-256", new Uint8Array(msgBuffer));
106
+ const signed = await this.signIntents(intents || [], { nonce: new Uint8Array(nonce), signerId: options?.signerId || this.omniAddress });
107
+
108
+ if (options?.customAuth) return await options.customAuth(signed, seed);
109
+ return (await api.auth(signed, seed)) as T;
110
+ };
111
+
112
+ if (typeof window === "undefined") return await authFn();
113
+ const { openAuthPopup } = await import("../ui/connect/AuthPopup");
114
+ return openAuthPopup(this, authFn);
115
+ }
116
+
117
+ async waitUntilOmniBalance(need: Record<string, bigint>, receiver = this.omniAddress, attempts = 0) {
118
+ if (attempts > 120) throw "Balance is not enough";
119
+ const assets = Object.keys(need) as string[];
120
+ const balances = await Intents.getIntentsBalances(assets, receiver);
121
+ if (assets.every((asset) => (balances[asset] || 0n) >= (need[asset] || 0n))) return;
122
+ await new Promise((resolve) => setTimeout(resolve, 1000));
123
+ await this.waitUntilOmniBalance(need, receiver, attempts + 1);
124
+ }
125
+ }
@@ -0,0 +1,155 @@
1
+ import { Address } from "@ton/core";
2
+ import { Address as StellarAddress } from "@stellar/stellar-sdk";
3
+ import { base32, base58, hex } from "@scure/base";
4
+ import { sha256 } from "@noble/hashes/sha2.js";
5
+ import * as ethers from "ethers";
6
+ import { chains, Network, WalletType } from "./chains";
7
+
8
+ export const MinAccountIdLen = 2;
9
+ export const MaxAccountIdLen = 64;
10
+ export const ValidAccountRe = /^(([a-z\d]+[-_])*[a-z\d]+\.)*([a-z\d]+[-_])*[a-z\d]+$/;
11
+ export const NEAR_DOMAINS = [".near", ".sweat", ".usn", ".tg"];
12
+ export const NEAR_ADDRESS_HEX_LENGTH = 64;
13
+ export const EVM_DOMAINS = [".eth", ".cb.id"];
14
+
15
+ export const validateAddress = (address: string) => {
16
+ if (isValidNearAddress(address)) return { chainId: Network.Near, isEvm: false };
17
+ if (isValidSolanaAddress(address)) return { chainId: Network.Solana, isEvm: false };
18
+ if (isValidTronAddress(address)) return { chainId: Network.Tron, isEvm: false };
19
+ if (isValidTonAddress(address)) return { chainId: Network.Ton, isEvm: false };
20
+ if (isValidEvmAddress(address)) return { chainId: 1, isEvm: true };
21
+ if (isValidBtcAddress(address)) return { chainId: Network.Btc, isEvm: false };
22
+ if (isValidStellarAddress(address)) return { chainId: Network.Stellar, isEvm: false };
23
+ return { chainId: -1, isEvm: false };
24
+ };
25
+
26
+ export const isBase58 = (address: string) => {
27
+ try {
28
+ base58.decode(address);
29
+ return true;
30
+ } catch (e) {
31
+ return false;
32
+ }
33
+ };
34
+
35
+ export const isBase32 = (address: string) => {
36
+ try {
37
+ base32.decode(address);
38
+ return true;
39
+ } catch (e) {
40
+ return false;
41
+ }
42
+ };
43
+
44
+ export const isHex = (address: string) => {
45
+ try {
46
+ hex.decode(address);
47
+ return true;
48
+ } catch (e) {
49
+ return false;
50
+ }
51
+ };
52
+
53
+ export const isValidBtcAddress = (address: string) => {
54
+ // Basic validation for Bitcoin addresses (P2PKH, P2SH, Bech32)
55
+ const p2pkhRegex = /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/;
56
+ const p2shRegex = /^[2mn][a-km-zA-HJ-NP-Z1-9]{25,39}$/;
57
+ const bech32Regex = /^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,90}$/;
58
+
59
+ return p2pkhRegex.test(address) || p2shRegex.test(address) || bech32Regex.test(address);
60
+ };
61
+
62
+ export function isValidNearAccountId(accountId: string) {
63
+ return !!accountId && accountId.length >= MinAccountIdLen && accountId.length <= MaxAccountIdLen && accountId.match(ValidAccountRe) != null;
64
+ }
65
+
66
+ export const isValidNearAddress = (address: string, { allowWithoutDomain, allowSubdomain } = { allowWithoutDomain: false, allowSubdomain: true }) => {
67
+ if (!isValidNearAccountId(address)) return false;
68
+
69
+ if (address.length === NEAR_ADDRESS_HEX_LENGTH) return true;
70
+ if (allowWithoutDomain && !address.includes(".")) return true;
71
+
72
+ const endsWithValidDomain = NEAR_DOMAINS.some((t) => address.endsWith(t));
73
+ if (!endsWithValidDomain) return false;
74
+
75
+ const parts = address.split(".");
76
+
77
+ const lastPart = `.${parts[parts.length - 1]}`;
78
+ if (!NEAR_DOMAINS.includes(lastPart)) return false;
79
+
80
+ const otherParts = parts.slice(0, -1);
81
+ const hasOtherDomains = otherParts.some((part) => NEAR_DOMAINS.includes(`.${part}`));
82
+ if (hasOtherDomains) return false;
83
+
84
+ if (allowSubdomain) return true;
85
+ return parts.length <= 2;
86
+ };
87
+
88
+ export const isValidTronAddress = (base58Sting: string) => {
89
+ if (base58Sting.length <= 4) return false;
90
+ let address: Uint8Array;
91
+
92
+ try {
93
+ address = base58.decode(base58Sting);
94
+ } catch (e) {
95
+ return false;
96
+ }
97
+
98
+ if (base58Sting.length <= 4) return false;
99
+
100
+ const len = address.length;
101
+ const offset = len - 4;
102
+ const checkSum = address.slice(offset);
103
+ address = address.slice(0, offset);
104
+ const hash0 = sha256(address);
105
+ const hash1 = sha256(new Uint8Array(hash0));
106
+ const checkSum1 = hash1.slice(0, 4);
107
+
108
+ if (checkSum[0] === checkSum1[0] && checkSum[1] === checkSum1[1] && checkSum[2] === checkSum1[2] && checkSum[3] === checkSum1[3]) {
109
+ return true;
110
+ }
111
+
112
+ return false;
113
+ };
114
+
115
+ export const isValidSolanaAddress = (address: string) => {
116
+ if (address.startsWith("0x")) return false;
117
+ if (ethers.isAddress(address) as boolean) return false;
118
+ if (isBase58(address) && [32, 44].includes(address.length)) return true;
119
+ return !!isValidNearAccountId(address) && address.endsWith(".sol");
120
+ };
121
+
122
+ export const isValidEvmAddress = (address: string) => {
123
+ return EVM_DOMAINS.some((t) => address.endsWith(t)) || ethers.isAddress(address);
124
+ };
125
+
126
+ export const isValidStellarAddress = (address: string) => {
127
+ try {
128
+ new StellarAddress(address);
129
+ return true;
130
+ } catch (e) {
131
+ return false;
132
+ }
133
+ };
134
+
135
+ export const isValidTonAddress = (address: string) => {
136
+ try {
137
+ Address.parse(address);
138
+ return true;
139
+ } catch (e) {
140
+ return false;
141
+ }
142
+ };
143
+
144
+ export const isValidAddress = (chain: number, address: string) => {
145
+ if (chains.get(chain)?.type === WalletType.EVM) return isValidEvmAddress(address);
146
+ if (chains.get(chain)?.type === WalletType.TON) return isValidTonAddress(address);
147
+
148
+ if (chain === Network.Omni) return isValidNearAddress(address, { allowWithoutDomain: true, allowSubdomain: false });
149
+ if (chain === Network.Near) return isValidNearAddress(address);
150
+ if (chain === Network.Solana) return isValidSolanaAddress(address);
151
+ if (chain === Network.Tron) return isValidTronAddress(address);
152
+ if (chain === Network.Btc) return isValidBtcAddress(address);
153
+ if (chain === Network.Stellar) return isValidStellarAddress(address);
154
+ return false;
155
+ };
@@ -34,7 +34,7 @@ export enum WalletType {
34
34
 
35
35
  export enum Network {
36
36
  Omni_v1 = 0,
37
- Hot = -4,
37
+ Omni = -4,
38
38
 
39
39
  Zcash = -5,
40
40
  Btc = -6,
@@ -332,13 +332,13 @@ const chainsRepository: Record<number, ChainConfig> = {
332
332
  rpc: rpc(Network.Xlayer),
333
333
  type: WalletType.EVM,
334
334
  },
335
- [Network.Hot]: {
336
- id: Network.Hot,
335
+ [Network.Omni]: {
336
+ id: Network.Omni,
337
337
  key: "hot",
338
338
  name: "Omni",
339
339
  logo: "https://tgapp.herewallet.app/images/hot/hot-icon.png",
340
- currency: { id: "native", symbol: "OMNI", decimals: 6, logo: logo(Network.Hot) },
341
- rpc: rpc(Network.Hot),
340
+ currency: { id: "native", symbol: "OMNI", decimals: 6, logo: logo(Network.Omni) },
341
+ rpc: rpc(Network.Omni),
342
342
  type: WalletType.OMNI,
343
343
  },
344
344
  [Network.Cardano]: {