Skip to content

Commit

Permalink
TD-1515: chore: add examples for signing ERC1155 listings in Passport…
Browse files Browse the repository at this point in the history
… sample app. (#1939)
  • Loading branch information
naveen-imtb authored Jun 25, 2024
1 parent 5e3f5f8 commit f4d7312
Show file tree
Hide file tree
Showing 5 changed files with 333 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, {
useCallback, useEffect, useMemo, useState,
} from 'react';
import {
Accordion, Alert, Form, Stack,
} from 'react-bootstrap';
import WorkflowButton from '@/components/WorkflowButton';
import { RequestExampleProps } from '@/types';
import { useImmutableProvider } from '@/context/ImmutableProvider';
import { usePassportProvider } from '@/context/PassportProvider';
import { getCreateERC1155ListingPayload } from './SeaportCreateListingExample';

function SeaportCreateERC1155ListingDefault({ disabled, handleExampleSubmitted }: RequestExampleProps) {
const { orderbookClient } = useImmutableProvider();
const { zkEvmProvider } = usePassportProvider();

const [params, setParams] = useState<any>();

const seaportContractAddress = useMemo(
() => (
orderbookClient.config().seaportContractAddress
),
[orderbookClient],
);

useEffect(() => {
const getAddress = async () => {
if (zkEvmProvider) {
const [address] = await zkEvmProvider.request({
method: 'eth_requestAccounts',
});
const chainIdHex = await zkEvmProvider.request({ method: 'eth_chainId' });
const chainId = parseInt(chainIdHex, 16);
const data = getCreateERC1155ListingPayload({ seaportContractAddress, walletAddress: address, chainId });
setParams([address, data]);
}
};
getAddress().catch(console.log);
}, [zkEvmProvider, seaportContractAddress]);

const handleSubmit = useCallback(async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
e.stopPropagation();

return handleExampleSubmitted({
method: 'eth_signTypedData_v4',
params,
});
}, [handleExampleSubmitted, params]);

return (
<Accordion.Item eventKey="5">
<Accordion.Header>Seaport Create Listing - ERC1155 order (Hardcoded example)</Accordion.Header>
<Accordion.Body>
<Alert variant="warning">
Note: This method only returns a signed message, it does not submit an order to the orderbook.
</Alert>
<Form onSubmit={handleSubmit} className="mb-4">
<Form.Group className="mb-3">
<Form.Label>
Preview
</Form.Label>
<Form.Control
required
disabled
as="textarea"
rows={7}
value={JSON.stringify(params, null, '\t')}
/>
</Form.Group>
<Stack direction="horizontal" gap={3}>
<WorkflowButton
disabled={disabled}
type="submit"
>
Submit
</WorkflowButton>
</Stack>
</Form>
</Accordion.Body>
</Accordion.Item>
);
}

export default SeaportCreateERC1155ListingDefault;
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import WorkflowButton from '@/components/WorkflowButton';
import { RequestExampleProps } from '@/types';
import { useImmutableProvider } from '@/context/ImmutableProvider';
import { usePassportProvider } from '@/context/PassportProvider';
import { getCreateListingPayload } from './SeaportCreateListingExample';
import { getCreateERC721ListingPayload } from './SeaportCreateListingExample';

