Skip to content

Feature implementation from commits 2cc3802..c365984 #1

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

Open
wants to merge 45 commits into
base: feature-base-1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
fcf40ec
Merge pull request #157 from SmartInvoiceXYZ/develop
scottrepreneur Dec 19, 2023
fe8efd6
Merge pull request #212 from SmartInvoiceXYZ/develop
scottrepreneur May 15, 2024
43bbf6f
Merge pull request #215 from SmartInvoiceXYZ/develop
scottrepreneur May 16, 2024
a85d2ff
Merge pull request #217 from SmartInvoiceXYZ/develop
scottrepreneur May 25, 2024
b43cc71
Merge pull request #218 from SmartInvoiceXYZ/develop
scottrepreneur May 25, 2024
d681225
Merge pull request #220 from SmartInvoiceXYZ/develop
scottrepreneur May 31, 2024
1bd84b0
Merge pull request #223 from SmartInvoiceXYZ/develop
scottrepreneur Jun 17, 2024
797b1e5
Merge pull request #226 from SmartInvoiceXYZ/develop
scottrepreneur Jul 3, 2024
5fa29ac
Merge pull request #228 from SmartInvoiceXYZ/develop
wtfsayo Jul 3, 2024
6358090
Merge pull request #235 from SmartInvoiceXYZ/develop
wtfsayo Jul 16, 2024
59d0492
Merge pull request #238 from SmartInvoiceXYZ/develop
dan13ram Aug 12, 2024
c52b885
Merge pull request #251 from SmartInvoiceXYZ/develop
dan13ram Sep 27, 2024
2924563
Merge pull request #254 from SmartInvoiceXYZ/develop
dan13ram Oct 3, 2024
c3aa81e
Merge pull request #256 from SmartInvoiceXYZ/develop
dan13ram Oct 4, 2024
dd45eb4
Merge pull request #259 from SmartInvoiceXYZ/develop
dan13ram Oct 14, 2024
1b9fc32
Merge pull request #260 from SmartInvoiceXYZ/develop
dan13ram Oct 15, 2024
699973e
Merge pull request #272 from SmartInvoiceXYZ/develop
dan13ram Dec 1, 2024
feae756
Merge pull request #276 from SmartInvoiceXYZ/develop
dan13ram Dec 1, 2024
d39b807
Merge pull request #285 from SmartInvoiceXYZ/develop
dan13ram Dec 30, 2024
b8b6efd
Merge pull request #286 from SmartInvoiceXYZ/develop
dan13ram Dec 30, 2024
f775024
Merge pull request #287 from SmartInvoiceXYZ/develop
dan13ram Dec 30, 2024
5ecc577
Merge pull request #288 from SmartInvoiceXYZ/develop
dan13ram Jan 6, 2025
a2520fb
Merge pull request #289 from SmartInvoiceXYZ/develop
dan13ram Jan 9, 2025
784d858
Merge pull request #292 from SmartInvoiceXYZ/develop
dan13ram Mar 11, 2025
39e7848
Merge pull request #293 from SmartInvoiceXYZ/develop
dan13ram Mar 21, 2025
b90596c
Merge pull request #297 from SmartInvoiceXYZ/develop
dan13ram Mar 24, 2025
ed8765f
Merge pull request #301 from SmartInvoiceXYZ/develop
dan13ram Apr 2, 2025
27adccc
Merge pull request #306 from SmartInvoiceXYZ/develop
dan13ram May 28, 2025
b040cfa
Merge pull request #307 from SmartInvoiceXYZ/develop
dan13ram May 28, 2025
550d5cb
Merge pull request #308 from SmartInvoiceXYZ/develop
dan13ram May 30, 2025
46c494a
fixed env
dan13ram May 30, 2025
c493774
Merge pull request #309 from SmartInvoiceXYZ/develop
dan13ram May 30, 2025
5c5a417
fixed env
dan13ram May 30, 2025
949ba7b
Merge branch 'develop'
dan13ram May 30, 2025
735da6c
milestone details in pdf
dan13ram May 30, 2025
81c1225
fix: ensure result is a Date object in sevenDaysFromDate function
sshmm Jun 3, 2025
001ffbc
Merge pull request #311 from SmartInvoiceXYZ/fix_date_picker
dan13ram Jun 3, 2025
788ba3a
Update README.md
dan13ram Jun 9, 2025
8280241
refactor: update invoice query keys and enhance cache invalidation ac…
sshmm Jun 16, 2025
5652eaa
fix: increase default staleTime for queries to improve data freshness
sshmm Jun 20, 2025
5667121
increase stale time to 5 minutes
sshmm Jun 23, 2025
085df41
refactor: enhance invoice query key structure for improved cache inva…
sshmm Jun 23, 2025
e1bb06d
refactor: remove redundant cache invalidation for invoice details in …
sshmm Jun 23, 2025
76d8a53
refactor: implement server-side prefetching for invoice details and e…
sshmm Jun 23, 2025
c365984
refactor: minor fixes to query caching
dan13ram Jun 25, 2025
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
2 changes: 1 addition & 1 deletion apps/contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# @smartinvoicexyz/constracts
# @smartinvoicexyz/contracts

