Skip to content

Commit 7168630

Browse files
committed
fix: getTokenPrice on GridItem
1 parent 963ad2c commit 7168630

File tree

12 files changed

+452
-135
lines changed

12 files changed

+452
-135
lines changed

app/src/context/evm/larskristo-hellheads/LarskristoHellheadsContext.types.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export type LarskristoHellheadsContextControllerProps = {
88

99
export type LarskristoHellheadsContextActions = {
1010
fetchContractValues: { isLoading: boolean };
11+
getTokenPrice: { isLoading: boolean };
1112
buyToken: { isPending: boolean; isConfirmed: boolean; transactionHash?: string };
1213
};
1314

@@ -19,8 +20,8 @@ export type LarskristoHellheadsContractValues = {
1920
export type TokenPrice = {
2021
rawValue: bigint;
2122
formattedValue: string;
22-
exchangeRate: number;
23-
exchangeRateFormatted: string;
23+
exchangeRate?: number;
24+
exchangeRateFormatted?: string;
2425
};
2526

2627
export type Royalty = {
@@ -38,7 +39,8 @@ export type LarskristoHellheadsContextType = {
3839
royalty?: Royalty;
3940
fetchContractValues: (address: string) => Promise<void>;
4041
ownerOf: (tokenId: number) => Promise<void>;
41-
getTokenPrice: (tokenId: number) => Promise<void>;
42+
getTokenPrice: (tokenId: number, options?: { excludeExchangeRate?: boolean }) => Promise<TokenPrice | undefined>;
4243
royaltyInfo: (tokenId: number) => Promise<void>;
4344
buyToken: (tokenId: number) => Promise<void>;
45+
connectedAccountIsOwner: () => boolean;
4446
};

app/src/context/evm/larskristo-hellheads/LarskristoHellheadsContextController.tsx

+88-57
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import React, { useEffect, useState } from "react";
2-
import { Client, getContract } from "viem";
3-
import { useAccount, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
4-
import { getClient } from "@wagmi/core";
2+
import { getContract } from "viem";
3+
import { useAccount } from "wagmi";
54
import { ethers } from "ethers";
65

76
import { LarsKristoHellheads__factory } from "providers/evm/contracts/larskristohellheads/LarsKristoHellheads__factory";
8-
import { useEvmWalletSelectorContext } from "../wallet-selector/useEvmWalletSelectorContext";
97
import currency from "providers/currency";
108
import { ZeroXAddress } from "../wallet-selector/EvmWalletSelectorContext.types";
9+
import evm from "providers/evm";
1110

1211
import { LarskristoHellheadsContext } from "./LarskristoHellheadsContext";
1312
import {
@@ -36,82 +35,117 @@ export const LarskristoHellheadsContextController = ({ children }: LarskristoHel
3635
isPending: false,
3736
isConfirmed: false,
3837
},
38+
getTokenPrice: {
39+
isLoading: false,
40+
},
3941
});
4042

41-
const { address: connectedAccountAddress, chainId } = useAccount();
42-
const { wagmiConfig } = useEvmWalletSelectorContext();
43-
const { data: hash, error: writeContractError, writeContract, isPending } = useWriteContract();
44-
const {
45-
isLoading: isConfirming,
46-
isSuccess: isConfirmed,
47-
data,
48-
} = useWaitForTransactionReceipt({
49-
hash,
50-
});
51-
52-
useEffect(() => {
53-
setActions((prev) => ({
54-
...prev,
55-
buyToken: {
56-
isPending: isPending || isConfirming,
57-
isConfirmed,
58-
transactionHash: data?.transactionHash,
59-
},
60-
}));
61-
}, [isPending, isConfirming, isConfirmed, data]);
43+
const { address: connectedAccountAddress } = useAccount();
44+
const { publicClient } = evm;
6245

63-
if (writeContractError) {
64-
console.error(writeContractError);
65-
}
46+
const getContractInstance = () =>
47+
getContract({
48+
address: contractAddress as ZeroXAddress,
49+
abi: LarsKristoHellheads__factory.abi,
50+
client: publicClient,
51+
});
6652

67-
const client = getClient(wagmiConfig, { chainId }) as Client;
53+
const connectedAccountIsOwner = () => owner === connectedAccountAddress;
6854

6955
const buyToken = async (tokenId: number) => {
7056
try {
71-
await writeContract({
72-
address: contractAddress as ZeroXAddress,
73-
abi: LarsKristoHellheads__factory.abi,
74-
functionName: "buyToken" as "buyToken",
75-
args: [BigInt(tokenId)],
57+
setActions((prev) => ({
58+
...prev,
59+
buyToken: {
60+
isPending: true,
61+
isConfirmed: false,
62+
},
63+
}));
64+
65+
const contract = getContractInstance();
66+
67+
const hash = await contract.write.buyToken([BigInt(tokenId)], {
7668
account: connectedAccountAddress as ZeroXAddress,
7769
value: tokenPrice?.rawValue!,
70+
chain: undefined,
7871
});
72+
73+
console.log({ hash });
74+
75+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
76+
77+
console.log({ receipt });
78+
79+
setActions((prev) => ({
80+
...prev,
81+
buyToken: {
82+
isPending: false,
83+
isConfirmed: true,
84+
transactionHash: receipt.transactionHash,
85+
},
86+
}));
7987
} catch (error) {
8088
console.error(error);
8189
}
8290
};
8391

84-
const getTokenPrice = async (tokenId: number) => {
92+
const getTokenPrice = async (tokenId: number, options?: { excludeExchangeRate?: boolean }) => {
8593
try {
86-
const contract = getContract({
87-
address: contractAddress as ZeroXAddress,
88-
abi: LarsKristoHellheads__factory.abi,
89-
client,
90-
});
94+
setActions((prev) => ({
95+
...prev,
96+
getTokenPrice: {
97+
isLoading: true,
98+
},
99+
}));
100+
101+
const contract = getContractInstance();
91102

92103
const rawValue = await contract.read.getTokenPrice([BigInt(tokenId)]);
93104
const formattedValue = ethers.formatEther(rawValue);
94-
const exchangeRate = await currency.getCoinCurrentPrice("ethereum", "usd");
95-
const exchangeRateFormatted = currency.formatFiatCurrency(Number(formattedValue) * exchangeRate);
96105

97-
setTokenPrice({
106+
const values: TokenPrice = {
98107
rawValue,
99108
formattedValue,
100-
exchangeRate,
101-
exchangeRateFormatted,
102-
});
109+
};
110+
111+
if (!options?.excludeExchangeRate) {
112+
const exchangeRate = await currency.getCoinCurrentPrice("ethereum", "usd");
113+
const exchangeRateFormatted = currency.formatFiatCurrency(Number(formattedValue) * exchangeRate);
114+
values.exchangeRate = exchangeRate;
115+
values.exchangeRateFormatted = exchangeRateFormatted;
116+
}
117+
118+
setTokenPrice(values);
119+
120+
setActions((prev) => ({
121+
...prev,
122+
getTokenPrice: {
123+
isLoading: false,
124+
},
125+
}));
126+
127+
return values;
103128
} catch (error) {
104129
console.error(error);
130+
setTokenPrice(undefined);
105131
}
132+
133+
setActions((prev) => ({
134+
...prev,
135+
getTokenPrice: {
136+
isLoading: false,
137+
},
138+
}));
139+
140+
return {
141+
rawValue: BigInt(0),
142+
formattedValue: "0.00",
143+
};
106144
};
107145

108146
const royaltyInfo = async (tokenId: number) => {
109147
try {
110-
const contract = getContract({
111-
address: contractAddress as ZeroXAddress,
112-
abi: LarsKristoHellheads__factory.abi,
113-
client,
114-
});
148+
const contract = getContractInstance();
115149

116150
const [, rawValue] = await contract.read.royaltyInfo([BigInt(tokenId), tokenPrice!.rawValue]);
117151
const percentage = Number(ethers.formatEther(rawValue)) / Number(ethers.formatEther(tokenPrice!.rawValue));
@@ -128,11 +162,7 @@ export const LarskristoHellheadsContextController = ({ children }: LarskristoHel
128162

129163
const ownerOf = async (tokenId: number) => {
130164
try {
131-
const contract = getContract({
132-
address: contractAddress as ZeroXAddress,
133-
abi: LarsKristoHellheads__factory.abi,
134-
client,
135-
});
165+
const contract = getContractInstance();
136166

137167
const result = await contract.read.ownerOf([BigInt(tokenId)]);
138168

@@ -154,7 +184,7 @@ export const LarskristoHellheadsContextController = ({ children }: LarskristoHel
154184
const contract = getContract({
155185
address: address as ZeroXAddress,
156186
abi: LarsKristoHellheads__factory.abi,
157-
client,
187+
client: publicClient,
158188
});
159189

160190
const [name, symbol] = await Promise.all([contract.read.name(), contract.read.symbol()]);
@@ -199,6 +229,7 @@ export const LarskristoHellheadsContextController = ({ children }: LarskristoHel
199229
tokenPrice,
200230
royaltyInfo,
201231
royalty,
232+
connectedAccountIsOwner,
202233
};
203234

204235
return <LarskristoHellheadsContext.Provider value={props}>{children}</LarskristoHellheadsContext.Provider>;

app/src/providers/evm/client.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import { createWalletClient, http } from "viem";
2-
import { sepolia } from "viem/chains";
1+
import { createPublicClient, createWalletClient, custom, http } from "viem";
2+
import { mainnet, sepolia } from "viem/chains";
33

4-
const client = createWalletClient({
5-
chain: sepolia,
6-
transport: http(),
4+
export const walletClient = createWalletClient({
5+
chain: process.env.NEXT_PUBLIC_DEFAULT_NETWORK_ENV === "testnet" ? sepolia : mainnet,
6+
transport: window !== undefined && (window as any).ethereum ? custom((window as any).ethereum) : http(),
77
});
88

9-
export default client;
9+
export const publicClient = createPublicClient({
10+
chain: process.env.NEXT_PUBLIC_DEFAULT_NETWORK_ENV === "testnet" ? sepolia : mainnet,
11+
transport: window !== undefined && (window as any).ethereum ? custom((window as any).ethereum) : http(),
12+
});

app/src/providers/evm/index.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import client from "./client";
1+
import { walletClient, publicClient } from "./client";
22

33
const getBlockExplorerUrl = () =>
44
process.env.NEXT_PUBLIC_DEFAULT_NETWORK_ENV === "testnet" ? "https://sepolia.etherscan.io" : "https://etherscan.io";
55

66
export default {
7-
client,
7+
walletClient,
8+
publicClient,
89
getBlockExplorerUrl,
910
};

app/src/theme/forms/_input-fields.scss

+1-3
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@ textarea.materialize-textarea {
3030
border-radius: $border-radius-input;
3131
padding: $input-padding;
3232
color: $input-text-color;
33-
// General Styles
3433
outline: none;
35-
36-
// Disabled input style
34+
background-color: $input-background;
3735

3836
&:disabled,
3937
&[readonly="readonly"] {

app/src/theme/variants/_svpervnder.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ body[data-theme="lease-721"] {
135135
--color-value-decrease-bright: #e76823;
136136

137137
// Forms
138-
--color-input-text: var(--color-background);
138+
--color-input-text: var(--color-typography-text);
139139
--color-input-text-disabled: var(--color-typography-description);
140140
--color-input-background: white;
141141
--color-input-background-disabled: var(--color-background-contrast);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { LarskristoHellheadsContextController } from "context/evm/larskristo-hellheads/LarskristoHellheadsContextController";
2+
3+
import { LatestCollectionProps } from "./LarsKristoHellheads.types";
4+
import { LarsKristoHellheads } from "./LarsKristoHellheads";
5+
6+
export const LarsKristoHellheadsContainer: React.FC<LatestCollectionProps> = () => (
7+
<LarskristoHellheadsContextController>
8+
<LarsKristoHellheads />
9+
</LarskristoHellheadsContextController>
10+
);

app/src/ui/svpervnder/collections/larskristo_hellheads/details-modal/DetailsModal.module.scss

+70-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828

2929
&__price-card,
3030
&__details-card,
31-
&__author-card {
31+
&__author-card,
32+
&__forge-card {
3233
margin-bottom: $space-default;
3334
}
3435

@@ -39,15 +40,81 @@
3940
}
4041
}
4142

43+
&__forge-card {
44+
&--row {
45+
display: flex;
46+
justify-content: space-between;
47+
margin-bottom: $space-s;
48+
49+
&-price,
50+
&-button {
51+
display: block;
52+
}
53+
54+
> div {
55+
display: flex;
56+
flex-direction: column;
57+
justify-content: center;
58+
}
59+
60+
&-img {
61+
img {
62+
width: 100%;
63+
height: auto;
64+
border-radius: $border-radius;
65+
}
66+
}
67+
68+
&-details {
69+
display: flex;
70+
71+
p {
72+
margin-right: $space-m;
73+
}
74+
}
75+
}
76+
}
77+
78+
&__set-for-sale {
79+
display: block;
80+
81+
&--form {
82+
position: relative;
83+
84+
&-price-field {
85+
padding-right: 80px !important;
86+
font-size: $font-size-text-lead;
87+
88+
&::placeholder {
89+
font-size: $font-size-text-lead;
90+
}
91+
}
92+
93+
&-currency {
94+
position: absolute;
95+
top: 7px;
96+
right: $space-default;
97+
z-index: $z-index-content;
98+
}
99+
}
100+
101+
&--info {
102+
border-radius: $border-radius;
103+
padding: $space-default;
104+
text-align: center;
105+
background-color: var(--color-background);
106+
}
107+
}
108+
42109
&__price-block {
43110
display: flex;
44111
justify-content: space-between;
45112

46113
&--success {
47-
margin-top: $space-default;
48114
padding: $space-default;
115+
text-align: center;
49116
color: var(--color-background);
50-
background-color: var(--color-primary-shade-low);
117+
background-color: var(--color-background);
51118
}
52119

53120
&--connect-wallet {

0 commit comments

Comments
 (0)