@0xsequence/marketplace-sdk 0.4.9 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-BMWCIHCB.js → chunk-5NORRVPM.js} +1 -1
- package/dist/{chunk-BMWCIHCB.js.map → chunk-5NORRVPM.js.map} +1 -1
- package/dist/{chunk-ATDCYXXV.js → chunk-6YHHCGGY.js} +2 -2
- package/dist/{chunk-BJLOO4NP.js → chunk-F4E3WJ2K.js} +30 -26
- package/dist/chunk-F4E3WJ2K.js.map +1 -0
- package/dist/{chunk-CUA4SGWT.js → chunk-I37CRQ4S.js} +750 -561
- package/dist/chunk-I37CRQ4S.js.map +1 -0
- package/dist/{chunk-TFCSNRD5.js → chunk-LJAB3S6U.js} +1 -1
- package/dist/chunk-LJAB3S6U.js.map +1 -0
- package/dist/{chunk-Y3KINNAU.js → chunk-MKGSGTQC.js} +14 -7
- package/dist/chunk-MKGSGTQC.js.map +1 -0
- package/dist/{chunk-XXML5K3X.js → chunk-QTJF5GDQ.js} +2 -2
- package/dist/{chunk-LF44FCG5.js → chunk-TQWM4ER6.js} +2 -2
- package/dist/{chunk-LF44FCG5.js.map → chunk-TQWM4ER6.js.map} +1 -1
- package/dist/{chunk-7HWJ4DUX.js → chunk-WSCUPAGR.js} +7 -3
- package/dist/chunk-WSCUPAGR.js.map +1 -0
- package/dist/{create-config-CgYQDyMD.d.ts → create-config-BXvwUh55.d.ts} +2 -2
- package/dist/index.css +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/{marketplace-config-BP5-XnFG.d.ts → marketplace-config-znEu4L0K.d.ts} +1 -1
- package/dist/{marketplace.gen-BzmWLP9L.d.ts → marketplace.gen-CCJ-URn2.d.ts} +2 -0
- package/dist/react/_internal/api/index.d.ts +3 -2
- package/dist/react/_internal/api/index.js +1 -1
- package/dist/react/_internal/index.d.ts +5 -5
- package/dist/react/_internal/index.js +1 -1
- package/dist/react/_internal/wagmi/index.d.ts +3 -3
- package/dist/react/hooks/index.d.ts +299 -94
- package/dist/react/hooks/index.js +11 -5
- package/dist/react/index.css +2 -2
- package/dist/react/index.css.map +1 -1
- package/dist/react/index.d.ts +6 -6
- package/dist/react/index.js +15 -9
- package/dist/react/ssr/index.js +4 -0
- package/dist/react/ssr/index.js.map +1 -1
- package/dist/react/ui/components/collectible-card/index.css +2 -2
- package/dist/react/ui/components/collectible-card/index.css.map +1 -1
- package/dist/react/ui/components/collectible-card/index.d.ts +3 -3
- package/dist/react/ui/components/collectible-card/index.js +9 -9
- package/dist/react/ui/icons/index.js +3 -3
- package/dist/react/ui/index.css +2 -2
- package/dist/react/ui/index.css.map +1 -1
- package/dist/react/ui/index.d.ts +3 -3
- package/dist/react/ui/index.js +9 -9
- package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +3 -3
- package/dist/react/ui/modals/_internal/components/actionModal/index.js +6 -6
- package/dist/{sdk-config-LbbmA85k.d.ts → sdk-config-B32_2bG3.d.ts} +4 -2
- package/dist/{services-DW26ougH.d.ts → services-BRBVE0mm.d.ts} +1 -1
- package/dist/styles/index.css +2 -2
- package/dist/styles/index.css.map +1 -1
- package/dist/styles/index.js +2 -2
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +1 -1
- package/dist/{types-DhTZWw1U.d.ts → types-Yto6KrTN.d.ts} +2 -2
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +2 -2
- package/package.json +16 -16
- package/src/react/_internal/api/marketplace.gen.ts +6 -3
- package/src/react/_internal/api/query-keys.ts +4 -0
- package/src/react/hooks/index.ts +2 -0
- package/src/react/hooks/useAutoSelectFeeOption.tsx +197 -0
- package/src/react/hooks/useCancelOrder.tsx +41 -1
- package/src/react/hooks/useCollectionBalanceDetails.tsx +87 -0
- package/src/react/ui/components/collectible-card/CollectibleCard.tsx +10 -12
- package/src/react/ui/components/collectible-card/styles.css.ts +1 -1
- package/src/react/ui/icons/CartIcon.tsx +2 -2
- package/src/react/ui/modals/BuyModal/hooks/useBuyCollectable.ts +7 -4
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +5 -1
- package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx +14 -7
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/chunk-7HWJ4DUX.js.map +0 -1
- package/dist/chunk-BJLOO4NP.js.map +0 -1
- package/dist/chunk-CUA4SGWT.js.map +0 -1
- package/dist/chunk-TFCSNRD5.js.map +0 -1
- package/dist/chunk-Y3KINNAU.js.map +0 -1
- /package/dist/{chunk-ATDCYXXV.js.map → chunk-6YHHCGGY.js.map} +0 -0
- /package/dist/{chunk-XXML5K3X.js.map → chunk-QTJF5GDQ.js.map} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xsequence/marketplace-sdk",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
7
7
|
"**/*.css"
|
|
@@ -34,27 +34,27 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@legendapp/state": "^3.0.0-beta.26",
|
|
37
|
-
"@radix-ui/react-dialog": "^1.1.
|
|
38
|
-
"@radix-ui/react-popover": "^1.1.
|
|
39
|
-
"@radix-ui/react-select": "^2.1.
|
|
37
|
+
"@radix-ui/react-dialog": "^1.1.6",
|
|
38
|
+
"@radix-ui/react-popover": "^1.1.6",
|
|
39
|
+
"@radix-ui/react-select": "^2.1.6",
|
|
40
40
|
"date-fns": "^4.1.0",
|
|
41
41
|
"react-day-picker": "^9.5.1",
|
|
42
42
|
"zod": "^3.24.1"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"0xsequence": "^2.2.
|
|
46
|
-
"@0xsequence/api": "^2.2.
|
|
45
|
+
"0xsequence": "^2.2.13",
|
|
46
|
+
"@0xsequence/api": "^2.2.13",
|
|
47
47
|
"@0xsequence/design-system": "^1.9.0",
|
|
48
|
-
"@0xsequence/indexer": "^2.2.
|
|
49
|
-
"@0xsequence/kit": "^4.
|
|
50
|
-
"@0xsequence/kit-checkout": "^4.
|
|
51
|
-
"@0xsequence/metadata": "^2.2.
|
|
52
|
-
"@0xsequence/network": "^2.2.
|
|
53
|
-
"@tanstack/react-query": "^5.
|
|
48
|
+
"@0xsequence/indexer": "^2.2.13",
|
|
49
|
+
"@0xsequence/kit": "^4.6.0",
|
|
50
|
+
"@0xsequence/kit-checkout": "^4.6.0",
|
|
51
|
+
"@0xsequence/metadata": "^2.2.13",
|
|
52
|
+
"@0xsequence/network": "^2.2.13",
|
|
53
|
+
"@tanstack/react-query": "^5.66.0",
|
|
54
54
|
"react": "^18.3.1",
|
|
55
55
|
"react-dom": "^18.3.1",
|
|
56
|
-
"viem": "^2.
|
|
57
|
-
"wagmi": "^2.14.
|
|
56
|
+
"viem": "^2.23.2",
|
|
57
|
+
"wagmi": "^2.14.11"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@biomejs/biome": "^1.9.4",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"@testing-library/react": "^16.2.0",
|
|
63
63
|
"@types/react": "^18.3.18",
|
|
64
64
|
"@types/react-dom": "^18.3.5",
|
|
65
|
-
"@vanilla-extract/css": "^1.17.
|
|
66
|
-
"@vanilla-extract/esbuild-plugin": "^2.3.
|
|
65
|
+
"@vanilla-extract/css": "^1.17.1",
|
|
66
|
+
"@vanilla-extract/esbuild-plugin": "^2.3.15",
|
|
67
67
|
"@vanilla-extract/recipes": "^0.5.5",
|
|
68
68
|
"@vanilla-extract/vite-plugin": "^4.0.19",
|
|
69
69
|
"ctix": "^2.7.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
// marketplace-api
|
|
2
|
+
// marketplace-api 8d0cafb3a02c5db5bdd5d6b139a752349e301f0c
|
|
3
3
|
// --
|
|
4
4
|
// Code generated by webrpc-gen@v0.22.1 with typescript generator. DO NOT EDIT.
|
|
5
5
|
//
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
export const WebrpcHeader = "Webrpc"
|
|
9
9
|
|
|
10
|
-
export const WebrpcHeaderValue = "webrpc@v0.22.1;gen-typescript@v0.16.2;marketplace-api@v0.0.0-
|
|
10
|
+
export const WebrpcHeaderValue = "webrpc@v0.22.1;gen-typescript@v0.16.2;marketplace-api@v0.0.0-8d0cafb3a02c5db5bdd5d6b139a752349e301f0c"
|
|
11
11
|
|
|
12
12
|
// WebRPC description and code-gen version
|
|
13
13
|
export const WebRPCVersion = "v1"
|
|
@@ -16,7 +16,7 @@ export const WebRPCVersion = "v1"
|
|
|
16
16
|
export const WebRPCSchemaVersion = ""
|
|
17
17
|
|
|
18
18
|
// Schema hash generated from your RIDL schema
|
|
19
|
-
export const WebRPCSchemaHash = "
|
|
19
|
+
export const WebRPCSchemaHash = "8d0cafb3a02c5db5bdd5d6b139a752349e301f0c"
|
|
20
20
|
|
|
21
21
|
type WebrpcGenVersions = {
|
|
22
22
|
webrpcGenVersion: string;
|
|
@@ -350,6 +350,8 @@ export interface FeeBreakdown {
|
|
|
350
350
|
export interface CollectibleOrder {
|
|
351
351
|
metadata: TokenMetadata
|
|
352
352
|
order?: Order
|
|
353
|
+
listing?: Order
|
|
354
|
+
offer?: Order
|
|
353
355
|
}
|
|
354
356
|
|
|
355
357
|
export interface OrderFilter {
|
|
@@ -2119,3 +2121,4 @@ export const webrpcErrorByCode: { [code: number]: any } = {
|
|
|
2119
2121
|
}
|
|
2120
2122
|
|
|
2121
2123
|
export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise<Response>
|
|
2124
|
+
|
|
@@ -50,6 +50,10 @@ class CollectionKeys {
|
|
|
50
50
|
class BalanceQueries {
|
|
51
51
|
static all = ['balances'] as const;
|
|
52
52
|
static lists = [...BalanceQueries.all, 'tokenBalances'] as const;
|
|
53
|
+
static collectionBalanceDetails = [
|
|
54
|
+
...BalanceQueries.all,
|
|
55
|
+
'collectionBalanceDetails',
|
|
56
|
+
] as const;
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
// biome-ignore lint/complexity/noStaticOnlyClass:
|
package/src/react/hooks/index.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
export * from './useAutoSelectFeeOption';
|
|
1
2
|
export * from './useBalanceOfCollectible';
|
|
2
3
|
export * from './useCountOfCollectables';
|
|
3
4
|
export * from './useCollectible';
|
|
4
5
|
export * from './useCollection';
|
|
6
|
+
export * from './useCollectionBalanceDetails';
|
|
5
7
|
export * from './useConfig';
|
|
6
8
|
export * from './useCurrencies';
|
|
7
9
|
export * from './useCurrencyOptions';
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { zeroAddress, type Address } from 'viem';
|
|
2
|
+
import { useAccount } from 'wagmi';
|
|
3
|
+
import type { FeeOption } from '../ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect';
|
|
4
|
+
import { useCallback } from 'react';
|
|
5
|
+
import { useChain } from '@0xsequence/kit';
|
|
6
|
+
import { useCollectionBalanceDetails } from './useCollectionBalanceDetails';
|
|
7
|
+
|
|
8
|
+
enum AutoSelectFeeOptionError {
|
|
9
|
+
UserNotConnected = 'User not connected',
|
|
10
|
+
NoOptionsProvided = 'No options provided',
|
|
11
|
+
FailedToCheckBalances = 'Failed to check balances',
|
|
12
|
+
InsufficientBalanceForAnyFeeOption = 'Insufficient balance for any fee option',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type UseAutoSelectFeeOptionArgs = {
|
|
16
|
+
pendingFeeOptionConfirmation: {
|
|
17
|
+
id: string;
|
|
18
|
+
options: FeeOption[] | undefined;
|
|
19
|
+
chainId: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A React hook that automatically selects the first fee option for which the user has sufficient balance.
|
|
25
|
+
*
|
|
26
|
+
* @param {Object} params.pendingFeeOptionConfirmation - Configuration for fee option selection
|
|
27
|
+
*
|
|
28
|
+
* @returns {Promise<{
|
|
29
|
+
* selectedOption: FeeOption | null,
|
|
30
|
+
* error: AutoSelectFeeOptionError | null,
|
|
31
|
+
* isLoading?: boolean
|
|
32
|
+
* }>} A promise that resolves to an object containing:
|
|
33
|
+
* - selectedOption: The first fee option with sufficient balance, or null if none found
|
|
34
|
+
* - error: Error message if selection fails, null otherwise
|
|
35
|
+
* - isLoading: True while checking balances
|
|
36
|
+
*
|
|
37
|
+
* @throws {AutoSelectFeeOptionError} Possible errors:
|
|
38
|
+
* - UserNotConnected: When no wallet is connected
|
|
39
|
+
* - NoOptionsProvided: When fee options array is undefined
|
|
40
|
+
* - FailedToCheckBalances: When balance checking fails
|
|
41
|
+
* - InsufficientBalanceForAnyFeeOption: When user has insufficient balance for all options
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* function MyComponent() {
|
|
46
|
+
* const [pendingFeeOptionConfirmation, confirmPendingFeeOption] = useWaasFeeOptions();
|
|
47
|
+
*
|
|
48
|
+
* const autoSelectOptionPromise = useAutoSelectFeeOption({
|
|
49
|
+
* pendingFeeOptionConfirmation: pendingFeeOptionConfirmation
|
|
50
|
+
* ? {
|
|
51
|
+
* id: pendingFeeOptionConfirmation.id,
|
|
52
|
+
* options: pendingFeeOptionConfirmation.options,
|
|
53
|
+
* chainId: 1
|
|
54
|
+
* }
|
|
55
|
+
* : {
|
|
56
|
+
* id: '',
|
|
57
|
+
* options: undefined,
|
|
58
|
+
* chainId: 1
|
|
59
|
+
* }
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* useEffect(() => {
|
|
63
|
+
* autoSelectOptionPromise.then((result) => {
|
|
64
|
+
* if (result.isLoading) {
|
|
65
|
+
* console.log('Checking balances...');
|
|
66
|
+
* return;
|
|
67
|
+
* }
|
|
68
|
+
*
|
|
69
|
+
* if (result.error) {
|
|
70
|
+
* console.error('Failed to select fee option:', result.error);
|
|
71
|
+
* return;
|
|
72
|
+
* }
|
|
73
|
+
*
|
|
74
|
+
* if (pendingFeeOptionConfirmation?.id && result.selectedOption) {
|
|
75
|
+
* confirmPendingFeeOption(
|
|
76
|
+
* pendingFeeOptionConfirmation.id,
|
|
77
|
+
* result.selectedOption.token.contractAddress
|
|
78
|
+
* );
|
|
79
|
+
* }
|
|
80
|
+
* });
|
|
81
|
+
* }, [autoSelectOptionPromise, confirmPendingFeeOption, pendingFeeOptionConfirmation]);
|
|
82
|
+
*
|
|
83
|
+
* return <div>...</div>;
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export function useAutoSelectFeeOption({
|
|
88
|
+
pendingFeeOptionConfirmation,
|
|
89
|
+
}: UseAutoSelectFeeOptionArgs) {
|
|
90
|
+
const { address: userAddress } = useAccount();
|
|
91
|
+
|
|
92
|
+
// one token that has null contract address is native token, so we need to replace it with zero address
|
|
93
|
+
const contractWhitelist = pendingFeeOptionConfirmation.options?.map(
|
|
94
|
+
(option) =>
|
|
95
|
+
option.token.contractAddress === null
|
|
96
|
+
? zeroAddress
|
|
97
|
+
: (option.token.contractAddress as Address),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const {
|
|
101
|
+
data: balanceDetails,
|
|
102
|
+
isLoading: isBalanceDetailsLoading,
|
|
103
|
+
isError: isBalanceDetailsError,
|
|
104
|
+
} = useCollectionBalanceDetails({
|
|
105
|
+
chainId: pendingFeeOptionConfirmation.chainId,
|
|
106
|
+
filter: {
|
|
107
|
+
accountAddresses: userAddress ? [userAddress] : [],
|
|
108
|
+
contractWhitelist,
|
|
109
|
+
omitNativeBalances: false,
|
|
110
|
+
},
|
|
111
|
+
query: {
|
|
112
|
+
enabled: !!pendingFeeOptionConfirmation.options && !!userAddress,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
const chain = useChain(pendingFeeOptionConfirmation.chainId);
|
|
116
|
+
|
|
117
|
+
// combine native balance and erc20 balances
|
|
118
|
+
const combinedBalances = balanceDetails && [
|
|
119
|
+
...balanceDetails.nativeBalances.map((b) => ({
|
|
120
|
+
chainId: pendingFeeOptionConfirmation.chainId,
|
|
121
|
+
balance: b.balance,
|
|
122
|
+
symbol: chain?.nativeCurrency.symbol,
|
|
123
|
+
contractAddress: zeroAddress,
|
|
124
|
+
})),
|
|
125
|
+
...balanceDetails.balances.map((b) => ({
|
|
126
|
+
chainId: b.chainId,
|
|
127
|
+
balance: b.balance,
|
|
128
|
+
symbol: b.contractInfo?.symbol,
|
|
129
|
+
contractAddress: b.contractAddress,
|
|
130
|
+
})),
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
console.debug('currency balances', combinedBalances);
|
|
134
|
+
|
|
135
|
+
const autoSelectedOption = useCallback(async () => {
|
|
136
|
+
if (!userAddress) {
|
|
137
|
+
return {
|
|
138
|
+
selectedOption: null,
|
|
139
|
+
error: AutoSelectFeeOptionError.UserNotConnected,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!pendingFeeOptionConfirmation.options) {
|
|
144
|
+
return {
|
|
145
|
+
selectedOption: null,
|
|
146
|
+
error: AutoSelectFeeOptionError.NoOptionsProvided,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (isBalanceDetailsLoading) {
|
|
151
|
+
return { selectedOption: null, error: null, isLoading: true };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (isBalanceDetailsError || !combinedBalances) {
|
|
155
|
+
return {
|
|
156
|
+
selectedOption: null,
|
|
157
|
+
error: AutoSelectFeeOptionError.FailedToCheckBalances,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const selectedOption = pendingFeeOptionConfirmation.options.find(
|
|
162
|
+
(option) => {
|
|
163
|
+
const tokenBalance = combinedBalances.find(
|
|
164
|
+
(balance) =>
|
|
165
|
+
balance.contractAddress.toLowerCase() ===
|
|
166
|
+
(option.token.contractAddress === null
|
|
167
|
+
? zeroAddress
|
|
168
|
+
: option.token.contractAddress
|
|
169
|
+
).toLowerCase(),
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
if (!tokenBalance) return false;
|
|
173
|
+
|
|
174
|
+
return BigInt(tokenBalance.balance) >= BigInt(option.value);
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
if (!selectedOption) {
|
|
179
|
+
return {
|
|
180
|
+
selectedOption: null,
|
|
181
|
+
error: AutoSelectFeeOptionError.InsufficientBalanceForAnyFeeOption,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
console.debug('auto selected option', selectedOption);
|
|
186
|
+
|
|
187
|
+
return { selectedOption, error: null };
|
|
188
|
+
}, [
|
|
189
|
+
userAddress,
|
|
190
|
+
pendingFeeOptionConfirmation.options,
|
|
191
|
+
isBalanceDetailsLoading,
|
|
192
|
+
isBalanceDetailsError,
|
|
193
|
+
combinedBalances,
|
|
194
|
+
]);
|
|
195
|
+
|
|
196
|
+
return autoSelectedOption();
|
|
197
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
2
|
import { useCancelTransactionSteps } from './useCancelTransactionSteps';
|
|
3
3
|
import type { MarketplaceKind } from '../../types';
|
|
4
|
+
import { useWaasFeeOptions } from '@0xsequence/kit';
|
|
5
|
+
import { useAutoSelectFeeOption } from './useAutoSelectFeeOption';
|
|
4
6
|
|
|
5
7
|
interface UseCancelOrderArgs {
|
|
6
8
|
collectionAddress: string;
|
|
@@ -29,6 +31,44 @@ export const useCancelOrder = ({
|
|
|
29
31
|
const [cancellingOrderId, setCancellingOrderId] = useState<string | null>(
|
|
30
32
|
null,
|
|
31
33
|
);
|
|
34
|
+
const [pendingFeeOptionConfirmation, confirmPendingFeeOption] =
|
|
35
|
+
useWaasFeeOptions();
|
|
36
|
+
const autoSelectOptionPromise = useAutoSelectFeeOption({
|
|
37
|
+
pendingFeeOptionConfirmation: pendingFeeOptionConfirmation
|
|
38
|
+
? {
|
|
39
|
+
id: pendingFeeOptionConfirmation.id,
|
|
40
|
+
options: pendingFeeOptionConfirmation.options?.map((opt) => ({
|
|
41
|
+
...opt,
|
|
42
|
+
token: {
|
|
43
|
+
...opt.token,
|
|
44
|
+
contractAddress: opt.token.contractAddress || null,
|
|
45
|
+
decimals: opt.token.decimals || 0,
|
|
46
|
+
tokenID: opt.token.tokenID || null,
|
|
47
|
+
},
|
|
48
|
+
})),
|
|
49
|
+
chainId: Number(chainId),
|
|
50
|
+
}
|
|
51
|
+
: {
|
|
52
|
+
id: '',
|
|
53
|
+
options: undefined,
|
|
54
|
+
chainId: Number(chainId),
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
autoSelectOptionPromise.then((res) => {
|
|
60
|
+
if (pendingFeeOptionConfirmation?.id && res.selectedOption) {
|
|
61
|
+
confirmPendingFeeOption(
|
|
62
|
+
pendingFeeOptionConfirmation.id,
|
|
63
|
+
res.selectedOption.token.contractAddress,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}, [
|
|
68
|
+
autoSelectOptionPromise,
|
|
69
|
+
confirmPendingFeeOption,
|
|
70
|
+
pendingFeeOptionConfirmation,
|
|
71
|
+
]);
|
|
32
72
|
|
|
33
73
|
const { cancelOrder: cancelOrderBase } = useCancelTransactionSteps({
|
|
34
74
|
collectionAddress,
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import {
|
|
3
|
+
AddressSchema,
|
|
4
|
+
ChainIdSchema,
|
|
5
|
+
QueryArgSchema,
|
|
6
|
+
balanceQueries,
|
|
7
|
+
getIndexerClient,
|
|
8
|
+
} from '../_internal';
|
|
9
|
+
import { queryOptions, useQuery } from '@tanstack/react-query';
|
|
10
|
+
import { useConfig } from './useConfig';
|
|
11
|
+
import type { GetTokenBalancesDetailsReturn } from '@0xsequence/indexer';
|
|
12
|
+
import type { SdkConfig } from '../../types';
|
|
13
|
+
|
|
14
|
+
const filterSchema = z.object({
|
|
15
|
+
accountAddresses: z.array(AddressSchema),
|
|
16
|
+
contractWhitelist: z.array(AddressSchema).optional(),
|
|
17
|
+
omitNativeBalances: z.boolean(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const useCollectionBalanceDetailsArgsSchema = z.object({
|
|
21
|
+
chainId: ChainIdSchema.pipe(z.coerce.number()),
|
|
22
|
+
filter: filterSchema,
|
|
23
|
+
query: QueryArgSchema.optional(),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export type CollectionBalanceFilter = z.infer<typeof filterSchema>;
|
|
27
|
+
export type UseCollectionBalanceDetailsArgs = z.input<
|
|
28
|
+
typeof useCollectionBalanceDetailsArgsSchema
|
|
29
|
+
>;
|
|
30
|
+
|
|
31
|
+
const fetchCollectionBalanceDetails = async (
|
|
32
|
+
args: UseCollectionBalanceDetailsArgs,
|
|
33
|
+
indexerClient: Awaited<ReturnType<typeof getIndexerClient>>,
|
|
34
|
+
) => {
|
|
35
|
+
const promises = args.filter.accountAddresses.map((accountAddress) =>
|
|
36
|
+
indexerClient.getTokenBalancesDetails({
|
|
37
|
+
filter: {
|
|
38
|
+
accountAddresses: [accountAddress],
|
|
39
|
+
contractWhitelist: args.filter.contractWhitelist,
|
|
40
|
+
omitNativeBalances: args.filter.omitNativeBalances,
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const responses = await Promise.all(promises);
|
|
46
|
+
const mergedResponse = responses.reduce<GetTokenBalancesDetailsReturn>(
|
|
47
|
+
(acc, curr) => {
|
|
48
|
+
if (!curr) return acc;
|
|
49
|
+
return {
|
|
50
|
+
page: curr.page,
|
|
51
|
+
nativeBalances: [
|
|
52
|
+
...(acc.nativeBalances || []),
|
|
53
|
+
...(curr.nativeBalances || []),
|
|
54
|
+
],
|
|
55
|
+
balances: [...(acc.balances || []), ...(curr.balances || [])],
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
{ page: {}, nativeBalances: [], balances: [] },
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
if (!mergedResponse) {
|
|
62
|
+
throw new Error('Failed to fetch collection balance details');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return mergedResponse;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const collectionBalanceDetailsOptions = (
|
|
69
|
+
args: UseCollectionBalanceDetailsArgs,
|
|
70
|
+
config: SdkConfig,
|
|
71
|
+
) => {
|
|
72
|
+
const parsedArgs = useCollectionBalanceDetailsArgsSchema.parse(args);
|
|
73
|
+
const indexerClient = getIndexerClient(parsedArgs.chainId, config);
|
|
74
|
+
|
|
75
|
+
return queryOptions({
|
|
76
|
+
queryKey: [...balanceQueries.collectionBalanceDetails, args, config],
|
|
77
|
+
queryFn: () => fetchCollectionBalanceDetails(parsedArgs, indexerClient),
|
|
78
|
+
...args.query,
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const useCollectionBalanceDetails = (
|
|
83
|
+
args: UseCollectionBalanceDetailsArgs,
|
|
84
|
+
) => {
|
|
85
|
+
const config = useConfig();
|
|
86
|
+
return useQuery(collectionBalanceDetailsOptions(args, config));
|
|
87
|
+
};
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
Order,
|
|
10
10
|
OrderbookKind,
|
|
11
11
|
} from '../../../_internal';
|
|
12
|
-
import { useCurrency
|
|
12
|
+
import { useCurrency } from '../../../hooks';
|
|
13
13
|
import SvgDiamondEyeIcon from '../../icons/DiamondEye';
|
|
14
14
|
import ChessTileImage from '../../images/chess-tile.png';
|
|
15
15
|
import { ActionButton } from '../_internals/action-button/ActionButton';
|
|
@@ -95,13 +95,8 @@ export function CollectibleCard({
|
|
|
95
95
|
onCannotPerformAction,
|
|
96
96
|
}: CollectibleCardProps) {
|
|
97
97
|
const collectibleMetadata = lowestListing?.metadata;
|
|
98
|
+
const highestOffer = lowestListing?.offer
|
|
98
99
|
const [imageLoadingError, setImageLoadingError] = useState(false);
|
|
99
|
-
const { data: highestOffer, isLoading: highestOfferLoading } =
|
|
100
|
-
useHighestOffer({
|
|
101
|
-
chainId: String(chainId),
|
|
102
|
-
collectionAddress,
|
|
103
|
-
tokenId: collectibleId,
|
|
104
|
-
});
|
|
105
100
|
|
|
106
101
|
const { data: lowestListingCurrency } = useCurrency({
|
|
107
102
|
chainId,
|
|
@@ -111,13 +106,13 @@ export function CollectibleCard({
|
|
|
111
106
|
enabled: !!lowestListing?.order?.priceCurrencyAddress,
|
|
112
107
|
},
|
|
113
108
|
});
|
|
114
|
-
if (
|
|
109
|
+
if (cardLoading) {
|
|
115
110
|
return <CollectibleSkeleton />;
|
|
116
111
|
}
|
|
117
112
|
|
|
118
113
|
const action = (
|
|
119
114
|
balance
|
|
120
|
-
? (highestOffer
|
|
115
|
+
? (highestOffer && CollectibleCardAction.SELL) ||
|
|
121
116
|
(!lowestListing?.order && CollectibleCardAction.LIST) ||
|
|
122
117
|
CollectibleCardAction.TRANSFER
|
|
123
118
|
: (lowestListing?.order && CollectibleCardAction.BUY) ||
|
|
@@ -158,6 +153,8 @@ export function CollectibleCard({
|
|
|
158
153
|
<IconButton
|
|
159
154
|
as="a"
|
|
160
155
|
href={externalUrl}
|
|
156
|
+
target="_blank"
|
|
157
|
+
rel="noopener noreferrer"
|
|
161
158
|
size="sm"
|
|
162
159
|
backdropFilter="blur"
|
|
163
160
|
variant="glass"
|
|
@@ -165,6 +162,7 @@ export function CollectibleCard({
|
|
|
165
162
|
e.stopPropagation();
|
|
166
163
|
}}
|
|
167
164
|
position="absolute"
|
|
165
|
+
zIndex="20"
|
|
168
166
|
top="2"
|
|
169
167
|
left="2"
|
|
170
168
|
icon={SvgDiamondEyeIcon}
|
|
@@ -181,8 +179,8 @@ export function CollectibleCard({
|
|
|
181
179
|
<Footer
|
|
182
180
|
name={name || ''}
|
|
183
181
|
type={collectionType}
|
|
184
|
-
onOfferClick={() => onOfferClick?.({ order: highestOffer
|
|
185
|
-
highestOffer={highestOffer
|
|
182
|
+
onOfferClick={() => onOfferClick?.({ order: highestOffer })}
|
|
183
|
+
highestOffer={highestOffer}
|
|
186
184
|
lowestListingPriceAmount={lowestListing?.order?.priceAmount}
|
|
187
185
|
lowestListingCurrency={lowestListingCurrency}
|
|
188
186
|
balance={balance}
|
|
@@ -202,7 +200,7 @@ export function CollectibleCard({
|
|
|
202
200
|
tokenId={collectibleId}
|
|
203
201
|
orderbookKind={orderbookKind}
|
|
204
202
|
action={action}
|
|
205
|
-
highestOffer={highestOffer
|
|
203
|
+
highestOffer={highestOffer}
|
|
206
204
|
lowestListing={lowestListing?.order}
|
|
207
205
|
owned={!!balance}
|
|
208
206
|
onCannotPerformAction={onCannotPerformAction}
|
|
@@ -9,7 +9,7 @@ export const collectibleCard = style([
|
|
|
9
9
|
border: '1px solid hsla(247, 100%, 75%, 1)',
|
|
10
10
|
boxShadow: '0px 0px 0px 1px hsla(247, 100%, 75%, 1)',
|
|
11
11
|
},
|
|
12
|
-
':focus': {
|
|
12
|
+
':focus-visible': {
|
|
13
13
|
border: '1px solid hsla(247, 100%, 75%, 1)',
|
|
14
14
|
boxShadow: '0px 0px 0px 2px hsla(247, 100%, 75%, 1)',
|
|
15
15
|
outline: '4px solid hsla(254, 100%, 57%, 1)',
|
|
@@ -13,8 +13,8 @@ const Svg = () => (
|
|
|
13
13
|
>
|
|
14
14
|
<title id="cart-title">Cart Icon</title>
|
|
15
15
|
<path
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
fillRule="evenodd"
|
|
17
|
+
clipRule="evenodd"
|
|
18
18
|
d="M2.5 3.46836C2.5 3.20969 2.72366 3 2.99955 3H5.16925C5.88938 3 6.5077 3.48022 6.64172 4.14359L8.33188 12.5093C8.37655 12.7304 8.58266 12.8905 8.8227 12.8905H16.987C17.2629 12.8905 17.4866 13.1002 17.4866 13.3589C17.4866 13.6175 17.2629 13.8272 16.987 13.8272H8.8227C8.10257 13.8272 7.48425 13.347 7.35023 12.6836L5.66007 4.31793C5.6154 4.0968 5.40929 3.93673 5.16925 3.93673H2.99955C2.72366 3.93673 2.5 3.72704 2.5 3.46836Z"
|
|
19
19
|
fill="white"
|
|
20
20
|
/>
|
|
@@ -117,17 +117,20 @@ export const useBuyCollectable = ({
|
|
|
117
117
|
enableSwapPayments: !!input.checkoutOptions.swap,
|
|
118
118
|
creditCardProviders: input.checkoutOptions.nftCheckout || [],
|
|
119
119
|
onSuccess: (hash: string) => {
|
|
120
|
+
callbacks?.onSuccess?.({ hash: hash as Hash });
|
|
121
|
+
},
|
|
122
|
+
onError: callbacks?.onError,
|
|
123
|
+
onClose: () => {
|
|
120
124
|
invalidateQueries([
|
|
121
125
|
collectableKeys.listings,
|
|
126
|
+
collectableKeys.lowestListings,
|
|
122
127
|
collectableKeys.listingsCount,
|
|
123
128
|
collectableKeys.lists,
|
|
124
129
|
collectableKeys.userBalances,
|
|
125
130
|
balanceQueries.all,
|
|
131
|
+
balanceQueries.collectionBalanceDetails,
|
|
126
132
|
]);
|
|
127
|
-
|
|
128
|
-
},
|
|
129
|
-
onError: callbacks?.onError,
|
|
130
|
-
onClose: () => {
|
|
133
|
+
|
|
131
134
|
buyModal$.close();
|
|
132
135
|
},
|
|
133
136
|
});
|
|
@@ -62,7 +62,11 @@ const useHandleTransfer = () => {
|
|
|
62
62
|
collectibleId,
|
|
63
63
|
price: undefined,
|
|
64
64
|
type: TransactionType.TRANSFER,
|
|
65
|
-
queriesToInvalidate: [
|
|
65
|
+
queriesToInvalidate: [
|
|
66
|
+
balanceQueries.all,
|
|
67
|
+
balanceQueries.collectionBalanceDetails,
|
|
68
|
+
collectableKeys.userBalances,
|
|
69
|
+
],
|
|
66
70
|
});
|
|
67
71
|
} catch (error) {
|
|
68
72
|
transferModal$.view.set('enterReceiverAddress');
|
package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { Box, Image, Text } from '@0xsequence/design-system';
|
|
|
2
2
|
import type { Observable } from '@legendapp/state';
|
|
3
3
|
import { observer } from '@legendapp/state/react';
|
|
4
4
|
import { useEffect } from 'react';
|
|
5
|
-
import { formatUnits } from 'viem';
|
|
5
|
+
import { formatUnits, zeroAddress } from 'viem';
|
|
6
6
|
import {
|
|
7
7
|
CustomSelect,
|
|
8
8
|
type SelectItem,
|
|
@@ -32,12 +32,19 @@ const WaasFeeOptionsSelect = observer(
|
|
|
32
32
|
options: FeeOption[];
|
|
33
33
|
selectedFeeOption$: Observable<FeeOption | undefined>;
|
|
34
34
|
}) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
35
|
+
options = options.map((option) => ({
|
|
36
|
+
...option,
|
|
37
|
+
token: {
|
|
38
|
+
...option.token,
|
|
39
|
+
contractAddress: option.token.contractAddress || zeroAddress,
|
|
40
|
+
},
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const feeOptions = options.map((option) => {
|
|
44
|
+
const value = option.token.contractAddress ?? '';
|
|
45
|
+
|
|
46
|
+
return FeeOptionSelectItem({ value, option });
|
|
47
|
+
});
|
|
41
48
|
|
|
42
49
|
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
43
50
|
useEffect(() => {
|