@hot-labs/kit 1.1.0-beta.4 → 1.1.0-beta.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.
- package/build/core/Intents.d.ts +15 -19
- package/build/core/Intents.js +85 -61
- package/build/core/Intents.js.map +1 -1
- package/build/core/utils.js +11 -1
- package/build/core/utils.js.map +1 -1
- package/build/exchange.js +1 -1
- package/build/exchange.js.map +1 -1
- package/build/solana/wallet.js +1 -1
- package/build/solana/wallet.js.map +1 -1
- package/build/ui/Popup.d.ts +1 -1
- package/build/ui/Popup.js +4 -0
- package/build/ui/Popup.js.map +1 -1
- package/build/ui/Toast.d.ts +4 -0
- package/build/ui/Toast.js +33 -0
- package/build/ui/Toast.js.map +1 -0
- package/build/ui/payment/Payment.d.ts +6 -5
- package/build/ui/payment/Payment.js +13 -20
- package/build/ui/payment/Payment.js.map +1 -1
- package/build/ui/router.d.ts +4 -3
- package/build/ui/router.js +6 -2
- package/build/ui/router.js.map +1 -1
- package/package.json +1 -1
- package/src/core/Intents.ts +88 -61
- package/src/core/utils.ts +6 -1
- package/src/exchange.ts +1 -1
- package/src/solana/wallet.ts +1 -2
- package/src/ui/Popup.tsx +5 -0
- package/src/ui/Toast.tsx +45 -0
- package/src/ui/payment/Payment.tsx +18 -25
- package/src/ui/router.tsx +9 -4
package/src/core/Intents.ts
CHANGED
|
@@ -7,10 +7,9 @@ import { rpc } from "../near/rpc";
|
|
|
7
7
|
import type { Intent, Commitment, TokenDiffIntent, MtWithdrawIntent, FtWithdrawIntent, NftWithdrawIntent, TransferIntent } from "./types";
|
|
8
8
|
import { OmniToken } from "./chains";
|
|
9
9
|
import { tokens } from "./tokens";
|
|
10
|
-
import { formatter } from "./utils";
|
|
11
10
|
import { api } from "./api";
|
|
12
11
|
|
|
13
|
-
import { openPayment } from "../ui/router";
|
|
12
|
+
import { openPayment, openToast } from "../ui/router";
|
|
14
13
|
|
|
15
14
|
export const TGAS = 1000000000000n;
|
|
16
15
|
|
|
@@ -21,14 +20,22 @@ export class Intents {
|
|
|
21
20
|
return new Intents();
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
intents: Intent[] = [];
|
|
26
|
-
signer?: OmniWallet;
|
|
27
|
-
nonce?: Uint8Array;
|
|
28
|
-
deadline?: Date;
|
|
29
|
-
|
|
23
|
+
signedHashes: string[] = [];
|
|
30
24
|
commitments: Commitment[] = [];
|
|
31
25
|
need = new Map<OmniToken, bigint>();
|
|
26
|
+
signer?: OmniWallet;
|
|
27
|
+
|
|
28
|
+
unsignedCommitment?: {
|
|
29
|
+
intents: Intent[];
|
|
30
|
+
nonce?: Uint8Array;
|
|
31
|
+
deadline?: Date;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
addIntent(intent: Intent) {
|
|
35
|
+
if (!this.unsignedCommitment) this.unsignedCommitment = { intents: [] };
|
|
36
|
+
this.unsignedCommitment.intents.push(intent);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
32
39
|
|
|
33
40
|
addNeed(token: OmniToken, amount: bigint) {
|
|
34
41
|
if (!this.need.has(token)) this.need.set(token, 0n);
|
|
@@ -38,7 +45,7 @@ export class Intents {
|
|
|
38
45
|
|
|
39
46
|
authCall(args: { contractId: string; msg: string; attachNear: bigint; tgas: number }) {
|
|
40
47
|
this.addNeed(OmniToken.NEAR, args.attachNear);
|
|
41
|
-
this.
|
|
48
|
+
this.addIntent({
|
|
42
49
|
min_gas: (BigInt(args.tgas) * TGAS).toString(),
|
|
43
50
|
attached_deposit: args.attachNear.toString(),
|
|
44
51
|
contract_id: args.contractId,
|
|
@@ -58,7 +65,7 @@ export class Intents {
|
|
|
58
65
|
recipient: "pay.fi.tg",
|
|
59
66
|
amount,
|
|
60
67
|
token,
|
|
61
|
-
}).
|
|
68
|
+
}).yieldExecute({ email });
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
transfer(args: { recipient: string; token: OmniToken; amount: number | bigint; memo?: string; msg?: string; tgas?: number }) {
|
|
@@ -74,7 +81,7 @@ export class Intents {
|
|
|
74
81
|
};
|
|
75
82
|
|
|
76
83
|
this.addNeed(args.token, BigInt(amount));
|
|
77
|
-
this.
|
|
84
|
+
this.addIntent(intent);
|
|
78
85
|
return this;
|
|
79
86
|
}
|
|
80
87
|
|
|
@@ -96,7 +103,7 @@ export class Intents {
|
|
|
96
103
|
msg: args.msg,
|
|
97
104
|
};
|
|
98
105
|
|
|
99
|
-
this.
|
|
106
|
+
this.addIntent(intent);
|
|
100
107
|
return this;
|
|
101
108
|
}
|
|
102
109
|
|
|
@@ -119,7 +126,7 @@ export class Intents {
|
|
|
119
126
|
}
|
|
120
127
|
}
|
|
121
128
|
|
|
122
|
-
this.
|
|
129
|
+
this.addIntent(intent);
|
|
123
130
|
return this;
|
|
124
131
|
}
|
|
125
132
|
|
|
@@ -156,7 +163,7 @@ export class Intents {
|
|
|
156
163
|
this.addNeed(token, BigInt(rawIntent.amounts[i]));
|
|
157
164
|
}
|
|
158
165
|
|
|
159
|
-
this.
|
|
166
|
+
this.addIntent({
|
|
160
167
|
intent: "mt_withdraw",
|
|
161
168
|
amounts: rawIntent.amounts,
|
|
162
169
|
receiver_id: rawIntent.receiver_id,
|
|
@@ -211,12 +218,12 @@ export class Intents {
|
|
|
211
218
|
}
|
|
212
219
|
|
|
213
220
|
addPublicKey(publicKey: string) {
|
|
214
|
-
this.
|
|
221
|
+
this.addIntent({ intent: "add_public_key", public_key: publicKey });
|
|
215
222
|
return this;
|
|
216
223
|
}
|
|
217
224
|
|
|
218
225
|
removePublicKey(publicKey: string) {
|
|
219
|
-
this.
|
|
226
|
+
this.addIntent({ intent: "remove_public_key", public_key: publicKey });
|
|
220
227
|
return this;
|
|
221
228
|
}
|
|
222
229
|
|
|
@@ -229,7 +236,7 @@ export class Intents {
|
|
|
229
236
|
if (standart === "nep245") {
|
|
230
237
|
const mtContract = tokenParts[0];
|
|
231
238
|
const tokenId = tokenParts.slice(1).join(":");
|
|
232
|
-
this.
|
|
239
|
+
this.addIntent({
|
|
233
240
|
intent: "mt_withdraw",
|
|
234
241
|
amounts: [amount],
|
|
235
242
|
receiver_id: args.receiver,
|
|
@@ -243,7 +250,7 @@ export class Intents {
|
|
|
243
250
|
}
|
|
244
251
|
|
|
245
252
|
if (standart === "nep141") {
|
|
246
|
-
this.
|
|
253
|
+
this.addIntent({
|
|
247
254
|
intent: "ft_withdraw",
|
|
248
255
|
receiver_id: args.receiver,
|
|
249
256
|
token: tokenParts.join(":"),
|
|
@@ -255,7 +262,7 @@ export class Intents {
|
|
|
255
262
|
}
|
|
256
263
|
|
|
257
264
|
if (standart === "nep171") {
|
|
258
|
-
this.
|
|
265
|
+
this.addIntent({
|
|
259
266
|
intent: "nft_withdraw",
|
|
260
267
|
receiver_id: args.receiver,
|
|
261
268
|
token_id: tokenParts.join(":"),
|
|
@@ -270,7 +277,7 @@ export class Intents {
|
|
|
270
277
|
}
|
|
271
278
|
|
|
272
279
|
attachHashes(hashes: string[]) {
|
|
273
|
-
this.
|
|
280
|
+
this.signedHashes.push(...hashes);
|
|
274
281
|
return this;
|
|
275
282
|
}
|
|
276
283
|
|
|
@@ -280,22 +287,26 @@ export class Intents {
|
|
|
280
287
|
}
|
|
281
288
|
|
|
282
289
|
attachDeadline(deadline: Date) {
|
|
283
|
-
this.
|
|
290
|
+
if (!this.unsignedCommitment) this.unsignedCommitment = { intents: [] };
|
|
291
|
+
this.unsignedCommitment.deadline = deadline;
|
|
284
292
|
return this;
|
|
285
293
|
}
|
|
286
294
|
|
|
287
295
|
attachNonce(nonce: Uint8Array) {
|
|
288
|
-
this.
|
|
296
|
+
if (!this.unsignedCommitment) this.unsignedCommitment = { intents: [] };
|
|
297
|
+
this.unsignedCommitment.nonce = nonce;
|
|
289
298
|
return this;
|
|
290
299
|
}
|
|
291
300
|
|
|
292
301
|
attachTimeout(seconds: number) {
|
|
293
|
-
this.
|
|
302
|
+
if (!this.unsignedCommitment) this.unsignedCommitment = { intents: [] };
|
|
303
|
+
this.unsignedCommitment.deadline = new Date(Date.now() + seconds * 1000);
|
|
294
304
|
return this;
|
|
295
305
|
}
|
|
296
306
|
|
|
297
307
|
attachSeed(seed: string) {
|
|
298
|
-
this.
|
|
308
|
+
if (!this.unsignedCommitment) this.unsignedCommitment = { intents: [] };
|
|
309
|
+
this.unsignedCommitment.nonce = new Uint8Array(sha256(new TextEncoder().encode(seed))).slice(0, 32);
|
|
299
310
|
return this;
|
|
300
311
|
}
|
|
301
312
|
|
|
@@ -308,10 +319,10 @@ export class Intents {
|
|
|
308
319
|
const intAmount = typeof amount === "number" ? tokens.get(token).int(amount) : amount;
|
|
309
320
|
|
|
310
321
|
// this.addNeed(token, -intAmount); Do we need to add the need here?
|
|
311
|
-
const tokenDiff = this.intents.find((intent) => intent.intent === "token_diff");
|
|
322
|
+
const tokenDiff = this.unsignedCommitment?.intents.find((intent) => intent.intent === "token_diff");
|
|
312
323
|
|
|
313
324
|
if (tokenDiff) tokenDiff.diff[token.toString()] = intAmount.toString();
|
|
314
|
-
else this.
|
|
325
|
+
else this.addIntent({ intent: "token_diff", diff: { [token.toString()]: intAmount.toString() } });
|
|
315
326
|
return this;
|
|
316
327
|
}
|
|
317
328
|
|
|
@@ -319,10 +330,10 @@ export class Intents {
|
|
|
319
330
|
const intAmount = typeof amount === "number" ? tokens.get(token).int(amount) : amount;
|
|
320
331
|
|
|
321
332
|
this.addNeed(token as OmniToken, intAmount);
|
|
322
|
-
const tokenDiff = this.intents.find((intent) => intent.intent === "token_diff");
|
|
333
|
+
const tokenDiff = this.unsignedCommitment?.intents.find((intent) => intent.intent === "token_diff");
|
|
323
334
|
|
|
324
335
|
if (tokenDiff) tokenDiff.diff[token.toString()] = (-intAmount).toString();
|
|
325
|
-
else this.
|
|
336
|
+
else this.addIntent({ intent: "token_diff", diff: { [token.toString()]: (-intAmount).toString() } });
|
|
326
337
|
return this;
|
|
327
338
|
}
|
|
328
339
|
|
|
@@ -332,9 +343,13 @@ export class Intents {
|
|
|
332
343
|
if (!signer.omniAddress) throw new Error("No omni address");
|
|
333
344
|
|
|
334
345
|
const commitments: Commitment[] = [];
|
|
335
|
-
for (const intent of this.intents) {
|
|
336
|
-
|
|
337
|
-
|
|
346
|
+
for (const intent of this.unsignedCommitment?.intents || []) {
|
|
347
|
+
commitments.push(
|
|
348
|
+
await signer.signIntents([intent], {
|
|
349
|
+
deadline: this.unsignedCommitment?.deadline ? +this.unsignedCommitment.deadline : undefined,
|
|
350
|
+
nonce: this.unsignedCommitment?.nonce,
|
|
351
|
+
})
|
|
352
|
+
);
|
|
338
353
|
}
|
|
339
354
|
|
|
340
355
|
return commitments;
|
|
@@ -344,48 +359,60 @@ export class Intents {
|
|
|
344
359
|
const signer = this.signer;
|
|
345
360
|
if (!signer) throw new Error("No signer attached");
|
|
346
361
|
if (!signer.omniAddress) throw new Error("No omni address");
|
|
347
|
-
|
|
348
|
-
deadline: this.deadline ? +this.deadline : undefined,
|
|
349
|
-
nonce: this.nonce,
|
|
362
|
+
const commitment = await signer.signIntents(this.unsignedCommitment?.intents || [], {
|
|
363
|
+
deadline: this.unsignedCommitment?.deadline ? +this.unsignedCommitment.deadline : undefined,
|
|
364
|
+
nonce: this.unsignedCommitment?.nonce,
|
|
350
365
|
});
|
|
366
|
+
|
|
367
|
+
this.unsignedCommitment = undefined;
|
|
368
|
+
this.commitments.push(commitment);
|
|
369
|
+
return this;
|
|
351
370
|
}
|
|
352
371
|
|
|
353
372
|
async simulate() {
|
|
354
|
-
if (
|
|
355
|
-
|
|
356
|
-
return await Intents.simulateIntents([signed]);
|
|
373
|
+
if (this.commitments.length === 0) throw new Error("No commitments attached");
|
|
374
|
+
return await Intents.simulateIntents(this.commitments);
|
|
357
375
|
}
|
|
358
376
|
|
|
359
|
-
async
|
|
377
|
+
async yieldExecute(payload?: Record<string, any>) {
|
|
360
378
|
if (!this.wibe3) throw new Error("No wibe3 attached");
|
|
361
|
-
|
|
362
|
-
|
|
379
|
+
const { depositQoute, processing } = await openPayment(this.wibe3, this);
|
|
380
|
+
const depositAddress = depositQoute === "direct" ? undefined : typeof depositQoute?.qoute === "object" ? depositQoute?.qoute?.depositAddress : undefined;
|
|
363
381
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
async executeBatch(params = { checkTokens: true, chunkSize: this.intents.length, onSuccess: (bucket: number, hash: string) => {} }) {
|
|
371
|
-
if (!this.signer) throw new Error("No signer attached");
|
|
372
|
-
const batches = formatter.chunk(this.intents, params.chunkSize);
|
|
373
|
-
let index = 0;
|
|
382
|
+
if (depositAddress) {
|
|
383
|
+
const { near_trx } = await api.yieldIntentCall({ depositAddress, commitment: this.commitments[0], payload });
|
|
384
|
+
return near_trx;
|
|
385
|
+
}
|
|
374
386
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
deadline: this.deadline ? +this.deadline : undefined,
|
|
379
|
-
nonce: this.nonce,
|
|
380
|
-
});
|
|
387
|
+
await processing?.();
|
|
388
|
+
return this.execute();
|
|
389
|
+
}
|
|
381
390
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
391
|
+
async depositAndExecute({ actionName = "Payment", message }: { actionName?: string; message?: string } = {}) {
|
|
392
|
+
if (!this.wibe3) throw new Error("No wibe3 attached");
|
|
393
|
+
const { processing } = await openPayment(this.wibe3, this, actionName);
|
|
394
|
+
const close = openToast(message || "Executing payment");
|
|
395
|
+
|
|
396
|
+
try {
|
|
397
|
+
await processing?.();
|
|
398
|
+
const result = await this.execute();
|
|
399
|
+
close();
|
|
400
|
+
return result;
|
|
401
|
+
} catch (e) {
|
|
402
|
+
close();
|
|
403
|
+
throw e;
|
|
386
404
|
}
|
|
405
|
+
}
|
|
387
406
|
|
|
388
|
-
|
|
407
|
+
async execute() {
|
|
408
|
+
if (this.unsignedCommitment != null) await this.sign();
|
|
409
|
+
const task = Intents.publish(this.commitments, this.signedHashes);
|
|
410
|
+
this.commitments = [];
|
|
411
|
+
this.signedHashes = [];
|
|
412
|
+
|
|
413
|
+
const hash = await task;
|
|
414
|
+
await rpc.waitTransactionResult(hash, "intents.near");
|
|
415
|
+
return hash;
|
|
389
416
|
}
|
|
390
417
|
|
|
391
418
|
static async publish(signed: Commitment[], hashes: string[] = []): Promise<string> {
|
package/src/core/utils.ts
CHANGED
|
@@ -148,7 +148,12 @@ export const formatter = {
|
|
|
148
148
|
},
|
|
149
149
|
|
|
150
150
|
amount(value: Value, decimals = 24) {
|
|
151
|
-
|
|
151
|
+
if (+formatter.num(value) > 1_000_000_000_000_000_000) return `${formatter.round(+formatter.num(value) / 1_000_000_000_000_000, 2)}Q`;
|
|
152
|
+
if (+formatter.num(value) > 1_000_000_000_000_000) return `${formatter.round(+formatter.num(value) / 1_000_000_000_000, 2)}T`;
|
|
153
|
+
if (+formatter.num(value) > 1_000_000_000_000) return `${formatter.round(+formatter.num(value) / 1_000_000_000, 2)}B`;
|
|
154
|
+
if (+formatter.num(value) > 1_000_000_000) return `${formatter.round(+formatter.num(value) / 1_000_000, 2)}M`;
|
|
155
|
+
const num = formatter.num(value).toFixed(decimals);
|
|
156
|
+
if (+num === 0) return "0";
|
|
152
157
|
return formatter.formatNumberWithSubscriptZeros(num, 3, 0.0001);
|
|
153
158
|
},
|
|
154
159
|
|
package/src/exchange.ts
CHANGED
|
@@ -184,7 +184,7 @@ export class Exchange {
|
|
|
184
184
|
if (!intentFrom) throw new Error("Unsupported token");
|
|
185
185
|
if (!intentTo) throw new Error("Unsupported token");
|
|
186
186
|
|
|
187
|
-
const deadlineTime =
|
|
187
|
+
const deadlineTime = 5 * 60 * 1000;
|
|
188
188
|
const directChains = [Network.Near, Network.Juno, Network.Gonka, Network.ADI];
|
|
189
189
|
const deadline = new Date(Date.now() + deadlineTime).toISOString();
|
|
190
190
|
const noFee = from.symbol === to.symbol || (from.symbol.toLowerCase().includes("usd") && to.symbol.toLowerCase().includes("usd"));
|
package/src/solana/wallet.ts
CHANGED
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
} from "@solana/spl-token";
|
|
15
15
|
|
|
16
16
|
import { Network, WalletType } from "../core/chains";
|
|
17
|
-
import { OmniConnector } from "../OmniConnector";
|
|
18
17
|
import { OmniWallet } from "../OmniWallet";
|
|
19
18
|
|
|
20
19
|
import { Token } from "../core/token";
|
|
@@ -148,7 +147,7 @@ class SolanaWallet extends OmniWallet {
|
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
async getPriorityFeeEstimate(params: any): Promise<any> {
|
|
151
|
-
const response = await fetch(api.baseUrl + "/api/v1/
|
|
150
|
+
const response = await fetch(api.baseUrl + "/api/v1/evm/helius/staked", {
|
|
152
151
|
body: JSON.stringify({ jsonrpc: "2.0", id: "helius-sdk", method: "getPriorityFeeEstimate", params: [params] }),
|
|
153
152
|
headers: { "Content-Type": "application/json" },
|
|
154
153
|
method: "POST",
|
package/src/ui/Popup.tsx
CHANGED
package/src/ui/Toast.tsx
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Loader } from "./payment/Profile";
|
|
3
|
+
|
|
4
|
+
const Toast = ({ message }: { message: string }) => {
|
|
5
|
+
return (
|
|
6
|
+
<ToastRoot>
|
|
7
|
+
<div style={{ width: 44, height: 44, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 12, background: "rgba(255, 255, 255, 0.07)" }}>
|
|
8
|
+
<Loader />
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div>
|
|
12
|
+
<p style={{ color: "#ADA5A4" }}>Executing transaction</p>
|
|
13
|
+
<p style={{ marginTop: 2 }}>{message}</p>
|
|
14
|
+
</div>
|
|
15
|
+
</ToastRoot>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default Toast;
|
|
20
|
+
|
|
21
|
+
const ToastRoot = styled.div`
|
|
22
|
+
position: fixed;
|
|
23
|
+
bottom: 48px;
|
|
24
|
+
left: 12px;
|
|
25
|
+
right: 12px;
|
|
26
|
+
background: var(--surface-common-container--low, #262729);
|
|
27
|
+
border: 1px solid var(--border-lowest, rgba(255, 255, 255, 0.07));
|
|
28
|
+
border-radius: 8px;
|
|
29
|
+
padding: 12px;
|
|
30
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
justify-content: space-between;
|
|
34
|
+
z-index: 1000000000;
|
|
35
|
+
width: fit-content;
|
|
36
|
+
padding-right: 24px;
|
|
37
|
+
gap: 12px;
|
|
38
|
+
|
|
39
|
+
p {
|
|
40
|
+
color: var(--text-primary, #fff);
|
|
41
|
+
font-size: 16px;
|
|
42
|
+
font-weight: 500;
|
|
43
|
+
margin: 0;
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
@@ -7,7 +7,6 @@ import { Commitment, formatter, Intents } from "../../core";
|
|
|
7
7
|
import { Recipient } from "../../core/recipient";
|
|
8
8
|
import { Network } from "../../core/chains";
|
|
9
9
|
import { Token } from "../../core/token";
|
|
10
|
-
import { api } from "../../core/api";
|
|
11
10
|
|
|
12
11
|
import { BridgeReview } from "../../exchange";
|
|
13
12
|
import { openConnector } from "../router";
|
|
@@ -22,10 +21,10 @@ import { Loader } from "./Profile";
|
|
|
22
21
|
|
|
23
22
|
interface PaymentProps {
|
|
24
23
|
intents: Intents;
|
|
24
|
+
actionName?: string;
|
|
25
25
|
connector: HotConnector;
|
|
26
|
-
payload?: Record<string, any>;
|
|
27
26
|
onReject: (message: string) => void;
|
|
28
|
-
|
|
27
|
+
onConfirm: (args: { depositQoute: BridgeReview | "direct"; processing?: () => Promise<BridgeReview> }) => void;
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
const animations = {
|
|
@@ -36,7 +35,7 @@ const animations = {
|
|
|
36
35
|
|
|
37
36
|
const PAY_SLIPPAGE = 0.002;
|
|
38
37
|
|
|
39
|
-
export const Payment = observer(({ connector, intents,
|
|
38
|
+
export const Payment = observer(({ connector, intents, actionName = "Payment", onReject, onConfirm }: PaymentProps) => {
|
|
40
39
|
useState(() => {
|
|
41
40
|
fetch(animations.loading);
|
|
42
41
|
fetch(animations.success);
|
|
@@ -53,16 +52,15 @@ export const Payment = observer(({ connector, intents, payload, onReject, onSucc
|
|
|
53
52
|
wallet?: OmniWallet;
|
|
54
53
|
commitment?: Commitment;
|
|
55
54
|
review?: BridgeReview | "direct";
|
|
56
|
-
|
|
55
|
+
success?: { depositQoute: BridgeReview | "direct"; processing?: () => Promise<BridgeReview> };
|
|
57
56
|
step?: "selectToken" | "sign" | "transfer" | "success" | "error" | "loading";
|
|
58
|
-
success?: boolean;
|
|
59
57
|
loading?: boolean;
|
|
60
58
|
error?: any;
|
|
61
59
|
} | null>(null);
|
|
62
60
|
|
|
63
61
|
const need = connector.omni(intents.need.keys().next().value!);
|
|
64
62
|
const needAmount = intents.need.values().next().value || 0n;
|
|
65
|
-
const title =
|
|
63
|
+
const title = `${actionName} for ${need.readable(needAmount)} ${need.symbol}`;
|
|
66
64
|
|
|
67
65
|
const selectToken = async (from: Token, wallet?: OmniWallet) => {
|
|
68
66
|
if (!wallet) return;
|
|
@@ -96,8 +94,8 @@ export const Payment = observer(({ connector, intents, payload, onReject, onSucc
|
|
|
96
94
|
const signStep = async () => {
|
|
97
95
|
try {
|
|
98
96
|
setFlow((t) => (t ? { ...t, step: "sign", loading: true } : null));
|
|
99
|
-
|
|
100
|
-
setFlow((t) => (t ? { ...t, step: "transfer",
|
|
97
|
+
await intents.sign();
|
|
98
|
+
setFlow((t) => (t ? { ...t, step: "transfer", loading: false } : null));
|
|
101
99
|
} catch (error) {
|
|
102
100
|
console.error(error);
|
|
103
101
|
setFlow((t) => (t ? { ...t, step: "error", loading: false, error } : null));
|
|
@@ -107,20 +105,15 @@ export const Payment = observer(({ connector, intents, payload, onReject, onSucc
|
|
|
107
105
|
|
|
108
106
|
const confirmPaymentStep = async () => {
|
|
109
107
|
try {
|
|
110
|
-
const commitment = flow?.commitment;
|
|
111
|
-
if (!commitment) throw new Error("Commitment not found");
|
|
112
108
|
if (!flow?.review) throw new Error("Review not found");
|
|
113
109
|
setFlow((t) => (t ? { ...t, step: "loading" } : null));
|
|
114
110
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (flow.review != "direct") {
|
|
118
|
-
const result = await connector.exchange.makeSwap(flow.review, { log: () => {} });
|
|
119
|
-
depositAddress = typeof result.review?.qoute === "object" ? result.review?.qoute?.depositAddress : undefined;
|
|
111
|
+
if (flow.review == "direct") {
|
|
112
|
+
return setFlow({ step: "success", loading: false, success: { depositQoute: "direct" } });
|
|
120
113
|
}
|
|
121
114
|
|
|
122
|
-
const
|
|
123
|
-
setFlow(
|
|
115
|
+
const result = await connector.exchange.makeSwap(flow.review, { log: () => {} });
|
|
116
|
+
setFlow({ loading: false, step: "success", success: { depositQoute: result.review, processing: result.processing } });
|
|
124
117
|
} catch (error) {
|
|
125
118
|
console.error(error);
|
|
126
119
|
setFlow((t) => (t ? { ...t, step: "error", loading: false, error } : null));
|
|
@@ -134,9 +127,9 @@ export const Payment = observer(({ connector, intents, payload, onReject, onSucc
|
|
|
134
127
|
<div style={{ width: "100%", height: 400, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
135
128
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
136
129
|
<dotlottie-wc key="success" src={animations.success} speed="1" style={{ width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
137
|
-
<p style={{ fontSize: 24, marginTop: -32, fontWeight: "bold" }}>
|
|
130
|
+
<p style={{ fontSize: 24, marginTop: -32, fontWeight: "bold" }}>{actionName} successful</p>
|
|
138
131
|
</div>
|
|
139
|
-
<PopupButton style={{ marginTop: "auto" }} onClick={() =>
|
|
132
|
+
<PopupButton style={{ marginTop: "auto" }} onClick={() => onConfirm(flow.success!)}>
|
|
140
133
|
Continue
|
|
141
134
|
</PopupButton>
|
|
142
135
|
</Popup>
|
|
@@ -149,7 +142,7 @@ export const Payment = observer(({ connector, intents, payload, onReject, onSucc
|
|
|
149
142
|
<div style={{ width: "100%", height: 400, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
150
143
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
151
144
|
<dotlottie-wc key="loading" src={animations.loading} speed="1" style={{ marginTop: -64, width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
152
|
-
<p style={{ fontSize: 24, marginTop: -16, fontWeight: "bold" }}>Processing
|
|
145
|
+
<p style={{ fontSize: 24, marginTop: -16, fontWeight: "bold" }}>Processing {actionName.toLowerCase()}</p>
|
|
153
146
|
</div>
|
|
154
147
|
</Popup>
|
|
155
148
|
);
|
|
@@ -161,7 +154,7 @@ export const Payment = observer(({ connector, intents, payload, onReject, onSucc
|
|
|
161
154
|
<div style={{ width: "100%", height: 400, gap: 8, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
162
155
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
163
156
|
<dotlottie-wc key="error" src={animations.failed} speed="1" style={{ width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
164
|
-
<p style={{ fontSize: 24, marginTop: -32, fontWeight: "bold" }}>
|
|
157
|
+
<p style={{ fontSize: 24, marginTop: -32, fontWeight: "bold" }}>{actionName} failed</p>
|
|
165
158
|
<p style={{ fontSize: 14, width: "80%", textAlign: "center", overflowY: "auto", lineBreak: "anywhere" }}>{flow.error?.toString?.() ?? "Unknown error"}</p>
|
|
166
159
|
</div>
|
|
167
160
|
<PopupButton onClick={() => onReject(flow.error?.toString?.() ?? "Unknown error")}>Close</PopupButton>
|
|
@@ -197,7 +190,7 @@ export const Payment = observer(({ connector, intents, payload, onReject, onSucc
|
|
|
197
190
|
</PopupOption>
|
|
198
191
|
|
|
199
192
|
<PopupButton style={{ marginTop: 24 }} disabled={!flow?.review} onClick={confirmPaymentStep}>
|
|
200
|
-
{flow?.loading ? "Confirming..." :
|
|
193
|
+
{flow?.loading ? "Confirming..." : `Confirm ${actionName.toLowerCase()}`}
|
|
201
194
|
</PopupButton>
|
|
202
195
|
</Popup>
|
|
203
196
|
);
|
|
@@ -273,8 +266,8 @@ export const Payment = observer(({ connector, intents, payload, onReject, onSucc
|
|
|
273
266
|
<WalletIcon />
|
|
274
267
|
</div>
|
|
275
268
|
<PopupOptionInfo>
|
|
276
|
-
<p>
|
|
277
|
-
<span className="wallet-address">
|
|
269
|
+
<p>Don't find the right token?</p>
|
|
270
|
+
<span className="wallet-address">Connect another wallet</span>
|
|
278
271
|
</PopupOptionInfo>
|
|
279
272
|
</PopupOption>
|
|
280
273
|
</Popup>
|
package/src/ui/router.tsx
CHANGED
|
@@ -21,16 +21,17 @@ import { LogoutPopup } from "./connect/LogoutPopup";
|
|
|
21
21
|
import { WalletPicker } from "./connect/WalletPicker";
|
|
22
22
|
import { Connector } from "./connect/ConnectWallet";
|
|
23
23
|
import { WCRequest } from "./connect/WCRequest";
|
|
24
|
+
import Toast from "./Toast";
|
|
24
25
|
|
|
25
|
-
export const openPayment = (connector: HotConnector, intents: Intents,
|
|
26
|
-
return new Promise<{
|
|
26
|
+
export const openPayment = (connector: HotConnector, intents: Intents, actionName?: string) => {
|
|
27
|
+
return new Promise<{ depositQoute: BridgeReview | "direct"; processing?: () => Promise<BridgeReview> }>((resolve, reject) => {
|
|
27
28
|
present((close) => (
|
|
28
29
|
<Payment //
|
|
30
|
+
actionName={actionName}
|
|
29
31
|
onReject={() => (close(), reject(new Error("User rejected")))}
|
|
30
|
-
|
|
32
|
+
onConfirm={(args) => (close(), resolve(args))}
|
|
31
33
|
connector={connector}
|
|
32
34
|
intents={intents}
|
|
33
|
-
payload={payload}
|
|
34
35
|
/>
|
|
35
36
|
));
|
|
36
37
|
});
|
|
@@ -92,3 +93,7 @@ export const openWCRequest = <T,>(args: { task: () => Promise<T>; deeplink?: str
|
|
|
92
93
|
present((close) => <WCRequest deeplink={args.deeplink} name={args.name} icon={args.icon} onClose={close} task={taskPromise} />);
|
|
93
94
|
return taskPromise;
|
|
94
95
|
};
|
|
96
|
+
|
|
97
|
+
export const openToast = (message: string) => {
|
|
98
|
+
return present(() => <Toast message={message} />);
|
|
99
|
+
};
|