@hot-labs/kit 1.4.5 → 1.4.7

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 (45) hide show
  1. package/build/core/OmniConnector.d.ts +2 -0
  2. package/build/core/OmniConnector.js.map +1 -1
  3. package/build/core/OmniWallet.js +0 -1
  4. package/build/core/OmniWallet.js.map +1 -1
  5. package/build/cosmos/adr36.d.ts +21 -0
  6. package/build/cosmos/adr36.js +51 -0
  7. package/build/cosmos/adr36.js.map +1 -0
  8. package/build/cosmos/connector.d.ts +8 -2
  9. package/build/cosmos/connector.js +82 -60
  10. package/build/cosmos/connector.js.map +1 -1
  11. package/build/cosmos/wallet.d.ts +22 -4
  12. package/build/cosmos/wallet.js +53 -5
  13. package/build/cosmos/wallet.js.map +1 -1
  14. package/build/defaults.d.ts +1 -1
  15. package/build/defaults.js +2 -1
  16. package/build/defaults.js.map +1 -1
  17. package/build/evm/connector.d.ts +1 -0
  18. package/build/evm/wallet.js +0 -1
  19. package/build/evm/wallet.js.map +1 -1
  20. package/build/solana/connector.d.ts +1 -0
  21. package/build/solana/connector.js +1 -1
  22. package/build/solana/connector.js.map +1 -1
  23. package/build/stellar/connector.d.ts +1 -0
  24. package/build/tron/connector.d.ts +0 -7
  25. package/build/tron/connector.js +3 -3
  26. package/build/tron/connector.js.map +1 -1
  27. package/build/ui/connect/ConnectWallet.js +2 -2
  28. package/build/ui/connect/ConnectWallet.js.map +1 -1
  29. package/build/ui/profile/Payment.js +31 -16
  30. package/build/ui/profile/Payment.js.map +1 -1
  31. package/build/ui/profile/Profile.js +1 -1
  32. package/build/ui/profile/Profile.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/core/OmniConnector.ts +2 -2
  35. package/src/core/OmniWallet.ts +0 -1
  36. package/src/cosmos/adr36.ts +54 -0
  37. package/src/cosmos/connector.ts +91 -57
  38. package/src/cosmos/wallet.ts +68 -8
  39. package/src/defaults.ts +2 -1
  40. package/src/evm/wallet.ts +0 -1
  41. package/src/solana/connector.ts +1 -1
  42. package/src/tron/connector.ts +3 -3
  43. package/src/ui/connect/ConnectWallet.tsx +2 -2
  44. package/src/ui/profile/Payment.tsx +23 -12
  45. package/src/ui/profile/Profile.tsx +1 -1
@@ -1,5 +1,7 @@
1
1
  import { Keplr } from "@keplr-wallet/provider-extension";
2
+ import { StdSignature } from "@keplr-wallet/types";
2
3
  import { TxRaw } from "@keplr-wallet/proto-types/cosmos/tx/v1beta1/tx";
4
+ import UniversalProvider from "@walletconnect/universal-provider";
3
5
  import { StargateClient } from "@cosmjs/stargate";
4
6
  import { base64, hex } from "@scure/base";
5
7
  import { runInAction } from "mobx";
@@ -55,7 +57,7 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
55
57
  isSupported = true;
56
58
  id = "cosmos";
57
59
 
58
- constructor(wibe3: HotConnector) {
60
+ constructor(wibe3: HotConnector, readonly chainId = "gonka-mainnet") {
59
61
  super(wibe3);
60
62
 
61
63
  this.options = Object.values(wallets);
@@ -67,16 +69,18 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
67
69
  });
68
70
  });
69
71
 
