Skip to content

Commit 7c215fc

Browse files
authored
Merge pull request #47 from interledger/41-receiver-in-url---pp-as-url-to-show-payment-ui
Add pay with interledger when url is a PP
2 parents 56fb9cc + f00f403 commit 7c215fc

File tree

7 files changed

+314
-7
lines changed

7 files changed

+314
-7
lines changed

app/components/ui/button.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const buttonVariants = cva(
2121
default: 'w-48',
2222
sm: 'w-40',
2323
lg: 'w-48',
24-
xl: 'w-full',
24+
xl: 'w-56',
2525
icon: 'h-10 w-10'
2626
}
2727
},

app/components/ui/logo.tsx

+76
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,79 @@ export const Logo = (props: SVGProps<SVGSVGElement>) => {
9595
</svg>
9696
)
9797
}
98+
99+
export const PayWithInterledgerMark = (props: SVGProps<SVGSVGElement>) => {
100+
return (
101+
<svg
102+
xmlns="http://www.w3.org/2000/svg"
103+
fill="currentColor"
104+
viewBox="0 0 1020 253"
105+
{...props}
106+
>
107+
<path
108+
fill="currentColor"
109+
d="M10.069 167.271c-11.514-24.695-13.214-52.583-4.786-78.513C13.627 63.083 31.172 41.65 54.68 28.41l2.845 5.06C35.285 45.996 18.695 66.269 10.8 90.558c-7.972 24.528-6.363 50.898 4.529 74.266l-5.26 2.455v-.008Z"
110+
/>
111+
<path
112+
fill="currentColor"
113+
d="M114.969 252.76c-22.546 0-44.512-7.092-62.985-20.514-21.841-15.868-36.805-39.177-42.13-65.631l5.69-1.144c5.035 25.018 19.194 47.066 39.85 62.072 20.861 15.155 46.444 21.775 72.026 18.639l.705 5.765c-4.397.539-8.793.805-13.165.805l.009.008Z"
114+
/>
115+
<path
116+
fill="currentColor"
117+
d="M139.879 252.677c-4.131 0-8.279-.24-12.426-.722l.672-5.765c25.349 2.937 50.691-3.708 71.354-18.722 20.862-15.155 35.063-37.444 39.982-62.744l5.699 1.112c-5.201 26.751-20.215 50.309-42.272 66.336-18.456 13.413-40.455 20.505-63.001 20.505h-.008Z"
118+
/>
119+
<path
120+
fill="currentColor"
121+
d="m244.945 166.491-5.276-2.422c10.626-23.202 12.136-49.356 4.247-73.644-7.972-24.529-24.777-44.918-47.315-57.419l2.812-5.076c23.832 13.214 41.6 34.773 50.019 60.703 8.345 25.682 6.753 53.329-4.487 77.858Z"
122+
/>
123+
<path
124+
fill="currentColor"
125+
d="m58.08 33.064-3.956-4.247C74.057 10.237 100.046 0 127.312 0c27.266 0 52.798 10.062 72.657 28.328l-3.932 4.272c-18.78-17.279-43.193-26.793-68.725-26.793-25.533 0-50.376 9.68-69.231 27.257ZM62.37 219.406c-22.986-10.577-41.567-29.091-52.301-52.135l-.15-.315-.066-.34c-5.018-24.927-1.045-50.858 11.19-73.014l5.085 2.804c-11.513 20.845-15.296 45.241-10.65 68.716 10.186 21.651 27.688 39.037 49.322 49l-2.43 5.275v.009Z"
126+
/>
127+
<path
128+
fill="currentColor"
129+
d="m127.793 251.997-.34-.042c-25.259-2.928-48.692-14.723-65.98-33.205l4.24-3.965c16.266 17.395 38.298 28.527 62.063 31.364 23.733-2.995 45.681-14.268 61.84-31.77l4.264 3.94c-17.163 18.597-40.513 30.542-65.747 33.636l-.34.042Z"
130+
/>
131+
<path
132+
fill="currentColor"
133+
d="m192.976 218.974-2.464-5.259c21.576-10.095 38.962-27.614 49.008-49.331 4.487-23.5.547-47.863-11.099-68.633l5.068-2.837c12.377 22.073 16.524 47.97 11.671 72.922l-.066.34-.141.315c-10.593 23.119-29.049 41.758-51.969 52.492l-.008-.009ZM26.468 95.352l-5.765-.68c2.962-25.134 14.824-48.518 33.421-65.855l.257-.24.299-.175c22.156-12.475 48.045-16.714 72.897-11.92l-1.103 5.7c-23.392-4.513-47.755-.565-68.642 11.106-17.444 16.375-28.576 38.398-31.355 62.047l-.009.017Z"
134+
/>
135+
<path
136+
fill="currentColor"
137+
d="M228.064 94.689c-2.936-23.633-14.218-45.59-31.779-61.849-20.961-11.53-45.349-15.312-68.7-10.65l-1.136-5.7c24.819-4.951 50.725-.895 72.955 11.431l.307.166.258.233c18.713 17.22 30.741 40.53 33.86 65.647l-5.765.713v.009ZM107.462 229.293c-11.24 0-22.48-1.767-33.264-5.267a109.863 109.863 0 0 1-11.829-4.621l-.514-.24-.39-.415a107.382 107.382 0 0 1-8.527-10.336c-10.651-14.657-17.453-31.844-19.684-49.712l5.765-.722c2.107 16.897 8.544 33.156 18.614 47.017a102.919 102.919 0 0 0 7.681 9.365c3.46 1.568 7.05 2.961 10.676 4.139 16.524 5.367 34.201 6.421 51.131 3.045l1.136 5.698a106.224 106.224 0 0 1-20.804 2.049h.009Z"
138+
/>
139+
<path
140+
fill="currentColor"
141+
d="M147.245 229.16c-6.736 0-13.471-.63-20.099-1.908l1.095-5.698c16.723 3.218 34.176 2.115 50.476-3.177a102.405 102.405 0 0 0 11.281-4.413 103.083 103.083 0 0 0 7.233-8.876c10.212-14.052 16.673-30.543 18.697-47.689l5.766.681c-2.141 18.133-8.976 35.569-19.768 50.426a108.942 108.942 0 0 1-8.054 9.821l-.39.415-.514.24a108.482 108.482 0 0 1-12.468 4.919 107.704 107.704 0 0 1-33.263 5.268l.008-.009ZM33.602 159.763c-8.925-15.926-13.645-34.051-13.645-52.408 0-4.222.248-8.494.746-12.675l.067-.564.273-.498a108.85 108.85 0 0 1 7.192-11.306C38.886 67.655 53.13 55.876 69.437 48.228l2.463 5.259C56.48 60.712 43.01 71.86 32.93 85.72a102.733 102.733 0 0 0-6.528 10.203 103.19 103.19 0 0 0-.639 11.431c0 17.37 4.463 34.516 12.899 49.572l-5.068 2.836h.008Z"
142+
/>
143+
<path
144+
fill="currentColor"
145+
d="m72.796 52.823-4.263-3.94c12.384-13.413 28.162-23.5 45.631-29.174a108.686 108.686 0 0 1 12.285-3.21l.556-.108.556.108c4.371.846 8.734 1.966 12.973 3.343 17.229 5.6 32.84 15.503 45.142 28.651l-4.239 3.965c-11.638-12.434-26.403-21.8-42.703-27.1a103.976 103.976 0 0 0-11.721-3.06c-3.724.762-7.449 1.75-11.074 2.927-16.524 5.367-31.447 14.907-43.16 27.59l.017.008Z"
146+
/>
147+
<path
148+
fill="currentColor"
149+
d="m221.353 159.142-5.085-2.804c8.229-14.906 12.576-31.845 12.576-48.983 0-4.031-.241-8.096-.714-12.094a102.867 102.867 0 0 0-6.204-9.622c-10.212-14.052-23.899-25.3-39.576-32.525l2.43-5.276c16.582 7.64 31.049 19.527 41.841 34.383a110.203 110.203 0 0 1 6.851 10.692l.282.498.067.564c.547 4.413.829 8.917.829 13.372 0 18.116-4.595 36.026-13.297 51.786v.009ZM127.702 227.361l-.556-.108a107.664 107.664 0 0 1-52.475-26.412l3.924-4.28a101.919 101.919 0 0 0 49.09 24.885 101.87 101.87 0 0 0 48.933-25.209l3.957 4.247a107.677 107.677 0 0 1-52.309 26.769l-.556.108h-.008Z"
150+
/>
151+
<path
152+
fill="currentColor"
153+
d="M75.219 201.239a107.574 107.574 0 0 1-41.617-41.475l-.282-.498-.066-.564a107.61 107.61 0 0 1 8.909-58.074l5.284 2.414a101.794 101.794 0 0 0-8.495 54.374 101.824 101.824 0 0 0 39.095 38.747l-2.82 5.076h-.008Z"
154+
/>
155+
<path
156+
fill="currentColor"
157+
d="m47.646 102.395-5.699-1.112a107.634 107.634 0 0 1 26.586-52.4l.39-.415.514-.24a107.574 107.574 0 0 1 57.983-9.473l-.664 5.773a101.788 101.788 0 0 0-54.341 8.727 101.875 101.875 0 0 0-24.77 49.156v-.016Z"
158+
/>
159+
<path
160+
fill="currentColor"
161+
d="M206.928 101.864a101.757 101.757 0 0 0-25.093-48.983 101.809 101.809 0 0 0-54.399-8.361l-.697-5.765a107.553 107.553 0 0 1 58.05 9.091l.514.24.39.415a107.607 107.607 0 0 1 26.926 52.218l-5.691 1.153v-.008Z"
162+
/>
163+
<path
164+
fill="currentColor"
165+
d="m180.019 200.882-2.854-5.06a101.83 101.83 0 0 0 38.83-38.995 101.804 101.804 0 0 0-8.859-54.325l5.267-2.447a107.663 107.663 0 0 1 9.291 58.016l-.067.564-.274.498a107.658 107.658 0 0 1-41.334 41.749Z"
166+
/>
167+
<path
168+
fill="currentColor"
169+
d="M127.304 214.702c-18.233 0-36.242-4.654-52.085-13.463l-.299-.166-.249-.232c-13.538-12.426-23.716-28.286-29.423-45.864-5.632-17.345-6.768-35.909-3.293-53.694l.067-.34.14-.315C49.795 83.913 61.74 69.33 76.688 58.472c14.749-10.717 32.06-17.536 50.052-19.726l.341-.041.34.041c18.257 2.099 35.81 8.942 50.766 19.809 14.748 10.717 26.585 25.068 34.225 41.509l.141.315.067.34c3.649 18.009 2.563 36.822-3.153 54.399-5.632 17.337-15.627 33.031-28.9 45.374l-.248.233-.299.166c-16.001 9.033-34.226 13.811-52.715 13.811Zm-48.966-18.374c14.906 8.221 31.828 12.567 48.966 12.567 17.137 0 34.499-4.454 49.554-12.89 12.427-11.638 21.783-26.387 27.084-42.687 5.367-16.515 6.42-34.184 3.053-51.114-7.225-15.412-18.366-28.875-32.227-38.946-14.052-10.21-30.526-16.673-47.672-18.697-16.897 2.115-33.139 8.544-47 18.614-14.052 10.212-25.292 23.882-32.517 39.56-3.21 16.723-2.115 34.159 3.186 50.451 5.367 16.515 14.898 31.43 27.58 43.151l-.007-.009ZM310.21 185.354V71.537h12.667v113.817H310.21ZM357.584 185.354h-12.335v-82.238h12.169v5.757c8.884-4.935 17.378-7.399 25.491-7.399 10.966 0 18.34 2.961 22.123 8.884 3.782 5.923 5.674 16.449 5.674 31.579v43.425h-12.169v-43.093c0-11.406-1.128-19.211-3.368-23.442-2.248-4.222-7.051-6.329-14.392-6.329-3.509 0-7.209.523-11.099 1.56-3.89 1.045-6.885 2.057-8.967 3.044l-3.127 1.476v66.776ZM472.388 113.808h-26.155v39.311c0 9.431.681 15.628 2.058 18.589 1.368 2.962 4.628 4.438 9.788 4.438l14.641-.987.821 10.195c-7.35 1.202-12.94 1.808-16.781 1.808-8.552 0-14.475-2.082-17.76-6.246-3.293-4.164-4.935-12.111-4.935-23.849v-43.259h-11.68v-10.692h11.68V77.949h12.168v25.167h26.155v10.692ZM540.151 175.151l4.769-.489.332 9.705c-12.501 1.75-23.193 2.629-32.077 2.629-11.845 0-20.232-3.426-25.167-10.277-4.936-6.852-7.4-17.52-7.4-31.994 0-28.834 11.456-43.259 34.375-43.259 11.074 0 19.353 3.102 24.836 9.29 5.483 6.197 8.22 15.927 8.22 29.191l-.655 9.373h-54.275c0 9.1 1.643 15.844 4.936 20.232s9.016 6.578 17.187 6.578c8.171 0 16.474-.332 24.919-.987v.008Zm-4.438-35.694c0-10.087-1.618-17.212-4.853-21.385-3.235-4.164-8.502-6.246-15.785-6.246-7.284 0-12.775 2.198-16.45 6.578-3.674 4.388-5.566 11.406-5.673 21.053h42.761ZM563.999 185.354v-82.238h12.169v11.182c9.539-6.578 19.576-10.908 30.103-12.99v12.501c-4.604.879-9.407 2.248-14.392 4.114-4.994 1.867-8.801 3.509-11.431 4.936l-4.114 2.14v60.363h-12.335v-.008ZM618.606 185.354V67.257h12.335v118.097h-12.335ZM708.243 175.151l4.769-.489.332 9.705c-12.501 1.75-23.193 2.629-32.077 2.629-11.845 0-20.232-3.426-25.167-10.277-4.936-6.852-7.4-17.52-7.4-31.994 0-28.834 11.456-43.259 34.375-43.259 11.074 0 19.353 3.102 24.836 9.29 5.483 6.197 8.22 15.927 8.22 29.191l-.655 9.373h-54.275c0 9.1 1.643 15.844 4.936 20.232s9.017 6.578 17.187 6.578c8.171 0 16.474-.332 24.919-.987v.008Zm-4.438-35.694c0-10.087-1.618-17.212-4.853-21.385-3.235-4.164-8.502-6.246-15.785-6.246-7.284 0-12.775 2.198-16.45 6.578-3.674 4.388-5.566 11.406-5.673 21.053h42.761ZM795.25 67.257v118.097h-12.169v-5.591c-8.444 4.828-16.773 7.233-25.001 7.233-4.389 0-8.221-.547-11.514-1.642-3.293-1.095-6.362-3.069-9.208-5.923-5.922-5.922-8.884-16.855-8.884-32.815 0-15.96 2.655-27.465 7.98-34.541 5.317-7.076 14.119-10.609 26.395-10.609 6.363 0 13.098.713 20.232 2.14v-36.35h12.169Zm-42.761 107.57c1.974.772 4.521 1.153 7.648 1.153s6.636-.522 10.526-1.559c3.891-1.045 6.935-2.057 9.125-3.044l3.293-1.477v-55.759c-7.018-1.319-13.546-1.975-19.576-1.975-8.337 0-14.144 2.663-17.437 7.98-3.293 5.317-4.935 13.571-4.935 24.753 0 12.724 1.916 21.277 5.756 25.656 1.751 2.083 3.617 3.509 5.591 4.281l.009-.009ZM847.55 224.001c-13.156 0-22.347-1.784-27.548-5.342-5.209-3.567-7.814-10.062-7.814-19.494 0-4.496.987-8.146 2.962-10.941 1.974-2.795 5.317-5.948 10.037-9.456-3.069-2.082-4.604-5.865-4.604-11.348 0-1.866 1.369-5.317 4.114-10.361l1.477-2.629c-8.66-3.949-12.99-12.227-12.99-24.836 0-18.747 10.253-28.128 30.758-28.128 5.259 0 10.145.547 14.641 1.642l2.464.489 24.346-.655v10.527l-15.628-.332c3.616 3.616 5.425 9.1 5.425 16.449 0 10.311-2.547 17.519-7.648 21.625-5.102 4.115-13.132 6.172-24.098 6.172-2.961 0-5.649-.216-8.063-.655-1.974 4.827-2.961 7.955-2.961 9.373 0 3.401 1.045 5.508 3.127 6.329 2.082.821 8.387 1.236 18.913 1.236 10.527 0 18.092 1.643 22.696 4.936 4.603 3.293 6.909 9.705 6.909 19.244 0 17.437-12.169 26.155-36.515 26.155Zm-23.193-25.823c0 5.807 1.618 9.838 4.853 12.086 3.235 2.248 9.207 3.368 17.926 3.368 8.718 0 14.964-1.211 18.747-3.617 3.782-2.414 5.673-6.445 5.673-12.086 0-5.64-1.368-9.29-4.114-10.941-2.746-1.642-8.113-2.464-16.117-2.464l-17.76-.821c-3.617 2.63-6.064 4.936-7.316 6.91-1.261 1.974-1.892 4.496-1.892 7.565Zm1.153-68.584c0 6.47 1.452 11.074 4.355 13.82 2.903 2.746 7.706 4.114 14.392 4.114 6.686 0 11.456-1.368 14.309-4.114 2.854-2.737 4.28-7.374 4.28-13.894 0-6.52-1.426-11.157-4.28-13.895-2.853-2.737-7.623-4.114-14.309-4.114-6.686 0-11.489 1.402-14.392 4.197-2.903 2.796-4.355 7.433-4.355 13.895v-.009ZM952.981 175.151l4.77-.489.332 9.705c-12.501 1.75-23.193 2.629-32.077 2.629-11.846 0-20.232-3.426-25.168-10.277-4.935-6.852-7.399-17.52-7.399-31.994 0-28.834 11.456-43.259 34.375-43.259 11.074 0 19.352 3.102 24.835 9.29 5.483 6.197 8.221 15.927 8.221 29.191l-.655 9.373H905.94c0 9.1 1.642 15.844 4.935 20.232 3.293 4.388 9.017 6.578 17.188 6.578 8.17 0 16.474-.332 24.918-.987v.008Zm-4.438-35.694c0-10.087-1.617-17.212-4.852-21.385-3.235-4.164-8.503-6.246-15.786-6.246-7.283 0-12.774 2.198-16.449 6.578-3.675 4.388-5.566 11.406-5.674 21.053h42.761ZM976.83 185.354v-82.238h12.169v11.182c9.539-6.578 19.571-10.908 30.101-12.99v12.501c-4.6.879-9.41 2.248-14.39 4.114-4.994 1.867-8.802 3.509-11.431 4.936l-4.115 2.14v60.363H976.83v-.008Z"
170+
/>
171+
</svg>
172+
)
173+
}