Solidity smart contracts of the Smart Invoice protocol.
19 changes: 13 additions & 6 deletions apps/dapp/next.config.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
const {
VERCEL_ENV = 'development',
VERCEL_URL,
VERCEL_GIT_COMMIT_REF,
VERCEL_PROJECT_PRODUCTION_URL,
} = process.env;

const protocol = VERCEL_ENV === 'development' ? 'http' : 'https';
const url = VERCEL_URL ?? 'localhost:3000';
const productionUrl = VERCEL_PROJECT_PRODUCTION_URL ?? url;
let url = VERCEL_URL ?? 'localhost:3000';

const baseUrl =
VERCEL_ENV === 'production'
? `${protocol}://${productionUrl}`
: `${protocol}://${url}`;
if (VERCEL_GIT_COMMIT_REF === 'main') {
url = `app.smartinvoice.xyz`;
} else if (VERCEL_GIT_COMMIT_REF === 'develop') {
url = `dev.smartinvoice.xyz`;
}

if (VERCEL_ENV === 'production') {
url = VERCEL_PROJECT_PRODUCTION_URL ?? url;
}

const baseUrl = `${protocol}://${url}`;

/** @type {import('next').NextConfig} */
const nextConfig = {
Expand Down
3 changes: 2 additions & 1 deletion apps/dapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"react-dom": "^19.1.0",
"react-hook-form": "^7.56.4",
"viem": "^2.30.2",
"wagmi": "^2.15.4"
"wagmi": "^2.15.4",
"@wagmi/core": "2.17.2"
},
"devDependencies": {
"@next/eslint-plugin-next": "^14.2.7",
Expand Down
69 changes: 41 additions & 28 deletions apps/dapp/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,57 @@ import {
theme,
} from '@smartinvoicexyz/ui';
import { wagmiConfig } from '@smartinvoicexyz/utils';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import {
HydrationBoundary,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { hashFn } from '@wagmi/core/query';
import { AppProps } from 'next/app';
import React from 'react';
import React, { useState } from 'react';
import { WagmiProvider } from 'wagmi';

import { OverlayContextProvider } from '../contexts/OverlayContext';

const queryClient = new QueryClient({
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 5000,
refetchInterval: 5000,
},
},
});

function App({ Component, pageProps }: AppProps) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
queryKeyHashFn: hashFn,
staleTime: 300000,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
},
},
}),
);

