thirdweb 5.34.0-nightly-f6ff5a78fc2d65f0f250b154f1405210ca57ce0a-20240708000345 → 5.34.0-nightly-95c9d3d92406de619cb1e4cccc61b0766dd2a0d4-20240708205331
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/dist/cjs/auth/core/verify-jwt.js +1 -1
- package/dist/cjs/auth/core/verify-jwt.js.map +1 -1
- package/dist/cjs/auth/verify-hash.js +98 -0
- package/dist/cjs/auth/verify-hash.js.map +1 -0
- package/dist/cjs/auth/verify-signature.js +5 -60
- package/dist/cjs/auth/verify-signature.js.map +1 -1
- package/dist/cjs/auth/verify-typed-data.js +80 -0
- package/dist/cjs/auth/verify-typed-data.js.map +1 -0
- package/dist/cjs/chains/chain-definitions/blast.js +17 -0
- package/dist/cjs/chains/chain-definitions/blast.js.map +1 -0
- package/dist/cjs/exports/chains.js +3 -1
- package/dist/cjs/exports/chains.js.map +1 -1
- package/dist/cjs/exports/extensions/erc20.js +3 -1
- package/dist/cjs/exports/extensions/erc20.js.map +1 -1
- package/dist/cjs/exports/utils.js +10 -1
- package/dist/cjs/exports/utils.js.map +1 -1
- package/dist/cjs/exports/wallets/smart.js +10 -1
- package/dist/cjs/exports/wallets/smart.js.map +1 -1
- package/dist/cjs/extensions/erc1271/checkContractWalletSignature.js +1 -0
- package/dist/cjs/extensions/erc1271/checkContractWalletSignature.js.map +1 -1
- package/dist/cjs/extensions/erc1271/checkContractWalletSignedTypedData.js +1 -0
- package/dist/cjs/extensions/erc1271/checkContractWalletSignedTypedData.js.map +1 -1
- package/dist/cjs/extensions/erc20/write/transferBatch.js +61 -0
- package/dist/cjs/extensions/erc20/write/transferBatch.js.map +1 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +21 -12
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/PayWIthCreditCard.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js +4 -4
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useBuyTxStates.js +1 -3
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useBuyTxStates.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js +1 -4
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/Fees.js +4 -4
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/tx-history/BuyTxHistoryButton.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.js +1 -1
- package/dist/cjs/utils/hashing/hashTypedData.js +122 -0
- package/dist/cjs/utils/hashing/hashTypedData.js.map +1 -0
- package/dist/cjs/utils/jwt/decode-jwt.js +2 -2
- package/dist/cjs/utils/jwt/decode-jwt.js.map +1 -1
- package/dist/cjs/utils/jwt/refresh-jwt.js +1 -1
- package/dist/cjs/utils/jwt/refresh-jwt.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/smart/index.js +19 -9
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/bundler.js +57 -9
- package/dist/cjs/wallets/smart/lib/bundler.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/calls.js +31 -21
- package/dist/cjs/wallets/smart/lib/calls.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/paymaster.js +5 -6
- package/dist/cjs/wallets/smart/lib/paymaster.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/userop.js +45 -21
- package/dist/cjs/wallets/smart/lib/userop.js.map +1 -1
- package/dist/esm/auth/core/verify-jwt.js +2 -2
- package/dist/esm/auth/core/verify-jwt.js.map +1 -1
- package/dist/esm/auth/verify-hash.js +95 -0
- package/dist/esm/auth/verify-hash.js.map +1 -0
- package/dist/esm/auth/verify-signature.js +6 -61
- package/dist/esm/auth/verify-signature.js.map +1 -1
- package/dist/esm/auth/verify-typed-data.js +77 -0
- package/dist/esm/auth/verify-typed-data.js.map +1 -0
- package/dist/esm/chains/chain-definitions/blast.js +14 -0
- package/dist/esm/chains/chain-definitions/blast.js.map +1 -0
- package/dist/esm/exports/chains.js +1 -0
- package/dist/esm/exports/chains.js.map +1 -1
- package/dist/esm/exports/extensions/erc20.js +1 -0
- package/dist/esm/exports/extensions/erc20.js.map +1 -1
- package/dist/esm/exports/utils.js +6 -0
- package/dist/esm/exports/utils.js.map +1 -1
- package/dist/esm/exports/wallets/smart.js +3 -1
- package/dist/esm/exports/wallets/smart.js.map +1 -1
- package/dist/esm/extensions/erc1271/checkContractWalletSignature.js +1 -0
- package/dist/esm/extensions/erc1271/checkContractWalletSignature.js.map +1 -1
- package/dist/esm/extensions/erc1271/checkContractWalletSignedTypedData.js +1 -0
- package/dist/esm/extensions/erc1271/checkContractWalletSignedTypedData.js.map +1 -1
- package/dist/esm/extensions/erc20/write/transferBatch.js +58 -0
- package/dist/esm/extensions/erc20/write/transferBatch.js.map +1 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +21 -12
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/PayWIthCreditCard.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js +4 -4
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useBuyTxStates.js +1 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useBuyTxStates.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js +1 -4
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/Fees.js +4 -4
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/tx-history/BuyTxHistoryButton.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.js +1 -1
- package/dist/esm/utils/hashing/hashTypedData.js +118 -0
- package/dist/esm/utils/hashing/hashTypedData.js.map +1 -0
- package/dist/esm/utils/jwt/decode-jwt.js +1 -1
- package/dist/esm/utils/jwt/decode-jwt.js.map +1 -1
- package/dist/esm/utils/jwt/refresh-jwt.js +2 -2
- package/dist/esm/utils/jwt/refresh-jwt.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/smart/index.js +19 -9
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/esm/wallets/smart/lib/bundler.js +56 -8
- package/dist/esm/wallets/smart/lib/bundler.js.map +1 -1
- package/dist/esm/wallets/smart/lib/calls.js +31 -21
- package/dist/esm/wallets/smart/lib/calls.js.map +1 -1
- package/dist/esm/wallets/smart/lib/paymaster.js +5 -6
- package/dist/esm/wallets/smart/lib/paymaster.js.map +1 -1
- package/dist/esm/wallets/smart/lib/userop.js +46 -22
- package/dist/esm/wallets/smart/lib/userop.js.map +1 -1
- package/dist/types/auth/verify-hash.d.ts +45 -0
- package/dist/types/auth/verify-hash.d.ts.map +1 -0
- package/dist/types/auth/verify-signature.d.ts.map +1 -1
- package/dist/types/auth/verify-typed-data.d.ts +75 -0
- package/dist/types/auth/verify-typed-data.d.ts.map +1 -0
- package/dist/types/chains/chain-definitions/blast.d.ts +27 -0
- package/dist/types/chains/chain-definitions/blast.d.ts.map +1 -0
- package/dist/types/exports/chains.d.ts +1 -0
- package/dist/types/exports/chains.d.ts.map +1 -1
- package/dist/types/exports/extensions/erc20.d.ts +1 -0
- package/dist/types/exports/extensions/erc20.d.ts.map +1 -1
- package/dist/types/exports/utils.d.ts +4 -0
- package/dist/types/exports/utils.d.ts.map +1 -1
- package/dist/types/exports/wallets/smart.d.ts +3 -1
- package/dist/types/exports/wallets/smart.d.ts.map +1 -1
- package/dist/types/extensions/erc1271/checkContractWalletSignature.d.ts +1 -0
- package/dist/types/extensions/erc1271/checkContractWalletSignature.d.ts.map +1 -1
- package/dist/types/extensions/erc1271/checkContractWalletSignedTypedData.d.ts +1 -0
- package/dist/types/extensions/erc1271/checkContractWalletSignedTypedData.d.ts.map +1 -1
- package/dist/types/extensions/erc20/write/transferBatch.d.ts +42 -0
- package/dist/types/extensions/erc20/write/transferBatch.d.ts.map +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useBuyTxStates.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts.map +1 -1
- package/dist/types/utils/hashing/hashTypedData.d.ts +17 -0
- package/dist/types/utils/hashing/hashTypedData.d.ts.map +1 -0
- package/dist/types/utils/jwt/decode-jwt.d.ts +1 -1
- package/dist/types/utils/jwt/decode-jwt.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/wallets/smart/index.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/bundler.d.ts +53 -5
- package/dist/types/wallets/smart/lib/bundler.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/calls.d.ts +25 -7
- package/dist/types/wallets/smart/lib/calls.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/paymaster.d.ts +7 -2
- package/dist/types/wallets/smart/lib/paymaster.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/userop.d.ts +15 -4
- package/dist/types/wallets/smart/lib/userop.d.ts.map +1 -1
- package/dist/types/wallets/smart/types.d.ts +4 -2
- package/dist/types/wallets/smart/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/auth/core/verify-jwt.ts +2 -2
- package/src/auth/verify-hash.test.ts +66 -0
- package/src/auth/verify-hash.ts +126 -0
- package/src/auth/verify-signature.ts +6 -77
- package/src/auth/verify-typed-data.test.ts +82 -0
- package/src/auth/verify-typed-data.ts +110 -0
- package/src/chains/chain-definitions/blast.ts +14 -0
- package/src/exports/chains.ts +1 -0
- package/src/exports/extensions/erc20.ts +4 -0
- package/src/exports/utils.ts +8 -0
- package/src/exports/wallets/smart.ts +14 -1
- package/src/extensions/erc1271/checkContractWalletSignature.ts +1 -0
- package/src/extensions/erc1271/checkContractWalletSignedTypedData.ts +1 -0
- package/src/extensions/erc20/write/transferBatch.ts +78 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +42 -12
- package/src/react/web/ui/ConnectWallet/screens/Buy/PayWIthCreditCard.tsx +1 -1
- package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.tsx +5 -5
- package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.tsx +1 -1
- package/src/react/web/ui/ConnectWallet/screens/Buy/main/useBuyTxStates.ts +1 -5
- package/src/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.ts +1 -6
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.tsx +2 -2
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/Fees.tsx +4 -4
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx +1 -1
- package/src/react/web/ui/ConnectWallet/screens/Buy/tx-history/BuyTxHistoryButton.tsx +1 -1
- package/src/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.tsx +1 -1
- package/src/utils/hashing/hashTypedData.test.ts +207 -0
- package/src/utils/hashing/hashTypedData.ts +210 -0
- package/src/utils/jwt/decode-jwt.ts +1 -1
- package/src/utils/jwt/refresh-jwt.ts +2 -2
- package/src/version.ts +1 -1
- package/src/wallets/smart/index.ts +19 -9
- package/src/wallets/smart/lib/bundler.ts +56 -9
- package/src/wallets/smart/lib/calls.ts +67 -28
- package/src/wallets/smart/lib/paymaster.ts +12 -13
- package/src/wallets/smart/lib/userop.ts +74 -30
- package/src/wallets/smart/types.ts +6 -6
@@ -12,6 +12,7 @@ const MAGIC_VALUE = "0x1626ba7e";
|
|
12
12
|
|
13
13
|
/**
|
14
14
|
* Checks if a contract wallet signature is valid.
|
15
|
+
* @deprecated Use `verifySignature` instead
|
15
16
|
* @param options - The options for the checkContractWalletSignature function.
|
16
17
|
* @param options.contract - The contract to check the signature against.
|
17
18
|
* @param options.message - The message to check the signature against.
|
@@ -15,6 +15,7 @@ const MAGIC_VALUE = "0x1626ba7e";
|
|
15
15
|
|
16
16
|
/**
|
17
17
|
* Checks if a contract wallet signature is valid.
|
18
|
+
* @deprecated Use `verifyTypedData` instead
|
18
19
|
* @param options - The options for the checkContractWalletSignature function.
|
19
20
|
* @param options.contract - The contract to check the signature against.
|
20
21
|
* @param options.message - The message to check the signature against.
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
2
|
+
import type { Prettify } from "../../../utils/type-utils.js";
|
3
|
+
import { toUnits } from "../../../utils/units.js";
|
4
|
+
import { multicall } from "../../common/__generated__/IMulticall/write/multicall.js";
|
5
|
+
import { encodeTransfer } from "../__generated__/IERC20/write/transfer.js";
|
6
|
+
/**
|
7
|
+
* Represents the parameters for a batch transfer operation.
|
8
|
+
*/
|
9
|
+
export type TransferBatchParams = Prettify<{
|
10
|
+
batch: Array<
|
11
|
+
{ to: string } & (
|
12
|
+
| {
|
13
|
+
amount: number | string;
|
14
|
+
}
|
15
|
+
| {
|
16
|
+
amountWei: bigint;
|
17
|
+
}
|
18
|
+
)
|
19
|
+
>;
|
20
|
+
}>;
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Transfers a batch of ERC20 tokens from the sender's address to the specified recipient address.
|
24
|
+
* @param options - The options for the batch transfer transaction.
|
25
|
+
* @returns A promise that resolves to the prepared transaction.
|
26
|
+
* @extension ERC20
|
27
|
+
* @example
|
28
|
+
* ```ts
|
29
|
+
* import { transferBatch } from "thirdweb/extensions/erc20";
|
30
|
+
* import { sendTransaction } from "thirdweb";
|
31
|
+
*
|
32
|
+
* const transaction = transferBatch({
|
33
|
+
* contract,
|
34
|
+
* batch: [
|
35
|
+
* {
|
36
|
+
* to: "0x...",
|
37
|
+
* amount: 100,
|
38
|
+
* },
|
39
|
+
* {
|
40
|
+
* to: "0x...",
|
41
|
+
* amount: "0.1",
|
42
|
+
* },
|
43
|
+
* ]);
|
44
|
+
*
|
45
|
+
* await sendTransaction({ transaction, account });
|
46
|
+
* ```
|
47
|
+
*/
|
48
|
+
export function transferBatch(
|
49
|
+
options: BaseTransactionOptions<TransferBatchParams>,
|
50
|
+
) {
|
51
|
+
return multicall({
|
52
|
+
contract: options.contract,
|
53
|
+
asyncParams: async () => {
|
54
|
+
return {
|
55
|
+
data: await Promise.all(
|
56
|
+
options.batch.map(async (transfer) => {
|
57
|
+
let amount: bigint;
|
58
|
+
if ("amount" in transfer) {
|
59
|
+
// if we need to parse the amount from ether to gwei then we pull in the decimals extension
|
60
|
+
const { decimals } = await import("../read/decimals.js");
|
61
|
+
// it's OK to call this multiple times because the call is cached
|
62
|
+
// if this fails we fall back to `18` decimals
|
63
|
+
const d = await decimals(options).catch(() => 18);
|
64
|
+
// turn ether into gwei
|
65
|
+
amount = toUnits(transfer.amount.toString(), d);
|
66
|
+
} else {
|
67
|
+
amount = transfer.amountWei;
|
68
|
+
}
|
69
|
+
return encodeTransfer({
|
70
|
+
to: transfer.to,
|
71
|
+
value: amount,
|
72
|
+
});
|
73
|
+
}),
|
74
|
+
),
|
75
|
+
};
|
76
|
+
},
|
77
|
+
});
|
78
|
+
}
|
@@ -141,6 +141,8 @@ function BuyScreenContent(props: BuyScreenContentProps) {
|
|
141
141
|
id: "main",
|
142
142
|
});
|
143
143
|
|
144
|
+
const [hasEditedAmount, setHasEditedAmount] = useState(false);
|
145
|
+
|
144
146
|
// UI selection
|
145
147
|
const {
|
146
148
|
tokenAmount,
|
@@ -408,6 +410,8 @@ function BuyScreenContent(props: BuyScreenContentProps) {
|
|
408
410
|
supportedDestinations={supportedDestinations}
|
409
411
|
onBack={props.onBack}
|
410
412
|
theme={props.theme}
|
413
|
+
hasEditedAmount={hasEditedAmount}
|
414
|
+
setHasEditedAmount={setHasEditedAmount}
|
411
415
|
/>
|
412
416
|
)}
|
413
417
|
|
@@ -486,6 +490,7 @@ function BuyScreenContent(props: BuyScreenContentProps) {
|
|
486
490
|
}}
|
487
491
|
payer={payer}
|
488
492
|
setTokenAmount={setTokenAmount}
|
493
|
+
setHasEditedAmount={setHasEditedAmount}
|
489
494
|
/>
|
490
495
|
)}
|
491
496
|
</TokenSelectedLayout>
|
@@ -512,8 +517,8 @@ function SelectedTokenInfo(props: {
|
|
512
517
|
}}
|
513
518
|
>
|
514
519
|
<Container flex="row" gap="xs" center="y">
|
515
|
-
<Text color="primaryText" data-testid="tokenAmount" size="
|
516
|
-
{formatNumber(Number(props.tokenAmount),
|
520
|
+
<Text color="primaryText" data-testid="tokenAmount" size="xl">
|
521
|
+
{formatNumber(Number(props.tokenAmount), 6)}
|
517
522
|
</Text>
|
518
523
|
|
519
524
|
<Container flex="row" gap="xxs" center="y">
|
@@ -559,6 +564,8 @@ function MainScreen(props: {
|
|
559
564
|
supportedDestinations: SupportedChainAndTokens;
|
560
565
|
onBack: (() => void) | undefined;
|
561
566
|
theme: "light" | "dark" | Theme;
|
567
|
+
hasEditedAmount: boolean;
|
568
|
+
setHasEditedAmount: (hasEdited: boolean) => void;
|
562
569
|
}) {
|
563
570
|
const { showPaymentSelection, buyWithCryptoEnabled, buyWithFiatEnabled } =
|
564
571
|
useEnabledPaymentMethods({
|
@@ -568,7 +575,6 @@ function MainScreen(props: {
|
|
568
575
|
toToken: props.toToken,
|
569
576
|
});
|
570
577
|
|
571
|
-
const [hasEditedAmount, setHasEditedAmount] = useState(false);
|
572
578
|
const {
|
573
579
|
buyForTx,
|
574
580
|
setTokenAmount,
|
@@ -584,7 +590,7 @@ function MainScreen(props: {
|
|
584
590
|
const { amountNeeded } = useBuyTxStates({
|
585
591
|
setTokenAmount,
|
586
592
|
buyForTx: buyForTx || null,
|
587
|
-
hasEditedAmount,
|
593
|
+
hasEditedAmount: props.hasEditedAmount,
|
588
594
|
account: payerAccount || null,
|
589
595
|
});
|
590
596
|
|
@@ -605,7 +611,7 @@ function MainScreen(props: {
|
|
605
611
|
<Spacer y="lg" />
|
606
612
|
<BuyForTxUI
|
607
613
|
amountNeeded={String(
|
608
|
-
formatNumber(Number(toEther(amountNeeded)),
|
614
|
+
formatNumber(Number(toEther(amountNeeded)), 6),
|
609
615
|
)}
|
610
616
|
buyForTx={props.buyForTx}
|
611
617
|
client={client}
|
@@ -619,7 +625,7 @@ function MainScreen(props: {
|
|
619
625
|
<BuyTokenInput
|
620
626
|
value={tokenAmount}
|
621
627
|
onChange={async (value) => {
|
622
|
-
setHasEditedAmount(true);
|
628
|
+
props.setHasEditedAmount(true);
|
623
629
|
setTokenAmount(value);
|
624
630
|
}}
|
625
631
|
freezeAmount={payOptions.prefillBuy?.allowEdits?.amount === false}
|
@@ -1094,6 +1100,7 @@ function FiatScreenContent(props: {
|
|
1094
1100
|
isEmbed: boolean;
|
1095
1101
|
payer: PayerInfo;
|
1096
1102
|
setTokenAmount: (amount: string) => void;
|
1103
|
+
setHasEditedAmount: (hasEdited: boolean) => void;
|
1097
1104
|
}) {
|
1098
1105
|
const [receiverAddress, setReceiverAddress] = useState(
|
1099
1106
|
props.payer.account.address,
|
@@ -1182,18 +1189,27 @@ function FiatScreenContent(props: {
|
|
1182
1189
|
try {
|
1183
1190
|
if (err.error.code === "MINIMUM_PURCHASE_AMOUNT") {
|
1184
1191
|
const obj = err.error as AmountTooLowError;
|
1185
|
-
|
1186
1192
|
const minAmountUSD = obj.data.minimumAmountUSDCents;
|
1187
1193
|
const currentAmountUSD = obj.data.requestedAmountUSDCents;
|
1194
|
+
|
1195
|
+
// avoid divide by zero
|
1196
|
+
// if we can't calculate the minimum amount in # of tokens, don't show the button to set the minimum amount
|
1197
|
+
if (obj.data.requestedAmountUSDCents === 0) {
|
1198
|
+
return {
|
1199
|
+
msg: [
|
1200
|
+
"Purchase amount is too low",
|
1201
|
+
"Increase the amount and try again",
|
1202
|
+
],
|
1203
|
+
};
|
1204
|
+
}
|
1205
|
+
|
1188
1206
|
const currentAmountToken = Number(props.tokenAmount);
|
1189
1207
|
const minAmountToken =
|
1190
1208
|
(minAmountUSD * currentAmountToken) / currentAmountUSD;
|
1191
1209
|
const minAmountTokenWithBuffer = minAmountToken * 1.2; // 20% buffer
|
1192
|
-
const formattedNum = formatNumber(minAmountTokenWithBuffer, 3);
|
1193
1210
|
|
1194
1211
|
return {
|
1195
|
-
|
1196
|
-
minAmount: formattedNum,
|
1212
|
+
minAmount: minAmountTokenWithBuffer,
|
1197
1213
|
};
|
1198
1214
|
}
|
1199
1215
|
} catch {}
|
@@ -1279,7 +1295,20 @@ function FiatScreenContent(props: {
|
|
1279
1295
|
{/* Error message */}
|
1280
1296
|
{errorMsg && (
|
1281
1297
|
<div>
|
1282
|
-
{errorMsg.
|
1298
|
+
{errorMsg.minAmount && (
|
1299
|
+
<Text color="danger" size="sm" center multiline>
|
1300
|
+
Minimum amount is {formatNumber(errorMsg.minAmount, 6)}{" "}
|
1301
|
+
<TokenSymbol
|
1302
|
+
token={toToken}
|
1303
|
+
chain={toChain}
|
1304
|
+
size="sm"
|
1305
|
+
inline
|
1306
|
+
color="danger"
|
1307
|
+
/>
|
1308
|
+
</Text>
|
1309
|
+
)}
|
1310
|
+
|
1311
|
+
{errorMsg.msg?.map((msg) => (
|
1283
1312
|
<Text color="danger" size="sm" center multiline key={msg}>
|
1284
1313
|
{msg}
|
1285
1314
|
</Text>
|
@@ -1293,6 +1322,7 @@ function FiatScreenContent(props: {
|
|
1293
1322
|
fullWidth
|
1294
1323
|
onClick={() => {
|
1295
1324
|
props.setTokenAmount(String(errorMsg.minAmount));
|
1325
|
+
props.setHasEditedAmount(true);
|
1296
1326
|
}}
|
1297
1327
|
>
|
1298
1328
|
Set Minimum
|
@@ -1376,7 +1406,7 @@ function BuyForTxUI(props: {
|
|
1376
1406
|
<Text size="sm">Your Balance</Text>
|
1377
1407
|
<Container flex="row" gap="xs">
|
1378
1408
|
<Text color="primaryText" size="sm">
|
1379
|
-
{formatNumber(Number(toEther(props.buyForTx.balance)),
|
1409
|
+
{formatNumber(Number(toEther(props.buyForTx.balance)), 6)}{" "}
|
1380
1410
|
{props.buyForTx.tokenSymbol}
|
1381
1411
|
</Text>
|
1382
1412
|
<TokenIcon
|
@@ -82,7 +82,7 @@ export function PayWithCreditCard(props: {
|
|
82
82
|
<Skeleton width="100px" height={fontSize.lg} />
|
83
83
|
) : (
|
84
84
|
<Text size="lg" color={props.value ? "primaryText" : "secondaryText"}>
|
85
|
-
{props.value ? `${formatNumber(Number(props.value),
|
85
|
+
{props.value ? `${formatNumber(Number(props.value), 6)}` : "--"}
|
86
86
|
</Text>
|
87
87
|
)}
|
88
88
|
</div>
|
@@ -163,7 +163,7 @@ export function FiatSteps(props: {
|
|
163
163
|
const onRampTokenInfo = (
|
164
164
|
<div>
|
165
165
|
<Text color="primaryText" size="sm">
|
166
|
-
{formatNumber(Number(onRampTokenAmount),
|
166
|
+
{formatNumber(Number(onRampTokenAmount), 6)}{" "}
|
167
167
|
<TokenSymbol token={onRampToken} chain={onRampChain} size="sm" inline />
|
168
168
|
</Text>
|
169
169
|
</div>
|
@@ -203,7 +203,7 @@ export function FiatSteps(props: {
|
|
203
203
|
textDecoration: "line-through",
|
204
204
|
}}
|
205
205
|
>
|
206
|
-
{formatNumber(Number(toTokenAmount),
|
206
|
+
{formatNumber(Number(toTokenAmount), 6)}{" "}
|
207
207
|
<TokenSymbol
|
208
208
|
token={toToken}
|
209
209
|
chain={toChain}
|
@@ -213,7 +213,7 @@ export function FiatSteps(props: {
|
|
213
213
|
/>
|
214
214
|
</Text>{" "}
|
215
215
|
<Text color="danger" size="sm" inline>
|
216
|
-
{formatNumber(Number(props.status.destination.amount),
|
216
|
+
{formatNumber(Number(props.status.destination.amount), 6)}{" "}
|
217
217
|
<TokenSymbol
|
218
218
|
token={{
|
219
219
|
address: props.status.destination.token.tokenAddress,
|
@@ -231,7 +231,7 @@ export function FiatSteps(props: {
|
|
231
231
|
|
232
232
|
const toTokenInfo = partialSuccessToTokenInfo || (
|
233
233
|
<Text color="primaryText" size="sm">
|
234
|
-
{formatNumber(Number(toTokenAmount),
|
234
|
+
{formatNumber(Number(toTokenAmount), 6)}{" "}
|
235
235
|
<TokenSymbol token={toToken} chain={toChain} size="sm" inline />
|
236
236
|
</Text>
|
237
237
|
);
|
@@ -330,7 +330,7 @@ export function FiatSteps(props: {
|
|
330
330
|
icon: fiatIcon,
|
331
331
|
primaryText: (
|
332
332
|
<Text color="primaryText" size="sm">
|
333
|
-
{formatNumber(Number(fromCurrencyAmount),
|
333
|
+
{formatNumber(Number(fromCurrencyAmount), 6)} {fromCurrencySymbol}
|
334
334
|
</Text>
|
335
335
|
),
|
336
336
|
}}
|
@@ -75,7 +75,7 @@ export function OnRampTxDetailsTable(props: {
|
|
75
75
|
<Container flex="row" gap="xs" center="y">
|
76
76
|
<currencyMeta.icon size={iconSize.sm} />
|
77
77
|
<Text color="primaryText">
|
78
|
-
{formatNumber(Number(props.fiat.amount),
|
78
|
+
{formatNumber(Number(props.fiat.amount), 2)}{" "}
|
79
79
|
{props.fiat.currencySymbol}
|
80
80
|
</Text>
|
81
81
|
</Container>
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { useEffect, useState } from "react";
|
2
|
-
import { formatNumber } from "../../../../../../../utils/formatNumber.js";
|
3
2
|
import { toEther } from "../../../../../../../utils/units.js";
|
4
3
|
import type { Account } from "../../../../../../../wallets/interfaces/wallet.js";
|
5
4
|
import { getTotalTxCostForBuy } from "../../../../../../core/hooks/transaction/useSendTransaction.js";
|
@@ -48,10 +47,7 @@ export function useBuyTxStates(options: {
|
|
48
47
|
|
49
48
|
if (shouldRefreshTokenAmount) {
|
50
49
|
if (totalCost > buyForTx.balance) {
|
51
|
-
|
52
|
-
formatNumber(Number(toEther(totalCost - buyForTx.balance)), 4),
|
53
|
-
);
|
54
|
-
setTokenAmount(_tokenAmount);
|
50
|
+
setTokenAmount(toEther(totalCost - buyForTx.balance));
|
55
51
|
}
|
56
52
|
}
|
57
53
|
} catch {
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import { useState } from "react";
|
2
2
|
import { polygon } from "../../../../../../../chains/chain-definitions/polygon.js";
|
3
3
|
import type { Chain } from "../../../../../../../chains/types.js";
|
4
|
-
import { formatNumber } from "../../../../../../../utils/formatNumber.js";
|
5
4
|
import { toEther } from "../../../../../../../utils/units.js";
|
6
5
|
import type { PayUIOptions } from "../../../../../../core/hooks/connection/ConnectButtonProps.js";
|
7
6
|
import { useActiveWalletChain } from "../../../../../hooks/wallets/useActiveWalletChain.js";
|
@@ -24,11 +23,7 @@ export function useUISelectionStates(options: {
|
|
24
23
|
// buy token amount ---------------------------------------------------------
|
25
24
|
const initialTokenAmount =
|
26
25
|
payOptions.prefillBuy?.amount ||
|
27
|
-
(buyForTx
|
28
|
-
? String(
|
29
|
-
formatNumber(Number(toEther(buyForTx.cost - buyForTx.balance)), 4),
|
30
|
-
)
|
31
|
-
: "");
|
26
|
+
(buyForTx ? String(toEther(buyForTx.cost - buyForTx.balance)) : "");
|
32
27
|
|
33
28
|
const [tokenAmount, setTokenAmount] = useState<string>(initialTokenAmount);
|
34
29
|
const deferredTokenAmount = useDebouncedValue(tokenAmount, 300);
|
@@ -84,7 +84,7 @@ export function SwapConfirmationScreen(props: {
|
|
84
84
|
<ConfirmItem label="Pay">
|
85
85
|
<RenderTokenInfo
|
86
86
|
chain={props.fromChain}
|
87
|
-
amount={String(formatNumber(Number(props.fromAmount),
|
87
|
+
amount={String(formatNumber(Number(props.fromAmount), 6))}
|
88
88
|
symbol={props.fromTokenSymbol || ""}
|
89
89
|
token={props.fromToken}
|
90
90
|
client={props.client}
|
@@ -95,7 +95,7 @@ export function SwapConfirmationScreen(props: {
|
|
95
95
|
<ConfirmItem label="Receive">
|
96
96
|
<RenderTokenInfo
|
97
97
|
chain={props.toChain}
|
98
|
-
amount={String(formatNumber(Number(props.toAmount),
|
98
|
+
amount={String(formatNumber(Number(props.toAmount), 6))}
|
99
99
|
symbol={props.toTokenSymbol}
|
100
100
|
token={props.toToken}
|
101
101
|
client={props.client}
|
@@ -21,7 +21,7 @@ export function SwapFees(props: {
|
|
21
21
|
}}
|
22
22
|
>
|
23
23
|
{props.quote.processingFees.map((fee) => {
|
24
|
-
const feeAmount = formatNumber(Number(fee.amount),
|
24
|
+
const feeAmount = formatNumber(Number(fee.amount), 6);
|
25
25
|
return (
|
26
26
|
<Container
|
27
27
|
key={`${fee.token.chainId}_${fee.token.tokenAddress}_${feeAmount}`}
|
@@ -61,14 +61,14 @@ export function FiatFees(props: {
|
|
61
61
|
Amount
|
62
62
|
</Text>
|
63
63
|
<Text color="primaryText" inline>
|
64
|
-
{formatNumber(Number(props.quote.fromCurrency.amount),
|
64
|
+
{formatNumber(Number(props.quote.fromCurrency.amount), 2)}{" "}
|
65
65
|
{props.quote.fromCurrency.currencySymbol}
|
66
66
|
</Text>
|
67
67
|
</div>
|
68
68
|
|
69
69
|
{/* Processing Fees */}
|
70
70
|
{props.quote.processingFees.map((fee, i) => {
|
71
|
-
const feeAmount = formatNumber(Number(fee.amount),
|
71
|
+
const feeAmount = formatNumber(Number(fee.amount), 6);
|
72
72
|
|
73
73
|
return (
|
74
74
|
<div
|
@@ -106,7 +106,7 @@ export function FiatFees(props: {
|
|
106
106
|
Total
|
107
107
|
</Text>
|
108
108
|
<Text color="primaryText" inline>
|
109
|
-
{formatNumber(Number(props.quote.fromCurrencyWithFees.amount),
|
109
|
+
{formatNumber(Number(props.quote.fromCurrencyWithFees.amount), 6)}{" "}
|
110
110
|
{props.quote.fromCurrencyWithFees.currencySymbol}
|
111
111
|
</Text>
|
112
112
|
</div>
|
@@ -46,7 +46,7 @@ export function TokenInfoRow(props: {
|
|
46
46
|
client={props.client}
|
47
47
|
/>
|
48
48
|
<Text color="primaryText">
|
49
|
-
{formatNumber(Number(props.tokenAmount),
|
49
|
+
{formatNumber(Number(props.tokenAmount), 6)} {props.tokenSymbol}
|
50
50
|
</Text>
|
51
51
|
</Container>
|
52
52
|
<Text size="sm">{name}</Text>
|
@@ -0,0 +1,207 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
|
3
|
+
import { pad } from "viem";
|
4
|
+
import { typedData } from "../../../test/src/typed-data.js";
|
5
|
+
import { toHex } from "../encoding/hex.js";
|
6
|
+
import { hashTypedData } from "./hashTypedData.js";
|
7
|
+
|
8
|
+
test("default", () => {
|
9
|
+
expect(
|
10
|
+
hashTypedData({
|
11
|
+
...typedData.basic,
|
12
|
+
primaryType: "Mail",
|
13
|
+
}),
|
14
|
+
).toMatchInlineSnapshot(
|
15
|
+
'"0x448f54762ef8ecccdc4d19bb7d467161383cd4b271617a8cee05c790eb745d74"',
|
16
|
+
);
|
17
|
+
});
|
18
|
+
|
19
|
+
test("complex", () => {
|
20
|
+
expect(
|
21
|
+
hashTypedData({
|
22
|
+
...typedData.complex,
|
23
|
+
primaryType: "Mail",
|
24
|
+
}),
|
25
|
+
).toMatchInlineSnapshot(
|
26
|
+
'"0x9a74cb859ad30835ffb2da406423233c212cf6dd78e6c2c98b0c9289568954ae"',
|
27
|
+
);
|
28
|
+
});
|
29
|
+
|
30
|
+
test("no domain", () => {
|
31
|
+
expect(
|
32
|
+
hashTypedData({
|
33
|
+
...typedData.complex,
|
34
|
+
domain: undefined,
|
35
|
+
primaryType: "Mail",
|
36
|
+
}),
|
37
|
+
).toMatchInlineSnapshot(
|
38
|
+
'"0x14ed1dbbfecbe5de3919f7ea47daafdf3a29dfbb60dd88d85509f79773d503a5"',
|
39
|
+
);
|
40
|
+
expect(
|
41
|
+
hashTypedData({
|
42
|
+
...typedData.complex,
|
43
|
+
domain: {},
|
44
|
+
primaryType: "Mail",
|
45
|
+
}),
|
46
|
+
).toMatchInlineSnapshot(
|
47
|
+
'"0x14ed1dbbfecbe5de3919f7ea47daafdf3a29dfbb60dd88d85509f79773d503a5"',
|
48
|
+
);
|
49
|
+
});
|
50
|
+
|
51
|
+
test("domain: empty name", () => {
|
52
|
+
expect(
|
53
|
+
hashTypedData({
|
54
|
+
...typedData.complex,
|
55
|
+
domain: { name: "" },
|
56
|
+
primaryType: "Mail",
|
57
|
+
}),
|
58
|
+
).toMatchInlineSnapshot(
|
59
|
+
'"0xc3f4f9ebd774352940f60aebbc83fcee20d0b17eb42bd1b20c91a748001ecb53"',
|
60
|
+
);
|
61
|
+
});
|
62
|
+
|
63
|
+
test("minimal valid typed message", () => {
|
64
|
+
const hash = hashTypedData({
|
65
|
+
types: {
|
66
|
+
EIP712Domain: [],
|
67
|
+
},
|
68
|
+
primaryType: "EIP712Domain",
|
69
|
+
domain: {},
|
70
|
+
});
|
71
|
+
|
72
|
+
expect(hash).toMatchInlineSnapshot(
|
73
|
+
'"0x8d4a3f4082945b7879e2b55f181c31a77c8c0a464b70669458abbaaf99de4c38"',
|
74
|
+
);
|
75
|
+
});
|
76
|
+
|
77
|
+
test("typed message with a domain separator that uses all fields.", () => {
|
78
|
+
const hash = hashTypedData({
|
79
|
+
types: {
|
80
|
+
EIP712Domain: [
|
81
|
+
{
|
82
|
+
name: "name",
|
83
|
+
type: "string",
|
84
|
+
},
|
85
|
+
{
|
86
|
+
name: "version",
|
87
|
+
type: "string",
|
88
|
+
},
|
89
|
+
{
|
90
|
+
name: "chainId",
|
91
|
+
type: "uint256",
|
92
|
+
},
|
93
|
+
{
|
94
|
+
name: "verifyingContract",
|
95
|
+
type: "address",
|
96
|
+
},
|
97
|
+
{
|
98
|
+
name: "salt",
|
99
|
+
type: "bytes32",
|
100
|
+
},
|
101
|
+
],
|
102
|
+
},
|
103
|
+
primaryType: "EIP712Domain",
|
104
|
+
domain: {
|
105
|
+
name: "example.metamask.io",
|
106
|
+
version: "1",
|
107
|
+
chainId: 1n,
|
108
|
+
verifyingContract: "0x0000000000000000000000000000000000000000",
|
109
|
+
salt: pad(toHex(new Uint8Array([1, 2, 3])), { dir: "right" }),
|
110
|
+
},
|
111
|
+
});
|
112
|
+
|
113
|
+
expect(hash).toMatchInlineSnapshot(
|
114
|
+
'"0x54ffed5209a17ac210ef3823740b3852ee9cd518b84ee39f0a3fa7f2f9b4205b"',
|
115
|
+
);
|
116
|
+
});
|
117
|
+
|
118
|
+
test("typed message with only custom domain separator fields", () => {
|
119
|
+
const hash = hashTypedData({
|
120
|
+
types: {
|
121
|
+
EIP712Domain: [
|
122
|
+
{
|
123
|
+
name: "customName",
|
124
|
+
type: "string",
|
125
|
+
},
|
126
|
+
{
|
127
|
+
name: "customVersion",
|
128
|
+
type: "string",
|
129
|
+
},
|
130
|
+
{
|
131
|
+
name: "customChainId",
|
132
|
+
type: "uint256",
|
133
|
+
},
|
134
|
+
{
|
135
|
+
name: "customVerifyingContract",
|
136
|
+
type: "address",
|
137
|
+
},
|
138
|
+
{
|
139
|
+
name: "customSalt",
|
140
|
+
type: "bytes32",
|
141
|
+
},
|
142
|
+
{
|
143
|
+
name: "extraField",
|
144
|
+
type: "string",
|
145
|
+
},
|
146
|
+
],
|
147
|
+
},
|
148
|
+
primaryType: "EIP712Domain",
|
149
|
+
domain: {
|
150
|
+
customName: "example.metamask.io",
|
151
|
+
customVersion: "1",
|
152
|
+
customChainId: 1n,
|
153
|
+
customVerifyingContract: "0x0000000000000000000000000000000000000000",
|
154
|
+
customSalt: pad(toHex(new Uint8Array([1, 2, 3])), { dir: "right" }),
|
155
|
+
extraField: "stuff",
|
156
|
+
},
|
157
|
+
});
|
158
|
+
|
159
|
+
expect(hash).toMatchInlineSnapshot(
|
160
|
+
'"0x3efa3ef0305f56ba5bba62000500e29fe82c5314bca2f958c64e31b2498560f8"',
|
161
|
+
);
|
162
|
+
});
|
163
|
+
|
164
|
+
test("typed message with data", () => {
|
165
|
+
const hash = hashTypedData({
|
166
|
+
types: {
|
167
|
+
EIP712Domain: [
|
168
|
+
{
|
169
|
+
name: "name",
|
170
|
+
type: "string",
|
171
|
+
},
|
172
|
+
{
|
173
|
+
name: "version",
|
174
|
+
type: "string",
|
175
|
+
},
|
176
|
+
{
|
177
|
+
name: "chainId",
|
178
|
+
type: "uint256",
|
179
|
+
},
|
180
|
+
{
|
181
|
+
name: "verifyingContract",
|
182
|
+
type: "address",
|
183
|
+
},
|
184
|
+
{
|
185
|
+
name: "salt",
|
186
|
+
type: "bytes32",
|
187
|
+
},
|
188
|
+
],
|
189
|
+
Message: [{ name: "data", type: "string" }],
|
190
|
+
},
|
191
|
+
primaryType: "Message",
|
192
|
+
domain: {
|
193
|
+
name: "example.metamask.io",
|
194
|
+
version: "1",
|
195
|
+
chainId: 1n,
|
196
|
+
verifyingContract: "0x0000000000000000000000000000000000000000",
|
197
|
+
salt: pad(toHex(new Uint8Array([1, 2, 3])), { dir: "right" }),
|
198
|
+
},
|
199
|
+
message: {
|
200
|
+
data: "Hello!",
|
201
|
+
},
|
202
|
+
});
|
203
|
+
|
204
|
+
expect(hash).toMatchInlineSnapshot(
|
205
|
+
'"0xd2669f23b7849020ad41bcbff5b51372793f91320e0f901641945568ed7322be"',
|
206
|
+
);
|
207
|
+
});
|