app/root.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export default function App() {
7171
>
7272
<div
7373
className={cn(
74-
isEmbeded ? 'w-full h-full pt-4' : 'w-full h-full p-20'
74+
isEmbeded ? 'w-full h-full pt-4' : 'w-full h-full p-5 md:p-20'
7575
)}
7676
>
7777
<BackdropProvider>

app/routes/_index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default function Index() {
3636
})
3737

3838
return (
39-
<div className="flex justify-center flex-col h-full w-full gap-10 sm:px-20 px-4">
39+
<div className="flex justify-center flex-col h-full w-full gap-10 md:px-4">
4040
<Header />
4141
<div className="text-3xl">Pay anyone, anywhere in the world.</div>
4242
<Form method="POST" {...form.props}>

app/routes/pay-with-interledger.tsx

+220
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
import { conform, useForm } from '@conform-to/react'
2+
import { getFieldsetConstraint, parse } from '@conform-to/zod'
3+
import { type WalletAddress } from '@interledger/open-payments'
4+
import {
5+
type ActionFunctionArgs,
6+
json,
7+
redirect,
8+
type LoaderFunctionArgs
9+
} from '@remix-run/node'
10+
import { Form, useActionData, useLoaderData } from '@remix-run/react'
11+
import { z } from 'zod'
12+
import { Header } from '~/components/header'
13+
import Quote from '~/components/quoteDialog'
14+
import { Button } from '~/components/ui/button'
15+
import { Field } from '~/components/ui/form/form'
16+
import { PayWithInterledgerMark } from '~/components/ui/logo'
17+
import { useDialogContext } from '~/lib/context/dialog'
18+
import { fetchQuote, initializePayment } from '~/lib/open-payments.server'
19+
import { getValidWalletAddress } from '~/lib/validators.server'
20+
import { commitSession, destroySession, getSession } from '~/session'
21+
import { formatAmount } from '~/utils/helpers'
22+
23+
export async function loader({ request }: LoaderFunctionArgs) {
24+
const searchParams = new URL(request.url).searchParams
25+
const isQuote = searchParams.get('quote') || false
26+
const receiver = searchParams.get('receiver') || ''
27+
const session = await getSession(request.headers.get('Cookie'))
28+
29+
let receiverName = ''
30+
let receiveAmount = null
31+
let debitAmount = null
32+
33+
if (isQuote) {
34+
const quote = session.get('quote')
35+
const receiver = session.get('receiver-wallet-address')
36+
37+
if (quote === undefined) {
38+
throw new Error('Payment session expired.')
39+
}
40+
41+
receiverName =
42+
receiver.publicName === undefined ? 'Recepient' : receiver.publicName
43+
44+
receiveAmount = formatAmount({
45+
value: quote.receiveAmount.value,
46+
assetCode: quote.receiveAmount.assetCode,
47+
assetScale: quote.receiveAmount.assetScale
48+
})
49+
50+
debitAmount = formatAmount({
51+
value: quote.debitAmount.value,
52+
assetCode: quote.debitAmount.assetCode,
53+
assetScale: quote.debitAmount.assetScale
54+
})
55+
} else if (receiver !== '') {
56+
try {
57+
await getValidWalletAddress(receiver)
58+
} catch (error) {
59+
throw new Error(
60+
'Receiver Wallet Address is not valid. Please check and try again.'
61+
)
62+
}
63+
} else {
64+
return redirect('/', {
65+
headers: { 'Set-Cookie': await destroySession(session) }
66+
})
67+
}
68+
69+
return json({
70+
receiver: receiver,
71+
receiveAmount: receiveAmount ? receiveAmount.amountWithCurrency : null,
72+
debitAmount: debitAmount ? debitAmount.amountWithCurrency : null,
73+
receiverName: receiverName,
74+
isQuote: isQuote
75+
} as const)
76+
}
77+
78+
const schema = z.object({
79+
receiver: z.string(),
80+
walletAddress: z
81+
.string()
82+
.transform((val) => val.replace('$', 'https://'))
83+
.pipe(z.string().url({ message: 'The input is not a wallet address.' })),
84+
amount: z.coerce.number(),
85+
note: z.string().optional()
86+
})
87+
88+
export default function PayWithInterledger() {
89+
const data = useLoaderData<typeof loader>()
90+
const actionData = useActionData<typeof action>()
91+
const { setOpen } = useDialogContext()
92+
const [form, fields] = useForm({
93+
id: 'pay-with-interledger-form',
94+
constraint: getFieldsetConstraint(schema),
95+
lastSubmission: actionData,
96+
shouldRevalidate: 'onSubmit'
97+
})
98+
99+
data.isQuote ? setOpen(true) : setOpen(false)
100+
101+
return (
102+
<>
103+
<Header />
104+
<div className="flex h-full flex-col justify-center gap-10">
105+
<div className="mx-auto w-full max-w-sm">
106+
<Form method="POST" {...form.props}>
107+
<div className="flex flex-col gap-4">
108+
<Field
109+
label="Pay into Wallet Address"
110+
variant="highlight"
111+
{...conform.input(fields.receiver)}
112+
defaultValue={data.receiver}
113+
readOnly
114+
/>
115+
<Field
116+
label="Pay from"
117+
placeholder="Enter your wallet address"
118+
{...conform.input(fields.walletAddress)}
119+
errors={fields.walletAddress.errors}
120+
/>
121+
<Field
122+
label="Amount"
123+
placeholder="Amount"
124+
{...conform.input(fields.amount)}
125+
errors={fields.amount.errors}
126+
/>
127+
<Field
128+
label="Payment note"
129+
placeholder="Note"
130+
{...conform.input(fields.note)}
131+
errors={fields.note.errors}
132+
/>
133+
<div className="flex justify-center">
134+
<Button
135+
aria-label="pay"
136+
type="submit"
137+
name="intent"
138+
value="pay"
139+
size="xl"
140+
>
141+
<span className="text-md">Pay with</span>
142+
<PayWithInterledgerMark className="h-8 w-40 mx-2" />
143+
</Button>
144+
</div>
145+
</div>
146+
</Form>
147+
</div>
148+
<Quote
149+
receiverName={data.receiverName}
150+
receiveAmount={data.receiveAmount || ''}
151+
debitAmount={data.debitAmount || ''}
152+
/>
153+
</div>
154+
</>
155+
)
156+
}
157+
158+
export async function action({ request }: ActionFunctionArgs) {
159+
const session = await getSession(request.headers.get('Cookie'))
160+
161+
let walletAddress = {} as WalletAddress
162+
let receiverWalletAddress = {} as WalletAddress
163+
164+
const formData = await request.formData()
165+
const intent = formData.get('intent')
166+
167+
if (intent === 'pay') {
168+
const submission = await parse(formData, {
169+
schema: schema.superRefine(async (data, context) => {
170+
try {
171+
walletAddress = await getValidWalletAddress(data.walletAddress)
172+
receiverWalletAddress = await getValidWalletAddress(data.receiver)
173+
} catch (error) {
174+
context.addIssue({
175+
path: ['walletAddress'],
176+
code: z.ZodIssueCode.custom,
177+
message: 'Your wallet address is not valid.'
178+
})
179+
}
180+
}),
181+
async: true
182+
})
183+
184+
if (!submission.value || submission.intent !== 'submit') {
185+
return json(submission)
186+
}
187+
188+
const quote = await fetchQuote(submission.value, receiverWalletAddress)
189+
session.set('quote', quote)
190+
session.set('wallet-address', {
191+
walletAddress: walletAddress
192+
})
193+
session.set('receiver-wallet-address', receiverWalletAddress)
194+
195+
return redirect(`/pay-with-interledger?quote=true`, {
196+
headers: { 'Set-Cookie': await commitSession(session) }
197+
})
198+
} else if (intent === 'confirm') {
199+
const quote = session.get('quote')
200+
const walletAddressInfo = session.get('wallet-address')
201+
202+
if (quote === undefined || walletAddressInfo === undefined) {
203+
throw new Error('Payment session expired.')
204+
}
205+
206+
const grant = await initializePayment({
207+
walletAddress: walletAddressInfo.walletAddress.id,
208+
quote: quote
209+
})
210+
211+
session.set('payment-grant', grant)
212+
return redirect(grant.interact.redirect, {
213+
headers: { 'Set-Cookie': await commitSession(session) }
214+
})
215+
} else {
216+
return redirect('/', {
217+
headers: { 'Set-Cookie': await destroySession(session) }
218+
})
219+
}
220+
}

0 commit comments

Comments
 (0)