70
- this.getStorage().then(async ({ type, address, publicKey }) => {
71
- if (!address || !publicKey) return;
72
+ this.getStorage().then(async (data) => {
73
+ if (!data[this.chainId]) return;
72
74
 
73
- if (type === "keplr") {
75
+ if (data.type === "keplr") {
74
76
  const keplr = await Keplr.getKeplr();
75
- if (keplr) this.setKeplrWallet(keplr, address, publicKey);
77
+ if (keplr) this.setKeplrWallet(keplr, data[this.chainId]);
76
78
  else this.disconnect();
77
79
  }
78
80
 
79
- if (type === "leap" && window.leap) this.setKeplrWallet(window.leap, address, publicKey);
81
+ if (data.type === "leap" && window.leap) {
82
+ this.setKeplrWallet(window.leap, data[this.chainId]);
83
+ }
80
84
  });
81
85
 
82
86
  this.initWalletConnect()
@@ -105,45 +109,59 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
105
109
  return chains.getByType(WalletType.COSMOS).map((t) => t.key);
106
110
  }
107
111
 
112
+ async getAccountFromWalletConnect(wc: UniversalProvider, chainId: string, id?: "keplr" | "leap" | "gonkaWallet") {
113
+ const properties = JSON.parse(wc.session?.sessionProperties?.keys || "{}");
114
+ const account = properties?.find?.((t: any) => t.chainId === chainId);
115
+
116
+ if (account) {
117
+ const publicKey = Buffer.from(account.pubKey, "base64").toString("hex");
118
+ const address = account.bech32Address || "";
119
+ return { publicKey, address };
120
+ }
121
+
122
+ const savedAccount = await this.getStorage().catch(() => null);
123
+ if (savedAccount?.[chainId]) return savedAccount[chainId];
124
+
125
+ const data = await this.requestWalletConnect({
126
+ deeplink: id ? wallets[id].deeplink : undefined,
127
+ icon: id ? wallets[id].icon : undefined,
128
+ name: id ? wallets[id].name : undefined,
129
+ request: {
130
+ method: "cosmos_getAccounts",
131
+ params: { chainId },
132
+ },
133
+ });
134
+
135
+ if (!Array.isArray(data) || data.length === 0) throw new Error("Account not found");
136
+ return { publicKey: hex.encode(base64.decode(data[0].pubkey)), address: data[0].address };
137
+ }
138
+
108
139
  async setupWalletConnect(id?: "keplr" | "leap" | "gonkaWallet"): Promise<CosmosWallet> {
109
140
  const wc = await this.wc;
110
141
  if (!wc) throw new Error("WalletConnect not found");
111
142
 
112
- const properties = JSON.parse(wc.session?.sessionProperties?.keys || "{}");
113
- const account = properties?.find?.((t: any) => t.chainId === "gonka-mainnet");
114
- let publicKey = "";
115
- let address = "";
143
+ const chainAccount = await this.getAccountFromWalletConnect(wc, this.chainId, id);
144
+ await this.setStorage({ type: "walletconnect", id, [this.chainId]: chainAccount });
116
145
 
117
- if (account) {
118
- publicKey = Buffer.from(account.pubKey, "base64").toString("hex");
119
- address = account.bech32Address || "";
120
- } else {
121
- const savedAccount = await this.getStorage().catch(() => null);
122
- if (savedAccount?.address && savedAccount?.publicKey) {
123
- publicKey = savedAccount.publicKey;
124
- address = savedAccount.address;
125
- } else {
126
- const data = await this.requestWalletConnect({
127
- deeplink: id ? wallets[id].deeplink : undefined,
128
- icon: id ? wallets[id].icon : undefined,
129
- name: id ? wallets[id].name : undefined,
146
+ const cosmosAccount = await this.getAccountFromWalletConnect(wc, "cosmoshub-4", id);
147
+ await this.setStorage({ type: "walletconnect", id, [this.chainId]: chainAccount, "cosmoshub-4": cosmosAccount });
148
+
149
+ const wallet = new CosmosWallet({
150
+ chainId: this.chainId,
151
+ account: chainAccount,
152
+ cosmos: cosmosAccount,
153
+ disableOmni: true,
154
+
155
+ disconnect: () => this.disconnectWalletConnect(),
156
+ signAmino: async (chainId: string, address: string, signDoc: any) => {
157
+ return await this.requestWalletConnect<{ signature: StdSignature }>({
130
158
  request: {
131
- method: "cosmos_getAccounts",
132
- params: { chainId: "gonka-mainnet" },
159
+ method: "cosmos_signAmino",
160
+ params: { signerAddress: address, signDoc },
133
161
  },
134
162
  });
163
+ },
135
164
 
136
- if (!Array.isArray(data) || data.length === 0) throw new Error("Account not found");
137
- publicKey = hex.encode(base64.decode(data[0].pubkey));
138
- address = data[0].address;
139
- }
140
- }
141
-
142
- this.setStorage({ type: "walletconnect", id, address, publicKey });
143
- const wallet = new CosmosWallet({
144
- address: address,
145
- publicKeyHex: publicKey,
146
- disconnect: () => this.disconnectWalletConnect(),
147
165
  sendTransaction: async (signDoc: any) => {
148
166
  const { signed, signature } = await this.requestWalletConnect<{ signed: TxRaw; signature: { signature: string } }>({
149
167
  chain: `cosmos:${signDoc.chainId}`,
@@ -153,7 +171,7 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
153
171
  request: {
154
172
  method: "cosmos_signDirect",
155
173
  params: {
156
- signerAddress: address,
174
+ signerAddress: chainAccount.address,
157
175
  signDoc: {
158
176
  chainId: signDoc.chainId,
159
177
  accountNumber: signDoc.accountNumber?.toString(),
@@ -183,17 +201,30 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
183
201
  return this.setWallet(wallet);
184
202
  }
185
203
 
186
- async setKeplrWallet(keplr: Keplr, address: string, publicKey: string) {
204
+ async setKeplrWallet(keplr: Keplr, data: { address: string; publicKey: string }) {
205
+ const account = await keplr.getKey("cosmoshub-4");
187
206
  return this.setWallet(
188
207
  new CosmosWallet({
189
- address: address,
190
- publicKeyHex: publicKey,
208
+ account: data,
209
+ cosmos: { address: account.bech32Address, publicKey: hex.encode(account.pubKey) },
210
+ chainId: this.chainId,
211
+ disableOmni: true,
212
+
191
213
  disconnect: () => keplr.disable(),
214
+
215
+ signMessage: async (chainId: string, address: string, message: string) => {
216
+ return await keplr.signArbitrary(chainId, address, message);
217
+ },
218
+
192
219
  sendTransaction: async (signDoc: any) => {
193
220
  await keplr.enable(this.chains);
194
221
  const rpcEndpoint = chains.getByKey(signDoc.chainId)?.rpc || "";
195
222
  return await signAndSendTx(keplr, rpcEndpoint, api.apiKey, signDoc);
196
223
  },
224
+
225
+ signAmino: async (chainId: string, address: string, signDoc: any) => {
226
+ return await keplr.signAmino(chainId, address, signDoc);
227
+ },
197
228
  })
198
229
  );
199
230
  }
@@ -204,9 +235,9 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
204
235
  deeplink: wallets["gonkaWallet"].deeplink,
205
236
  namespaces: {
206
237
  cosmos: {
238
+ chains: [...new Set([`cosmos:${this.chainId}`, "cosmos:cosmoshub-4"])],
207
239
  methods: ["cosmos_getAccounts", "cosmos_signDirect"],
208
240
  events: ["chainChanged", "accountsChanged"],
209
- chains: this.chains.map((chain) => `cosmos:${chain}`),
210
241
  rpcMap: {},
211
242
  },
212
243
  },
@@ -223,31 +254,34 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
223
254
  deeplink: wallets[type].deeplink,
224
255
  namespaces: {
225
256
  cosmos: {
257
+ chains: [...new Set([`cosmos:${this.chainId}`, "cosmos:cosmoshub-4"])],
226
258
  methods: ["cosmos_getAccounts", "cosmos_signDirect"],
227
259
  events: ["chainChanged", "accountsChanged"],
228
- chains: this.chains.map((chain) => `cosmos:${chain}`),
229
260
  rpcMap: {},
230
261
  },
231
262
  },
232
263
  });
233
264
  }
234
265
 
235
- await extension.experimentalSuggestChain({
236
- bech32Config: { bech32PrefixAccAddr: "gonka", bech32PrefixAccPub: "gonka", bech32PrefixValAddr: "gonka", bech32PrefixValPub: "gonka", bech32PrefixConsAddr: "gonka", bech32PrefixConsPub: "gonka" },
237
- feeCurrencies: [{ coinDenom: "GNK", coinMinimalDenom: "ngonka", coinDecimals: 9, coinGeckoId: "gonka", gasPriceStep: { low: 0, average: 0, high: 0 } }],
238
- stakeCurrency: { coinDenom: "GNK", coinMinimalDenom: "ngonka", coinDecimals: 9, coinGeckoId: "gonka" },
239
- currencies: [{ coinDenom: "GNK", coinMinimalDenom: "ngonka", coinDecimals: 9, coinGeckoId: "gonka" }],
240
- rpc: "https://gonka04.6block.com:8443/chain-rpc",
241
- rest: "https://gonka04.6block.com:8443/chain-api",
242
- bip44: { coinType: 1200 },
243
- chainId: "gonka-mainnet",
244
- chainName: "Gonka",
245
- });
266
+ if (this.chainId === "gonka-mainnet") {
267
+ await extension.experimentalSuggestChain({
268
+ bech32Config: { bech32PrefixAccAddr: "gonka", bech32PrefixAccPub: "gonka", bech32PrefixValAddr: "gonka", bech32PrefixValPub: "gonka", bech32PrefixConsAddr: "gonka", bech32PrefixConsPub: "gonka" },
269
+ feeCurrencies: [{ coinDenom: "GNK", coinMinimalDenom: "ngonka", coinDecimals: 9, coinGeckoId: "gonka", gasPriceStep: { low: 0, average: 0, high: 0 } }],
270
+ stakeCurrency: { coinDenom: "GNK", coinMinimalDenom: "ngonka", coinDecimals: 9, coinGeckoId: "gonka" },
271
+ currencies: [{ coinDenom: "GNK", coinMinimalDenom: "ngonka", coinDecimals: 9, coinGeckoId: "gonka" }],
272
+ rpc: "https://gonka04.6block.com:8443/chain-rpc",
273
+ rest: "https://gonka04.6block.com:8443/chain-api",
274
+ bip44: { coinType: 1200 },
275
+ chainId: "gonka-mainnet",
276
+ chainName: "Gonka",
277
+ });
278
+ }
246
279
 
247
280
  await extension.enable(this.chains);
248
- const account = await extension.getKey("gonka-mainnet");
249
- await this.setStorage({ type, address: account.bech32Address, publicKey: hex.encode(account.pubKey) });
250
- return await this.setKeplrWallet(extension, account.bech32Address, hex.encode(account.pubKey));
281
+ const account = await extension.getKey(this.chainId);
282
+ const chainAccount = { address: account.bech32Address, publicKey: hex.encode(account.pubKey) };
283
+ await this.setStorage({ type, [this.chainId]: chainAccount });
284
+ return await this.setKeplrWallet(extension, chainAccount);
251
285
  }
252
286
 
253
287
  async connect(id: string) {
@@ -256,9 +290,9 @@ export default class CosmosConnector extends OmniConnector<CosmosWallet> {
256
290
  onConnect: () => this.setupWalletConnect(),
257
291
  namespaces: {
258
292
  cosmos: {
293
+ chains: [...new Set([`cosmos:${this.chainId}`, "cosmos:cosmoshub-4"])],
259
294
  methods: ["cosmos_getAccounts", "cosmos_signDirect"],
260
295
  events: ["chainChanged", "accountsChanged"],
261
- chains: this.chains.map((chain) => `cosmos:${chain}`),
262
296
  rpcMap: {},
263
297
  },
264
298
  },
@@ -1,14 +1,25 @@
1
+ import { Signature, computeAddress, recoverAddress } from "ethers";
2
+ import { StdSignature } from "@keplr-wallet/types";
1
3
  import { StargateClient } from "@cosmjs/stargate";
4
+ import { sha256 } from "@noble/hashes/sha2.js";
5
+ import { base58, base64, hex } from "@scure/base";
6
+
2
7
  import { OmniWallet } from "../core/OmniWallet";
3
8
  import { chains, WalletType } from "../core/chains";
9
+ import { Commitment } from "../core/types";
4
10
  import { ReviewFee } from "../core/bridge";
5
- import { Commitment } from "../core";
11
+
12
+ import { makeADR36AminoSignDoc, serializeSignDoc } from "./adr36";
6
13
 
7
14
  interface ProtocolWallet {
8
15
  disconnect?: () => Promise<void>;
16
+ signMessage?: (chainId: string, address: string, message: string) => Promise<StdSignature>;
17
+ signAmino: (chainId: string, address: string, signDoc: any) => Promise<{ signature: StdSignature }>;
9
18
  sendTransaction?: (signDoc: any) => Promise<string>;
10
- address: string;
11
- publicKeyHex: string;
19
+ account: { address: string; publicKey: string };
20
+ cosmos: { address: string; publicKey: string };
21
+ disableOmni: boolean;
22
+ chainId: string;
12
23
  }
13
24
 
14
25
  export default class CosmosWallet extends OmniWallet {
@@ -20,15 +31,16 @@ export default class CosmosWallet extends OmniWallet {
20
31
  }
21
32
 
22
33
  get address() {
23
- return this.wallet.address;
34
+ return this.wallet.account.address;
24
35
  }
25
36
 
26
37
  get publicKey() {
27
- return this.wallet.publicKeyHex;
38
+ return this.wallet.account.publicKey;
28
39
  }
29
40
 
30
41
  get omniAddress() {
31
- return "";
42
+ if (this.wallet.disableOmni) return "";
43
+ return computeAddress(`0x${this.wallet.cosmos.publicKey}`).toLowerCase();
32
44
  }
33
45
 
34
46
  sendTransaction(signDoc: any): Promise<string> {
@@ -44,8 +56,56 @@ export default class CosmosWallet extends OmniWallet {
44
56
  throw "Not impl";
45
57
  }
46
58
 
47
- signIntents(): Promise<Commitment> {
48
- throw new Error("Method not implemented.");
59
+ async findFullSignature(signature: Uint8Array, msgHash: Uint8Array) {
60
+ const validate = (v: 0 | 1) => {
61
+ const sign = Signature.from({ v: v, r: "0x" + hex.encode(signature.slice(0, 32)), s: "0x" + hex.encode(signature.slice(32)) });
62
+ const recoveredAddr = recoverAddress(msgHash, sign.serialized);
63
+ if (this.omniAddress === recoveredAddr.toLowerCase()) return new Uint8Array([...signature, v]);
64
+ return null;
65
+ };
66
+
67
+ const sig27 = validate(0);
68
+ if (sig27) return sig27;
69
+
70
+ const sig28 = validate(1);
71
+ if (sig28) return sig28;
72
+
73
+ throw "Invalid signature";
74
+ }
75
+
76
+ async signMessage(message: string): Promise<StdSignature> {
77
+ if (!this.wallet.signMessage) {
78
+ const signDoc = makeADR36AminoSignDoc(this.wallet.cosmos.address, message);
79
+ const { signature } = await this.wallet.signAmino("cosmoshub-4", this.wallet.cosmos.address, signDoc);
80
+ return signature;
81
+ }
82
+
83
+ return await this.wallet.signMessage("cosmoshub-4", this.wallet.cosmos.address, message);
84
+ }
85
+
86
+ async signIntents(intents: Record<string, any>[], options?: { deadline?: number; nonce?: Uint8Array }): Promise<Commitment> {
87
+ if (this.wallet.disableOmni) throw "Sign intents is not supported for this wallet";
88
+
89
+ const nonce = new Uint8Array(options?.nonce || window.crypto.getRandomValues(new Uint8Array(32)));
90
+ const message = JSON.stringify({
91
+ deadline: options?.deadline ? new Date(options.deadline).toISOString() : "2100-01-01T00:00:00.000Z",
92
+ verifying_contract: "intents.near",
93
+ signer_id: this.omniAddress,
94
+ nonce: base64.encode(nonce),
95
+ intents: intents,
96
+ });
97
+
98
+ const signDoc = makeADR36AminoSignDoc(this.wallet.cosmos.address, message);
99
+ const { signature } = await this.signMessage(message);
100
+
101
+ const msgHash = sha256(serializeSignDoc(signDoc));
102
+ const fullSignature = await this.findFullSignature(base64.decode(signature), msgHash);
103
+
104
+ return {
105
+ standard: "adr36",
106
+ signature: `secp256k1:${base58.encode(fullSignature)}`,
107
+ payload: { signer: this.wallet.cosmos.address, message },
108
+ };
49
109
  }
50
110
 
51
111
  async fetchBalances(chain: number, whitelist: string[] = []): Promise<Record<string, bigint>> {
package/src/defaults.ts CHANGED
@@ -3,5 +3,6 @@ import solana from "./solana";
3
3
  import near from "./near";
4
4
  import evm from "./evm";
5
5
  import ton from "./ton";
6
+ import tron from "./tron";
6
7
 
7
- export const defaultConnectors = [near(), evm(), solana(), ton(), stellar()];
8
+ export const defaultConnectors = [near(), evm(), solana(), ton(), stellar(), tron()];
package/src/evm/wallet.ts CHANGED
@@ -35,7 +35,6 @@ class EvmWallet extends OmniWallet {
35
35
 
36
36
  private rpcs: Record<number, JsonRpcProvider> = {};
37
37
  rpc(chain: number) {
38
- console.log("getting rpc for chain", { chain });
39
38
  if (chain < 1 || chain == null) throw "Invalid chain";
40
39
  if (this.rpcs[chain]) return this.rpcs[chain];
41
40
 
@@ -58,7 +58,7 @@ class SolanaConnector extends OmniConnector<SolanaWallet, { wallet: Wallet }> {
58
58
 
59
59
  try {
60
60
  const connected = await this.getConnectedWallet();
61
- if (connected !== wallet.name) return;
61
+ if (connected.id !== wallet.name) return;
62
62
  const protocolWallet = await SolanaProtocolWallet.connect(wallet, { silent: true });
63
63
  this.setWallet(new SolanaWallet(protocolWallet));
64
64
  } catch {
@@ -26,8 +26,8 @@ declare global {
26
26
  const TRONLINK = {
27
27
  id: "tronlink",
28
28
  name: "Tron Link",
29
- type: window?.tronLink ? ("extension" as const) : ("external" as const),
30
- icon: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tron/info/logo.png",
29
+ type: "extension" as const,
30
+ icon: "https://cdn.brandfetch.io/id0PcTcDBs/w/400/h/400/theme/dark/icon.jpeg",
31
31
  download: "https://www.tronlink.org/",
32
32
  };
33
33
 
@@ -36,11 +36,11 @@ class TronConnector extends OmniConnector<TronWallet> {
36
36
  walletTypes = [WalletType.Tron, WalletType.OMNI];
37
37
  icon = "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tron/info/logo.png";
38
38
  name = "TRON Wallet";
39
- options = [TRONLINK];
40
39
  id = "tron";
41
40
 
42
41
  constructor(wibe3: HotConnector) {
43
42
  super(wibe3);
43
+ this.options = [TRONLINK];
44
44
 
45
45
  this.syncFromProvider().catch(() => this.removeStorage());
46
46
  window.addEventListener("message", () => {
@@ -22,8 +22,8 @@ interface MultichainPopupProps {
22
22
  }
23
23
 
24
24
  export const Connector = observer(({ hot, onClose, title, walletType, widget }: MultichainPopupProps) => {
25
- const onechain = hot.connectors.filter((t) => t.type === ConnectorType.WALLET && (walletType == null || t.walletTypes.includes(walletType as WalletType)));
26
- const social = hot.connectors.filter((t) => t.type === ConnectorType.SOCIAL && (walletType == null || t.walletTypes.includes(walletType as WalletType)));
25
+ const onechain = hot.connectors.filter((t) => t.type === ConnectorType.WALLET && (walletType == null || t.walletTypes.includes(walletType as WalletType)) && t.options.length > 0);
26
+ const social = hot.connectors.filter((t) => t.type === ConnectorType.SOCIAL && (walletType == null || t.walletTypes.includes(walletType as WalletType)) && t.options.length > 0);
27
27
 
28
28
  const selectConnector = async (t: OmniConnector) => {
29
29
  if (t.wallets[0]) return t.disconnect();
@@ -4,7 +4,6 @@ import styled from "styled-components";
4
4
 
5
5
  import { HelpIcon } from "../icons/help";
6
6
  import { WalletIcon } from "../icons/wallet";
7
- import { PopupOption, PopupOptionInfo } from "../styles";
8
7
 
9
8
  import { Commitment, Intents } from "../../core";
10
9
  import { BridgeReview } from "../../core/exchange";
@@ -17,9 +16,10 @@ import { ActionButton } from "../uikit/button";
17
16
  import { H6, PSmall } from "../uikit/text";
18
17
  import { Loader } from "../uikit/loader";
19
18
 
20
- import { openConnector } from "../router";
19
+ import { PopupOption, PopupOptionInfo } from "../styles";
21
20
  import { HotConnector } from "../../HotConnector";
22
21
  import { TokenCard } from "../bridge/TokenCard";
22
+ import { openConnector } from "../router";
23
23
  import Popup from "../Popup";
24
24
 
25
25
  interface PaymentProps {
@@ -81,11 +81,12 @@ export const Payment = observer(({ connector, intents, title = "Payment", allowe
81
81
  const isStable = isStableFrom && isStableTo;
82
82
 
83
83
  let tasks: Promise<BridgeReview>[] = [];
84
- if (isStable) {
84
+ if (isStable && !isDirectDeposit) {
85
85
  const slippages = [0.0005, 0.001, 0.0015];
86
- tasks = slippages.map((slippage) =>
87
- connector.exchange.reviewSwap({
88
- amount: needAmount + (isDirectDeposit ? 0n : (needAmount * BigInt(Math.floor(slippage * 1000))) / BigInt(1000)),
86
+ tasks = slippages.map((slippage) => {
87
+ const extra = (needAmount * BigInt(Math.floor(slippage * 1000))) / BigInt(1000);
88
+ return connector.exchange.reviewSwap({
89
+ amount: from.int(payableToken.float(needAmount + extra)),
89
90
  recipient: intents.signer!,
90
91
  slippage: slippage,
91
92
  sender: wallet,
@@ -93,12 +94,12 @@ export const Payment = observer(({ connector, intents, title = "Payment", allowe
93
94
  type: "exactIn",
94
95
  to: payableToken,
95
96
  from,
96
- })
97
- );
97
+ });
98
+ });
98
99
  }
99
100
 
100
- tasks.push(
101
- connector.exchange.reviewSwap({
101
+ const exectOutReview = await connector.exchange
102
+ .reviewSwap({
102
103
  slippage: isStable ? STABLE_SLIPPAGE : PAY_SLIPPAGE,
103
104
  recipient: intents.signer!,
104
105
  amount: needAmount,
@@ -108,7 +109,7 @@ export const Payment = observer(({ connector, intents, title = "Payment", allowe
108
109
  to: payableToken,
109
110
  from,
110
111
  })
111
- );
112
+ .catch(() => null);
112
113
 
113
114
  for (const task of tasks) {
114
115
  const review = await task.catch((e) => {
@@ -116,12 +117,22 @@ export const Payment = observer(({ connector, intents, title = "Payment", allowe
116
117
  return null;
117
118
  });
118
119
 
120
+ // console.log(task);
119
121
  if (!review) continue;
122
+ // console.log(review.to.float(review.minAmountOut), review.to.float(needAmount));
120
123
  if (review.minAmountOut < needAmount) continue;
124
+
125
+ // If exact out review is available and it's qoute is better than the exact in qoute, skip the exact in qoute
126
+ // console.log("EXACT IN", review.from.float(review.amountIn), "EXECT_OUT", exectOutReview?.from.float(exectOutReview.amountIn));
127
+ if (exectOutReview != null && review.amountIn > exectOutReview.amountIn) continue;
128
+
129
+ // console.log("RESULT EXACT IN", review);
121
130
  return setFlow({ token: from, wallet, review, step: "sign" });
122
131
  }
123
132
 
124
- setFlow({ token: from, wallet, error: true, step: "sign" });
133
+ if (exectOutReview == null) return setFlow({ token: from, wallet, error: true, step: "sign" });
134
+ setFlow({ token: from, wallet, review: exectOutReview, step: "sign" });
135
+ // console.log("RESULT EXECT OUT", exectOutReview);
125
136
  };
126
137
 
127
138
  const signStep = async () => {
@@ -64,7 +64,7 @@ export const Profile = observer(({ hot, onClose }: { hot: HotConnector; onClose:
64
64
  ))
65
65
  )}
66
66
 
67
- {hot.wallets.length < 6 && (
67
+ {hot.wallets.length < hot.connectors.length && (
68
68
  <WalletCard style={{ paddingRight: 12 }} onClick={() => openConnector(hot)}>
69
69
  <PlusIcon />
70
70
  Add wallet