Skip to content

Commit 309f75d

Browse files
authored
Merge pull request #55 from trader-xyz/fix/expiry
Adds custom expiry option to accept a unix timestamp directly as number
2 parents 672685e + 8d5a6f5 commit 309f75d

File tree

2 files changed

+100
-6
lines changed

2 files changed

+100
-6
lines changed

src/sdk/v4/pure.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,16 @@ export const generateErc721Order = (
290290
erc20: UserFacingERC20AssetDataSerializedV4,
291291
orderData: Partial<OrderStructOptionsCommon> & OrderStructOptionsCommonStrict
292292
): ERC721OrderStructSerialized => {
293+
let expiry = INFINITE_EXPIRATION_TIMESTAMP_SEC.toString();
294+
if (orderData.expiry) {
295+
// If number is provided, assume given as unix timestamp
296+
if (typeof orderData.expiry === 'number') {
297+
expiry = orderData.expiry.toString();
298+
} else {
299+
// If date is provided, convert to unix timestamp
300+
expiry = getUnixTime(orderData.expiry).toString();
301+
}
302+
}
293303
const erc721Order: ERC721OrderStructSerialized = {
294304
erc721Token: nft.tokenAddress.toLowerCase(),
295305
erc721TokenId: nft.tokenId,
@@ -311,9 +321,7 @@ export const generateErc721Order = (
311321
feeData: x.feeData?.toString() ?? '0x',
312322
};
313323
}) ?? [],
314-
expiry: orderData.expiry
315-
? getUnixTime(orderData.expiry).toString()
316-
: INFINITE_EXPIRATION_TIMESTAMP_SEC.toString(),
324+
expiry: expiry,
317325
nonce: orderData.nonce?.toString() ?? generateRandomV4OrderNonce(),
318326
taker: orderData.taker?.toLowerCase() ?? NULL_ADDRESS,
319327
};
@@ -326,6 +334,16 @@ export const generateErc1155Order = (
326334
erc20: UserFacingERC20AssetDataSerializedV4,
327335
orderData: Partial<OrderStructOptionsCommon> & OrderStructOptionsCommonStrict
328336
): ERC1155OrderStructSerialized => {
337+
let expiry = INFINITE_EXPIRATION_TIMESTAMP_SEC.toString();
338+
if (orderData.expiry) {
339+
// If number is provided, assume given as unix timestamp
340+
if (typeof orderData.expiry === 'number') {
341+
expiry = orderData.expiry.toString();
342+
} else {
343+
// If date is provided, convert to unix timestamp
344+
expiry = getUnixTime(orderData.expiry).toString();
345+
}
346+
}
329347
const erc1155Order: ERC1155OrderStructSerialized = {
330348
erc1155Token: nft.tokenAddress.toLowerCase(),
331349
erc1155TokenId: nft.tokenId,
@@ -348,9 +366,7 @@ export const generateErc1155Order = (
348366
feeData: fee.feeData?.toString() ?? '0x',
349367
};
350368
}) ?? [],
351-
expiry: orderData.expiry
352-
? getUnixTime(orderData.expiry).toString()
353-
: INFINITE_EXPIRATION_TIMESTAMP_SEC.toString(),
369+
expiry: expiry,
354370
nonce: orderData.nonce?.toString() ?? generateRandomV4OrderNonce(),
355371
taker: orderData.taker?.toLowerCase() ?? NULL_ADDRESS,
356372
};

test/v4/order.test.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { BigNumber, ethers } from 'ethers';
2+
import { NftSwapV4 } from '../../src/sdk/v4/NftSwapV4';
3+
4+
import {
5+
SwappableAssetV4,
6+
UserFacingERC721AssetDataSerializedV4,
7+
} from '../../src/sdk/v4/types';
8+
9+
jest.setTimeout(120 * 1000);
10+
11+
const MAKER_WALLET_ADDRESS = '0xabc23F70Df4F45dD3Df4EC6DA6827CB05853eC9b';
12+
const MAKER_PRIVATE_KEY =
13+
'fc5db508b0a52da8fbcac3ab698088715595f8de9cccf2467d51952eec564ec9';
14+
// NOTE(johnrjj) - NEVER use these private keys for anything of value, testnets only!
15+
16+
const DAI_TOKEN_ADDRESS_TESTNET = '0x31f42841c2db5173425b5223809cf3a38fede360';
17+
const TEST_NFT_CONTRACT_ADDRESS = '0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b'; // https://ropsten.etherscan.io/token/0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b?a=0xabc23F70Df4F45dD3Df4EC6DA6827CB05853eC9b
18+
19+
const RPC_TESTNET =
20+
'https://eth-ropsten.alchemyapi.io/v2/is1WqyAFM1nNFFx2aCozhTep7IxHVNGo';
21+
22+
const MAKER_WALLET = new ethers.Wallet(MAKER_PRIVATE_KEY);
23+
24+
const PROVIDER = new ethers.providers.StaticJsonRpcProvider(RPC_TESTNET);
25+
26+
const MAKER_SIGNER = MAKER_WALLET.connect(PROVIDER);
27+
28+
const ROPSTEN_CHAIN_ID = 3;
29+
30+
const nftSwapperMaker = new NftSwapV4(
31+
MAKER_SIGNER as any,
32+
MAKER_SIGNER,
33+
ROPSTEN_CHAIN_ID
34+
);
35+
36+
const ERC20_ASSET: SwappableAssetV4 = {
37+
type: 'ERC20',
38+
tokenAddress: DAI_TOKEN_ADDRESS_TESTNET,
39+
amount: '100000000000', // 1 USDC
40+
} as const;
41+
const NFT_ASSET: UserFacingERC721AssetDataSerializedV4 = {
42+
type: 'ERC721',
43+
tokenAddress: TEST_NFT_CONTRACT_ADDRESS,
44+
tokenId: '11045',
45+
} as const;
46+
47+
describe('NFTSwapV4', () => {
48+
it('custom expiry as unix timestamp number works', async () => {
49+
const v4Erc721Order = nftSwapperMaker.buildOrder(
50+
NFT_ASSET,
51+
ERC20_ASSET,
52+
MAKER_WALLET_ADDRESS,
53+
{
54+
expiry: 2420696969,
55+
}
56+
);
57+
58+
const v4Erc721SignedOrder = await nftSwapperMaker.signOrder(v4Erc721Order);
59+
expect(v4Erc721SignedOrder.expiry.toString()).toEqual('2420696969');
60+
});
61+
62+
it('custom expiry as Date object works', async () => {
63+
const v4Erc721Order = nftSwapperMaker.buildOrder(
64+
NFT_ASSET,
65+
ERC20_ASSET,
66+
MAKER_WALLET_ADDRESS,
67+
{
68+
expiry: new Date(2030, 1, 11),
69+
}
70+
);
71+
72+
const v4Erc721SignedOrder = await nftSwapperMaker.signOrder(v4Erc721Order);
73+
74+
const expiryBn = BigNumber.from(v4Erc721SignedOrder.expiry);
75+
// Depending on where this test is run it'll vary by a few hours. This assets on a valid range (24hrs)
76+
expect(expiryBn.sub('1897016400').abs().toNumber()).toBeLessThan(24_000);
77+
});
78+
});

0 commit comments

Comments
 (0)