@0xsequence/marketplace-sdk 0.8.7 → 0.8.8
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/CHANGELOG.md +26 -0
- package/dist/chunk-2PSNAIAT.js +1 -0
- package/dist/chunk-2PSNAIAT.js.map +1 -0
- package/dist/{chunk-7FVZD2LL.js → chunk-4XLXOEXQ.js} +2 -2
- package/dist/{chunk-Y6AOCO3Q.js → chunk-7IYKUVC3.js} +312 -145
- package/dist/chunk-7IYKUVC3.js.map +1 -0
- package/dist/{chunk-5HEZNTSU.js → chunk-D7RVSZAQ.js} +131 -83
- package/dist/chunk-D7RVSZAQ.js.map +1 -0
- package/dist/chunk-DWTLVJAW.js +42 -0
- package/dist/chunk-DWTLVJAW.js.map +1 -0
- package/dist/{chunk-YAUZLETY.js → chunk-G3447GIP.js} +37 -18
- package/dist/chunk-G3447GIP.js.map +1 -0
- package/dist/{chunk-O6GWM7C3.js → chunk-HHYNOPPI.js} +2 -2
- package/dist/{chunk-KTT27YUN.js → chunk-KGM2WLSP.js} +12 -156
- package/dist/chunk-KGM2WLSP.js.map +1 -0
- package/dist/chunk-MAD64DLJ.js +81 -0
- package/dist/chunk-MAD64DLJ.js.map +1 -0
- package/dist/chunk-N7BPFK46.js +1 -0
- package/dist/chunk-N7BPFK46.js.map +1 -0
- package/dist/chunk-NX52D7NX.js +135 -0
- package/dist/chunk-NX52D7NX.js.map +1 -0
- package/dist/chunk-O34GCB47.js +32 -0
- package/dist/chunk-O34GCB47.js.map +1 -0
- package/dist/{chunk-Q2DA477S.js → chunk-YALXP2PW.js} +3 -3
- package/dist/{chunk-A6V7XDY4.js → chunk-YBOFRP65.js} +2 -2
- package/dist/{create-config-CdooE7aU.d.ts → create-config-DwrnzwpM.d.ts} +2 -2
- package/dist/{index-ClKHzm0B.d.ts → index-DGsVBflk.d.ts} +3 -12
- package/dist/index.css +7 -5
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +13 -4
- package/dist/index.js +13 -5
- package/dist/{lowestListing-kFyrUGha.d.ts → lowestListing-BQHIuvNF.d.ts} +2 -2
- package/dist/{marketplace.gen-BU6T6f0m.d.ts → marketplace.gen-DQzWciwC.d.ts} +1 -1
- package/dist/marketplaceConfig-B4Fdsmxu.d.ts +17 -0
- package/dist/react/_internal/api/index.d.ts +3 -3
- package/dist/react/_internal/api/index.js +4 -3
- package/dist/react/_internal/databeat/index.d.ts +2 -1
- package/dist/react/_internal/databeat/index.js +11 -7
- package/dist/react/_internal/index.d.ts +6 -6
- package/dist/react/_internal/index.js +13 -10
- package/dist/react/_internal/wagmi/index.d.ts +6 -5
- package/dist/react/_internal/wagmi/index.js +2 -2
- package/dist/react/hooks/index.d.ts +9 -8
- package/dist/react/hooks/index.js +10 -6
- package/dist/react/hooks/options/index.d.ts +4 -4
- package/dist/react/hooks/options/index.js +7 -4
- package/dist/react/index.css +2650 -0
- package/dist/react/index.css.map +1 -1
- package/dist/react/index.d.ts +8 -8
- package/dist/react/index.js +16 -11
- package/dist/react/queries/index.d.ts +3 -3
- package/dist/react/queries/index.js +6 -3
- package/dist/react/ssr/index.d.ts +3 -3
- package/dist/react/ssr/index.js +6 -3
- package/dist/react/ssr/index.js.map +1 -1
- package/dist/react/ui/components/collectible-card/index.css +2650 -0
- package/dist/react/ui/components/collectible-card/index.css.map +1 -1
- package/dist/react/ui/components/collectible-card/index.d.ts +1 -1
- package/dist/react/ui/components/collectible-card/index.js +14 -9
- package/dist/react/ui/icons/index.js +5 -2
- package/dist/react/ui/index.css +2650 -0
- package/dist/react/ui/index.css.map +1 -1
- package/dist/react/ui/index.d.ts +2 -1
- package/dist/react/ui/index.js +14 -9
- package/dist/react/ui/modals/_internal/components/actionModal/index.js +11 -7
- package/dist/sdk-config-txlivEKe.d.ts +133 -0
- package/dist/{services-9ApY0U-o.d.ts → services-BI_w8Eq4.d.ts} +4 -4
- package/dist/types/index.d.ts +5 -4
- package/dist/types/index.js +9 -6
- package/dist/{types-DsTwmKG-.d.ts → types-isjvwapz.d.ts} +3 -3
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +5 -2
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/react/{hooks/options/__mocks__/marketplaceConfig.msw.ts → _internal/api/__mocks__/builder.msw.ts} +70 -63
- package/src/react/_internal/api/__mocks__/metadata.msw.ts +30 -10
- package/src/react/_internal/api/builder-api.ts +32 -0
- package/src/react/_internal/api/builder.gen.ts +215 -0
- package/src/react/_internal/api/services.ts +9 -2
- package/src/react/_internal/databeat/types.ts +1 -0
- package/src/react/_internal/wagmi/__tests__/create-config.test.ts +16 -41
- package/src/react/_internal/wagmi/create-config.ts +3 -16
- package/src/react/_internal/wagmi/get-connectors.ts +31 -21
- package/src/react/_internal/wallet/__tests__/wallet.test.ts +30 -0
- package/src/react/_internal/wallet/wallet.ts +25 -2
- package/src/react/hooks/__tests__/__snapshots__/useMarketplaceConfig.test.tsx.snap +96 -0
- package/src/react/hooks/__tests__/useCollection.test.tsx +4 -5
- package/src/react/hooks/__tests__/useCurrencies.test.tsx +1 -1
- package/src/react/hooks/__tests__/useInventory.test.tsx +15 -16
- package/src/react/hooks/__tests__/useListCollections.test.tsx +18 -163
- package/src/react/hooks/__tests__/useMarketplaceConfig.test.tsx +10 -11
- package/src/react/hooks/options/index.ts +1 -1
- package/src/react/hooks/useAutoSelectFeeOption.tsx +1 -0
- package/src/react/hooks/useMarketplaceConfig.tsx +2 -2
- package/src/react/queries/marketplaceConfig.ts +101 -0
- package/src/react/ssr/__tests__/__snapshots__/create-ssr-client.test.ts.snap +1 -0
- package/src/react/ssr/create-ssr-client.ts +1 -1
- package/src/react/ui/components/collectible-card/CollectibleCard.tsx +2 -2
- package/src/react/ui/components/collectible-card/__tests__/CollectibleAsset.test.tsx +72 -42
- package/src/react/ui/components/collectible-card/{CollectibleAsset.tsx → collectible-asset/CollectibleAsset.tsx} +44 -44
- package/src/react/ui/components/collectible-card/collectible-asset/CollectibleAssetSkeleton.tsx +14 -0
- package/src/react/ui/components/collectible-card/collectible-asset/utils.ts +36 -0
- package/src/react/ui/modals/BuyModal/hooks/usePaymentModalParams.ts +6 -1
- package/src/react/ui/modals/BuyModal/store.ts +1 -0
- package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +20 -2
- package/src/react/ui/modals/MakeOfferModal/hooks/useTransactionSteps.tsx +17 -1
- package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +4 -0
- package/src/react/ui/modals/_internal/components/actionModal/ActionModal.test.tsx +7 -1
- package/src/types/index.ts +7 -1
- package/src/types/sdk-config.ts +4 -9
- package/src/utils/fetchContentType.ts +101 -0
- package/src/utils/getSequenceMarketRequestId.ts +32 -0
- package/test/mocks/wallet.ts +3 -1
- package/test/test-utils.tsx +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/builder-types-D5HgAUWR.d.ts +0 -82
- package/dist/chunk-5HEZNTSU.js.map +0 -1
- package/dist/chunk-KTT27YUN.js.map +0 -1
- package/dist/chunk-N7E37ENQ.js +0 -58
- package/dist/chunk-N7E37ENQ.js.map +0 -1
- package/dist/chunk-Y6AOCO3Q.js.map +0 -1
- package/dist/chunk-YAUZLETY.js.map +0 -1
- package/dist/sdk-config-DIzJk_tI.d.ts +0 -26
- package/src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx +0 -134
- package/src/react/hooks/options/marketplaceConfigOptions.ts +0 -71
- package/src/types/builder-types.ts +0 -88
- /package/dist/{chunk-7FVZD2LL.js.map → chunk-4XLXOEXQ.js.map} +0 -0
- /package/dist/{chunk-O6GWM7C3.js.map → chunk-HHYNOPPI.js.map} +0 -0
- /package/dist/{chunk-Q2DA477S.js.map → chunk-YALXP2PW.js.map} +0 -0
- /package/dist/{chunk-A6V7XDY4.js.map → chunk-YBOFRP65.js.map} +0 -0
|
@@ -17,13 +17,10 @@ import {
|
|
|
17
17
|
} from '@0xsequence/connect';
|
|
18
18
|
import React, { type FunctionComponent } from 'react';
|
|
19
19
|
import type { CreateConnectorFn } from 'wagmi';
|
|
20
|
-
import {
|
|
21
|
-
type Env,
|
|
22
|
-
type MarketplaceConfig,
|
|
23
|
-
MarketplaceWallet,
|
|
24
|
-
type SdkConfig,
|
|
25
|
-
} from '../../../types';
|
|
20
|
+
import type { Env, SdkConfig } from '../../../types';
|
|
26
21
|
import { MissingConfigError } from '../../../utils/_internal/error/transaction';
|
|
22
|
+
import type { MarketplaceConfig } from '../../queries/marketplaceConfig';
|
|
23
|
+
import { MarketplaceWallet } from '../api/builder.gen';
|
|
27
24
|
import { DEFAULT_NETWORK } from '../consts';
|
|
28
25
|
|
|
29
26
|
export function getConnectors({
|
|
@@ -40,7 +37,7 @@ export function getConnectors({
|
|
|
40
37
|
if (walletType === MarketplaceWallet.UNIVERSAL) {
|
|
41
38
|
connectors.push(...getUniversalWalletConfigs(sdkConfig, marketplaceConfig));
|
|
42
39
|
} else if (walletType === MarketplaceWallet.EMBEDDED) {
|
|
43
|
-
connectors.push(...getWaasConnectors(sdkConfig));
|
|
40
|
+
connectors.push(...getWaasConnectors(sdkConfig, marketplaceConfig));
|
|
44
41
|
} else if (walletType === MarketplaceWallet.ECOSYSTEM) {
|
|
45
42
|
connectors.push(getEcosystemConnector(marketplaceConfig, sdkConfig));
|
|
46
43
|
} else {
|
|
@@ -57,7 +54,7 @@ function commonConnectors(
|
|
|
57
54
|
const wallets = [];
|
|
58
55
|
const { title: appName } = marketplaceConfig;
|
|
59
56
|
const walletOptions = marketplaceConfig.walletOptions;
|
|
60
|
-
const walletConnectProjectId = sdkConfig.
|
|
57
|
+
const walletConnectProjectId = sdkConfig.walletConnectProjectId;
|
|
61
58
|
|
|
62
59
|
if (walletOptions.connectors.includes('coinbase')) {
|
|
63
60
|
wallets.push(
|
|
@@ -110,23 +107,36 @@ function getUniversalWalletConfigs(
|
|
|
110
107
|
] as const;
|
|
111
108
|
}
|
|
112
109
|
|
|
113
|
-
export function getWaasConnectors(
|
|
114
|
-
|
|
110
|
+
export function getWaasConnectors(
|
|
111
|
+
config: SdkConfig,
|
|
112
|
+
marketplaceConfig: MarketplaceConfig,
|
|
113
|
+
): Wallet[] {
|
|
114
|
+
const { projectAccessKey } = config;
|
|
115
115
|
|
|
116
|
-
const waasConfigKey =
|
|
116
|
+
const waasConfigKey = marketplaceConfig.walletOptions.waas?.tenantKey;
|
|
117
117
|
|
|
118
|
-
if (!waasConfigKey)
|
|
118
|
+
if (!waasConfigKey)
|
|
119
|
+
throw new MissingConfigError(
|
|
120
|
+
'Embedded wallet config is missing, please check your access key',
|
|
121
|
+
);
|
|
119
122
|
|
|
120
|
-
const
|
|
121
|
-
|
|
123
|
+
const waasOptions = marketplaceConfig.walletOptions.oidcIssuers;
|
|
124
|
+
const googleClientId = waasOptions.google;
|
|
125
|
+
const appleClientId = waasOptions.apple;
|
|
126
|
+
const appleRedirectURI = globalThis.window
|
|
127
|
+
? `https://${globalThis.window?.location?.origin}${globalThis.window?.location?.pathname}`
|
|
128
|
+
: undefined;
|
|
122
129
|
|
|
123
|
-
const wallets: Wallet[] = [
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
const wallets: Wallet[] = [];
|
|
131
|
+
|
|
132
|
+
if (marketplaceConfig.walletOptions.waas?.emailEnabled) {
|
|
133
|
+
wallets.push(
|
|
134
|
+
emailWaas({
|
|
135
|
+
projectAccessKey,
|
|
136
|
+
waasConfigKey,
|
|
137
|
+
}),
|
|
138
|
+
);
|
|
139
|
+
}
|
|
130
140
|
|
|
131
141
|
if (googleClientId) {
|
|
132
142
|
wallets.push(
|
|
@@ -3,8 +3,10 @@ import { server } from '@test';
|
|
|
3
3
|
import {
|
|
4
4
|
type Account,
|
|
5
5
|
type Address,
|
|
6
|
+
BaseError,
|
|
6
7
|
type Chain,
|
|
7
8
|
type PublicClient,
|
|
9
|
+
UserRejectedRequestError as ViemUserRejectedRequestError,
|
|
8
10
|
type WalletClient,
|
|
9
11
|
hexToBigInt,
|
|
10
12
|
} from 'viem';
|
|
@@ -264,6 +266,21 @@ describe('wallet', () => {
|
|
|
264
266
|
walletInstance.handleSignMessageStep(mockSignatureStep),
|
|
265
267
|
).rejects.toThrow(TransactionSignatureError);
|
|
266
268
|
});
|
|
269
|
+
|
|
270
|
+
it('should throw UserRejectedRequestError when user rejects signature', async () => {
|
|
271
|
+
const error = new TransactionSignatureError(
|
|
272
|
+
StepType.signEIP191,
|
|
273
|
+
new ViemUserRejectedRequestError(
|
|
274
|
+
new BaseError('User rejected request', {
|
|
275
|
+
cause: new Error('User rejected request'),
|
|
276
|
+
}),
|
|
277
|
+
),
|
|
278
|
+
);
|
|
279
|
+
vi.mocked(mockWalletClient.signMessage).mockRejectedValueOnce(error);
|
|
280
|
+
await expect(
|
|
281
|
+
walletInstance.handleSignMessageStep(mockSignatureStep),
|
|
282
|
+
).rejects.toThrow(UserRejectedRequestError);
|
|
283
|
+
});
|
|
267
284
|
});
|
|
268
285
|
|
|
269
286
|
describe('handleSendTransactionStep', () => {
|
|
@@ -315,6 +332,19 @@ describe('wallet', () => {
|
|
|
315
332
|
).rejects.toThrow(TransactionExecutionError);
|
|
316
333
|
});
|
|
317
334
|
|
|
335
|
+
it('should throw UserRejectedRequestError when user rejects transaction', async () => {
|
|
336
|
+
const error = new TransactionExecutionError(
|
|
337
|
+
StepType.buy,
|
|
338
|
+
new ViemUserRejectedRequestError(
|
|
339
|
+
new BaseError('User rejected request'),
|
|
340
|
+
),
|
|
341
|
+
);
|
|
342
|
+
vi.mocked(mockWalletClient.sendTransaction).mockRejectedValueOnce(error);
|
|
343
|
+
await expect(
|
|
344
|
+
walletInstance.handleSendTransactionStep(1, mockTxStep),
|
|
345
|
+
).rejects.toThrow(UserRejectedRequestError);
|
|
346
|
+
});
|
|
347
|
+
|
|
318
348
|
it('should handle transaction with contract interaction', async () => {
|
|
319
349
|
const mockContractTxStep: TransactionStep = {
|
|
320
350
|
id: StepType.buy,
|
|
@@ -2,11 +2,13 @@ import type { TransactionReceipt } from '@0xsequence/indexer';
|
|
|
2
2
|
import {
|
|
3
3
|
type Account,
|
|
4
4
|
type Address,
|
|
5
|
+
BaseError,
|
|
5
6
|
type Chain,
|
|
6
7
|
type Hex,
|
|
7
8
|
type PublicClient,
|
|
8
9
|
TransactionReceiptNotFoundError,
|
|
9
10
|
type TypedDataDomain,
|
|
11
|
+
UserRejectedRequestError as ViemUserRejectedRequestError,
|
|
10
12
|
type WalletClient as ViemWalletClient,
|
|
11
13
|
WaitForTransactionReceiptTimeoutError,
|
|
12
14
|
custom,
|
|
@@ -59,6 +61,7 @@ export interface WalletInstance {
|
|
|
59
61
|
contractAddress: Address;
|
|
60
62
|
spender: Address | 'sequenceMarketV1' | 'sequenceMarketV2';
|
|
61
63
|
}) => Promise<bigint | boolean>;
|
|
64
|
+
publicClient: PublicClient;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
const isSequenceWallet = (connector: Connector) =>
|
|
@@ -147,8 +150,17 @@ export const wallet = ({
|
|
|
147
150
|
message: stepItem.signature!.value,
|
|
148
151
|
});
|
|
149
152
|
}
|
|
150
|
-
} catch (
|
|
153
|
+
} catch (e) {
|
|
154
|
+
const error = e as TransactionSignatureError;
|
|
151
155
|
logger.error('Signature failed', error);
|
|
156
|
+
|
|
157
|
+
if (error.cause instanceof BaseError) {
|
|
158
|
+
const viemError = error.cause as BaseError;
|
|
159
|
+
if (viemError instanceof ViemUserRejectedRequestError) {
|
|
160
|
+
throw new UserRejectedRequestError();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
152
164
|
throw new TransactionSignatureError(stepItem.id, error as Error);
|
|
153
165
|
}
|
|
154
166
|
},
|
|
@@ -180,8 +192,17 @@ export const wallet = ({
|
|
|
180
192
|
gas: hexToBigInt(stepItem.gas),
|
|
181
193
|
}),
|
|
182
194
|
});
|
|
183
|
-
} catch (
|
|
195
|
+
} catch (e) {
|
|
196
|
+
const error = e as TransactionExecutionError;
|
|
184
197
|
logger.error('Transaction failed', error);
|
|
198
|
+
|
|
199
|
+
if (error.cause instanceof BaseError) {
|
|
200
|
+
const viemError = error.cause as BaseError;
|
|
201
|
+
if (viemError instanceof ViemUserRejectedRequestError) {
|
|
202
|
+
throw new UserRejectedRequestError();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
185
206
|
throw new TransactionExecutionError(stepItem.id, error as Error);
|
|
186
207
|
}
|
|
187
208
|
},
|
|
@@ -197,6 +218,7 @@ export const wallet = ({
|
|
|
197
218
|
return receipt;
|
|
198
219
|
} catch (error) {
|
|
199
220
|
logger.error('Transaction confirmation failed', error);
|
|
221
|
+
|
|
200
222
|
throw new TransactionConfirmationError(txHash, error as Error);
|
|
201
223
|
}
|
|
202
224
|
},
|
|
@@ -243,6 +265,7 @@ export const wallet = ({
|
|
|
243
265
|
throw new Error('Unsupported contract type for approval checking');
|
|
244
266
|
}
|
|
245
267
|
},
|
|
268
|
+
publicClient,
|
|
246
269
|
};
|
|
247
270
|
|
|
248
271
|
return walletInstance;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`useMarketplaceConfig > should fetch marketplace config and styles successfully 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"bannerUrl": "",
|
|
6
|
+
"collections": [
|
|
7
|
+
{
|
|
8
|
+
"address": "0x0000000000000000000000000000000000000000",
|
|
9
|
+
"bannerUrl": "",
|
|
10
|
+
"chainId": 1,
|
|
11
|
+
"currencyOptions": [
|
|
12
|
+
"0x0000000000000000000000000000000000000000",
|
|
13
|
+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
14
|
+
],
|
|
15
|
+
"destinationMarketplace": "sequence_marketplace_v2",
|
|
16
|
+
"exchanges": [],
|
|
17
|
+
"feePercentage": 3.5,
|
|
18
|
+
"filterSettings": {
|
|
19
|
+
"exclusions": [
|
|
20
|
+
{
|
|
21
|
+
"condition": "SPECIFIC_VALUE",
|
|
22
|
+
"key": "Type",
|
|
23
|
+
"value": "Sample",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
"filterOrder": [
|
|
27
|
+
"Type",
|
|
28
|
+
"Rarity",
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
"marketplaceType": "ORDERBOOK",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"address": "0x1234567890123456789012345678901234567890",
|
|
35
|
+
"bannerUrl": "https://example.com/collection-banner.png",
|
|
36
|
+
"chainId": 137,
|
|
37
|
+
"currencyOptions": [
|
|
38
|
+
"0x0000000000000000000000000000000000000000",
|
|
39
|
+
],
|
|
40
|
+
"destinationMarketplace": "opensea",
|
|
41
|
+
"exchanges": [],
|
|
42
|
+
"feePercentage": 2.5,
|
|
43
|
+
"filterSettings": {
|
|
44
|
+
"exclusions": [
|
|
45
|
+
{
|
|
46
|
+
"condition": "ENTIRE_KEY",
|
|
47
|
+
"key": "Category",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"condition": "SPECIFIC_VALUE",
|
|
51
|
+
"key": "Level",
|
|
52
|
+
"value": "Legendary",
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
"filterOrder": [
|
|
56
|
+
"Category",
|
|
57
|
+
"Level",
|
|
58
|
+
"Element",
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
"marketplaceType": "ORDERBOOK",
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
"cssString": "
|
|
65
|
+
.marketplace-theme {
|
|
66
|
+
--primary-color: #000000;
|
|
67
|
+
}
|
|
68
|
+
",
|
|
69
|
+
"faviconUrl": "https://example.com/favicon.png",
|
|
70
|
+
"landingBannerUrl": "https://example.com/banner.png",
|
|
71
|
+
"landingPageLayout": "default",
|
|
72
|
+
"logoUrl": "https://example.com/logo.png",
|
|
73
|
+
"manifestUrl": "https://api.sequence.build/marketplace//manifest.json",
|
|
74
|
+
"projectId": 1,
|
|
75
|
+
"publisherId": "test-publisher",
|
|
76
|
+
"shortDescription": "A test marketplace",
|
|
77
|
+
"socials": {
|
|
78
|
+
"discord": "https://discord.com/test",
|
|
79
|
+
"instagram": "https://instagram.com/test",
|
|
80
|
+
"tiktok": "",
|
|
81
|
+
"twitter": "https://twitter.com/test",
|
|
82
|
+
"website": "",
|
|
83
|
+
"youtube": "",
|
|
84
|
+
},
|
|
85
|
+
"title": "Test Marketplace",
|
|
86
|
+
"walletOptions": {
|
|
87
|
+
"connectors": [
|
|
88
|
+
"coinbase",
|
|
89
|
+
"walletconnect",
|
|
90
|
+
],
|
|
91
|
+
"includeEIP6963Wallets": true,
|
|
92
|
+
"oidcIssuers": {},
|
|
93
|
+
"walletType": "UNIVERSAL",
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
@@ -3,7 +3,7 @@ import { http, HttpResponse } from 'msw';
|
|
|
3
3
|
import { zeroAddress } from 'viem';
|
|
4
4
|
import { describe, expect, it } from 'vitest';
|
|
5
5
|
import {
|
|
6
|
-
|
|
6
|
+
mockEthCollection,
|
|
7
7
|
mockMetadataEndpoint,
|
|
8
8
|
} from '../../_internal/api/__mocks__/metadata.msw';
|
|
9
9
|
import type { UseCollectionArgs } from '../useCollection';
|
|
@@ -11,9 +11,8 @@ import { useCollection } from '../useCollection';
|
|
|
11
11
|
|
|
12
12
|
describe('useCollection', () => {
|
|
13
13
|
const defaultArgs: UseCollectionArgs = {
|
|
14
|
-
chainId:
|
|
15
|
-
collectionAddress:
|
|
16
|
-
query: {},
|
|
14
|
+
chainId: mockEthCollection.chainId,
|
|
15
|
+
collectionAddress: mockEthCollection.address,
|
|
17
16
|
};
|
|
18
17
|
|
|
19
18
|
it('should fetch collection data successfully', async () => {
|
|
@@ -29,7 +28,7 @@ describe('useCollection', () => {
|
|
|
29
28
|
});
|
|
30
29
|
|
|
31
30
|
// Verify the data matches our mock
|
|
32
|
-
expect(result.current.data).toEqual(
|
|
31
|
+
expect(result.current.data).toEqual(mockEthCollection);
|
|
33
32
|
expect(result.current.error).toBeNull();
|
|
34
33
|
});
|
|
35
34
|
|
|
@@ -2,11 +2,11 @@ import { renderHook, server, waitFor } from '@test';
|
|
|
2
2
|
import { USDC_ADDRESS } from '@test/const';
|
|
3
3
|
import { http, HttpResponse } from 'msw';
|
|
4
4
|
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { mockConfig } from '../../_internal/api/__mocks__/builder.msw';
|
|
5
6
|
import {
|
|
6
7
|
mockCurrencies,
|
|
7
8
|
mockMarketplaceEndpoint,
|
|
8
9
|
} from '../../_internal/api/__mocks__/marketplace.msw';
|
|
9
|
-
import { mockConfig } from '../options/__mocks__/marketplaceConfig.msw';
|
|
10
10
|
import { useCurrencies } from '../useCurrencies';
|
|
11
11
|
|
|
12
12
|
describe('useCurrencies', () => {
|
|
@@ -2,6 +2,10 @@ import { renderHook, server, waitFor } from '@test';
|
|
|
2
2
|
import { http, HttpResponse } from 'msw';
|
|
3
3
|
import { zeroAddress } from 'viem';
|
|
4
4
|
import { beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import {
|
|
6
|
+
createLookupMarketplaceConfigHandler,
|
|
7
|
+
mockConfig,
|
|
8
|
+
} from '../../_internal/api/__mocks__/builder.msw';
|
|
5
9
|
import {
|
|
6
10
|
mockIndexerEndpoint,
|
|
7
11
|
mockTokenBalance,
|
|
@@ -11,7 +15,6 @@ import {
|
|
|
11
15
|
mockMarketplaceEndpoint,
|
|
12
16
|
} from '../../_internal/api/__mocks__/marketplace.msw';
|
|
13
17
|
import type { UseInventoryArgs } from '../../queries/inventory';
|
|
14
|
-
import { mockConfig } from '../options/__mocks__/marketplaceConfig.msw';
|
|
15
18
|
import { useInventory } from '../useInventory';
|
|
16
19
|
|
|
17
20
|
// Make sure mockCollectibleOrder has a tokenId of "1" for tests
|
|
@@ -128,21 +131,17 @@ describe('useInventory', () => {
|
|
|
128
131
|
it('should use isLaos721 flag from marketplaceConfig', async () => {
|
|
129
132
|
// Setup config with LAOS collection
|
|
130
133
|
const laosCollectionAddress = '0x1234567890123456789012345678901234567890';
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
collections
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
};
|
|
143
|
-
return HttpResponse.json(configWithLaos);
|
|
144
|
-
}),
|
|
145
|
-
);
|
|
134
|
+
const configWithLaos = {
|
|
135
|
+
...mockConfig,
|
|
136
|
+
collections: [
|
|
137
|
+
{
|
|
138
|
+
...mockConfig.collections[0],
|
|
139
|
+
address: laosCollectionAddress,
|
|
140
|
+
isLAOSERC721: true,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
};
|
|
144
|
+
server.use(createLookupMarketplaceConfigHandler(configWithLaos));
|
|
146
145
|
|
|
147
146
|
const laosArgs: UseInventoryArgs = {
|
|
148
147
|
...defaultArgs,
|
|
@@ -1,51 +1,20 @@
|
|
|
1
|
-
import { ResourceStatus } from '@0xsequence/metadata';
|
|
2
1
|
import { renderHook, server, waitFor } from '@test';
|
|
3
2
|
import { http, HttpResponse } from 'msw';
|
|
4
3
|
import { describe, expect, it } from 'vitest';
|
|
5
4
|
import { MarketplaceType, OrderbookKind } from '../../../types';
|
|
6
|
-
import { mockContractInfo } from '../../_internal/api/__mocks__/metadata.msw';
|
|
7
5
|
import {
|
|
8
|
-
|
|
6
|
+
createLookupMarketplaceConfigHandler,
|
|
9
7
|
mockConfig,
|
|
10
|
-
} from '
|
|
8
|
+
} from '../../_internal/api/__mocks__/builder.msw';
|
|
9
|
+
import {
|
|
10
|
+
mockEthCollection,
|
|
11
|
+
mockPolCollection,
|
|
12
|
+
} from '../../_internal/api/__mocks__/metadata.msw';
|
|
11
13
|
import { useListCollections } from '../useListCollections';
|
|
12
14
|
|
|
13
15
|
describe('useListCollections', () => {
|
|
14
|
-
const defaultArgs = {
|
|
15
|
-
query: {
|
|
16
|
-
enabled: true,
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
|
|
20
16
|
it('should fetch collections successfully', async () => {
|
|
21
|
-
|
|
22
|
-
server.use(
|
|
23
|
-
createConfigHandler({
|
|
24
|
-
...mockConfig,
|
|
25
|
-
collections: [
|
|
26
|
-
{
|
|
27
|
-
chainId: 1,
|
|
28
|
-
address:
|
|
29
|
-
'0x1234567890123456789012345678901234567890' as `0x${string}`,
|
|
30
|
-
feePercentage: 2.5,
|
|
31
|
-
marketplaceType: MarketplaceType.ORDERBOOK,
|
|
32
|
-
currencyOptions: [],
|
|
33
|
-
exchanges: [],
|
|
34
|
-
bannerUrl: '',
|
|
35
|
-
destinationMarketplace: OrderbookKind.sequence_marketplace_v2,
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
}),
|
|
39
|
-
http.post('*/rpc/Metadata/GetContractInfoBatch', () => {
|
|
40
|
-
return HttpResponse.json({
|
|
41
|
-
contractInfoMap: {
|
|
42
|
-
'0x1234567890123456789012345678901234567890': mockContractInfo,
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
}),
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const { result } = renderHook(() => useListCollections(defaultArgs));
|
|
17
|
+
const { result } = renderHook(() => useListCollections());
|
|
49
18
|
|
|
50
19
|
// Wait for data to be loaded
|
|
51
20
|
await waitFor(() => {
|
|
@@ -53,20 +22,20 @@ describe('useListCollections', () => {
|
|
|
53
22
|
});
|
|
54
23
|
|
|
55
24
|
// Verify the data matches our mock
|
|
56
|
-
expect(result.current.data).toEqual([
|
|
25
|
+
expect(result.current.data).toEqual([mockEthCollection, mockPolCollection]);
|
|
57
26
|
expect(result.current.error).toBeNull();
|
|
58
27
|
});
|
|
59
28
|
|
|
60
29
|
it('should handle empty collections', async () => {
|
|
61
30
|
// Mock marketplace config with empty collections
|
|
62
31
|
server.use(
|
|
63
|
-
|
|
32
|
+
createLookupMarketplaceConfigHandler({
|
|
64
33
|
...mockConfig,
|
|
65
34
|
collections: [],
|
|
66
35
|
}),
|
|
67
36
|
);
|
|
68
37
|
|
|
69
|
-
const { result } = renderHook(() => useListCollections(
|
|
38
|
+
const { result } = renderHook(() => useListCollections());
|
|
70
39
|
|
|
71
40
|
await waitFor(() => {
|
|
72
41
|
expect(result.current.data).toBeDefined();
|
|
@@ -79,7 +48,7 @@ describe('useListCollections', () => {
|
|
|
79
48
|
it('should handle error states', async () => {
|
|
80
49
|
// Mock marketplace config with collection
|
|
81
50
|
server.use(
|
|
82
|
-
|
|
51
|
+
createLookupMarketplaceConfigHandler({
|
|
83
52
|
...mockConfig,
|
|
84
53
|
collections: [
|
|
85
54
|
{
|
|
@@ -103,7 +72,7 @@ describe('useListCollections', () => {
|
|
|
103
72
|
}),
|
|
104
73
|
);
|
|
105
74
|
|
|
106
|
-
const { result } = renderHook(() => useListCollections(
|
|
75
|
+
const { result } = renderHook(() => useListCollections());
|
|
107
76
|
|
|
108
77
|
await waitFor(() => {
|
|
109
78
|
expect(result.current.isError).toBe(true);
|
|
@@ -118,7 +87,7 @@ describe('useListCollections', () => {
|
|
|
118
87
|
|
|
119
88
|
// Mock marketplace config with collection
|
|
120
89
|
server.use(
|
|
121
|
-
|
|
90
|
+
createLookupMarketplaceConfigHandler({
|
|
122
91
|
...mockConfig,
|
|
123
92
|
collections: [
|
|
124
93
|
{
|
|
@@ -138,7 +107,7 @@ describe('useListCollections', () => {
|
|
|
138
107
|
requestMade = true;
|
|
139
108
|
return HttpResponse.json({
|
|
140
109
|
contractInfoMap: {
|
|
141
|
-
'0x1234567890123456789012345678901234567890':
|
|
110
|
+
'0x1234567890123456789012345678901234567890': mockEthCollection,
|
|
142
111
|
},
|
|
143
112
|
});
|
|
144
113
|
}),
|
|
@@ -160,128 +129,14 @@ describe('useListCollections', () => {
|
|
|
160
129
|
});
|
|
161
130
|
|
|
162
131
|
it('should handle multiple collections from different chains', async () => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
chainId: 137, // Different chain (Polygon)
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
// Mock marketplace config with multiple collections
|
|
170
|
-
server.use(
|
|
171
|
-
createConfigHandler({
|
|
172
|
-
...mockConfig,
|
|
173
|
-
collections: [
|
|
174
|
-
{
|
|
175
|
-
chainId: 1,
|
|
176
|
-
address:
|
|
177
|
-
'0x1234567890123456789012345678901234567890' as `0x${string}`,
|
|
178
|
-
feePercentage: 2.5,
|
|
179
|
-
marketplaceType: MarketplaceType.ORDERBOOK,
|
|
180
|
-
currencyOptions: [],
|
|
181
|
-
exchanges: [],
|
|
182
|
-
bannerUrl: '',
|
|
183
|
-
destinationMarketplace: OrderbookKind.sequence_marketplace_v2,
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
chainId: 137,
|
|
187
|
-
address: mockContractInfo2.address,
|
|
188
|
-
feePercentage: 2.5,
|
|
189
|
-
marketplaceType: MarketplaceType.ORDERBOOK,
|
|
190
|
-
currencyOptions: [],
|
|
191
|
-
exchanges: [],
|
|
192
|
-
bannerUrl: '',
|
|
193
|
-
destinationMarketplace: OrderbookKind.sequence_marketplace_v2,
|
|
194
|
-
},
|
|
195
|
-
],
|
|
196
|
-
}),
|
|
197
|
-
http.post('*/rpc/Metadata/GetContractInfoBatch', async ({ request }) => {
|
|
198
|
-
const body = (await request.json()) as { chainID: string };
|
|
199
|
-
if (body.chainID === '1') {
|
|
200
|
-
return HttpResponse.json({
|
|
201
|
-
contractInfoMap: {
|
|
202
|
-
'0x1234567890123456789012345678901234567890': mockContractInfo,
|
|
203
|
-
},
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
return HttpResponse.json({
|
|
207
|
-
contractInfoMap: {
|
|
208
|
-
[mockContractInfo2.address]: mockContractInfo2,
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
|
-
}),
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
const { result } = renderHook(() => useListCollections(defaultArgs));
|
|
132
|
+
// TODO: This test should be more robust, make sure we validate that the marketplace config has multiple chains
|
|
133
|
+
// then the to equal should just check that we are fetching the data from those
|
|
134
|
+
const { result } = renderHook(() => useListCollections());
|
|
215
135
|
|
|
216
136
|
await waitFor(() => {
|
|
217
137
|
expect(result.current.data).toBeDefined();
|
|
218
138
|
});
|
|
219
139
|
|
|
220
|
-
expect(result.current.data).
|
|
221
|
-
expect(result.current.data).toEqual(
|
|
222
|
-
expect.arrayContaining([mockContractInfo, mockContractInfo2]),
|
|
223
|
-
);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('should handle collections with different resource statuses', async () => {
|
|
227
|
-
const mockUnavailableContract = {
|
|
228
|
-
...mockContractInfo,
|
|
229
|
-
address: '0x9876543210987654321098765432109876543210' as `0x${string}`,
|
|
230
|
-
status: ResourceStatus.NOT_AVAILABLE,
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
// Mock marketplace config with multiple collections
|
|
234
|
-
server.use(
|
|
235
|
-
createConfigHandler({
|
|
236
|
-
...mockConfig,
|
|
237
|
-
collections: [
|
|
238
|
-
{
|
|
239
|
-
chainId: 1,
|
|
240
|
-
address:
|
|
241
|
-
'0x1234567890123456789012345678901234567890' as `0x${string}`,
|
|
242
|
-
feePercentage: 2.5,
|
|
243
|
-
marketplaceType: MarketplaceType.ORDERBOOK,
|
|
244
|
-
currencyOptions: [],
|
|
245
|
-
exchanges: [],
|
|
246
|
-
bannerUrl: '',
|
|
247
|
-
destinationMarketplace: OrderbookKind.sequence_marketplace_v2,
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
chainId: 1,
|
|
251
|
-
address: mockUnavailableContract.address,
|
|
252
|
-
feePercentage: 2.5,
|
|
253
|
-
marketplaceType: MarketplaceType.ORDERBOOK,
|
|
254
|
-
currencyOptions: [],
|
|
255
|
-
exchanges: [],
|
|
256
|
-
bannerUrl: '',
|
|
257
|
-
destinationMarketplace: OrderbookKind.sequence_marketplace_v2,
|
|
258
|
-
},
|
|
259
|
-
],
|
|
260
|
-
}),
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
// Mock metadata response for both contracts
|
|
264
|
-
server.use(
|
|
265
|
-
http.post('*/rpc/Metadata/GetContractInfoBatch', () => {
|
|
266
|
-
return HttpResponse.json({
|
|
267
|
-
contractInfoMap: {
|
|
268
|
-
'0x1234567890123456789012345678901234567890': mockContractInfo,
|
|
269
|
-
'0x9876543210987654321098765432109876543210':
|
|
270
|
-
mockUnavailableContract,
|
|
271
|
-
},
|
|
272
|
-
});
|
|
273
|
-
}),
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
const { result } = renderHook(() => useListCollections(defaultArgs));
|
|
277
|
-
|
|
278
|
-
await waitFor(() => {
|
|
279
|
-
expect(result.current.data).toBeDefined();
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
expect(result.current.data).toHaveLength(2);
|
|
283
|
-
expect(result.current.data).toEqual(
|
|
284
|
-
expect.arrayContaining([mockContractInfo, mockUnavailableContract]),
|
|
285
|
-
);
|
|
140
|
+
expect(result.current.data).toEqual([mockEthCollection, mockPolCollection]);
|
|
286
141
|
});
|
|
287
142
|
});
|