return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider avatar={AccountAvatar}>
<ChakraProvider theme={theme}>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<CSSReset />
<Global styles={globalStyles} />
<ErrorBoundary>
<OverlayContextProvider>
<Layout>
<Component {...pageProps} />
</Layout>
</OverlayContextProvider>
</ErrorBoundary>
</ChakraProvider>
<ReactQueryDevtools initialIsOpen={false} />
</RainbowKitProvider>
<HydrationBoundary state={pageProps.dehydratedState}>
<RainbowKitProvider avatar={AccountAvatar}>
<ChakraProvider theme={theme}>
<ColorModeScript
initialColorMode={theme.config.initialColorMode}
/>
<CSSReset />
<Global styles={globalStyles} />
<ErrorBoundary>
<OverlayContextProvider>
<Layout>
<Component {...pageProps} />
</Layout>
</OverlayContextProvider>
</ErrorBoundary>
</ChakraProvider>
<ReactQueryDevtools initialIsOpen={false} />
</RainbowKitProvider>
</HydrationBoundary>
</QueryClientProvider>
</WagmiProvider>
);
Expand Down
9 changes: 1 addition & 8 deletions apps/dapp/pages/create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,13 @@ import {
ProjectDetailsForm,
RegisterSuccess,
} from '@smartinvoicexyz/forms';
import {
QUERY_KEY_INVOICE_DETAILS,
useInvoiceCreate,
} from '@smartinvoicexyz/hooks';
import { useInvoiceCreate } from '@smartinvoicexyz/hooks';
import {
Container,
StepInfo,
useMediaStyles,
useToast,
} from '@smartinvoicexyz/ui';
import { useQueryClient } from '@tanstack/react-query';
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { Address, Hex } from 'viem';
Expand All @@ -30,7 +26,6 @@ import { useChainId } from 'wagmi';
export function CreateInvoiceEscrow() {
const invoiceForm = useForm();
const toast = useToast();
const queryClient = useQueryClient();
const [currentStep, setCurrentStep] = useState<number>(1);
const [txHash, setTxHash] = useState<Hex>();

Expand All @@ -57,8 +52,6 @@ export function CreateInvoiceEscrow() {
const onTxSuccess = (result: Address) => {
toast.success(TOASTS.useInvoiceCreate.success);
// invalidate cache
queryClient.invalidateQueries({ queryKey: [QUERY_KEY_INVOICE_DETAILS] });
queryClient.invalidateQueries({ queryKey: ['invoiceList'] });

setInvoiceId(result as Address);

Expand Down
57 changes: 43 additions & 14 deletions apps/dapp/pages/invoice/[chainId]/[invoiceId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
InvoiceButtonManager,
InvoicePaymentDetails,
} from '@smartinvoicexyz/forms';
import { useInvoiceDetails } from '@smartinvoicexyz/hooks';
import {
prefetchInvoiceDetails,
useInvoiceDetails,
} from '@smartinvoicexyz/hooks';
import {
Container,
InvoiceMetaDetails,
Expand All @@ -19,32 +22,58 @@ import {
parseChainId,
} from '@smartinvoicexyz/utils';
import _ from 'lodash';
import { GetServerSidePropsContext } from 'next';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { Hex, isAddress } from 'viem';
import { useAccount, useChainId, useSwitchChain } from 'wagmi';

import { useOverlay } from '../../../../contexts/OverlayContext';

export async function getServerSideProps(context: GetServerSidePropsContext) {
const { invoiceId: invId, chainId: urlChainId } = context.params as {
invoiceId: string;
chainId: string;
};

const invoiceId = _.toLower(String(invId)) as Hex;
const chainId = parseChainId(urlChainId);

// If chainId is undefined, return 404
if (!chainId) {
return {
notFound: true,
};
}

const chainLabel = chainLabelFromId(chainId);

// If the chain label doesn't match the URL chain ID, redirect to the correct URL
if (chainLabel !== urlChainId) {
return {
redirect: {
destination: `/invoice/${chainLabel}/${invoiceId}`,
permanent: false,
},
};
}

// Prefetch all invoice details
const dehydratedState = await prefetchInvoiceDetails(invoiceId, chainId);

return {
props: {
dehydratedState,
},
};
}

function ViewInvoice() {
const router = useRouter();
const { invoiceId: invId, chainId: urlChainId } = router.query;

const invoiceId = _.toLower(String(invId)) as Hex;
const invoiceChainId = parseChainId(urlChainId);

useEffect(() => {
if (invoiceId && invoiceChainId) {
const chainLabel = chainLabelFromId(invoiceChainId);
if (chainLabel !== urlChainId) {
router.replace({
pathname: `/invoice/${chainLabelFromId(invoiceChainId)}/${invoiceId}`,
query: undefined,
});
}
}
}, [invoiceId, urlChainId, invoiceChainId, router]);

const { invoiceDetails, isLoading } = useInvoiceDetails({
chainId: invoiceChainId,
address: invoiceId,
Expand Down
30 changes: 19 additions & 11 deletions packages/forms/src/AddMilestones.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@chakra-ui/react';
import { yupResolver } from '@hookform/resolvers/yup';
import {
QUERY_KEY_INVOICE_DETAILS,
createInvoiceDetailsQueryKey,
useAddMilestones,
} from '@smartinvoicexyz/hooks';
import { FormInvoice, InvoiceDetails } from '@smartinvoicexyz/types';
Expand Down Expand Up @@ -59,15 +59,23 @@ export function AddMilestones({
onClose: () => void;
}) {
const toast = useToast();
const { address, tokenMetadata, resolutionRate, total, deposited, amounts } =
_.pick(invoice, [
'address',
'tokenMetadata',
'resolutionRate',
'total',
'deposited',
'amounts',
]);
const {
address,
tokenMetadata,
resolutionRate,
total,
deposited,
amounts,
chainId,
} = _.pick(invoice, [
'address',
'tokenMetadata',
'resolutionRate',
'total',
'deposited',
'amounts',
'chainId',
]);

const localForm = useForm<Partial<FormInvoice>>({
resolver: yupResolver(addMilestonesSchema),
Expand Down Expand Up @@ -106,7 +114,7 @@ export function AddMilestones({
const onTxSuccess = () => {
// invalidate cache
queryClient.invalidateQueries({
queryKey: [QUERY_KEY_INVOICE_DETAILS],
queryKey: createInvoiceDetailsQueryKey(chainId, address),
});
// close modal
onClose();
Expand Down
4 changes: 2 additions & 2 deletions packages/forms/src/DepositFunds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from '@chakra-ui/react';
import { PAYMENT_TYPES, TOASTS } from '@smartinvoicexyz/constants';
import {
QUERY_KEY_INVOICE_DETAILS,
createInvoiceDetailsQueryKey,
useDeposit,
useTokenBalance,
} from '@smartinvoicexyz/hooks';
Expand Down Expand Up @@ -120,7 +120,7 @@ export function DepositFunds({
onClose();
// invalidate cache
queryClient.invalidateQueries({
queryKey: [QUERY_KEY_INVOICE_DETAILS],
queryKey: createInvoiceDetailsQueryKey(chainId, address),
});
};

Expand Down
4 changes: 2 additions & 2 deletions packages/forms/src/DepositTip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@chakra-ui/react';
import { PAYMENT_TYPES, TOASTS } from '@smartinvoicexyz/constants';
import {
QUERY_KEY_INVOICE_DETAILS,
createInvoiceDetailsQueryKey,
useDeposit,
useTokenBalance,
} from '@smartinvoicexyz/hooks';
Expand Down Expand Up @@ -114,7 +114,7 @@ export function DepositTip({
toast.success(TOASTS.useDeposit.success);
// invalidate cache
queryClient.invalidateQueries({
queryKey: [QUERY_KEY_INVOICE_DETAILS],
queryKey: createInvoiceDetailsQueryKey(chainId, address),
});
// close modal
onClose();
Expand Down
2 changes: 1 addition & 1 deletion packages/forms/src/InvoicePaymentDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const getDisputesWithResolution = (
return { dispute, resolution, resolutionDetails };
});

return _.reverse([...parsed]);
return [...parsed].reverse();
};

export function InvoicePaymentDetails({
Expand Down
30 changes: 18 additions & 12 deletions packages/forms/src/LockFunds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
import { yupResolver } from '@hookform/resolvers/yup';
import { KLEROS_GOOGLE_FORM } from '@smartinvoicexyz/constants';
import {
createInvoiceDetailsQueryKey,
FormLock,
QUERY_KEY_INVOICE_DETAILS,
useLock,
} from '@smartinvoicexyz/hooks';
import { InvoiceDetails } from '@smartinvoicexyz/types';
Expand Down Expand Up @@ -39,16 +39,22 @@ export function LockFunds({
const toast = useToast();
const queryClient = useQueryClient();

const { resolver, resolverFee, resolverInfo, tokenBalance } = _.pick(
invoice,
[
'resolver',
'resolverFee',
'resolverInfo',
'tokenBalance',
'resolutionRate',
],
);
const {
resolver,
resolverFee,
resolverInfo,
tokenBalance,
address,
chainId: invoiceChainId,
} = _.pick(invoice, [
'resolver',
'resolverFee',
'resolverInfo',
'tokenBalance',
'resolutionRate',
'address',
'chainId',
]);
const localForm = useForm<FormLock>({
resolver: yupResolver(lockFundsSchema),
});
Expand All @@ -58,7 +64,7 @@ export function LockFunds({

const onTxSuccess = () => {
queryClient.invalidateQueries({
queryKey: [QUERY_KEY_INVOICE_DETAILS],
queryKey: createInvoiceDetailsQueryKey(invoiceChainId, address),
});

onClose();
Expand Down
Loading