-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use a global provider for optimistic purchases (#4868)
* Use a global provider for optimistic purchases * Fix season ts issue * Show tx hash on success * Check for pending nft status * Revert handlePendingTransaction * e2e for metamask buy nft * Update mocked metamask * Update with working solution of mocking metamaks * Relocate record nft mint * Fix Farcaster id * Updated buy test * Update currentSEason * Create utils and separete concerns * Mock mainnet * Remove unnecessary id * Update PR * Small update to trigger the build * revert setting changes * Bypass decent api key * Update login test and util * Fix flacky tests * Fix again flacky test --------- Co-authored-by: motechFR <[email protected]>
- Loading branch information
1 parent
c91f6f9
commit 1b700e9
Showing
35 changed files
with
4,520 additions
and
460 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { prisma } from '@charmverse/core/prisma-client'; | ||
import { getBuilderContractAddress } from '@packages/scoutgame/builderNfts/constants'; | ||
import { currentSeason } from '@packages/scoutgame/dates'; | ||
import { mockBuilder, mockBuilderNft } from '@packages/scoutgame/testing/database'; | ||
import { delay } from '@root/lib/utils/async'; | ||
import { custom, http } from 'viem'; | ||
import { optimism } from 'viem/chains'; | ||
|
||
import { expect, test } from '../test'; | ||
|
||
test.describe('Buy Nft', () => { | ||
test.beforeEach(async ({ utils }) => { | ||
utils.initMockWallet(); | ||
}); | ||
|
||
test('Should be able to buy an nft', async ({ utils, page, userPage }) => { | ||
// Only for testing locally. Ensure the database is clean | ||
// await prisma.scout.deleteMany({}); | ||
const builder = await mockBuilder({ | ||
nftSeason: currentSeason, | ||
avatar: | ||
'https://cdn.charmverse.io/user-content/5906c806-9497-43c7-9ffc-2eecd3c3a3ec/cbed10a8-4f05-4b35-9463-fe8f15413311/b30047899c1514539cc32cdb3db0c932.jpg', | ||
bio: 'Software Engineer @charmverse.', | ||
builderStatus: 'approved', | ||
sendMarketing: false, | ||
farcasterId: Math.floor(Math.random() * 1000000), | ||
agreedToTermsAt: new Date('2024-10-03T11:03:00.308Z'), | ||
onboardedAt: new Date('2024-10-03T11:03:02.071Z'), | ||
currentBalance: 200 | ||
}); | ||
|
||
const builderNft = await mockBuilderNft({ | ||
builderId: builder.id, | ||
chainId: 10, | ||
contractAddress: getBuilderContractAddress(), | ||
tokenId: Math.floor(Math.random() * 1000000) | ||
}); | ||
|
||
await userPage.mockNftAPIs({ | ||
builder, | ||
isSuccess: true | ||
}); | ||
|
||
await utils.loginAsUserId(builder.id); | ||
await page.goto(`/home`); | ||
await page.waitForURL('**/home'); | ||
|
||
await page.goto(`/u/${builder.username}`); | ||
await page.waitForURL(`**/u/${builder.username}`); | ||
|
||
// Card CTA button | ||
const scoutButton = page.locator('data-test=scout-button').first(); | ||
await scoutButton.click(); | ||
|
||
// NFT buy button | ||
const buyButton = page.locator('data-test=purchase-button').first(); | ||
await buyButton.click(); | ||
|
||
// Success view after purchase | ||
const successView = page.locator('data-test=success-view'); | ||
await expect(successView).toBeVisible(); | ||
|
||
// Success message from snackbar | ||
const successMessage = page.locator('data-test=snackbar-success'); | ||
await expect(successMessage).toBeVisible(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
import type { Page } from '@playwright/test'; | ||
|
||
import { GeneralPageLayout } from './GeneralPageLayout.po'; | ||
|
||
export class UserPage extends GeneralPageLayout { | ||
constructor(protected page: Page) { | ||
super(page); | ||
} | ||
|
||
async mockNftAPIs({ builder, isSuccess }: { builder: { id: string; username: string }; isSuccess: boolean }) { | ||
// Used for debugging all routes. Keep caution as the next page.route() function will not run anymore. | ||
// await page.route('**', (route) => { | ||
// console.log('Intercepted URL:', route.request().url()); | ||
// route.continue(); | ||
// }); | ||
|
||
await this.page.route('**/**/api/getTokens**', async (route) => { | ||
await route.fulfill({ | ||
status: 200, | ||
json: [ | ||
{ | ||
chainId: 10, | ||
address: '0x0000000000000000000000000000000000000000', | ||
name: 'Ether', | ||
symbol: 'ETH', | ||
decimals: 18, | ||
isNative: true, | ||
logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png?v=025', | ||
balanceFloat: 0.023361258953913493, | ||
balance: '23361258953913492n' | ||
}, | ||
{ | ||
chainId: 10, | ||
address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', | ||
name: 'USD Coin', | ||
symbol: 'USDC', | ||
decimals: 6, | ||
logo: 'https://box-v2.api.decent.xyz/tokens/usdc.png', | ||
isNative: false, | ||
balanceFloat: 727.9495, | ||
balance: '727949500n' | ||
}, | ||
{ | ||
chainId: 10, | ||
address: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', | ||
name: 'Tether USD', | ||
symbol: 'USDT', | ||
decimals: 6, | ||
logo: 'https://static.alchemyapi.io/images/assets/825.png', | ||
isNative: false, | ||
balanceFloat: 0, | ||
balance: '0n' | ||
}, | ||
{ | ||
chainId: 10, | ||
address: '0x4200000000000000000000000000000000000042', | ||
name: 'Optimism', | ||
symbol: 'OP', | ||
decimals: 18, | ||
logo: 'https://optimistic.etherscan.io/token/images/optimism_32.png', | ||
isNative: false, | ||
balanceFloat: 0, | ||
balance: '0n' | ||
} | ||
] | ||
}); | ||
}); | ||
|
||
// Mock the builder id verification and contract | ||
await this.page.route('https://mainnet.optimism.io/', async (route) => { | ||
await route.fulfill({ | ||
status: 200, | ||
json: { | ||
jsonrpc: '2.0', | ||
id: 1, | ||
result: | ||
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000005a4d8d2f5de4d6ae29a91ee67e3adaedb53b0081000000000000000000000000a2c122be93b0074270ebee7f6b7292c7deb450470000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41000000000000000000000000000000000000000000000000000000000000000c76616c336e74696e2e6574680000000000000000000000000000000000000000' | ||
} | ||
}); | ||
}); | ||
|
||
await this.page.route('**/**/api/getBoxAction**', async (route) => { | ||
await route.fulfill({ | ||
status: 200, | ||
json: { | ||
tx: { | ||
to: '0x1572D48a52906B834FB236AA77831d669F6d87A1', | ||
chainId: 10, | ||
data: '0x62ae41170000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000743ec903fe6d05e73b19a6db807271bb66100e83000000000000000000000000743ec903fe6d05e73b19a6db807271bb66100e830000000000000000000000005a4d8d2f5de4d6ae29a91ee67e3adaedb53b0081000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000600000000000000000000000001572d48a52906b834fb236aa77831d669f6d87a10000000000000000000000005a4d8d2f5de4d6ae29a91ee67e3adaedb53b00810000000000000000000000000000000000000000000000000013d653ffed83d20000000000000000000000000000000000000000000000000000000000d59f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff85000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002b0b2c639c533813f4aa9d7837caf62653d097ff85000064420000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4bb7fde710000000000000000000000005a4d8d2f5de4d6ae29a91ee67e3adaedb53b0081000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000002435663566343537382d393236392d346633302d393963632d3130616231356565303630630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b812f17c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041a4f424514cb6555ebb4d92ab371a69d4c9a7f0aca26cd9e0ec6a17df684870e222cad453ac4a7796846396b024116d571988273057d5eaed123969b1cb24b5651c00000000000000000000000000000000000000000000000000000000000000', | ||
value: '5680381238874219n' | ||
}, | ||
tokenPayment: { | ||
amount: '5583680821887954n', | ||
tokenAddress: '0x0000000000000000000000000000000000000000', | ||
chainId: 10, | ||
isNative: true, | ||
name: 'Ether', | ||
symbol: 'ETH', | ||
decimals: 18 | ||
}, | ||
amountOut: { | ||
amount: '14000000n', | ||
tokenAddress: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', | ||
chainId: 10, | ||
isNative: false, | ||
name: 'USD Coin', | ||
symbol: 'USDC', | ||
decimals: 6 | ||
}, | ||
protocolFee: { | ||
amount: '96700416986265n', | ||
tokenAddress: '0x0000000000000000000000000000000000000000', | ||
chainId: 10, | ||
isNative: true, | ||
name: 'Ether', | ||
symbol: 'ETH', | ||
decimals: 18 | ||
}, | ||
applicationFee: { | ||
amount: '0n', | ||
tokenAddress: '0x0000000000000000000000000000000000000000', | ||
chainId: 10, | ||
isNative: true, | ||
name: 'Ether', | ||
symbol: 'ETH', | ||
decimals: 18 | ||
}, | ||
exchangeRate: 2507.3066399354684, | ||
estimatedTxTime: 0, | ||
estimatedPriceImpact: null | ||
} | ||
}); | ||
}); | ||
|
||
// Mocking server action to handle the pending transaction and mint the NFT without calling decent | ||
await this.page.route(`**/u/${builder.username}`, async (route) => { | ||
const method = route.request().method(); | ||
const body = route.request().postDataJSON()?.[0]; | ||
|
||
if (method === 'POST' && body?.pendingTransactionId) { | ||
if (isSuccess) { | ||
await route.fulfill({ | ||
status: 200, | ||
json: { success: true } | ||
}); | ||
} else { | ||
await route.fulfill({ | ||
status: 500, | ||
json: { success: false } | ||
}); | ||
} | ||
} else { | ||
await route.continue(); | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.