diff --git a/packages/react-kit/src/components/modal/components/Redeem/Confirmation/Confirmation.tsx b/packages/react-kit/src/components/modal/components/Redeem/Confirmation/Confirmation.tsx
index 6b079e5b0..bd6b3ff20 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/Confirmation/Confirmation.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/Confirmation/Confirmation.tsx
@@ -371,13 +371,13 @@ ${FormModel.formFields.phone.placeholder}: ${phoneField.value}`;
console.error("Error while redeeming", error);
// call postRedemptionSubmitted if error before the transaction is submitted OR postRedemptionConfirmed if error after
if (isTxPending) {
- postRedemptionSubmitted?.({
+ postRedemptionConfirmed?.({
redemptionInfo,
isError: true,
error: { ...error }
});
} else {
- postRedemptionConfirmed?.({
+ postRedemptionSubmitted?.({
redemptionInfo,
isError: true,
error: { ...error }
diff --git a/packages/react-kit/src/components/modal/components/Redeem/Confirmation/ConfirmationView.tsx b/packages/react-kit/src/components/modal/components/Redeem/Confirmation/ConfirmationView.tsx
index 7cf9cd6d6..8d86ec8a9 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/Confirmation/ConfirmationView.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/Confirmation/ConfirmationView.tsx
@@ -5,6 +5,7 @@ import Confirmation, { ConfirmationProps } from "./Confirmation";
import { NonModalProps, useNonModalContext } from "../../../nonModal/NonModal";
import Typography from "../../../../ui/Typography";
import { theme } from "../../../../../theme";
+import { useAccount } from "wagmi";
const colors = theme.colors.light;
@@ -29,6 +30,7 @@ export function ConfirmationView({
? getAddress(exchange.seller.assistant)
: "";
const dispatch = useNonModalContext();
+ const { address } = useAccount();
useEffect(() => {
dispatch({
payload: {
@@ -45,7 +47,13 @@ export function ConfirmationView({
}, [dispatch]);
return (
<>
- {exchange ? (
+ {!exchange ? (
+
Exchange could not be retrieved.
+ ) : exchange.buyer?.wallet?.toLowerCase() !== address?.toLowerCase() ? (
+ You do not own this exchange.
+ ) : exchange.state !== "COMMITTED" ? (
+ Invalid exchange state.
+ ) : (
- ) : (
- Exchange could not be retrieved
)}
>
);
diff --git a/packages/react-kit/src/components/widgets/redemption/RedemptionWidget.tsx b/packages/react-kit/src/components/widgets/redemption/RedemptionWidget.tsx
index f63edaf47..718208087 100644
--- a/packages/react-kit/src/components/widgets/redemption/RedemptionWidget.tsx
+++ b/packages/react-kit/src/components/widgets/redemption/RedemptionWidget.tsx
@@ -38,7 +38,7 @@ type RedemptionProps = {
type WidgetProps = RedemptionProps &
IpfsProviderProps &
Omit &
- RedemptionContextProps &
+ Omit &
EnvironmentProviderProps &
ConvertionRateProviderProps &
Omit;
diff --git a/packages/react-kit/src/components/widgets/redemption/provider/RedemptionProvider.tsx b/packages/react-kit/src/components/widgets/redemption/provider/RedemptionProvider.tsx
index 9c4db3175..02a59f42a 100644
--- a/packages/react-kit/src/components/widgets/redemption/provider/RedemptionProvider.tsx
+++ b/packages/react-kit/src/components/widgets/redemption/provider/RedemptionProvider.tsx
@@ -4,7 +4,7 @@ import { RedemptionContext, RedemptionContextProps } from "./RedemptionContext";
export function RedemptionProvider({
children,
...rest
-}: RedemptionContextProps & { children: ReactNode }) {
+}: Omit & { children: ReactNode }) {
const [widgetAction, setWidgetAction] = useState(rest.widgetAction);
return (
{
+ try {
+ const response = await fetch(input, init);
+ const isTrueOrOkOrYes = (s: string) =>
+ !!s && ["true", "ok", "yes"].includes(s.toLowerCase());
+ let responseBody;
+ try {
+ responseBody = await response.json();
+ } catch {}
+ const accepted =
+ response.ok && isTrueOrOkOrYes(responseBody?.accepted?.toString());
+ if (!accepted) {
+ throw new Error(responseBody?.reason?.toString() || response.statusText);
+ }
+ return {
+ accepted,
+ resume:
+ step !== "deliveryInfo"
+ ? undefined
+ : isTrueOrOkOrYes(responseBody?.resume?.toString()),
+ reason: ""
+ };
+ } catch (error) {
+ console.error(`An error happened when posting ${step}: ${error}`);
+ return {
+ accepted: false,
+ reason: (error as Error).toString(),
+ resume: step !== "deliveryInfo" ? undefined : false
+ };
+ }
+}
+
function postDeliveryInfoCallback(
postDeliveryInfoUrl: string,
postDeliveryInfoHeaders: { [key: string]: string } | undefined
@@ -60,43 +110,18 @@ function postDeliveryInfoCallback(
const signature = signer
? await signer.signMessage(JSON.stringify(message))
: undefined;
- try {
- const response = await fetch(postDeliveryInfoUrl, {
- method: "POST",
- body: JSON.stringify({
- message,
- signature
- }),
- headers: {
- "content-type": "application/json;charset=UTF-8",
- ...postDeliveryInfoHeaders
- }
- });
- const isTrueOrOkOrYes = (s: string) =>
- !!s && ["true", "ok", "yes"].includes(s.toLowerCase());
- let responseBody;
- try {
- responseBody = await response.json();
- } catch {}
- const accepted =
- response.ok && isTrueOrOkOrYes(responseBody?.accepted?.toString());
- const resume =
- accepted && isTrueOrOkOrYes(responseBody?.resume?.toString());
- const reason = accepted
- ? ""
- : responseBody?.reason?.toString() || response.statusText;
- return {
- accepted,
- resume,
- reason
- };
- } catch (error) {
- return {
- accepted: false,
- reason: (error as Error).toString(),
- resume: false
- };
- }
+ return fetchAndReadResponse("deliveryInfo", postDeliveryInfoUrl, {
+ method: "POST",
+ body: JSON.stringify({
+ step: "deliveryInfo",
+ message,
+ signature
+ }),
+ headers: {
+ "content-type": "application/json;charset=UTF-8",
+ ...postDeliveryInfoHeaders
+ }
+ }) as Promise;
};
}
@@ -104,21 +129,29 @@ function postRedemptionSubmittedCallback(
postRedemptionSubmittedUrl: string,
postRedemptionSubmittedHeaders: { [key: string]: string } | undefined
) {
- return async (message: RedeemTransactionSubmittedMessage) => {
+ return async (
+ message: RedeemTransactionSubmittedMessage
+ ): Promise => {
if (!postRedemptionSubmittedUrl) {
throw new Error(
"[postRedemptionSubmittedCallback] postRedemptionSubmittedUrl is not defined"
);
}
- // TODO: get response from server and throw exception in case of an error
- await fetch(postRedemptionSubmittedUrl, {
- method: "POST",
- body: JSON.stringify(message),
- headers: {
- "content-type": "application/json;charset=UTF-8",
- ...postRedemptionSubmittedHeaders
+ return fetchAndReadResponse(
+ "redemptionSubmitted",
+ postRedemptionSubmittedUrl,
+ {
+ method: "POST",
+ body: JSON.stringify({
+ step: "redemptionSubmitted",
+ message
+ }),
+ headers: {
+ "content-type": "application/json;charset=UTF-8",
+ ...postRedemptionSubmittedHeaders
+ }
}
- });
+ ) as Promise;
};
}
@@ -126,21 +159,29 @@ function postRedemptionConfirmedCallback(
postRedemptionConfirmedUrl: string,
postRedemptionConfirmedHeaders: { [key: string]: string } | undefined
) {
- return async (message: RedeemTransactionConfirmedMessage) => {
+ return async (
+ message: RedeemTransactionConfirmedMessage
+ ): Promise => {
if (!postRedemptionConfirmedUrl) {
throw new Error(
- "[postDeliveryInfoCallback] postDeliveryInfoUrl is not defined"
+ "[postRedemptionConfirmedCallback] postRedemptionConfirmedUrl is not defined"
);
}
- // TODO: get response from server and throw exception in case of an error
- await fetch(postRedemptionConfirmedUrl, {
- method: "POST",
- body: JSON.stringify(message),
- headers: {
- "content-type": "application/json;charset=UTF-8",
- ...postRedemptionConfirmedHeaders
+ return fetchAndReadResponse(
+ "redemptionConfirmed",
+ postRedemptionConfirmedUrl,
+ {
+ method: "POST",
+ body: JSON.stringify({
+ step: "redemptionConfirmed",
+ message
+ }),
+ headers: {
+ "content-type": "application/json;charset=UTF-8",
+ ...postRedemptionConfirmedHeaders
+ }
}
- });
+ ) as Promise;
};
}
diff --git a/packages/react-kit/src/stories/widgets/Redemption.stories.tsx b/packages/react-kit/src/stories/widgets/Redemption.stories.tsx
index c7c14068b..b47cd0074 100644
--- a/packages/react-kit/src/stories/widgets/Redemption.stories.tsx
+++ b/packages/react-kit/src/stories/widgets/Redemption.stories.tsx
@@ -95,7 +95,7 @@ RedemptionCallbacksRedeemConfirm.args = {
...Redemption.args,
showRedemptionOverview: false,
widgetAction: RedemptionWidgetAction.CONFIRM_REDEEM,
- exchangeId: "133",
+ exchangeId: "149",
deliveryInfo: process.env.REACT_APP_DELIVERY_ADDRESS_MOCK
? JSON.parse(process.env.REACT_APP_DELIVERY_ADDRESS_MOCK)
: undefined,
@@ -123,8 +123,56 @@ RedemptionCallbacksFailure2.args = {
...Redemption.args,
showRedemptionOverview: false,
widgetAction: RedemptionWidgetAction.REDEEM_FORM,
- exchangeId: "133",
+ exchangeId: "149",
postDeliveryInfoUrl: "http://localhost:3666/fail2",
postRedemptionSubmittedUrl: "http://localhost:3666/submitted",
postRedemptionConfirmedUrl: "http://localhost:3666/confirmed"
};
+
+export const RedemptionCallbacksFailure3: ComponentStory<
+ typeof RedemptionWidget
+> = Template.bind({});
+
+RedemptionCallbacksFailure3.args = {
+ ...Redemption.args,
+ showRedemptionOverview: false,
+ widgetAction: RedemptionWidgetAction.CONFIRM_REDEEM,
+ exchangeId: "149",
+ deliveryInfo: {
+ name: "TOTO",
+ streetNameAndNumber: "1 grand place",
+ city: "LILLE",
+ state: "NORD",
+ zip: "59000",
+ country: "FR",
+ email: "toto@mail.com",
+ phone: "+33123456789"
+ },
+ postDeliveryInfoUrl: "http://localhost:3666/deliveryInfo",
+ postRedemptionSubmittedUrl: "http://localhost:3666/fail3",
+ postRedemptionConfirmedUrl: "http://localhost:3666/confirmed"
+};
+
+export const RedemptionCallbacksFailure4: ComponentStory<
+ typeof RedemptionWidget
+> = Template.bind({});
+
+RedemptionCallbacksFailure4.args = {
+ ...Redemption.args,
+ showRedemptionOverview: false,
+ widgetAction: RedemptionWidgetAction.CONFIRM_REDEEM,
+ exchangeId: "149",
+ deliveryInfo: {
+ name: "TOTO",
+ streetNameAndNumber: "1 grand place",
+ city: "LILLE",
+ state: "NORD",
+ zip: "59000",
+ country: "FR",
+ email: "toto@mail.com",
+ phone: "+33123456789"
+ },
+ postDeliveryInfoUrl: "http://localhost:3666/deliveryInfo",
+ postRedemptionSubmittedUrl: "http://localhost:3666/submitted",
+ postRedemptionConfirmedUrl: "http://localhost:3666/fail4"
+};