Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to marketplace settings #179

Merged
merged 2 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { createWagmiConfig } from '../create-config';
import { getWaasConnectors } from '../embedded';
import type { MarketplaceConfig, SdkConfig } from '../../../../types';
import { WalletOptions } from '../../../../types';
import {
MarketplaceType,
MarketplaceWallet,
OrderbookKind,
type MarketplaceConfig,
type SdkConfig,
} from '../../../../types';
import { polygon } from 'viem/chains';
import { MissingConfigError } from '../../../../utils/_internal/error/transaction';
import { cookieStorage, type Config } from 'wagmi';
Expand All @@ -13,25 +18,48 @@ describe('createWagmiConfig', () => {

beforeEach(() => {
baseMarketplaceConfig = {
projectId: 1,
cssString: '',
manifestUrl: '',
publisherId: 'test-publisher',
title: 'Test Marketplace',
shortDescription: 'Test Description',
socials: {
twitter: '',
discord: '',
website: '',
tiktok: '',
instagram: '',
youtube: '',
},
faviconUrl: 'https://test.com/favicon.ico',
landingBannerUrl: 'https://test.com/banner.jpg',
titleTemplate: '%s | Test',
walletOptions: [WalletOptions.Sequence],
walletOptions: {
walletType: MarketplaceWallet.UNIVERSAL,
oidcIssuers: {},
connectors: [],
includeEIP6963Wallets: false,
},
collections: [
{
collectionAddress: '0x1234567890123456789012345678901234567890',
address: '0x1234567890123456789012345678901234567890',
chainId: polygon.id,
marketplaceFeePercentage: 2.5,
marketplaceType: 'orderbook',
marketplaceType: MarketplaceType.ORDERBOOK,
currencyOptions: [],
destinationMarketplace: OrderbookKind.sequence_marketplace_v2,
filterSettings: {
filterOrder: [],
exclusions: [],
},
exchanges: [],
bannerUrl: '',
feePercentage: 0,
},
],
landingPageLayout: 'default',
cssString: '',
manifestUrl: 'https://test.com/manifest.json',
logoUrl: '',
bannerUrl: '',
fontUrl: '',
ogImage: '',
};

baseSdkConfig = {
Expand Down Expand Up @@ -59,10 +87,11 @@ describe('createWagmiConfig', () => {
it('should create config with universal wallet setup', () => {
const marketplaceConfig: MarketplaceConfig = {
...baseMarketplaceConfig,
walletOptionsNew: {
walletOptions: {
connectors: ['walletconnect', 'coinbase'],
includeEIP6963Wallets: true,
walletType: 'universal',
walletType: MarketplaceWallet.UNIVERSAL,
oidcIssuers: {},
},
};

Expand All @@ -81,10 +110,11 @@ describe('createWagmiConfig', () => {
it('should create config with embedded wallet setup', () => {
const marketplaceConfig: MarketplaceConfig = {
...baseMarketplaceConfig,
walletOptionsNew: {
walletOptions: {
connectors: ['walletconnect'],
includeEIP6963Wallets: false,
walletType: 'embedded',
walletType: MarketplaceWallet.EMBEDDED,
oidcIssuers: {},
},
};

Expand All @@ -109,10 +139,11 @@ describe('createWagmiConfig', () => {
it('should respect EIP6963 wallet inclusion setting', () => {
const marketplaceConfig: MarketplaceConfig = {
...baseMarketplaceConfig,
walletOptionsNew: {
walletOptions: {
connectors: ['walletconnect'],
includeEIP6963Wallets: false,
walletType: 'universal',
walletType: MarketplaceWallet.UNIVERSAL,
oidcIssuers: {},
},
};

Expand Down Expand Up @@ -145,10 +176,11 @@ describe('createWagmiConfig', () => {
it('should throw error when trying to use embedded wallet without waasConfigKey', () => {
const marketplaceConfig: MarketplaceConfig = {
...baseMarketplaceConfig,
walletOptionsNew: {
walletOptions: {
connectors: ['walletconnect'],
includeEIP6963Wallets: false,
walletType: 'embedded',
walletType: MarketplaceWallet.EMBEDDED,
oidcIssuers: {},
},
};

Expand Down Expand Up @@ -181,10 +213,11 @@ describe('createWagmiConfig', () => {
it('should still create config when walletConnectProjectId is missing', () => {
const marketplaceConfig: MarketplaceConfig = {
...baseMarketplaceConfig,
walletOptionsNew: {
walletOptions: {
connectors: ['walletconnect'],
includeEIP6963Wallets: true,
walletType: 'universal',
walletType: MarketplaceWallet.UNIVERSAL,
oidcIssuers: {},
},
};

Expand Down
7 changes: 3 additions & 4 deletions packages/sdk/src/react/_internal/wagmi/create-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ export const createWagmiConfig = (
? getUniversalConnectors(marketplaceConfig, sdkConfig)
: getWaasConnectors(marketplaceConfig, sdkConfig);

// The old config did not support disabling EIP-6963 wallets
const includeEIP6963Wallets =
marketplaceConfig.walletOptionsNew?.includeEIP6963Wallets ?? true;
const multiInjectedProviderDiscovery =
marketplaceConfig.walletOptions.includeEIP6963Wallets;

return createConfig({
connectors,
chains,
ssr,
multiInjectedProviderDiscovery: includeEIP6963Wallets,
multiInjectedProviderDiscovery,
storage: ssr
? createStorage({
storage: cookieStorage,
Expand Down
5 changes: 1 addition & 4 deletions packages/sdk/src/react/_internal/wagmi/embedded.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ export function getWaasConnectors(

const { title: appName } = marketplaceConfig;

// Normalizing the wallet options, TODO: remove this after the marketplaceConfig is updated
const walletOptions = marketplaceConfig.walletOptionsNew || {
connectors: ['coinbase', 'walletconnect'],
};
const walletOptions = marketplaceConfig.walletOptions;

const wallets: Wallet[] = [
emailWaas({
Expand Down
5 changes: 1 addition & 4 deletions packages/sdk/src/react/_internal/wagmi/universal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ function getWalletConfigs(
): Wallet[] {
const wallets: Wallet[] = [];

// Normalizing the wallet options, TODO: remove this after the marketplaceConfig is updated
const walletOptions = marketplaceConfig.walletOptionsNew || {
connectors: ['coinbase', 'walletconnect'],
};
const walletOptions = marketplaceConfig.walletOptions;

wallets.push(sequence(sequenceWalletOptions));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,50 @@
import { http, HttpResponse } from 'msw';
import { WalletOptions, type MarketplaceConfig } from '../../../../types';
import {
MarketplaceType,
MarketplaceWallet,
OrderbookKind,
type MarketplaceConfig,
} from '../../../../types';
import { mockCurrencies } from '../../../_internal/api/__mocks__/marketplace.msw';

// Mock data
export const mockConfig: MarketplaceConfig = {
projectId: 123,
publisherId: 'test-publisher',
title: 'Test Marketplace',
shortDescription: 'A test marketplace',
socials: {
twitter: 'https://twitter.com/test',
discord: 'https://discord.com/test',
instagram: 'https://instagram.com/test',
website: '',
tiktok: '',
youtube: '',
},
faviconUrl: 'https://example.com/favicon.png',
landingBannerUrl: 'https://example.com/banner.png',
logoUrl: 'https://example.com/logo.png',
titleTemplate: '%s | Test Marketplace',
walletOptions: [WalletOptions.Sequence],
walletOptions: {
walletType: MarketplaceWallet.UNIVERSAL,
oidcIssuers: {},
connectors: ['coinbase', 'walletconnect'],
includeEIP6963Wallets: true,
},
collections: [
{
collectionAddress: '0x1234567890123456789012345678901234567890',
address: '0x1234567890123456789012345678901234567890',
chainId: 1,
marketplaceFeePercentage: 2.5,
marketplaceType: 'orderbook',
marketplaceType: MarketplaceType.ORDERBOOK,
currencyOptions: mockCurrencies.map((c) => c.contractAddress),
exchanges: [],
bannerUrl: '',
feePercentage: 3.5,
destinationMarketplace: OrderbookKind.sequence_marketplace_v2,
},
],
landingPageLayout: 'default',
cssString: '',
manifestUrl: '',
bannerUrl: '',
};

export const mockStyles = `
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { queryOptions } from '@tanstack/react-query';
import type { Env, MarketplaceConfig, SdkConfig } from '../../../types';
import type {
Env,
MarketplaceConfig,
MarketplaceSettings,
SdkConfig,
} from '../../../types';
import {
MarketplaceConfigFetchError,
ProjectNotFoundError,
Expand All @@ -8,7 +13,7 @@

const fetchBuilderConfig = async (projectId: string, env: Env) => {
const url = `${builderMarketplaceApi(projectId, env)}`;
const response = await fetch(`${url}/config.json`);
const response = await fetch(`${url}/settings.json`);

Check failure on line 16 in packages/sdk/src/react/hooks/options/marketplaceConfigOptions.ts

View workflow job for this annotation

GitHub Actions / Build

src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx > marketplaceConfigOptions > should fetch marketplace config and styles successfully

NetworkError: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at "https://api.sequence.build/marketplace/test-project/settings.json". ❯ Fetch.send ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/fetch/Fetch.ts:190:11 ❯ GlobalWindow.fetch ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/window/BrowserWindow.ts:1540:10 ❯ fetchBuilderConfig src/react/hooks/options/marketplaceConfigOptions.ts:16:19 ❯ fetchMarketplaceConfig src/react/hooks/options/marketplaceConfigOptions.ts:46:41 ❯ src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx:43:16

Check failure on line 16 in packages/sdk/src/react/hooks/options/marketplaceConfigOptions.ts

View workflow job for this annotation

GitHub Actions / Build

src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx > marketplaceConfigOptions > should use custom environment and dev access key when provided

NetworkError: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at "https://dev-api.sequence.build/marketplace/test-project/settings.json". ❯ Fetch.send ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/fetch/Fetch.ts:190:11 ❯ GlobalWindow.fetch ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/window/BrowserWindow.ts:1540:10 ❯ fetchBuilderConfig src/react/hooks/options/marketplaceConfigOptions.ts:16:19 ❯ fetchMarketplaceConfig src/react/hooks/options/marketplaceConfigOptions.ts:46:41 ❯ src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx:74:16

Check failure on line 16 in packages/sdk/src/react/hooks/options/marketplaceConfigOptions.ts

View workflow job for this annotation

GitHub Actions / Build

src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx > marketplaceConfigOptions > should handle network errors when fetching styles

NetworkError: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at "https://api.sequence.build/marketplace/test-project/settings.json". ❯ Fetch.send ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/fetch/Fetch.ts:190:11 ❯ GlobalWindow.fetch ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/window/BrowserWindow.ts:1540:10 ❯ fetchBuilderConfig src/react/hooks/options/marketplaceConfigOptions.ts:16:19 ❯ fetchMarketplaceConfig src/react/hooks/options/marketplaceConfigOptions.ts:46:41 ❯ src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx:135:16

const json = await response.json();
if (!response.ok) {
Expand All @@ -22,7 +27,7 @@
throw new MarketplaceConfigFetchError(json.msg);
}
}
return json as MarketplaceConfig;
return json as MarketplaceSettings;
};

const fetchStyles = async (projectId: string, env: Env) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/src/react/hooks/useCurrencyOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const useCurrencyOptions = ({
const { data: marketplaceConfig } = useMarketplaceConfig();
const collections = marketplaceConfig?.collections;
const currencyOptions = collections?.find(
(collection) => collection.collectionAddress === collectionAddress,
(collection) => collection.address === collectionAddress,
)?.currencyOptions;

return currencyOptions;
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/src/react/hooks/useListCollections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ const fetchListCollections = async (
const collectionsByChain = marketplaceConfig.collections.reduce<
Record<string, string[]>
>((acc, curr) => {
const { chainId, collectionAddress } = curr;
const { chainId, address } = curr;
if (!acc[chainId]) {
acc[chainId] = [];
}
acc[chainId].push(collectionAddress);
acc[chainId].push(address);
return acc;
}, {});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export function CollectibleCard({
onCannotPerformAction,
}: CollectibleCardProps) {
const collectibleMetadata = lowestListing?.metadata;
const highestOffer = lowestListing?.offer
const highestOffer = lowestListing?.offer;
const [imageLoadingError, setImageLoadingError] = useState(false);

const { data: lowestListingCurrency } = useCurrency({
Expand Down
12 changes: 6 additions & 6 deletions packages/sdk/src/react/ui/modals/BuyModal/hooks/useFees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
export const useFees = ({
chainId,
collectionAddress,
}: { chainId: number; collectionAddress: string }) => {
}: {
chainId: number;
collectionAddress: string;
}) => {
const defaultFee = 2.5;
const defaultPlatformFeeRecipient =
'0x858dB1cbF6D09D447C96A11603189b49B2D1C219';
Expand All @@ -15,8 +18,7 @@

const collection = marketplaceConfig?.collections.find(
(collection) =>
collection.collectionAddress.toLowerCase() ===
collectionAddress.toLowerCase() &&
collection.address.toLowerCase() === collectionAddress.toLowerCase() &&

Check failure on line 21 in packages/sdk/src/react/ui/modals/BuyModal/hooks/useFees.ts

View workflow job for this annotation

GitHub Actions / Build

src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx > useFees > should return default fee when collection not found

TypeError: Cannot read properties of undefined (reading 'toLowerCase') ❯ src/react/ui/modals/BuyModal/hooks/useFees.ts:21:23 ❯ Module.useFees src/react/ui/modals/BuyModal/hooks/useFees.ts:19:52 ❯ src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx:58:39 ❯ TestComponent ../../node_modules/.pnpm/@testing-library[email protected]_@[email protected]_@[email protected]_@types+reac_7hpeg7dxohvcqb2kpextls7emq/node_modules/@testing-library/react/dist/pure.js:325:27 ❯ renderWithHooks ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ HTMLUnknownElement.callCallback ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:4164:14 ❯ HTMLUnknownElement.#callDispatchEventListeners ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/event/EventTarget.ts:290:41

Check failure on line 21 in packages/sdk/src/react/ui/modals/BuyModal/hooks/useFees.ts

View workflow job for this annotation

GitHub Actions / Build

src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx > useFees > should return collection-specific fee when found in config

TypeError: Cannot read properties of undefined (reading 'toLowerCase') ❯ src/react/ui/modals/BuyModal/hooks/useFees.ts:21:23 ❯ Module.useFees src/react/ui/modals/BuyModal/hooks/useFees.ts:19:52 ❯ src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx:90:10 ❯ TestComponent ../../node_modules/.pnpm/@testing-library[email protected]_@[email protected]_@[email protected]_@types+reac_7hpeg7dxohvcqb2kpextls7emq/node_modules/@testing-library/react/dist/pure.js:325:27 ❯ renderWithHooks ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ HTMLUnknownElement.callCallback ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:4164:14 ❯ HTMLUnknownElement.#callDispatchEventListeners ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/event/EventTarget.ts:290:41

Check failure on line 21 in packages/sdk/src/react/ui/modals/BuyModal/hooks/useFees.ts

View workflow job for this annotation

GitHub Actions / Build

src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx > useFees > should use Avalanche/Optimism fee recipient for those chains

TypeError: Cannot read properties of undefined (reading 'toLowerCase') ❯ src/react/ui/modals/BuyModal/hooks/useFees.ts:21:23 ❯ Module.useFees src/react/ui/modals/BuyModal/hooks/useFees.ts:19:52 ❯ src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx:106:10 ❯ TestComponent ../../node_modules/.pnpm/@testing-library[email protected]_@[email protected]_@[email protected]_@types+reac_7hpeg7dxohvcqb2kpextls7emq/node_modules/@testing-library/react/dist/pure.js:325:27 ❯ renderWithHooks ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ HTMLUnknownElement.callCallback ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:4164:14 ❯ HTMLUnknownElement.#callDispatchEventListeners ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/event/EventTarget.ts:290:41

Check failure on line 21 in packages/sdk/src/react/ui/modals/BuyModal/hooks/useFees.ts

View workflow job for this annotation

GitHub Actions / Build

src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx > useFees > should handle case-insensitive collection address matching

TypeError: Cannot read properties of undefined (reading 'toLowerCase') ❯ src/react/ui/modals/BuyModal/hooks/useFees.ts:21:23 ❯ Module.useFees src/react/ui/modals/BuyModal/hooks/useFees.ts:19:52 ❯ src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx:151:5 ❯ TestComponent ../../node_modules/.pnpm/@testing-library[email protected]_@[email protected]_@[email protected]_@types+reac_7hpeg7dxohvcqb2kpextls7emq/node_modules/@testing-library/react/dist/pure.js:325:27 ❯ renderWithHooks ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ HTMLUnknownElement.callCallback ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:4164:14 ❯ HTMLUnknownElement.#callDispatchEventListeners ../../node_modules/.pnpm/[email protected]/node_modules/happy-dom/src/event/EventTarget.ts:290:41
chainId === Number(collection.chainId),
);

Expand All @@ -30,9 +32,7 @@
(Number(percentage) * 10000) / 100;

return {
amount: percentageToBPS(
collection?.marketplaceFeePercentage || defaultFee,
).toString(),
amount: percentageToBPS(collection?.feePercentage || defaultFee).toString(),
receiver,
} satisfies AdditionalFee;
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const useCreateListing = ({
useMarketplaceConfig();

const collectionConfig = marketplaceConfig?.collections.find(
(c) => c.collectionAddress === collectionAddress,
(c) => c.address === collectionAddress,
);

orderbookKind =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const useMakeOffer = ({
useMarketplaceConfig();

const collectionConfig = marketplaceConfig?.collections.find(
(c) => c.collectionAddress === collectionAddress,
(c) => c.address === collectionAddress,
);

orderbookKind =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export default function TransactionDetails({

const marketplaceFeePercentage =
data?.collections.find(
(collection) => collection.collectionAddress === collectionAddress,
)?.marketplaceFeePercentage || DEFAULT_MARKETPLACE_FEE_PERCENTAGE;
(collection) => collection.address === collectionAddress,
)?.feePercentage || DEFAULT_MARKETPLACE_FEE_PERCENTAGE;
const { data: royaltyPercentage, isLoading: royaltyPercentageLoading } =
useRoyaltyPercentage({
chainId,
Expand Down
Loading
Loading