thirdweb 5.88.2-nightly-0c1bb6ccaec9dc4edf596dac7f7623d0ad90f757-20250212000327 → 5.88.3
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/exports/extensions/erc1155.js +4 -2
- package/dist/cjs/exports/extensions/erc1155.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/extensions/erc721.js +4 -2
- package/dist/cjs/exports/extensions/erc721.js.map +1 -1
- package/dist/cjs/extensions/erc1155/__generated__/DropERC1155/read/verifyClaim.js +191 -0
- package/dist/cjs/extensions/erc1155/__generated__/DropERC1155/read/verifyClaim.js.map +1 -0
- package/dist/cjs/extensions/erc1155/drops/read/canClaim.js +63 -0
- package/dist/cjs/extensions/erc1155/drops/read/canClaim.js.map +1 -0
- package/dist/cjs/extensions/erc20/__generated__/DropERC20/read/verifyClaim.js +182 -0
- package/dist/cjs/extensions/erc20/__generated__/DropERC20/read/verifyClaim.js.map +1 -0
- package/dist/cjs/extensions/erc20/drops/read/canClaim.js +68 -0
- package/dist/cjs/extensions/erc20/drops/read/canClaim.js.map +1 -0
- package/dist/cjs/extensions/erc721/__generated__/DropERC721/read/verifyClaim.js +182 -0
- package/dist/cjs/extensions/erc721/__generated__/DropERC721/read/verifyClaim.js.map +1 -0
- package/dist/cjs/extensions/erc721/drops/read/canClaim.js +59 -0
- package/dist/cjs/extensions/erc721/drops/read/canClaim.js.map +1 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +12 -5
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.js +9 -4
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js +3 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.js +1 -3
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.js +7 -3
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.js.map +1 -1
- package/dist/cjs/react/web/utils/errors.js +6 -1
- package/dist/cjs/react/web/utils/errors.js.map +1 -1
- package/dist/cjs/transaction/extract-error.js +11 -4
- package/dist/cjs/transaction/extract-error.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/esm/exports/extensions/erc1155.js +1 -0
- package/dist/esm/exports/extensions/erc1155.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/extensions/erc721.js +1 -0
- package/dist/esm/exports/extensions/erc721.js.map +1 -1
- package/dist/esm/extensions/erc1155/__generated__/DropERC1155/read/verifyClaim.js +183 -0
- package/dist/esm/extensions/erc1155/__generated__/DropERC1155/read/verifyClaim.js.map +1 -0
- package/dist/esm/extensions/erc1155/drops/read/canClaim.js +60 -0
- package/dist/esm/extensions/erc1155/drops/read/canClaim.js.map +1 -0
- package/dist/esm/extensions/erc20/__generated__/DropERC20/read/verifyClaim.js +174 -0
- package/dist/esm/extensions/erc20/__generated__/DropERC20/read/verifyClaim.js.map +1 -0
- package/dist/esm/extensions/erc20/drops/read/canClaim.js +65 -0
- package/dist/esm/extensions/erc20/drops/read/canClaim.js.map +1 -0
- package/dist/esm/extensions/erc721/__generated__/DropERC721/read/verifyClaim.js +174 -0
- package/dist/esm/extensions/erc721/__generated__/DropERC721/read/verifyClaim.js.map +1 -0
- package/dist/esm/extensions/erc721/drops/read/canClaim.js +56 -0
- package/dist/esm/extensions/erc721/drops/read/canClaim.js.map +1 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +12 -5
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.js +9 -4
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js +3 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.js +2 -4
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.js +7 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.js.map +1 -1
- package/dist/esm/react/web/utils/errors.js +6 -1
- package/dist/esm/react/web/utils/errors.js.map +1 -1
- package/dist/esm/transaction/extract-error.js +11 -5
- package/dist/esm/transaction/extract-error.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/exports/extensions/erc1155.d.ts +1 -0
- package/dist/types/exports/extensions/erc1155.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/extensions/erc721.d.ts +1 -0
- package/dist/types/exports/extensions/erc721.d.ts.map +1 -1
- package/dist/types/extensions/erc1155/__generated__/DropERC1155/read/verifyClaim.d.ts +143 -0
- package/dist/types/extensions/erc1155/__generated__/DropERC1155/read/verifyClaim.d.ts.map +1 -0
- package/dist/types/extensions/erc1155/drops/read/canClaim.d.ts +31 -0
- package/dist/types/extensions/erc1155/drops/read/canClaim.d.ts.map +1 -0
- package/dist/types/extensions/erc20/__generated__/DropERC20/read/verifyClaim.d.ts +136 -0
- package/dist/types/extensions/erc20/__generated__/DropERC20/read/verifyClaim.d.ts.map +1 -0
- package/dist/types/extensions/erc20/drops/read/canClaim.d.ts +32 -0
- package/dist/types/extensions/erc20/drops/read/canClaim.d.ts.map +1 -0
- package/dist/types/extensions/erc721/__generated__/DropERC721/read/verifyClaim.d.ts +136 -0
- package/dist/types/extensions/erc721/__generated__/DropERC721/read/verifyClaim.d.ts.map +1 -0
- package/dist/types/extensions/erc721/drops/read/canClaim.d.ts +29 -0
- package/dist/types/extensions/erc721/drops/read/canClaim.d.ts.map +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.d.ts +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.d.ts.map +1 -1
- package/dist/types/react/web/utils/errors.d.ts.map +1 -1
- package/dist/types/transaction/extract-error.d.ts +4 -0
- package/dist/types/transaction/extract-error.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/exports/extensions/erc1155.ts +5 -0
- package/src/exports/extensions/erc20.ts +5 -0
- package/src/exports/extensions/erc721.ts +5 -0
- package/src/extensions/erc1155/__generated__/DropERC1155/read/verifyClaim.ts +223 -0
- package/src/extensions/erc1155/drop1155.test.ts +42 -0
- package/src/extensions/erc1155/drops/read/canClaim.ts +75 -0
- package/src/extensions/erc20/__generated__/DropERC20/read/verifyClaim.ts +213 -0
- package/src/extensions/erc20/drop20.test.ts +38 -0
- package/src/extensions/erc20/drops/read/canClaim.ts +82 -0
- package/src/extensions/erc721/__generated__/DropERC721/read/verifyClaim.ts +213 -0
- package/src/extensions/erc721/drop721.test.ts +39 -0
- package/src/extensions/erc721/drops/read/canClaim.ts +70 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +16 -3
- package/src/react/web/ui/ConnectWallet/screens/Buy/WalletSelectorButton.tsx +40 -19
- package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.tsx +1 -2
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.tsx +7 -1
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.tsx +3 -7
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/PaymentSelectionScreen.tsx +28 -16
- package/src/react/web/utils/errors.ts +6 -1
- package/src/transaction/actions/gasless/providers/engine.test.ts +1 -1
- package/src/transaction/actions/gasless/providers/openzeppelin.test.ts +1 -1
- package/src/transaction/extract-error.ts +15 -13
- package/src/version.ts +1 -1
@@ -0,0 +1,82 @@
|
|
1
|
+
import { extractErrorResult } from "../../../../transaction/extract-error.js";
|
2
|
+
import type { BaseTransactionOptions } from "../../../../transaction/types.js";
|
3
|
+
import { getClaimParams } from "../../../../utils/extensions/drops/get-claim-params.js";
|
4
|
+
import { verifyClaim } from "../../__generated__/DropERC20/read/verifyClaim.js";
|
5
|
+
import { getActiveClaimConditionId } from "../../__generated__/IDropERC20/read/getActiveClaimConditionId.js";
|
6
|
+
import { decimals } from "../../read/decimals.js";
|
7
|
+
|
8
|
+
export type CanClaimParams = {
|
9
|
+
claimer: string;
|
10
|
+
from?: string;
|
11
|
+
} & ({ quantityInWei: bigint } | { quantity: string });
|
12
|
+
|
13
|
+
export type CanClaimResult = {
|
14
|
+
result: boolean;
|
15
|
+
reason?: string;
|
16
|
+
};
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Check if a user can claim a drop.
|
20
|
+
*
|
21
|
+
* @param options - The options for the transaction.
|
22
|
+
* @returns Whether the user can claim the drop.
|
23
|
+
*
|
24
|
+
* @example
|
25
|
+
* ```ts
|
26
|
+
* const claimResult = await canClaim({
|
27
|
+
* contract: contract,
|
28
|
+
* claimer: "0x1234567890123456789012345678901234567890",
|
29
|
+
* quantity: "1",
|
30
|
+
* });
|
31
|
+
* ```
|
32
|
+
*
|
33
|
+
* @extension ERC20
|
34
|
+
*/
|
35
|
+
export async function canClaim(
|
36
|
+
options: BaseTransactionOptions<CanClaimParams>,
|
37
|
+
): Promise<CanClaimResult> {
|
38
|
+
const quantityWei = await (async () => {
|
39
|
+
if ("quantityInWei" in options) {
|
40
|
+
return options.quantityInWei;
|
41
|
+
}
|
42
|
+
|
43
|
+
const { toUnits } = await import("../../../../utils/units.js");
|
44
|
+
return toUnits(
|
45
|
+
options.quantity,
|
46
|
+
await decimals({ contract: options.contract }),
|
47
|
+
);
|
48
|
+
})();
|
49
|
+
const [conditionId, { quantity, currency, pricePerToken, allowlistProof }] =
|
50
|
+
await Promise.all([
|
51
|
+
getActiveClaimConditionId({
|
52
|
+
contract: options.contract,
|
53
|
+
}),
|
54
|
+
getClaimParams({
|
55
|
+
contract: options.contract,
|
56
|
+
quantity: quantityWei,
|
57
|
+
to: options.claimer,
|
58
|
+
type: "erc20",
|
59
|
+
from: options.from,
|
60
|
+
tokenDecimals: await decimals({ contract: options.contract }),
|
61
|
+
}),
|
62
|
+
]);
|
63
|
+
try {
|
64
|
+
await verifyClaim({
|
65
|
+
contract: options.contract,
|
66
|
+
claimer: options.claimer,
|
67
|
+
quantity,
|
68
|
+
currency,
|
69
|
+
pricePerToken,
|
70
|
+
allowlistProof,
|
71
|
+
conditionId,
|
72
|
+
});
|
73
|
+
return {
|
74
|
+
result: true,
|
75
|
+
};
|
76
|
+
} catch (error) {
|
77
|
+
return {
|
78
|
+
result: false,
|
79
|
+
reason: await extractErrorResult({ error, contract: options.contract }),
|
80
|
+
};
|
81
|
+
}
|
82
|
+
}
|
@@ -0,0 +1,213 @@
|
|
1
|
+
import type { AbiParameterToPrimitiveType } from "abitype";
|
2
|
+
import { readContract } from "../../../../../transaction/read-contract.js";
|
3
|
+
import type { BaseTransactionOptions } from "../../../../../transaction/types.js";
|
4
|
+
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
5
|
+
import { decodeAbiParameters } from "viem";
|
6
|
+
import type { Hex } from "../../../../../utils/encoding/hex.js";
|
7
|
+
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Represents the parameters for the "verifyClaim" function.
|
11
|
+
*/
|
12
|
+
export type VerifyClaimParams = {
|
13
|
+
conditionId: AbiParameterToPrimitiveType<{
|
14
|
+
type: "uint256";
|
15
|
+
name: "_conditionId";
|
16
|
+
}>;
|
17
|
+
claimer: AbiParameterToPrimitiveType<{ type: "address"; name: "_claimer" }>;
|
18
|
+
quantity: AbiParameterToPrimitiveType<{ type: "uint256"; name: "_quantity" }>;
|
19
|
+
currency: AbiParameterToPrimitiveType<{ type: "address"; name: "_currency" }>;
|
20
|
+
pricePerToken: AbiParameterToPrimitiveType<{
|
21
|
+
type: "uint256";
|
22
|
+
name: "_pricePerToken";
|
23
|
+
}>;
|
24
|
+
allowlistProof: AbiParameterToPrimitiveType<{
|
25
|
+
type: "tuple";
|
26
|
+
name: "_allowlistProof";
|
27
|
+
components: [
|
28
|
+
{ type: "bytes32[]"; name: "proof" },
|
29
|
+
{ type: "uint256"; name: "quantityLimitPerWallet" },
|
30
|
+
{ type: "uint256"; name: "pricePerToken" },
|
31
|
+
{ type: "address"; name: "currency" },
|
32
|
+
];
|
33
|
+
}>;
|
34
|
+
};
|
35
|
+
|
36
|
+
export const FN_SELECTOR = "0x23a2902b" as const;
|
37
|
+
const FN_INPUTS = [
|
38
|
+
{
|
39
|
+
type: "uint256",
|
40
|
+
name: "_conditionId",
|
41
|
+
},
|
42
|
+
{
|
43
|
+
type: "address",
|
44
|
+
name: "_claimer",
|
45
|
+
},
|
46
|
+
{
|
47
|
+
type: "uint256",
|
48
|
+
name: "_quantity",
|
49
|
+
},
|
50
|
+
{
|
51
|
+
type: "address",
|
52
|
+
name: "_currency",
|
53
|
+
},
|
54
|
+
{
|
55
|
+
type: "uint256",
|
56
|
+
name: "_pricePerToken",
|
57
|
+
},
|
58
|
+
{
|
59
|
+
type: "tuple",
|
60
|
+
name: "_allowlistProof",
|
61
|
+
components: [
|
62
|
+
{
|
63
|
+
type: "bytes32[]",
|
64
|
+
name: "proof",
|
65
|
+
},
|
66
|
+
{
|
67
|
+
type: "uint256",
|
68
|
+
name: "quantityLimitPerWallet",
|
69
|
+
},
|
70
|
+
{
|
71
|
+
type: "uint256",
|
72
|
+
name: "pricePerToken",
|
73
|
+
},
|
74
|
+
{
|
75
|
+
type: "address",
|
76
|
+
name: "currency",
|
77
|
+
},
|
78
|
+
],
|
79
|
+
},
|
80
|
+
] as const;
|
81
|
+
const FN_OUTPUTS = [
|
82
|
+
{
|
83
|
+
type: "bool",
|
84
|
+
name: "isOverride",
|
85
|
+
},
|
86
|
+
] as const;
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Checks if the `verifyClaim` method is supported by the given contract.
|
90
|
+
* @param availableSelectors An array of 4byte function selectors of the contract. You can get this in various ways, such as using "whatsabi" or if you have the ABI of the contract available you can use it to generate the selectors.
|
91
|
+
* @returns A boolean indicating if the `verifyClaim` method is supported.
|
92
|
+
* @extension ERC721
|
93
|
+
* @example
|
94
|
+
* ```ts
|
95
|
+
* import { isVerifyClaimSupported } from "thirdweb/extensions/erc721";
|
96
|
+
* const supported = isVerifyClaimSupported(["0x..."]);
|
97
|
+
* ```
|
98
|
+
*/
|
99
|
+
export function isVerifyClaimSupported(availableSelectors: string[]) {
|
100
|
+
return detectMethod({
|
101
|
+
availableSelectors,
|
102
|
+
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
103
|
+
});
|
104
|
+
}
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Encodes the parameters for the "verifyClaim" function.
|
108
|
+
* @param options - The options for the verifyClaim function.
|
109
|
+
* @returns The encoded ABI parameters.
|
110
|
+
* @extension ERC721
|
111
|
+
* @example
|
112
|
+
* ```ts
|
113
|
+
* import { encodeVerifyClaimParams } from "thirdweb/extensions/erc721";
|
114
|
+
* const result = encodeVerifyClaimParams({
|
115
|
+
* conditionId: ...,
|
116
|
+
* claimer: ...,
|
117
|
+
* quantity: ...,
|
118
|
+
* currency: ...,
|
119
|
+
* pricePerToken: ...,
|
120
|
+
* allowlistProof: ...,
|
121
|
+
* });
|
122
|
+
* ```
|
123
|
+
*/
|
124
|
+
export function encodeVerifyClaimParams(options: VerifyClaimParams) {
|
125
|
+
return encodeAbiParameters(FN_INPUTS, [
|
126
|
+
options.conditionId,
|
127
|
+
options.claimer,
|
128
|
+
options.quantity,
|
129
|
+
options.currency,
|
130
|
+
options.pricePerToken,
|
131
|
+
options.allowlistProof,
|
132
|
+
]);
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Encodes the "verifyClaim" function into a Hex string with its parameters.
|
137
|
+
* @param options - The options for the verifyClaim function.
|
138
|
+
* @returns The encoded hexadecimal string.
|
139
|
+
* @extension ERC721
|
140
|
+
* @example
|
141
|
+
* ```ts
|
142
|
+
* import { encodeVerifyClaim } from "thirdweb/extensions/erc721";
|
143
|
+
* const result = encodeVerifyClaim({
|
144
|
+
* conditionId: ...,
|
145
|
+
* claimer: ...,
|
146
|
+
* quantity: ...,
|
147
|
+
* currency: ...,
|
148
|
+
* pricePerToken: ...,
|
149
|
+
* allowlistProof: ...,
|
150
|
+
* });
|
151
|
+
* ```
|
152
|
+
*/
|
153
|
+
export function encodeVerifyClaim(options: VerifyClaimParams) {
|
154
|
+
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
155
|
+
// we can do this because we know the specific formats of the values
|
156
|
+
return (FN_SELECTOR +
|
157
|
+
encodeVerifyClaimParams(options).slice(
|
158
|
+
2,
|
159
|
+
)) as `${typeof FN_SELECTOR}${string}`;
|
160
|
+
}
|
161
|
+
|
162
|
+
/**
|
163
|
+
* Decodes the result of the verifyClaim function call.
|
164
|
+
* @param result - The hexadecimal result to decode.
|
165
|
+
* @returns The decoded result as per the FN_OUTPUTS definition.
|
166
|
+
* @extension ERC721
|
167
|
+
* @example
|
168
|
+
* ```ts
|
169
|
+
* import { decodeVerifyClaimResult } from "thirdweb/extensions/erc721";
|
170
|
+
* const result = decodeVerifyClaimResultResult("...");
|
171
|
+
* ```
|
172
|
+
*/
|
173
|
+
export function decodeVerifyClaimResult(result: Hex) {
|
174
|
+
return decodeAbiParameters(FN_OUTPUTS, result)[0];
|
175
|
+
}
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Calls the "verifyClaim" function on the contract.
|
179
|
+
* @param options - The options for the verifyClaim function.
|
180
|
+
* @returns The parsed result of the function call.
|
181
|
+
* @extension ERC721
|
182
|
+
* @example
|
183
|
+
* ```ts
|
184
|
+
* import { verifyClaim } from "thirdweb/extensions/erc721";
|
185
|
+
*
|
186
|
+
* const result = await verifyClaim({
|
187
|
+
* contract,
|
188
|
+
* conditionId: ...,
|
189
|
+
* claimer: ...,
|
190
|
+
* quantity: ...,
|
191
|
+
* currency: ...,
|
192
|
+
* pricePerToken: ...,
|
193
|
+
* allowlistProof: ...,
|
194
|
+
* });
|
195
|
+
*
|
196
|
+
* ```
|
197
|
+
*/
|
198
|
+
export async function verifyClaim(
|
199
|
+
options: BaseTransactionOptions<VerifyClaimParams>,
|
200
|
+
) {
|
201
|
+
return readContract({
|
202
|
+
contract: options.contract,
|
203
|
+
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
204
|
+
params: [
|
205
|
+
options.conditionId,
|
206
|
+
options.claimer,
|
207
|
+
options.quantity,
|
208
|
+
options.currency,
|
209
|
+
options.pricePerToken,
|
210
|
+
options.allowlistProof,
|
211
|
+
],
|
212
|
+
});
|
213
|
+
}
|
@@ -25,6 +25,7 @@ import { setClaimConditions } from "./drops/write/setClaimConditions.js";
|
|
25
25
|
import { getNFT } from "./read/getNFT.js";
|
26
26
|
import { lazyMint } from "./write/lazyMint.js";
|
27
27
|
|
28
|
+
import { canClaim } from "./drops/read/canClaim.js";
|
28
29
|
describe.runIf(process.env.TW_SECRET_KEY)(
|
29
30
|
"DropERC721",
|
30
31
|
{
|
@@ -121,6 +122,19 @@ describe.runIf(process.env.TW_SECRET_KEY)(
|
|
121
122
|
}),
|
122
123
|
account: TEST_ACCOUNT_A,
|
123
124
|
});
|
125
|
+
|
126
|
+
expect(
|
127
|
+
await canClaim({
|
128
|
+
contract,
|
129
|
+
claimer: TEST_ACCOUNT_A.address,
|
130
|
+
quantity: 1n,
|
131
|
+
}),
|
132
|
+
).toMatchInlineSnapshot(`
|
133
|
+
{
|
134
|
+
"result": true,
|
135
|
+
}
|
136
|
+
`);
|
137
|
+
|
124
138
|
const claimTx = claimTo({
|
125
139
|
contract,
|
126
140
|
to: TEST_ACCOUNT_A.address,
|
@@ -208,6 +222,31 @@ describe.runIf(process.env.TW_SECRET_KEY)(
|
|
208
222
|
balanceOf({ contract, owner: TEST_ACCOUNT_B.address }),
|
209
223
|
).resolves.toBe(0n);
|
210
224
|
|
225
|
+
expect(
|
226
|
+
await canClaim({
|
227
|
+
contract,
|
228
|
+
claimer: TEST_ACCOUNT_A.address,
|
229
|
+
quantity: 1n,
|
230
|
+
}),
|
231
|
+
).toMatchInlineSnapshot(`
|
232
|
+
{
|
233
|
+
"result": true,
|
234
|
+
}
|
235
|
+
`);
|
236
|
+
|
237
|
+
expect(
|
238
|
+
await canClaim({
|
239
|
+
contract,
|
240
|
+
claimer: TEST_ACCOUNT_B.address,
|
241
|
+
quantity: 1n,
|
242
|
+
}),
|
243
|
+
).toMatchInlineSnapshot(`
|
244
|
+
{
|
245
|
+
"reason": "DropClaimExceedLimit - 0,1",
|
246
|
+
"result": false,
|
247
|
+
}
|
248
|
+
`);
|
249
|
+
|
211
250
|
await sendAndConfirmTransaction({
|
212
251
|
account: TEST_ACCOUNT_A,
|
213
252
|
transaction: claimTo({
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import { extractErrorResult } from "../../../../transaction/extract-error.js";
|
2
|
+
import type { BaseTransactionOptions } from "../../../../transaction/types.js";
|
3
|
+
import { getClaimParams } from "../../../../utils/extensions/drops/get-claim-params.js";
|
4
|
+
import { verifyClaim } from "../../__generated__/DropERC721/read/verifyClaim.js";
|
5
|
+
import { getActiveClaimConditionId } from "../../__generated__/IDrop/read/getActiveClaimConditionId.js";
|
6
|
+
|
7
|
+
export type CanClaimParams = {
|
8
|
+
claimer: string;
|
9
|
+
quantity: bigint;
|
10
|
+
from?: string;
|
11
|
+
};
|
12
|
+
|
13
|
+
export type CanClaimResult = {
|
14
|
+
result: boolean;
|
15
|
+
reason?: string;
|
16
|
+
};
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Check if a user can claim a drop.
|
20
|
+
*
|
21
|
+
* @param options - The options for the transaction.
|
22
|
+
* @returns Whether the user can claim the drop.
|
23
|
+
*
|
24
|
+
* @example
|
25
|
+
* ```ts
|
26
|
+
* const claimResult = await canClaim({
|
27
|
+
* contract: contract,
|
28
|
+
* claimer: "0x1234567890123456789012345678901234567890",
|
29
|
+
* quantity: "1",
|
30
|
+
* });
|
31
|
+
* ```
|
32
|
+
*
|
33
|
+
* @extension ERC721
|
34
|
+
*/
|
35
|
+
export async function canClaim(
|
36
|
+
options: BaseTransactionOptions<CanClaimParams>,
|
37
|
+
): Promise<CanClaimResult> {
|
38
|
+
const [conditionId, { quantity, currency, pricePerToken, allowlistProof }] =
|
39
|
+
await Promise.all([
|
40
|
+
getActiveClaimConditionId({
|
41
|
+
contract: options.contract,
|
42
|
+
}),
|
43
|
+
getClaimParams({
|
44
|
+
contract: options.contract,
|
45
|
+
quantity: options.quantity,
|
46
|
+
to: options.claimer,
|
47
|
+
type: "erc721",
|
48
|
+
from: options.from,
|
49
|
+
}),
|
50
|
+
]);
|
51
|
+
try {
|
52
|
+
await verifyClaim({
|
53
|
+
contract: options.contract,
|
54
|
+
claimer: options.claimer,
|
55
|
+
quantity,
|
56
|
+
currency,
|
57
|
+
pricePerToken,
|
58
|
+
allowlistProof,
|
59
|
+
conditionId,
|
60
|
+
});
|
61
|
+
return {
|
62
|
+
result: true,
|
63
|
+
};
|
64
|
+
} catch (error) {
|
65
|
+
return {
|
66
|
+
result: false,
|
67
|
+
reason: await extractErrorResult({ error, contract: options.contract }),
|
68
|
+
};
|
69
|
+
}
|
70
|
+
}
|
@@ -517,6 +517,11 @@ function BuyScreenContent(props: BuyScreenContentProps) {
|
|
517
517
|
screen.id === "buy-with-fiat") &&
|
518
518
|
payer && (
|
519
519
|
<TokenSelectedLayout
|
520
|
+
disabled={
|
521
|
+
("prefillBuy" in payOptions &&
|
522
|
+
payOptions.prefillBuy?.allowEdits?.amount === false) ||
|
523
|
+
payOptions.mode !== "fund_wallet"
|
524
|
+
}
|
520
525
|
title={props.title}
|
521
526
|
selectedChain={toChain}
|
522
527
|
selectedToken={toToken}
|
@@ -651,6 +656,7 @@ function SelectedTokenInfo(props: {
|
|
651
656
|
tokenAmount: string;
|
652
657
|
setTokenAmount: (amount: string) => void;
|
653
658
|
client: ThirdwebClient;
|
659
|
+
disabled?: boolean;
|
654
660
|
}) {
|
655
661
|
const getWidth = () => {
|
656
662
|
let chars = props.tokenAmount.replace(".", "").length;
|
@@ -680,7 +686,7 @@ function SelectedTokenInfo(props: {
|
|
680
686
|
type="text"
|
681
687
|
data-placeholder={props.tokenAmount === ""}
|
682
688
|
value={props.tokenAmount || "0"}
|
683
|
-
disabled={
|
689
|
+
disabled={props.disabled}
|
684
690
|
onClick={(e) => {
|
685
691
|
// put cursor at the end of the input
|
686
692
|
if (props.tokenAmount === "") {
|
@@ -865,8 +871,13 @@ function MainScreen(props: {
|
|
865
871
|
}}
|
866
872
|
freezeAmount={payOptions.prefillBuy?.allowEdits?.amount === false}
|
867
873
|
freezeChainAndToken={
|
868
|
-
payOptions.prefillBuy?.allowEdits?.chain === false &&
|
869
|
-
|
874
|
+
(payOptions.prefillBuy?.allowEdits?.chain === false &&
|
875
|
+
payOptions.prefillBuy?.allowEdits?.token === false) ||
|
876
|
+
(payOptions.buyWithCrypto !== false &&
|
877
|
+
payOptions.buyWithCrypto?.prefillSource?.allowEdits?.token ===
|
878
|
+
false &&
|
879
|
+
payOptions.buyWithCrypto?.prefillSource?.allowEdits?.chain ===
|
880
|
+
false)
|
870
881
|
}
|
871
882
|
token={toToken}
|
872
883
|
chain={toChain}
|
@@ -924,6 +935,7 @@ function TokenSelectedLayout(props: {
|
|
924
935
|
selectedChain: Chain;
|
925
936
|
client: ThirdwebClient;
|
926
937
|
onBack: () => void;
|
938
|
+
disabled?: boolean;
|
927
939
|
}) {
|
928
940
|
return (
|
929
941
|
<Container>
|
@@ -944,6 +956,7 @@ function TokenSelectedLayout(props: {
|
|
944
956
|
tokenAmount={props.tokenAmount}
|
945
957
|
setTokenAmount={props.setTokenAmount}
|
946
958
|
client={props.client}
|
959
|
+
disabled={props.disabled}
|
947
960
|
/>
|
948
961
|
|
949
962
|
<Spacer y="md" />
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import styled from "@emotion/styled";
|
2
|
+
import { ChevronRightIcon } from "@radix-ui/react-icons";
|
2
3
|
import { useState } from "react";
|
3
4
|
import type { Chain } from "../../../../../../chains/types.js";
|
4
5
|
import type { ThirdwebClient } from "../../../../../../client/client.js";
|
@@ -23,6 +24,7 @@ import { Button } from "../../../components/buttons.js";
|
|
23
24
|
import { Text } from "../../../components/text.js";
|
24
25
|
import { Blobbie } from "../../Blobbie.js";
|
25
26
|
import { formatTokenBalance } from "../formatTokenBalance.js";
|
27
|
+
import { FiatValue } from "./swap/FiatValue.js";
|
26
28
|
import type { TokenBalance } from "./swap/PaymentSelectionScreen.js";
|
27
29
|
|
28
30
|
export function WalletRowWithBalances(props: {
|
@@ -100,23 +102,42 @@ function TokenBalanceRow(props: {
|
|
100
102
|
onClick={() => onClick(tokenBalance.token, wallet)}
|
101
103
|
variant="secondary"
|
102
104
|
>
|
103
|
-
<
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
<
|
111
|
-
|
112
|
-
|
113
|
-
|
105
|
+
<Container flex="row" center="y" gap="md">
|
106
|
+
<TokenIcon
|
107
|
+
token={tokenBalance.token}
|
108
|
+
chain={tokenBalance.chain}
|
109
|
+
size="md"
|
110
|
+
client={client}
|
111
|
+
/>
|
112
|
+
<Container flex="column" gap="3xs">
|
113
|
+
<Text size="xs" color="primaryText">
|
114
|
+
{tokenBalance.token.symbol}
|
115
|
+
</Text>
|
116
|
+
{chainInfo && <Text size="xs">{chainInfo.name}</Text>}
|
117
|
+
</Container>
|
114
118
|
</Container>
|
115
|
-
<
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
119
|
+
<Container flex="row" center="y" gap="3xs" color="secondaryText">
|
120
|
+
<Container
|
121
|
+
flex="column"
|
122
|
+
color="secondaryText"
|
123
|
+
gap="3xs"
|
124
|
+
style={{
|
125
|
+
justifyContent: "flex-end",
|
126
|
+
alignItems: "flex-end",
|
127
|
+
}}
|
128
|
+
>
|
129
|
+
<Text size="xs" color="primaryText">
|
130
|
+
{formatTokenBalance(tokenBalance.balance, true, 2)}
|
131
|
+
</Text>
|
132
|
+
<FiatValue
|
133
|
+
tokenAmount={tokenBalance.balance.displayValue}
|
134
|
+
token={tokenBalance.token}
|
135
|
+
chain={tokenBalance.chain}
|
136
|
+
client={client}
|
137
|
+
size="xs"
|
138
|
+
/>
|
139
|
+
</Container>
|
140
|
+
<ChevronRightIcon width={iconSize.md} height={iconSize.md} />
|
120
141
|
</Container>
|
121
142
|
</StyledButton>
|
122
143
|
);
|
@@ -149,7 +170,7 @@ export function WalletRow(props: {
|
|
149
170
|
width={props.iconSize ? iconSize[props.iconSize] : iconSize.md}
|
150
171
|
height={props.iconSize ? iconSize[props.iconSize] : iconSize.md}
|
151
172
|
style={{
|
152
|
-
borderRadius:
|
173
|
+
borderRadius: radius.sm,
|
153
174
|
overflow: "hidden",
|
154
175
|
border: `1px solid ${theme.colors.borderColor}`,
|
155
176
|
}}
|
@@ -166,7 +187,7 @@ export function WalletRow(props: {
|
|
166
187
|
style={{
|
167
188
|
width: iconSize.md,
|
168
189
|
height: iconSize.md,
|
169
|
-
borderRadius:
|
190
|
+
borderRadius: radius.sm,
|
170
191
|
overflow: "hidden",
|
171
192
|
border: `1px solid ${theme.colors.borderColor}`,
|
172
193
|
}}
|
@@ -186,7 +207,7 @@ const StyledButton = /* @__PURE__ */ styled(Button)((_) => {
|
|
186
207
|
const theme = useCustomTheme();
|
187
208
|
return {
|
188
209
|
background: theme.colors.tertiaryBg,
|
189
|
-
justifyContent: "
|
210
|
+
justifyContent: "space-between",
|
190
211
|
flexDirection: "row",
|
191
212
|
padding: spacing.sm,
|
192
213
|
gap: spacing.sm,
|
@@ -122,7 +122,13 @@ export function BuyTokenInput(props: {
|
|
122
122
|
</Container>
|
123
123
|
</div>
|
124
124
|
|
125
|
-
<Container
|
125
|
+
<Container
|
126
|
+
flex="row"
|
127
|
+
center="both"
|
128
|
+
style={{
|
129
|
+
height: fontSize.xl,
|
130
|
+
}}
|
131
|
+
>
|
126
132
|
<FiatValue
|
127
133
|
tokenAmount={props.value}
|
128
134
|
token={props.token}
|
@@ -41,11 +41,7 @@ export function FiatValue(
|
|
41
41
|
return <Skeleton width={"50px"} height={fontSize.lg} />;
|
42
42
|
}
|
43
43
|
|
44
|
-
return (
|
45
|
-
<Text {...props}>
|
46
|
-
|
47
|
-
? `$${formatNumber(cryptoToFiatQuery.data.result, 2)}`
|
48
|
-
: "-"}
|
49
|
-
</Text>
|
50
|
-
);
|
44
|
+
return cryptoToFiatQuery.data?.result ? (
|
45
|
+
<Text {...props}>${formatNumber(cryptoToFiatQuery.data.result, 2)}</Text>
|
46
|
+
) : null;
|
51
47
|
}
|
@@ -166,25 +166,37 @@ export function PaymentSelectionScreen(props: {
|
|
166
166
|
return <LoadingScreen />;
|
167
167
|
}
|
168
168
|
|
169
|
+
const filteredWallets = Array.from(walletsAndBalances.data?.entries() || [])
|
170
|
+
.filter(([w]) => !props.hiddenWallets?.includes(w.id))
|
171
|
+
.filter(([, balances]) => {
|
172
|
+
const hasEnoughBalance = balances.some((b) => b.balance.value > 0);
|
173
|
+
return hasEnoughBalance;
|
174
|
+
});
|
175
|
+
|
169
176
|
return (
|
170
177
|
<Container>
|
171
178
|
<Container flex="column" gap="xs">
|
172
|
-
{
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
179
|
+
{filteredWallets.length === 0 && (
|
180
|
+
<Container flex="column" gap="xs" py="md">
|
181
|
+
<Text size="xs" color="secondaryText" center>
|
182
|
+
<i>Insufficient funds in connected wallets</i>
|
183
|
+
</Text>
|
184
|
+
</Container>
|
185
|
+
)}
|
186
|
+
{filteredWallets.map(([w, balances]) => {
|
187
|
+
const address = w.getAccount()?.address;
|
188
|
+
if (!address) return null;
|
189
|
+
return (
|
190
|
+
<WalletRowWithBalances
|
191
|
+
key={w.id}
|
192
|
+
wallet={w}
|
193
|
+
balances={balances}
|
194
|
+
client={props.client}
|
195
|
+
address={address}
|
196
|
+
onClick={props.onSelect}
|
197
|
+
/>
|
198
|
+
);
|
199
|
+
})}
|
188
200
|
{!hideConnectButton && (
|
189
201
|
<Button
|
190
202
|
variant="secondary"
|