function SeaportCreateListingDefault({ disabled, handleExampleSubmitted }: RequestExampleProps) {
function SeaportCreateERC721ListingDefault({ disabled, handleExampleSubmitted }: RequestExampleProps) {
const { orderbookClient } = useImmutableProvider();
const { zkEvmProvider } = usePassportProvider();

Expand All @@ -31,7 +31,7 @@ function SeaportCreateListingDefault({ disabled, handleExampleSubmitted }: Reque
});
const chainIdHex = await zkEvmProvider.request({ method: 'eth_chainId' });
const chainId = parseInt(chainIdHex, 16);
const data = getCreateListingPayload({ seaportContractAddress, walletAddress: address, chainId });
const data = getCreateERC721ListingPayload({ seaportContractAddress, walletAddress: address, chainId });
setParams([address, data]);
}
};
Expand All @@ -50,7 +50,7 @@ function SeaportCreateListingDefault({ disabled, handleExampleSubmitted }: Reque

return (
<Accordion.Item eventKey="4">
<Accordion.Header>Seaport Create Listing (Hardcoded example)</Accordion.Header>
<Accordion.Header>Seaport Create Listing - ERC721 order (Hardcoded example)</Accordion.Header>
<Accordion.Body>
<Alert variant="warning">
Note: This method only returns a signed message, it does not submit an order to the orderbook.
Expand Down Expand Up @@ -82,4 +82,4 @@ function SeaportCreateListingDefault({ disabled, handleExampleSubmitted }: Reque
);
}

export default SeaportCreateListingDefault;
export default SeaportCreateERC721ListingDefault;
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { RequestExampleProps } from '@/types';
import { useImmutableProvider } from '@/context/ImmutableProvider';
import { usePassportProvider } from '@/context/PassportProvider';
import {
ActionType, SignableAction, SignablePurpose,
ActionType, ERC1155Item, ERC721Item, SignableAction, SignablePurpose,
} from '@imtbl/orderbook';

type TokenType = 'NATIVE' | 'ERC20';
Expand All @@ -31,6 +31,9 @@ function SeaportCreateListing({ disabled, handleExampleSubmitted }: RequestExamp
const [buyAmount, setBuyAmount] = useState<string>('');
const [buyType, setBuyType] = useState<'NATIVE' | 'ERC20'>('NATIVE');
const [tokenId, setTokenId] = useState<string>('');
const [sellTokenUnits, setSellTokenUnits] = useState<string>('1');
const [showSellTokenUnitsField, setShowSellTokenUnitsField] = useState(false);
const [sellTokenType, setSellTokenType] = useState<'ERC721' | 'ERC1155'>('ERC721');

const seaportContractAddress = useMemo(
() => (
Expand All @@ -55,22 +58,46 @@ function SeaportCreateListing({ disabled, handleExampleSubmitted }: RequestExamp
useEffect(() => {
setSignMessageError('');
setTransaction(undefined);
}, [NFTContractAddress, tokenContractAddress, buyAmount, buyType, tokenId]);
}, [NFTContractAddress, tokenContractAddress, buyAmount, buyType, tokenId, sellTokenUnits, sellTokenType]);

const resetForm = () => {
setSellTokenType('ERC721');
setNFTContractAddress('');
setTokenContractAddress('');
setBuyAmount('');
setTokenId('');
setBuyType('NATIVE');
setSellTokenUnits('1');
setShowSellTokenUnitsField(false);
};

const validate = useCallback(async () => {
const buy = buyType === 'NATIVE'
? { amount: buyAmount, type: buyType }
: { amount: buyAmount, type: buyType, contractAddress: tokenContractAddress };
const sell = sellTokenType === 'ERC721'
? {
contractAddress: NFTContractAddress,
tokenId,
type: 'ERC721',
} as ERC721Item : {
contractAddress: NFTContractAddress,
tokenId,
type: 'ERC1155',
amount: sellTokenUnits,
} as ERC1155Item;

try {
setIsBuildingTransaction(true);

if (sellTokenType === 'ERC1155' && sellTokenUnits === '0') {
throw new Error('Units for sale must be greater than 0');
}

const { actions } = await orderbookClient.prepareListing({
makerAddress: walletAddress,
buy,
sell: {
contractAddress: NFTContractAddress,
tokenId,
type: 'ERC721',
},
sell,
});

const signAction = actions.find((action) => (
Expand All @@ -91,7 +118,18 @@ function SeaportCreateListing({ disabled, handleExampleSubmitted }: RequestExamp
} finally {
setIsBuildingTransaction(false);
}
}, [NFTContractAddress, buyAmount, buyType, orderbookClient, tokenContractAddress, tokenId, walletAddress]);
}, [NFTContractAddress, buyAmount, buyType, orderbookClient,
tokenContractAddress, tokenId, walletAddress, sellTokenUnits, sellTokenType]);

const handleSetSellTokenType = (e: React.ChangeEvent<HTMLSelectElement>) => {
resetForm();
const tokenType = e.target.value === 'ERC721'
? 'ERC721'
: 'ERC1155';
setSellTokenType(tokenType);
const showTokenUnits: boolean = tokenType === 'ERC1155';
setShowSellTokenUnitsField(showTokenUnits);
};

const handleSubmit = useCallback(async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
Expand All @@ -104,7 +142,7 @@ function SeaportCreateListing({ disabled, handleExampleSubmitted }: RequestExamp
}, [handleExampleSubmitted, transaction, walletAddress]);

return (
<Accordion.Item eventKey="5">
<Accordion.Item eventKey="3">
<Accordion.Header>Seaport Create Listing</Accordion.Header>
<Accordion.Body>
<Alert variant="warning">
Expand All @@ -117,6 +155,15 @@ function SeaportCreateListing({ disabled, handleExampleSubmitted }: RequestExamp
</Alert>
)}
<Form onSubmit={handleSubmit} className="mb-4">
<Form.Group className="mb-3">
<Form.Label>Listing Token Type</Form.Label>
<Form.Select
onChange={handleSetSellTokenType}
>
<option key="erc721" value="ERC721">ERC721</option>
<option key="erc1155" value="ERC1155">ERC1155</option>
</Form.Select>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>
Seaport Contract Address
Expand Down Expand Up @@ -154,6 +201,22 @@ function SeaportCreateListing({ disabled, handleExampleSubmitted }: RequestExamp
onChange={(e) => setTokenId(e.target.value)}
/>
</Form.Group>
{showSellTokenUnitsField
&& (
<Form.Group className="mb-3">
<Form.Label>
Units for sale
</Form.Label>
<Form.Control
type="number"
placeholder="1"
value={sellTokenUnits}
isValid={transaction && !transactionError}
isInvalid={!!transactionError}
onChange={(e) => setSellTokenUnits(e.target.value)}
/>
</Form.Group>
)}
<Form.Group className="mb-3">
<Form.Label>
Currency Type
Expand Down
Loading

0 comments on commit f4d7312

Please sign in to comment.